// Copyright 2012 The Closure Library Authors. All Rights Reserved. // Use of this source code is governed by the Apache License, Version 2.0. goog.provide('goog.result.chainTest'); goog.setTestOnly('goog.result.chainTest'); goog.require('goog.Timer'); goog.require('goog.result'); goog.require('goog.testing.MockClock'); goog.require('goog.testing.jsunit'); goog.require('goog.testing.recordFunction'); var givenResult, dependentResult, counter, actionCallback; var mockClock; function setUpPage() { mockClock = new goog.testing.MockClock(); mockClock.install(); } function setUp() { mockClock.reset(); givenResult = new goog.result.SimpleResult(); dependentResult = new goog.result.SimpleResult(); counter = new goog.testing.recordFunction(); actionCallback = goog.testing.recordFunction(function(result) { return dependentResult; }); } function tearDown() { givenResult = dependentResult = counter = null; } function tearDownPage() { mockClock.uninstall(); } // SYNCHRONOUS TESTS: function testChainWhenBothResultsSuccess() { var finalResult = goog.result.chain(givenResult, actionCallback); goog.result.wait(finalResult, counter); givenResult.setValue(1); dependentResult.setValue(2); assertSuccess(actionCallback, givenResult, 1); assertSuccess(counter, finalResult, 2); } function testChainWhenFirstResultError() { var finalResult = goog.result.chain(givenResult, actionCallback); goog.result.wait(finalResult, counter); givenResult.setError(4); assertNoCall(actionCallback); assertError(counter, finalResult, 4); } function testChainWhenSecondResultError() { var finalResult = goog.result.chain(givenResult, actionCallback); goog.result.wait(finalResult, counter); givenResult.setValue(1); dependentResult.setError(5); assertSuccess(actionCallback, givenResult, 1); assertError(counter, finalResult, 5); } function testChainCancelFirstResult() { var finalResult = goog.result.chain(givenResult, actionCallback); goog.result.wait(finalResult, counter); goog.result.cancelParentResults(finalResult); assertNoCall(actionCallback); assertTrue(givenResult.isCanceled()); assertTrue(finalResult.isCanceled()); } function testChainCancelSecondResult() { var finalResult = goog.result.chain(givenResult, actionCallback); goog.result.wait(finalResult, counter); givenResult.setValue(1); goog.result.cancelParentResults(finalResult); assertSuccess(actionCallback, givenResult, 1); assertTrue(dependentResult.isCanceled()); assertTrue(finalResult.isCanceled()); } function testDoubleChainCancel() { var intermediateResult = goog.result.chain(givenResult, actionCallback); var finalResult = goog.result.chain(intermediateResult, actionCallback); assertTrue(goog.result.cancelParentResults(finalResult)); assertTrue(finalResult.isCanceled()); assertTrue(intermediateResult.isCanceled()); assertFalse(givenResult.isCanceled()); assertFalse(goog.result.cancelParentResults(finalResult)); } function testCustomScope() { var scope = {}; var finalResult = goog.result.chain(givenResult, actionCallback, scope); goog.result.wait(finalResult, counter); givenResult.setValue(1); dependentResult.setValue(2); assertEquals(scope, actionCallback.popLastCall().getThis()); } // ASYNCHRONOUS TESTS: function testChainAsyncWhenBothResultsSuccess() { var finalResult = goog.result.chain(givenResult, actionCallback); goog.result.wait(finalResult, counter); goog.Timer.callOnce(function() { givenResult.setValue(1); }); mockClock.tick(); assertSuccess(actionCallback, givenResult, 1); goog.Timer.callOnce(function() { dependentResult.setValue(2); }); mockClock.tick(); assertSuccess(counter, finalResult, 2); } function testChainAsyncWhenFirstResultError() { var finalResult = goog.result.chain(givenResult, actionCallback); goog.result.wait(finalResult, counter); goog.Timer.callOnce(function() { givenResult.setError(6); }); mockClock.tick(); assertNoCall(actionCallback); assertError(counter, finalResult, 6); } function testChainAsyncWhenSecondResultError() { var finalResult = goog.result.chain(givenResult, actionCallback); goog.result.wait(finalResult, counter); goog.Timer.callOnce(function() { givenResult.setValue(1); }); mockClock.tick(); assertSuccess(actionCallback, givenResult, 1); goog.Timer.callOnce(function() { dependentResult.setError(7); }); mockClock.tick(); assertError(counter, finalResult, 7); } function testChainAsyncCancelFirstResult() { var finalResult = goog.result.chain(givenResult, actionCallback); goog.result.wait(finalResult, counter); goog.Timer.callOnce(function() { goog.result.cancelParentResults(finalResult); }); mockClock.tick(); assertNoCall(actionCallback); assertTrue(givenResult.isCanceled()); assertTrue(finalResult.isCanceled()); } function testChainAsyncCancelSecondResult() { var finalResult = goog.result.chain(givenResult, actionCallback); goog.result.wait(finalResult, counter); goog.Timer.callOnce(function() { givenResult.setValue(1); }); mockClock.tick(); assertSuccess(actionCallback, givenResult, 1); goog.Timer.callOnce(function() { goog.result.cancelParentResults(finalResult); }); mockClock.tick(); assertTrue(dependentResult.isCanceled()); assertTrue(finalResult.isCanceled()); } // HELPER FUNCTIONS: // Assert that the recordFunction was called once with an argument of // 'result' (the second argument) which has a state of SUCCESS and // a value of 'value' (the third argument). function assertSuccess(recordFunction, result, value) { assertEquals(1, recordFunction.getCallCount()); var res = recordFunction.popLastCall().getArgument(0); assertEquals(result, res); assertEquals(goog.result.Result.State.SUCCESS, res.getState()); assertEquals(value, res.getValue()); } // Assert that the recordFunction was called once with an argument of // 'result' (the second argument) which has a state of ERROR. function assertError(recordFunction, result, value) { assertEquals(1, recordFunction.getCallCount()); var res = recordFunction.popLastCall().getArgument(0); assertEquals(result, res); assertEquals(goog.result.Result.State.ERROR, res.getState()); assertEquals(value, res.getError()); } // Assert that the recordFunction wasn't called function assertNoCall(recordFunction) { assertEquals(0, recordFunction.getCallCount()); }