callbacks.html 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="utf-8">
  5. <meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
  6. <link rel="stylesheet" href="test.css">
  7. <title>Zepto Callbacks unit tests</title>
  8. <script src="../vendor/evidence.js"></script>
  9. <script src="evidence_runner.js"></script>
  10. <script>
  11. // avoid caching
  12. (function(){
  13. function load(scripts){
  14. scripts.split(' ').forEach(function(script){
  15. document.write('<script src="../src/'+script+'.js?'+(+new Date)+'"></scr'+'ipt>')
  16. })
  17. }
  18. load('zepto callbacks')
  19. })()
  20. </script>
  21. </head>
  22. <body>
  23. <h1>Zepto Callbacks unit tests</h1>
  24. <p id="results">
  25. Running… see browser console for results
  26. </p>
  27. <script>
  28. (function(){
  29. var output = "", cb
  30. function a() { output += "A" }
  31. function b() { output += "B" }
  32. function c() { output += "C" }
  33. function str(str) { output += str }
  34. Evidence('ZeptoCallbacksTest', {
  35. testOptionsAreCopied: function(t) {
  36. var options = {"unique": true},
  37. cb = $.Callbacks(options),
  38. count = 0,
  39. fn = function() {
  40. t.assertTrue(!(count++), "called once")
  41. }
  42. options["unique"] = false
  43. cb.add(fn, fn)
  44. cb.fire()
  45. },
  46. testFireWithOptionsAreCopied: function(t) {
  47. var cb = $.Callbacks({memory:1}),
  48. args = ["hello"]
  49. cb.fireWith(null, args)
  50. args[0] = "world"
  51. cb.add(function(hello) {
  52. t.assertEqual("hello", hello, "arguments are copied internally")
  53. })
  54. },
  55. testRemoveDeletesAllInstances: function(t) {
  56. var cb = $.Callbacks()
  57. function fn() {
  58. t.fail("function wasn't removed")
  59. }
  60. cb.add( fn, fn, function() {
  61. t.assertTrue(true, "end of test")
  62. }).remove(fn).fire()
  63. },
  64. testCallbacksHas: function(t) {
  65. var cb = $.Callbacks()
  66. cb.add(a, b, c)
  67. t.assertTrue(cb.has(), "No arguments to .has() returns whether callback function(s) are attached or not")
  68. t.assertTrue(cb.has(a), "Check if a specific callback function is in the Callbacks list" )
  69. cb.remove(b)
  70. t.assertFalse(cb.has(b), "Remove a specific callback function and make sure its no longer there" )
  71. t.assertTrue(cb.has(a), "Remove a specific callback function and make sure other callback function is still there" )
  72. cb.empty()
  73. t.assertFalse(cb.has(), "Empty list and make sure there are no callback function(s)" )
  74. t.assertFalse(cb.has(a), "Check for a specific function in an empty() list" )
  75. cb.add(a, b, function(){
  76. t.assertTrue(cb.has(), "Check if list has callback function(s) from within a callback function" )
  77. t.assertTrue(cb.has(a), "Check if list has a specific callback from within a callback function" )
  78. }).fire()
  79. t.assertTrue(cb.has(), "Callbacks list has callback function(s) after firing" )
  80. cb.disable()
  81. t.assertFalse(cb.has(), "disabled() list has no callback functions (returns false)" )
  82. t.assertFalse(cb.has(a), "Check for a specific function in a disabled() list" )
  83. cb = $.Callbacks({unique:1})
  84. cb.add(a)
  85. cb.add(a)
  86. t.assertTrue(cb.has(), "Check if unique list has callback function(s) attached" )
  87. cb.lock()
  88. t.assertFalse(cb.has(), "locked() list is empty and returns false" )
  89. },
  90. testAddStringNoCrash: function(t) {
  91. $.Callbacks().add("hello world")
  92. t.assertTrue(true, "no crash adding string" )
  93. },
  94. testUniqueAddIdenticalFn: function(t) {
  95. output = "X"
  96. $.Callbacks({unique:1}).add(a, function() { output += "A" }).fire()
  97. t.assertEqual("XAA", output, "Unique can add different, identical definitions of same function")
  98. },
  99. testUniqueAddSameFn: function(t) {
  100. output = "X"
  101. $.Callbacks({unique:1}).add(a, a).fire()
  102. t.assertEqual("XA", output, "Unique can not add multiple functions with the same reference")
  103. },
  104. testUniqueAddSameFnMultiRef: function(t) {
  105. var x = a
  106. output = "X"
  107. $.Callbacks({unique:1}).add(a, x).fire()
  108. t.assertEqual("XA", output, "Unique can not add multiple references to the same function")
  109. }
  110. })
  111. var configs = {
  112. 'Undefined': undefined,
  113. 'Null': null,
  114. 'Once': {once:1},
  115. 'Memory': {memory:1},
  116. 'Unique': {unique:1},
  117. 'StopOnFalse': {stopOnFalse:1},
  118. 'OnceMemory': {once:1, memory:1},
  119. 'OnceUnique': {once:1, unique:1},
  120. 'OnceStopOnFalse': {once:1, stopOnFalse:1},
  121. 'MemoryUnique': {memory:1, unique:1},
  122. 'MemoryStopOnFalse': {memory:1, stopOnFalse:1},
  123. 'UniqueStopOnFalse': {unique:1, stopOnFalse:1}
  124. }
  125. var ordering = {
  126. "Undefined": "XABC X XABCABCC X XBB X XABA X XX",
  127. "Null": "XABC X XABCABCC X XBB X XABA X XX",
  128. "Once": "XABC X X X X X XABA X XX",
  129. "Memory": "XABC XABC XABCABCCC XA XBB XB XABA XC XX",
  130. "Unique": "XABC X XABCA X XB X XAB X X",
  131. "StopOnFalse": "XABC X XABCABCC X XBB X XA X XX",
  132. "OnceMemory": "XABC XABC X XA X XA XABA XC XX",
  133. "OnceUnique": "XABC X X X X X XAB X X",
  134. "OnceStopOnFalse": "XABC X X X X X XA X XX",
  135. "MemoryUnique": "XABC XA XABCA X XB X XAB XC X",
  136. "MemoryStopOnFalse": "XABC XABC XABCABCCC XA XBB XB XA X XX",
  137. "UniqueStopOnFalse": "XABC X XABCA X XB X XA X X"
  138. }
  139. $.each(configs, function(name, config) {
  140. var results = ordering[name].split(/\s+/)
  141. Evidence("ZeptoCallbacksTest#" + name, {
  142. testBindAndFire: function(t) {
  143. output = "X", cb = $.Callbacks(config).add(str).fire("A")
  144. t.assertEqual("XA", output, "Basic binding and firing")
  145. t.assertTrue(cb.fired(), ".fired() detects firing")
  146. output = "X"
  147. cb.disable().add(str)
  148. t.assertEqual( "X", output, "Adding a callback after disabling" )
  149. cb.fire("A")
  150. t.assertEqual( "X", output, "Firing after disabling" )
  151. },
  152. testNoEmptyWhileFiring: function(t) {
  153. var cb = $.Callbacks(config)
  154. cb.add(cb.empty, function() { t.fail("not emptied") }).fire()
  155. },
  156. testNoDisablingWhileFiring: function(t) {
  157. var cb = $.Callbacks(config)
  158. cb.add(cb.disable, function() { t.fail("not disabled") }).fire()
  159. },
  160. testBindFireWithContextAndArgs: function(t) {
  161. output = "X"
  162. $.Callbacks(config).add(function() {
  163. t.assertEqual(window, this, "Basic binding and firing (context)" )
  164. output += Array.prototype.join.call(arguments, "")
  165. }).fireWith(window, [ "A", "B" ])
  166. t.assertEqual( "XAB", output, "Basic binding and firing (arguments)" )
  167. },
  168. testFireWithNoArgs: function(t) {
  169. $.Callbacks(config).add(function() {
  170. t.assertEqual(window, this, "fireWith with no arguments (context is window)")
  171. t.assertEqual(0, arguments.length, "fireWith with no arguments (no arguments)")
  172. }).fireWith()
  173. },
  174. testBindRemoveFire: function(t) {
  175. output = "X"
  176. $.Callbacks(config).add(a, b, c).remove(b, c).fire()
  177. t.assertEqual("XA", output)
  178. },
  179. testEmpty: function(t) {
  180. output = "X"
  181. $.Callbacks(config).add(a, b, c).empty().fire()
  182. t.assertEqual( "X", output, "Empty" )
  183. },
  184. testLocking: function(t) {
  185. output = "X"
  186. $.Callbacks(config).add(str).lock().add(str).fire("A").add(str)
  187. t.assertEqual("X", output, "Lock early")
  188. },
  189. testOrdering: function(t) {
  190. output = "X", cb = $.Callbacks(config)
  191. cb.add(function() {
  192. cb.add(c)
  193. a()
  194. }, b).fire()
  195. t.assertEqual( results.shift(), output, "Proper ordering" )
  196. output = "X"
  197. cb.add(function() {
  198. cb.add(c)
  199. a()
  200. }, b)
  201. t.assertEqual(results.shift(), output, "Add after fire")
  202. output = "X"
  203. cb.fire()
  204. t.assertEqual(results.shift(), output, "Fire again")
  205. output = "X", cb = $.Callbacks(config)
  206. cb.add(str).fire("A")
  207. t.assertEqual("XA", output, "Multiple fire (first fire)")
  208. output = "X"
  209. cb.add(str)
  210. t.assertEqual(results.shift(), output, "Multiple fire (first new callback)")
  211. output = "X"
  212. cb.fire("B")
  213. t.assertEqual(results.shift(), output, "Multiple fire (second fire)")
  214. output = "X"
  215. cb.add(str)
  216. t.assertEqual(results.shift(), output, "Multiple fire (second new callback)")
  217. output = "X", cb = $.Callbacks(config).add(a, function() { return false }, b).add(a).fire()
  218. t.assertEqual(results.shift(), output, "Callback returning false")
  219. output = "X"
  220. cb.add(c)
  221. t.assertEqual(results.shift(), output, "Adding a callback after one returned false")
  222. output = ""
  223. function handler() { output += "X" }
  224. handler.method = function() { output += "!" }
  225. cb = $.Callbacks(config).add(handler).add(handler).fire()
  226. t.assertEqual(results.shift(), output, "No callback iteration")
  227. }
  228. })
  229. })
  230. })()
  231. </script>
  232. </body>
  233. </html>