blob: 4c0e9faa5d6f690ac9e100d27bc417c3e68dc6ca [file] [log] [blame]
<!DOCTYPE html>
<html>
<!--
Copyright 2012 The Closure Library Authors. All Rights Reserved.
Use of this source code is governed by the Apache License, Version 2.0.
See the COPYING file for details.
-->
<head>
<title>Closure Unit Tests - goog.result.SimpleResult</title>
<script src="../base.js"></script>
<script>
goog.require('goog.Timer');
goog.require('goog.Promise');
goog.require('goog.Thenable');
goog.require('goog.result');
goog.require('goog.testing.MockClock');
goog.require('goog.testing.recordFunction');
goog.require('goog.testing.jsunit');
</script>
</head>
<body>
<script>
var result, mockClock, resultCallback;
function setUpPage() {
mockClock = new goog.testing.MockClock();
mockClock.install();
}
function setUp() {
mockClock.reset();
resultCallback = new goog.testing.recordFunction();
resultCallback1 = new goog.testing.recordFunction();
resultCallback2 = new goog.testing.recordFunction();
result = new goog.result.SimpleResult();
}
function tearDown() {
resultCallback = resultCallback1 = resultCallback2 = result = null;
}
function tearDownPage() {
mockClock.uninstall();
goog.dispose(mockClock);
}
function testHandlersCalledOnSuccess() {
result.wait(resultCallback1);
result.wait(resultCallback2);
assertEquals(goog.result.Result.State.PENDING, result.getState());
assertEquals(0, resultCallback1.getCallCount());
assertEquals(0, resultCallback2.getCallCount());
result.setValue(2);
assertEquals(goog.result.Result.State.SUCCESS, result.getState());
assertEquals(2, result.getValue());
assertEquals(1, resultCallback1.getCallCount());
assertEquals(1, resultCallback2.getCallCount());
var res1 = resultCallback1.popLastCall().getArgument(0);
assertObjectEquals(result, res1);
var res2 = resultCallback2.popLastCall().getArgument(0);
assertObjectEquals(result, res2);
}
function testCustomHandlerScope() {
result.wait(resultCallback1);
var scope = {};
result.wait(resultCallback2, scope);
result.setValue(2);
assertEquals(1, resultCallback1.getCallCount());
assertEquals(1, resultCallback2.getCallCount());
var this1 = resultCallback1.popLastCall().getThis();
assertObjectEquals(goog.global, this1);
var this2 = resultCallback2.popLastCall().getThis();
assertObjectEquals(scope, this2);
}
function testHandlersCalledOnError() {
result.wait(resultCallback1);
result.wait(resultCallback2);
assertEquals(goog.result.Result.State.PENDING, result.getState());
var error = "Network Error";
result.setError(error);
assertEquals(goog.result.Result.State.ERROR, result.getState());
assertEquals(error, result.getError());
assertEquals(1, resultCallback1.getCallCount());
assertEquals(1, resultCallback2.getCallCount());
var res1 = resultCallback1.popLastCall().getArgument(0);
assertObjectEquals(result, res1);
var res2 = resultCallback2.popLastCall().getArgument(0);
assertObjectEquals(result, res2);
}
function testAttachingHandlerOnSuccessfulResult() {
result.setValue(2);
assertEquals(goog.result.Result.State.SUCCESS, result.getState());
assertEquals(2, result.getValue());
// resultCallback should be called immediately on a resolved Result
assertEquals(0, resultCallback.getCallCount());
result.wait(resultCallback);
assertEquals(1, resultCallback.getCallCount());
var res = resultCallback.popLastCall().getArgument(0);
assertEquals(result, res);
}
function testAttachingHandlerOnErrorResult() {
var error = { code: -1, errorString: "Invalid JSON" };
result.setError(error);
assertEquals(goog.result.Result.State.ERROR, result.getState());
assertEquals(error, result.getError());
// resultCallback should be called immediately on a resolved Result
assertEquals(0, resultCallback.getCallCount());
result.wait(resultCallback);
assertEquals(1, resultCallback.getCallCount());
var res = resultCallback.popLastCall().getArgument(0);
assertEquals(result, res);
}
function testExceptionThrownOnMultipleSuccessfulResolutionAttempts() {
result.setValue(1);
assertEquals(goog.result.Result.State.SUCCESS, result.getState());
assertEquals(1, result.getValue());
// Try to set the value again
var e = assertThrows(goog.bind(result.setValue, result, 3));
assertTrue(e instanceof goog.result.SimpleResult.StateError);
}
function testExceptionThrownOnMultipleErrorResolutionAttempts() {
assertEquals(goog.result.Result.State.PENDING, result.getState());
result.setError(5);
assertEquals(goog.result.Result.State.ERROR, result.getState());
assertEquals(5, result.getError());
// Try to set error again
var e = assertThrows(goog.bind(result.setError, result, 4));
assertTrue(e instanceof goog.result.SimpleResult.StateError);
}
function testExceptionThrownOnSuccessThenErrorResolutionAttempt() {
assertEquals(goog.result.Result.State.PENDING, result.getState());
result.setValue(1);
assertEquals(goog.result.Result.State.SUCCESS, result.getState());
assertEquals(1, result.getValue());
// Try to set error after setting value
var e = assertThrows(goog.bind(result.setError, result, 3));
assertTrue(e instanceof goog.result.SimpleResult.StateError);
}
function testExceptionThrownOnErrorThenSuccessResolutionAttempt() {
assertEquals(goog.result.Result.State.PENDING, result.getState());
var error = "fail";
result.setError(error);
assertEquals(goog.result.Result.State.ERROR, result.getState());
assertEquals(error, result.getError());
// Try to set value after setting error
var e = assertThrows(goog.bind(result.setValue, result, 1));
assertTrue(e instanceof goog.result.SimpleResult.StateError);
}
function testSuccessfulAsyncResolution() {
result.wait(resultCallback);
assertEquals(goog.result.Result.State.PENDING, result.getState());
goog.Timer.callOnce(function() {
result.setValue(1);
});
mockClock.tick();
assertEquals(1, resultCallback.getCallCount());
var res = resultCallback.popLastCall().getArgument(0);
assertEquals(goog.result.Result.State.SUCCESS, res.getState());
assertEquals(1, res.getValue());
}
function testErrorAsyncResolution() {
result.wait(resultCallback);
assertEquals(goog.result.Result.State.PENDING, result.getState());
var error = 'Network failure';
goog.Timer.callOnce(function() {
result.setError(error);
});
mockClock.tick();
assertEquals(1, resultCallback.getCallCount());
var res = resultCallback.popLastCall().getArgument(0);
assertEquals(goog.result.Result.State.ERROR, res.getState());
assertEquals(error, res.getError());
}
function testCancelStateAndReturn() {
assertFalse(result.isCanceled());
var canceled = result.cancel();
assertTrue(result.isCanceled());
assertEquals(goog.result.Result.State.ERROR, result.getState());
assertTrue(result.getError() instanceof goog.result.Result.CancelError);
assertTrue(canceled);
}
function testErrorHandlersFireOnCancel() {
result.wait(resultCallback);
result.cancel();
assertEquals(1, resultCallback.getCallCount());
var lastCall = resultCallback.popLastCall();
var res = lastCall.getArgument(0);
assertEquals(goog.result.Result.State.ERROR, res.getState());
assertTrue(res.getError() instanceof goog.result.Result.CancelError);
}
function testCancelAfterSetValue() {
// cancel after setValue/setError => no-op
result.wait(resultCallback);
result.setValue(1);
assertEquals(goog.result.Result.State.SUCCESS, result.getState());
assertEquals(1, result.getValue());
assertEquals(1, resultCallback.getCallCount());
result.cancel();
assertEquals(goog.result.Result.State.SUCCESS, result.getState());
assertEquals(1, result.getValue());
assertEquals(1, resultCallback.getCallCount());
}
function testSetValueAfterCancel() {
// setValue/setError after cancel => no-op
result.wait(resultCallback);
result.cancel();
assertTrue(result.isCanceled());
assertTrue(result.getError() instanceof goog.result.Result.CancelError);
result.setValue(1);
assertTrue(result.isCanceled());
assertTrue(result.getError() instanceof goog.result.Result.CancelError);
result.setError(3);
assertTrue(result.isCanceled());
assertTrue(result.getError() instanceof goog.result.Result.CancelError);
}
function testFromResolvedPromise() {
var promise = goog.Promise.resolve('resolved');
result = goog.result.SimpleResult.fromPromise(promise);
assertEquals(goog.result.Result.State.PENDING, result.getState());
mockClock.tick();
assertEquals(goog.result.Result.State.SUCCESS, result.getState());
assertEquals('resolved', result.getValue());
assertEquals(undefined, result.getError());
}
function testFromRejectedPromise() {
var promise = goog.Promise.reject('rejected');
result = goog.result.SimpleResult.fromPromise(promise);
assertEquals(goog.result.Result.State.PENDING, result.getState());
mockClock.tick();
assertEquals(goog.result.Result.State.ERROR, result.getState());
assertEquals(undefined, result.getValue());
assertEquals('rejected', result.getError());
}
function testThen() {
var value1, value2;
result.then(function(val1) {
return value1 = val1;
}).then(function(val2) {
value2 = val2;
});
result.setValue('done');
assertUndefined(value1);
assertUndefined(value2);
mockClock.tick();
assertEquals('done', value1);
assertEquals('done', value2);
}
function testThen_reject() {
var value, reason;
result.then(
function(v) { value = v; },
function(r) { reason = r; });
result.setError(new Error('oops'));
assertUndefined(value);
mockClock.tick();
assertUndefined(value);
assertEquals('oops', reason.message);
}
function testPromiseAll() {
var promise = goog.Promise.resolve('promise');
goog.Promise.all([result, promise]).then(function(values) {
assertEquals(2, values.length);
assertEquals('result', values[0]);
assertEquals('promise', values[1]);
});
result.setValue('result');
mockClock.tick();
}
function testResolvingPromiseBlocksResult() {
var value;
goog.Promise.resolve('promise').then(function(value) {
result.setValue(value);
});
result.wait(function(r) {
value = r.getValue();
});
assertUndefined(value);
mockClock.tick();
assertEquals('promise', value);
}
function testRejectingPromiseBlocksResult() {
var err;
goog.Promise.reject(new Error('oops')).then(
undefined /* opt_onResolved */,
function(reason) {
result.setError(reason);
});
result.wait(function(r) {
err = r.getError();
});
assertUndefined(err);
mockClock.tick();
assertEquals('oops', err.message);
}
function testPromiseFromCanceledResult() {
var reason;
result.cancel();
result.then(
undefined /* opt_onResolved */,
function(r) {
reason = r;
});
mockClock.tick();
assertTrue(reason instanceof goog.Promise.CancellationError);
}
function testThenableInterface() {
assertTrue(goog.Thenable.isImplementedBy(result));
}
</script>
</body>
</html>