123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418 |
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="utf-8">
- <meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
- <link rel="stylesheet" href="test.css">
- <title>Zepto Deferred unit tests</title>
- <script src="../vendor/evidence.js"></script>
- <script src="evidence_runner.js"></script>
- <script>
- // avoid caching
- (function(){
- function load(scripts){
- scripts.split(' ').forEach(function(script){
- document.write('<script src="../src/'+script+'.js?'+(+new Date)+'"></scr'+'ipt>')
- })
- }
- load('zepto callbacks deferred')
- })()
- </script>
- </head>
- <body>
- <h1>Zepto Deferred unit tests</h1>
- <p id="results">
- Running… see browser console for results
- </p>
- <script>
- (function(){
- var promiseFns = "resolve reject notify resolveWith rejectWith notifyWith done fail progress always".split(/\s+/),
- deferredFns = "state always then promise done fail progress".split(/\s+/)
- $.each(['', 'WithNew'], function(_, withNew) {
- var createDeferred = function(fn) {
- return withNew ? new $.Deferred(fn) : $.Deferred(fn)
- }
- Evidence('ZeptoDeferredTest' + withNew, {
- testSuccessOnResolve: function(t) {
- var called = 0
- createDeferred().resolve().done(function() {
- t.assertEqual(0, called++)
- t.assertEqual("resolved", this.state(), "Deferred is resolved (state)")
- }).fail(function() {
- t.fail("Error on resolve")
- }).always(function() {
- t.assertEqual(1, called++)
- })
- t.assertEqual(2, called, "Success and Always handlers called")
- },
- testErrorOnReject: function(t) {
- var called = 0
- createDeferred().reject().done(function() {
- t.fail("Success on reject")
- }).fail(function() {
- t.assertEqual(0, called++)
- t.assertEqual( "rejected", this.state(), "Deferred is rejected (state)" )
- }).always(function() {
- t.assertEqual(1, called++)
- })
- t.assertEqual(2, called, "Error and Always handlers called")
- },
- testDeferredFnContextIsArg1: function(t) {
- var called
- createDeferred(function(defer) {
- called = true
- t.assertEqual(defer, this, "Defer passed as this & first argument")
- })
- t.assertTrue(called, "Deferred function was called")
- },
- testDoneWithResolvedValue: function(t) {
- var called
- createDeferred(function(defer) {
- defer.resolve("done")
- }).done(function(value) {
- called = true
- t.assertEqual("done", value, "Done() received resolved value")
- })
- t.assertTrue(called, "Deferred function was called")
- },
- testNoDoneOnReject: function(t) {
- var called = false
- createDeferred(function(defer) {
- defer.reject("done")
- }).done(function(value) {
- called = true
- t.fail("done() should not be called on error")
- })
- t.assertFalse(called, "Deferred function was called")
- },
- testIsChainable: function(t) {
- var deferred = createDeferred(), each = $.each
- // Ensure that each of the following methods are chainable
- each(promiseFns, function(_, method) {
- var object = {
- m: deferred[method]
- }
- t.assertEqual(object, object.m(), method + " is chainable" )
- })
- },
- testFilteringDone: function(t) {
- var value1, value2, value3,
- defer = createDeferred(),
- piped = defer.then(function(a, b) {
- return a * b
- })
- piped.done(function(result) { value3 = result })
- defer.done(function(a, b) { value1 = a, value2 = b }).resolve(2, 3)
- t.assertEqual(2, value1, "first resolve value ok")
- t.assertEqual(3, value2, "second resolve value ok")
- t.assertEqual(6, value3, "result of filter ok")
- createDeferred().reject().then(function() { t.fail("then should not be called on reject") })
- createDeferred().resolve().then($.noop).done(function(value) {
- t.assertEqual(undefined, value, "then done callback can return undefined/null")
- })
- },
- testSamePromise: function(t) {
- createDeferred(function(defer) {
- var promise = defer.promise()
- t.assertEqual(promise, defer.promise(), "promise is always the same")
- })
- },
- testExtendNonObject: function(t) {
- createDeferred(function(defer) {
- var func = function() {},
- funcPromise = defer.promise(func)
- t.assertEqual(func, funcPromise, "non objects get extended")
- })
- },
- testPromiseOnlyFns: function(t) {
- createDeferred(function(defer) {
- var promise = defer.promise()
- $.each(promise, function(key) {
- var type = typeof promise[key]
- t.assertEqual("function", type, key + " is a function (" + type + ")")
- t.assertTrue(deferredFns.indexOf(key) > -1, key + "() is a promise function")
- })
- })
- },
- testExtendObjectWithPromiseFns: function(t) {
- createDeferred(function(defer) {
- var promise = defer.promise(),
- func = function() {},
- funcPromise = defer.promise(func),
- fns = 0
- $.each(promise, function(key) {
- ++fns
- t.assertEqual(promise[key], func[key], key + " is the same")
- })
- t.assertEqual(deferredFns.length, fns, "should have all of the Deferred functions")
- })
- },
- testFilteringReject: function(t) {
- var value1, value2, value3,
- defer = createDeferred(),
- piped = defer.then(null, function(a, b) {
- return a * b
- })
- piped.fail(function(result) { value3 = result })
- defer.fail(function( a, b ) { value1 = a, value2 = b })
- defer.reject( 2, 3 )
- t.assertEqual(2, value1, "first reject value ok")
- t.assertEqual(3, value2, "second reject value ok")
- t.assertEqual(6, value3, "result of filter ok")
- createDeferred().resolve().then(null, function() {
- t.fail("then should not be called on resolve")
- })
- createDeferred().reject().then(null, $.noop).fail(function(value) {
- t.assertEqual(undefined, value, "then fail callback can return undefined/null")
- })
- },
- testFilteringProgress: function(t) {
- var value1, value2, value3,
- defer = createDeferred(),
- piped = defer.then(null, null, function(a, b) {
- return a * b
- })
- piped.progress(function(result) { value3 = result })
- defer.progress(function(a, b) { value1 = a, value2 = b })
- defer.notify( 2, 3 )
- t.assertEqual(2, value1, "first progress value ok")
- t.assertEqual(3, value2, "second progress value ok")
- t.assertEqual(6, value3, "result of filter ok")
- },
- testThenDeferredDone: function(t) {
- var value1, value2, value3,
- defer = createDeferred(),
- piped = defer.then(function(a, b) {
- return createDeferred(function(defer) {
- defer.reject(a * b)
- })
- })
- piped.fail(function(result) { value3 = result })
- defer.done(function(a, b) { value1 = a, value2 = b })
- defer.resolve(2, 3)
- t.assertEqual(2, value1, "first resolve value ok")
- t.assertEqual(3, value2, "second resolve value ok")
- t.assertEqual(6, value3, "result of filter ok")
- },
- testThenDeferredFail: function(t) {
- var value1, value2, value3,
- defer = createDeferred(),
- piped = defer.then(null, function(a, b) {
- return createDeferred(function(defer) {
- defer.resolve(a * b)
- })
- })
- piped.done(function(result) { value3 = result })
- defer.fail(function(a, b) { value1 = a, value2 = b })
- defer.reject(2, 3)
- t.assertEqual(2, value1, "first reject value ok")
- t.assertEqual(3, value2, "second reject value ok")
- t.assertEqual(6, value3, "result of filter ok")
- },
- testThenDeferredProgress: function(t) {
- var value1, value2, value3,
- defer = createDeferred(),
- piped = defer.then(null, null, function(a, b) {
- return createDeferred(function(defer) {
- defer.resolve( a * b )
- })
- })
- piped.done(function(result) { value3 = result })
- defer.progress(function(a, b) { value1 = a, value2 = b })
- defer.notify(2, 3)
- t.assertEqual(2, value1, "first progress value ok")
- t.assertEqual(3, value2, "second progress value ok")
- t.assertEqual(6, value3, "result of filter ok")
- },
- testThenWithContext: function(t) {
- var defer, piped, defer2, piped2, context = {}
- createDeferred().resolveWith(context, [2]).then(function(value) {
- return value * 3
- }).done(function(value) {
- t.assertEqual(context, this, "custom context correctly propagated")
- t.assertEqual(6, value, "proper value received")
- })
- createDeferred().resolve().then(function() {
- return createDeferred().resolveWith(context)
- }).done(function() {
- t.assertEqual(context, this, "custom context of returned deferred correctly propagated")
- })
- defer = createDeferred()
- piped = defer.then(function(value) {
- return value * 3
- })
- defer.resolve( 2 )
- piped.done(function(value) {
- t.assertEqual(piped, this, "default context gets updated to latest promise in the chain")
- t.assertEqual(6, value, "proper value received")
- })
- defer2 = createDeferred()
- piped2 = defer2.then()
- defer2.resolve(2)
- piped2.done(function(value) {
- t.assertEqual(piped2, this, "default context gets updated to latest promise in the chain (without passing function)")
- t.assertEqual(2, value, "proper value received (without passing function)")
- })
- },
- testWhenValueCreatesPromise: function(t) {
- $.each({
- "an empty string": "",
- "a non-empty string": "some string",
- "zero": 0,
- "a number other than zero": 1,
- "true": true,
- "false": false,
- "null": null,
- "undefined": undefined,
- "a plain object": {},
- "an array": [ 1, 2, 3 ]
- }, function(message, value) {
- t.assertTrue(
- $.isFunction($.when(value).done(function(resolveValue) {
- t.assertEqual(window, this, "Context is the global object with " + message)
- t.assertEqual(value, resolveValue, "Test the promise was resolved with " + message)
- }).promise), "Test " + message + " triggers the creation of a new Promise")
- })
- },
- testWhenNoValueCreatesPromise: function(t) {
- t.assertTrue(
- $.isFunction($.when().done(function(resolveValue) {
- t.assertEqual(window, this, "Context is the global object")
- t.assertEqual(undefined, resolveValue, "Test the promise was resolved with no parameter")
- }).promise), "Test calling when with no parameter triggers the creation of a new Promise")
- },
- testWhenPropagatesContext: function(t) {
- var context = {}, called = false
- $.when(createDeferred().resolveWith(context)).done(function() {
- called = true
- t.assertEqual(context, this, "when( promise ) propagates context")
- })
- t.assertTrue(called, "called done() after resolveWith")
- },
- testWhenDoneOnlyPromise: function(t) {
- var cache
- $.each([1,2,3], function(_, i) {
- $.when(cache || createDeferred(function() {
- this.resolve(i)
- })).done(function(value) {
- t.assertEqual(1, value, "Function executed" + (i > 1 ? " only once" : ""))
- cache = value
- })
- })
- },
- testWhenJoined: function(t) {
- var deferreds = {
- value: 1,
- success: createDeferred().resolve(1),
- error: createDeferred().reject(0),
- futureSuccess: createDeferred().notify(true),
- futureError: createDeferred().notify(true),
- notify: createDeferred().notify(true)
- },
- willSucceed = {
- value: true,
- success: true,
- futureSuccess: true
- },
- willError = {
- error: true,
- futureError: true
- },
- willNotify = {
- futureSuccess: true,
- futureError: true,
- notify: true
- }
- $.each(deferreds, function(id1, defer1) {
- $.each(deferreds, function(id2, defer2) {
- var shouldResolve = willSucceed[id1] && willSucceed[id2],
- shouldError = willError[id1] || willError[id2],
- shouldNotify = willNotify[id1] || willNotify[id2],
- expected = shouldResolve ? [1, 1] : [0, undefined],
- expectedNotify = shouldNotify && [willNotify[id1], willNotify[id2]],
- code = id1 + '/' + id2,
- context1 = defer1 && $.isFunction(defer1.promise) ? defer1.promise() : undefined,
- context2 = defer2 && $.isFunction(defer2.promise) ? defer2.promise() : undefined
- $.when(defer1, defer2).done(function(a, b) {
- if (shouldResolve) {
- t.assertEqual(expected[0], a, code + " => resolve" )
- t.assertEqual(expected[1], b, code + " => resolve" )
- t.assertIdentical(context1, this[0], code + " => first context OK")
- t.assertIdentical(context2, this[1], code + " => second context OK")
- } else {
- t.fail(code + " => resolve")
- }
- }).fail(function(a, b) {
- if (shouldError) {
- t.assertIdentical(expected[0], a, code + " => reject")
- t.assertIdentical(expected[1], b, code + " => reject")
- } else {
- t.fail(code + " => reject")
- }
- }).progress(function(a, b) {
- t.assertIdentical( expectedNotify[0], a, code + " => progress")
- t.assertIdentical( expectedNotify[1], b, code + " => progress")
- t.assertIdentical(expectedNotify[0] ? context1 : undefined, this[0], code + " => first context OK")
- t.assertIdentical(expectedNotify[1] ? context2 : undefined, this[1], code + " => second context OK")
- })
- })
- })
- deferreds.futureSuccess.resolve(1)
- deferreds.futureError.reject(0)
- }
- })
- })
- })()
- </script>
- </body>
- </html>
|