test-event-target.js 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. /* This Source Code Form is subject to the terms of the Mozilla Public
  2. * License, v. 2.0. If a copy of the MPL was not distributed with this
  3. * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  4. 'use strict';
  5. const { emit } = require('sdk/event/core');
  6. const { EventTarget } = require('sdk/event/target');
  7. const { Loader } = require('sdk/test/loader');
  8. exports['test add a listener'] = function(assert) {
  9. let events = [ { name: 'event#1' }, 'event#2' ];
  10. let target = EventTarget();
  11. target.on('message', function(message) {
  12. assert.equal(this, target, 'this is a target object');
  13. assert.equal(message, events.shift(), 'message is emitted event');
  14. });
  15. emit(target, 'message', events[0]);
  16. emit(target, 'message', events[0]);
  17. };
  18. exports['test pass in listeners'] = function(assert) {
  19. let actual = [ ];
  20. let target = EventTarget({
  21. onMessage: function onMessage(message) {
  22. assert.equal(this, target, 'this is an event target');
  23. actual.push(1);
  24. },
  25. onFoo: null,
  26. onbla: function() {
  27. assert.fail('`onbla` is not supposed to be called');
  28. }
  29. });
  30. target.on('message', function(message) {
  31. assert.equal(this, target, 'this is an event target');
  32. actual.push(2);
  33. });
  34. emit(target, 'message');
  35. emit(target, 'missing');
  36. assert.deepEqual([ 1, 2 ], actual, 'all listeners trigerred in right order');
  37. };
  38. exports['test that listener is unique per type'] = function(assert) {
  39. let actual = []
  40. let target = EventTarget();
  41. function listener() { actual.push(1) }
  42. target.on('message', listener);
  43. target.on('message', listener);
  44. target.on('message', listener);
  45. target.on('foo', listener);
  46. target.on('foo', listener);
  47. emit(target, 'message');
  48. assert.deepEqual([ 1 ], actual, 'only one message listener added');
  49. emit(target, 'foo');
  50. assert.deepEqual([ 1, 1 ], actual, 'same listener added for other event');
  51. };
  52. exports['test event type matters'] = function(assert) {
  53. let target = EventTarget();
  54. target.on('message', function() {
  55. assert.fail('no event is expected');
  56. });
  57. target.on('done', function() {
  58. assert.pass('event is emitted');
  59. });
  60. emit(target, 'foo');
  61. emit(target, 'done');
  62. };
  63. exports['test all arguments are pasesd'] = function(assert) {
  64. let foo = { name: 'foo' }, bar = 'bar';
  65. let target = EventTarget();
  66. target.on('message', function(a, b) {
  67. assert.equal(a, foo, 'first argument passed');
  68. assert.equal(b, bar, 'second argument passed');
  69. });
  70. emit(target, 'message', foo, bar);
  71. };
  72. exports['test no side-effects in emit'] = function(assert) {
  73. let target = EventTarget();
  74. target.on('message', function() {
  75. assert.pass('first listener is called');
  76. target.on('message', function() {
  77. assert.fail('second listener is called');
  78. });
  79. });
  80. emit(target, 'message');
  81. };
  82. exports['test order of propagation'] = function(assert) {
  83. let actual = [];
  84. let target = EventTarget();
  85. target.on('message', function() { actual.push(1); });
  86. target.on('message', function() { actual.push(2); });
  87. target.on('message', function() { actual.push(3); });
  88. emit(target, 'message');
  89. assert.deepEqual([ 1, 2, 3 ], actual, 'called in order they were added');
  90. };
  91. exports['test remove a listener'] = function(assert) {
  92. let target = EventTarget();
  93. let actual = [];
  94. target.on('message', function listener() {
  95. actual.push(1);
  96. target.on('message', function() {
  97. target.removeListener('message', listener);
  98. actual.push(2);
  99. })
  100. });
  101. target.off('message'); // must do nothing.
  102. emit(target, 'message');
  103. assert.deepEqual([ 1 ], actual, 'first listener called');
  104. emit(target, 'message');
  105. assert.deepEqual([ 1, 1, 2 ], actual, 'second listener called');
  106. emit(target, 'message');
  107. assert.deepEqual([ 1, 1, 2, 2, 2 ], actual, 'first listener removed');
  108. };
  109. exports['test error handling'] = function(assert) {
  110. let target = EventTarget();
  111. let error = Error('boom!');
  112. target.on('message', function() { throw error; })
  113. target.on('error', function(boom) {
  114. assert.equal(boom, error, 'thrown exception causes error event');
  115. });
  116. emit(target, 'message');
  117. };
  118. exports['test unhandled errors'] = function(assert) {
  119. let exceptions = [];
  120. let loader = Loader(module);
  121. let { emit } = loader.require('sdk/event/core');
  122. let { EventTarget } = loader.require('sdk/event/target');
  123. Object.defineProperties(loader.sandbox('sdk/event/core'), {
  124. console: { value: {
  125. exception: function(e) {
  126. exceptions.push(e);
  127. }
  128. }}
  129. });
  130. let target = EventTarget();
  131. let boom = Error('Boom!');
  132. let drax = Error('Draax!!');
  133. target.on('message', function() { throw boom; });
  134. emit(target, 'message');
  135. assert.ok(~String(exceptions[0]).indexOf('Boom!'),
  136. 'unhandled exception is logged');
  137. target.on('error', function() { throw drax; });
  138. emit(target, 'message');
  139. assert.ok(~String(exceptions[1]).indexOf('Draax!'),
  140. 'error in error handler is logged');
  141. };
  142. exports['test target is chainable'] = function (assert, done) {
  143. let loader = Loader(module);
  144. let exceptions = [];
  145. let { EventTarget } = loader.require('sdk/event/target');
  146. let { emit } = loader.require('sdk/event/core');
  147. Object.defineProperties(loader.sandbox('sdk/event/core'), {
  148. console: { value: {
  149. exception: function(e) {
  150. exceptions.push(e);
  151. }
  152. }}
  153. });
  154. let emitter = EventTarget();
  155. let boom = Error('Boom');
  156. let onceCalled = 0;
  157. emitter.once('oneTime', function () {
  158. assert.equal(++onceCalled, 1, 'once event called only once');
  159. }).on('data', function (message) {
  160. assert.equal(message, 'message', 'handles event');
  161. emit(emitter, 'oneTime');
  162. emit(emitter, 'data2', 'message2');
  163. }).on('phony', function () {
  164. assert.fail('removeListener does not remove chained event');
  165. }).removeListener('phony')
  166. .on('data2', function (message) {
  167. assert.equal(message, 'message2', 'handle chained event');
  168. emit(emitter, 'oneTime');
  169. throw boom;
  170. }).on('error', function (error) {
  171. assert.equal(error, boom, 'error handled in chained event');
  172. done();
  173. });
  174. emit(emitter, 'data', 'message');
  175. };
  176. require('test').run(exports);