PageRenderTime 87ms CodeModel.GetById 27ms RepoModel.GetById 2ms app.codeStats 0ms

/testing/mochitest/tests/MochiKit-1.4.2/tests/test_Signal.js

https://bitbucket.org/soko/mozilla-central
JavaScript | 481 lines | 391 code | 80 blank | 10 comment | 21 complexity | a8022f48ffccb3367a13723264eccf50 MD5 | raw file
Possible License(s): GPL-2.0, JSON, 0BSD, LGPL-3.0, AGPL-1.0, MIT, MPL-2.0-no-copyleft-exception, BSD-3-Clause, LGPL-2.1, Apache-2.0
  1. if (typeof(dojo) != 'undefined') { dojo.require('MochiKit.Signal'); }
  2. if (typeof(JSAN) != 'undefined') { JSAN.use('MochiKit.Signal'); }
  3. if (typeof(tests) == 'undefined') { tests = {}; }
  4. tests.test_Signal = function (t) {
  5. var submit = MochiKit.DOM.getElement('submit');
  6. var ident = null;
  7. var i = 0;
  8. var aFunction = function() {
  9. t.ok(this === submit, "aFunction should have 'this' as submit");
  10. i++;
  11. if (typeof(this.someVar) != 'undefined') {
  12. i += this.someVar;
  13. }
  14. };
  15. var aObject = {};
  16. aObject.aMethod = function() {
  17. t.ok(this === aObject, "aMethod should have 'this' as aObject");
  18. i++;
  19. };
  20. ident = connect('submit', 'onclick', aFunction);
  21. MochiKit.DOM.getElement('submit').click();
  22. t.is(i, 1, 'HTML onclick event can be connected to a function');
  23. disconnect(ident);
  24. MochiKit.DOM.getElement('submit').click();
  25. t.is(i, 1, 'HTML onclick can be disconnected from a function');
  26. var submit = MochiKit.DOM.getElement('submit');
  27. ident = connect(submit, 'onclick', aFunction);
  28. submit.click();
  29. t.is(i, 2, 'Checking that a DOM element can be connected to a function');
  30. disconnect(ident);
  31. submit.click();
  32. t.is(i, 2, '...and then disconnected');
  33. if (MochiKit.DOM.getElement('submit').fireEvent ||
  34. (document.createEvent &&
  35. typeof(document.createEvent('MouseEvents').initMouseEvent) == 'function')) {
  36. /*
  37. Adapted from:
  38. http://www.devdaily.com/java/jwarehouse/jforum/tests/selenium/javascript/htmlutils.js.shtml
  39. License: Apache
  40. Copyright: Copyright 2004 ThoughtWorks, Inc
  41. */
  42. var triggerMouseEvent = function(element, eventType, canBubble) {
  43. element = MochiKit.DOM.getElement(element);
  44. canBubble = (typeof(canBubble) == 'undefined') ? true : canBubble;
  45. if (element.fireEvent) {
  46. var newEvt = document.createEventObject();
  47. newEvt.clientX = 1;
  48. newEvt.clientY = 1;
  49. newEvt.button = 1;
  50. newEvt.detail = 3;
  51. element.fireEvent('on' + eventType, newEvt);
  52. } else if (document.createEvent && (typeof(document.createEvent('MouseEvents').initMouseEvent) == 'function')) {
  53. var evt = document.createEvent('MouseEvents');
  54. evt.initMouseEvent(eventType, canBubble, true, // event, bubbles, cancelable
  55. document.defaultView, 3, // view, detail (either scroll or # of clicks)
  56. 1, 0, 0, 0, // screenX, screenY, clientX, clientY
  57. false, false, false, false, // ctrlKey, altKey, shiftKey, metaKey
  58. 0, null); // buttonCode, relatedTarget
  59. element.dispatchEvent(evt);
  60. }
  61. };
  62. var eventTest = function(e) {
  63. i++;
  64. t.ok((typeof(e.event()) === 'object'), 'checking that event() is an object');
  65. t.ok((typeof(e.type()) === 'string'), 'checking that type() is a string');
  66. t.ok((e.target() === MochiKit.DOM.getElement('submit')), 'checking that target is "submit"');
  67. t.ok((typeof(e.modifier()) === 'object'), 'checking that modifier() is an object');
  68. t.ok(e.modifier().alt === false, 'checking that modifier().alt is defined, but false');
  69. t.ok(e.modifier().ctrl === false, 'checking that modifier().ctrl is defined, but false');
  70. t.ok(e.modifier().meta === false, 'checking that modifier().meta is defined, but false');
  71. t.ok(e.modifier().shift === false, 'checking that modifier().shift is defined, but false');
  72. t.ok((typeof(e.mouse()) === 'object'), 'checking that mouse() is an object');
  73. t.ok((typeof(e.mouse().button) === 'object'), 'checking that mouse().button is an object');
  74. t.ok(e.mouse().button.left === true, 'checking that mouse().button.left is true');
  75. t.ok(e.mouse().button.middle === false, 'checking that mouse().button.middle is false');
  76. t.ok(e.mouse().button.right === false, 'checking that mouse().button.right is false');
  77. t.ok((typeof(e.mouse().page) === 'object'), 'checking that mouse().page is an object');
  78. t.ok((typeof(e.mouse().page.x) === 'number'), 'checking that mouse().page.x is a number');
  79. t.ok((typeof(e.mouse().page.y) === 'number'), 'checking that mouse().page.y is a number');
  80. t.ok((typeof(e.mouse().client) === 'object'), 'checking that mouse().client is an object');
  81. t.ok((typeof(e.mouse().client.x) === 'number'), 'checking that mouse().client.x is a number');
  82. t.ok((typeof(e.mouse().client.y) === 'number'), 'checking that mouse().client.y is a number');
  83. /* these should not be defined */
  84. t.ok((typeof(e.relatedTarget()) === 'undefined'), 'checking that relatedTarget() is undefined');
  85. t.ok((typeof(e.key()) === 'undefined'), 'checking that key() is undefined');
  86. t.ok((typeof(e.mouse().wheel) === 'undefined'), 'checking that mouse().wheel is undefined');
  87. };
  88. ident = connect('submit', 'onmousedown', eventTest);
  89. triggerMouseEvent('submit', 'mousedown', false);
  90. t.is(i, 3, 'Connecting an event to an HTML object and firing a synthetic event');
  91. disconnect(ident);
  92. triggerMouseEvent('submit', 'mousedown', false);
  93. t.is(i, 3, 'Disconnecting an event to an HTML object and firing a synthetic event');
  94. ident = connect('submit', 'onmousewheel', function(e) {
  95. i++;
  96. t.ok((typeof(e.mouse()) === 'object'), 'checking that mouse() is an object');
  97. t.ok((typeof(e.mouse().wheel) === 'object'), 'checking that mouse().wheel is an object');
  98. t.ok((typeof(e.mouse().wheel.x) === 'number'), 'checking that mouse().wheel.x is a number');
  99. t.ok((typeof(e.mouse().wheel.y) === 'number'), 'checking that mouse().wheel.y is a number');
  100. });
  101. var nativeSignal = 'mousewheel';
  102. if (MochiKit.Signal._browserLacksMouseWheelEvent()) {
  103. nativeSignal = 'DOMMouseScroll';
  104. }
  105. triggerMouseEvent('submit', nativeSignal, false);
  106. t.is(i, 4, 'Connecting a mousewheel event to an HTML object and firing a synthetic event');
  107. disconnect(ident);
  108. triggerMouseEvent('submit', nativeSignal, false);
  109. t.is(i, 4, 'Disconnecting a mousewheel event to an HTML object and firing a synthetic event');
  110. }
  111. // non-DOM tests
  112. var hasNoSignals = {};
  113. var hasSignals = {someVar: 1};
  114. var i = 0;
  115. var aFunction = function() {
  116. i++;
  117. if (typeof(this.someVar) != 'undefined') {
  118. i += this.someVar;
  119. }
  120. };
  121. var bFunction = function(someArg, someOtherArg) {
  122. i += someArg + someOtherArg;
  123. };
  124. var aObject = {};
  125. aObject.aMethod = function() {
  126. i++;
  127. };
  128. aObject.bMethod = function() {
  129. i++;
  130. };
  131. var bObject = {};
  132. bObject.bMethod = function() {
  133. i++;
  134. };
  135. ident = connect(hasSignals, 'signalOne', aFunction);
  136. signal(hasSignals, 'signalOne');
  137. t.is(i, 2, 'Connecting function');
  138. i = 0;
  139. disconnect(ident);
  140. signal(hasSignals, 'signalOne');
  141. t.is(i, 0, 'New style disconnecting function');
  142. i = 0;
  143. ident = connect(hasSignals, 'signalOne', bFunction);
  144. signal(hasSignals, 'signalOne', 1, 2);
  145. t.is(i, 3, 'Connecting function');
  146. i = 0;
  147. disconnect(ident);
  148. signal(hasSignals, 'signalOne', 1, 2);
  149. t.is(i, 0, 'New style disconnecting function');
  150. i = 0;
  151. connect(hasSignals, 'signalOne', aFunction);
  152. signal(hasSignals, 'signalOne');
  153. t.is(i, 2, 'Connecting function');
  154. i = 0;
  155. disconnect(hasSignals, 'signalOne', aFunction);
  156. signal(hasSignals, 'signalOne');
  157. t.is(i, 0, 'Old style disconnecting function');
  158. i = 0;
  159. ident = connect(hasSignals, 'signalOne', aObject, aObject.aMethod);
  160. signal(hasSignals, 'signalOne');
  161. t.is(i, 1, 'Connecting obj-function');
  162. i = 0;
  163. disconnect(ident);
  164. signal(hasSignals, 'signalOne');
  165. t.is(i, 0, 'New style disconnecting obj-function');
  166. i = 0;
  167. connect(hasSignals, 'signalOne', aObject, aObject.aMethod);
  168. signal(hasSignals, 'signalOne');
  169. t.is(i, 1, 'Connecting obj-function');
  170. i = 0;
  171. disconnect(hasSignals, 'signalOne', aObject, aObject.aMethod);
  172. signal(hasSignals, 'signalOne');
  173. t.is(i, 0, 'Disconnecting obj-function');
  174. i = 0;
  175. ident = connect(hasSignals, 'signalTwo', aObject, 'aMethod');
  176. signal(hasSignals, 'signalTwo');
  177. t.is(i, 1, 'Connecting obj-string');
  178. i = 0;
  179. disconnect(ident);
  180. signal(hasSignals, 'signalTwo');
  181. t.is(i, 0, 'New style disconnecting obj-string');
  182. i = 0;
  183. connect(hasSignals, 'signalTwo', aObject, 'aMethod');
  184. signal(hasSignals, 'signalTwo');
  185. t.is(i, 1, 'Connecting obj-string');
  186. i = 0;
  187. disconnect(hasSignals, 'signalTwo', aObject, 'aMethod');
  188. signal(hasSignals, 'signalTwo');
  189. t.is(i, 0, 'Old style disconnecting obj-string');
  190. i = 0;
  191. var shouldRaise = function() { return undefined.attr; };
  192. try {
  193. connect(hasSignals, 'signalOne', shouldRaise);
  194. signal(hasSignals, 'signalOne');
  195. t.ok(false, 'An exception was not raised');
  196. } catch (e) {
  197. t.ok(true, 'An exception was raised');
  198. }
  199. disconnect(hasSignals, 'signalOne', shouldRaise);
  200. t.is(i, 0, 'Exception raised, signal should not have fired');
  201. i = 0;
  202. connect(hasSignals, 'signalOne', aObject, 'aMethod');
  203. connect(hasSignals, 'signalOne', aObject, 'bMethod');
  204. signal(hasSignals, 'signalOne');
  205. t.is(i, 2, 'Connecting one signal to two slots in one object');
  206. i = 0;
  207. disconnect(hasSignals, 'signalOne', aObject, 'aMethod');
  208. disconnect(hasSignals, 'signalOne', aObject, 'bMethod');
  209. signal(hasSignals, 'signalOne');
  210. t.is(i, 0, 'Disconnecting one signal from two slots in one object');
  211. i = 0;
  212. connect(hasSignals, 'signalOne', aObject, 'aMethod');
  213. connect(hasSignals, 'signalOne', bObject, 'bMethod');
  214. signal(hasSignals, 'signalOne');
  215. t.is(i, 2, 'Connecting one signal to two slots in two objects');
  216. i = 0;
  217. disconnect(hasSignals, 'signalOne', aObject, 'aMethod');
  218. disconnect(hasSignals, 'signalOne', bObject, 'bMethod');
  219. signal(hasSignals, 'signalOne');
  220. t.is(i, 0, 'Disconnecting one signal from two slots in two objects');
  221. i = 0;
  222. try {
  223. connect(nothing, 'signalOne', aObject, 'aMethod');
  224. signal(nothing, 'signalOne');
  225. t.ok(false, 'An exception was not raised when connecting undefined');
  226. } catch (e) {
  227. t.ok(true, 'An exception was raised when connecting undefined');
  228. }
  229. try {
  230. disconnect(nothing, 'signalOne', aObject, 'aMethod');
  231. t.ok(false, 'An exception was not raised when disconnecting undefined');
  232. } catch (e) {
  233. t.ok(true, 'An exception was raised when disconnecting undefined');
  234. }
  235. try {
  236. connect(hasSignals, 'signalOne', nothing);
  237. signal(hasSignals, 'signalOne');
  238. t.ok(false, 'An exception was not raised when connecting an undefined function');
  239. } catch (e) {
  240. t.ok(true, 'An exception was raised when connecting an undefined function');
  241. }
  242. try {
  243. disconnect(hasSignals, 'signalOne', nothing);
  244. t.ok(false, 'An exception was not raised when disconnecting an undefined function');
  245. } catch (e) {
  246. t.ok(true, 'An exception was raised when disconnecting an undefined function');
  247. }
  248. try {
  249. connect(hasSignals, 'signalOne', aObject, aObject.nothing);
  250. signal(hasSignals, 'signalOne');
  251. t.ok(false, 'An exception was not raised when connecting an undefined method');
  252. } catch (e) {
  253. t.ok(true, 'An exception was raised when connecting an undefined method');
  254. }
  255. try {
  256. connect(hasSignals, 'signalOne', aObject, 'nothing');
  257. signal(hasSignals, 'signalOne');
  258. t.ok(false, 'An exception was not raised when connecting an undefined method (as string)');
  259. } catch (e) {
  260. t.ok(true, 'An exception was raised when connecting an undefined method (as string)');
  261. }
  262. t.is(i, 0, 'Signals should not have fired');
  263. connect(hasSignals, 'signalOne', aFunction);
  264. connect(hasSignals, 'signalOne', aObject, 'aMethod');
  265. disconnectAll(hasSignals, 'signalOne');
  266. signal(hasSignals, 'signalOne');
  267. t.is(i, 0, 'disconnectAll works with single explicit signal');
  268. i = 0;
  269. connect(hasSignals, 'signalOne', aFunction);
  270. connect(hasSignals, 'signalOne', aObject, 'aMethod');
  271. connect(hasSignals, 'signalTwo', aFunction);
  272. connect(hasSignals, 'signalTwo', aObject, 'aMethod');
  273. disconnectAll(hasSignals, 'signalOne');
  274. signal(hasSignals, 'signalOne');
  275. t.is(i, 0, 'disconnectAll works with single explicit signal');
  276. signal(hasSignals, 'signalTwo');
  277. t.is(i, 3, 'disconnectAll does not disconnect unrelated signals');
  278. i = 0;
  279. connect(hasSignals, 'signalOne', aFunction);
  280. connect(hasSignals, 'signalOne', aObject, 'aMethod');
  281. connect(hasSignals, 'signalTwo', aFunction);
  282. connect(hasSignals, 'signalTwo', aObject, 'aMethod');
  283. disconnectAll(hasSignals, 'signalOne', 'signalTwo');
  284. signal(hasSignals, 'signalOne');
  285. signal(hasSignals, 'signalTwo');
  286. t.is(i, 0, 'disconnectAll works with two explicit signals');
  287. i = 0;
  288. connect(hasSignals, 'signalOne', aFunction);
  289. connect(hasSignals, 'signalOne', aObject, 'aMethod');
  290. connect(hasSignals, 'signalTwo', aFunction);
  291. connect(hasSignals, 'signalTwo', aObject, 'aMethod');
  292. disconnectAll(hasSignals, ['signalOne', 'signalTwo']);
  293. signal(hasSignals, 'signalOne');
  294. signal(hasSignals, 'signalTwo');
  295. t.is(i, 0, 'disconnectAll works with two explicit signals as a list');
  296. i = 0;
  297. connect(hasSignals, 'signalOne', aFunction);
  298. connect(hasSignals, 'signalOne', aObject, 'aMethod');
  299. connect(hasSignals, 'signalTwo', aFunction);
  300. connect(hasSignals, 'signalTwo', aObject, 'aMethod');
  301. disconnectAll(hasSignals);
  302. signal(hasSignals, 'signalOne');
  303. signal(hasSignals, 'signalTwo');
  304. t.is(i, 0, 'disconnectAll works with implicit signals');
  305. i = 0;
  306. var toggle = function() {
  307. disconnectAll(hasSignals, 'signalOne');
  308. connect(hasSignals, 'signalOne', aFunction);
  309. i++;
  310. };
  311. connect(hasSignals, 'signalOne', aFunction);
  312. connect(hasSignals, 'signalTwo', function() { i++; });
  313. connect(hasSignals, 'signalTwo', toggle);
  314. connect(hasSignals, 'signalTwo', function() { i++; }); // #147
  315. connect(hasSignals, 'signalTwo', function() { i++; });
  316. signal(hasSignals, 'signalTwo');
  317. t.is(i, 4, 'disconnectAll fired in a signal loop works');
  318. i = 0;
  319. disconnectAll('signalOne');
  320. disconnectAll('signalTwo');
  321. var testfunc = function () { arguments.callee.count++; };
  322. testfunc.count = 0;
  323. var testObj = {
  324. methOne: function () { this.countOne++; }, countOne: 0,
  325. methTwo: function () { this.countTwo++; }, countTwo: 0
  326. };
  327. connect(hasSignals, 'signalOne', testfunc);
  328. connect(hasSignals, 'signalTwo', testfunc);
  329. signal(hasSignals, 'signalOne');
  330. signal(hasSignals, 'signalTwo');
  331. t.is(testfunc.count, 2, 'disconnectAllTo func precondition');
  332. disconnectAllTo(testfunc);
  333. signal(hasSignals, 'signalOne');
  334. signal(hasSignals, 'signalTwo');
  335. t.is(testfunc.count, 2, 'disconnectAllTo func');
  336. connect(hasSignals, 'signalOne', testObj, 'methOne');
  337. connect(hasSignals, 'signalTwo', testObj, 'methTwo');
  338. signal(hasSignals, 'signalOne');
  339. signal(hasSignals, 'signalTwo');
  340. t.is(testObj.countOne, 1, 'disconnectAllTo obj precondition');
  341. t.is(testObj.countTwo, 1, 'disconnectAllTo obj precondition');
  342. disconnectAllTo(testObj);
  343. signal(hasSignals, 'signalOne');
  344. signal(hasSignals, 'signalTwo');
  345. t.is(testObj.countOne, 1, 'disconnectAllTo obj');
  346. t.is(testObj.countTwo, 1, 'disconnectAllTo obj');
  347. testObj.countOne = testObj.countTwo = 0;
  348. connect(hasSignals, 'signalOne', testObj, 'methOne');
  349. connect(hasSignals, 'signalTwo', testObj, 'methTwo');
  350. disconnectAllTo(testObj, 'methOne');
  351. signal(hasSignals, 'signalOne');
  352. signal(hasSignals, 'signalTwo');
  353. t.is(testObj.countOne, 0, 'disconnectAllTo obj+str');
  354. t.is(testObj.countTwo, 1, 'disconnectAllTo obj+str');
  355. has__Connect = {
  356. count: 0,
  357. __connect__: function (ident) {
  358. this.count += arguments.length;
  359. disconnect(ident);
  360. }
  361. };
  362. connect(has__Connect, 'signalOne', function() {
  363. t.fail("__connect__ should have disconnected signal");
  364. });
  365. t.is(has__Connect.count, 3, '__connect__ is called when it exists');
  366. signal(has__Connect, 'signalOne');
  367. has__Disconnect = {
  368. count: 0,
  369. __disconnect__: function (ident) {
  370. this.count += arguments.length;
  371. }
  372. };
  373. connect(has__Disconnect, 'signalOne', aFunction);
  374. connect(has__Disconnect, 'signalTwo', aFunction);
  375. disconnectAll(has__Disconnect);
  376. t.is(has__Disconnect.count, 8, '__disconnect__ is called when it exists');
  377. var events = {};
  378. var test_ident = connect(events, "test", function() {
  379. var fail_ident = connect(events, "fail", function () {
  380. events.failed = true;
  381. });
  382. disconnect(fail_ident);
  383. signal(events, "fail");
  384. });
  385. signal(events, "test");
  386. t.is(events.failed, undefined, 'disconnected slots do not fire');
  387. var sink = {f: function (ev) { this.ev = ev; }};
  388. var src = {};
  389. bindMethods(sink);
  390. connect(src, 'signal', sink.f);
  391. signal(src, 'signal', 'worked');
  392. t.is(sink.ev, 'worked', 'custom signal does not re-bind methods');
  393. var lateObj = { fun: function() { this.value = 1; } };
  394. connect(src, 'signal', lateObj, "fun");
  395. signal(src, 'signal');
  396. lateObj.fun = function() { this.value = 2; };
  397. signal(src, 'signal');
  398. t.is(lateObj.value, 2, 'connect uses late function binding');
  399. };