test_eventemitter_basic.html 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. <!DOCTYPE html>
  2. <!--
  3. Any copyright is dedicated to the Public Domain.
  4. http://creativecommons.org/publicdomain/zero/1.0/
  5. -->
  6. <html>
  7. <head>
  8. <meta charset="utf8">
  9. <title></title>
  10. <script type="application/javascript"
  11. src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
  12. <link rel="stylesheet" type="text/css"
  13. href="chrome://mochikit/content/tests/SimpleTest/test.css">
  14. </head>
  15. <body>
  16. <script type="application/javascript;version=1.8">
  17. "use strict";
  18. const { utils: Cu } = Components;
  19. const { require } = Cu.import("resource://devtools/shared/Loader.jsm", {});
  20. const promise = require("promise");
  21. const EventEmitter = require("devtools/shared/event-emitter");
  22. const { Task } = require("devtools/shared/task");
  23. SimpleTest.waitForExplicitFinish();
  24. testEmitter();
  25. testEmitter({});
  26. Task.spawn(testPromise)
  27. .then(null, ok.bind(null, false))
  28. .then(SimpleTest.finish);
  29. function testEmitter(aObject) {
  30. let emitter;
  31. if (aObject) {
  32. emitter = aObject;
  33. EventEmitter.decorate(emitter);
  34. } else {
  35. emitter = new EventEmitter();
  36. }
  37. ok(emitter, "We have an event emitter");
  38. let beenHere1 = false;
  39. let beenHere2 = false;
  40. emitter.on("next", next);
  41. emitter.emit("next", "abc", "def");
  42. function next(eventName, str1, str2) {
  43. is(eventName, "next", "Got event");
  44. is(str1, "abc", "Argument 1 is correct");
  45. is(str2, "def", "Argument 2 is correct");
  46. ok(!beenHere1, "first time in next callback");
  47. beenHere1 = true;
  48. emitter.off("next", next);
  49. emitter.emit("next");
  50. emitter.once("onlyonce", onlyOnce);
  51. emitter.emit("onlyonce");
  52. emitter.emit("onlyonce");
  53. }
  54. function onlyOnce() {
  55. ok(!beenHere2, "\"once\" listener has been called once");
  56. beenHere2 = true;
  57. emitter.emit("onlyonce");
  58. testThrowingExceptionInListener();
  59. }
  60. function testThrowingExceptionInListener() {
  61. function throwListener() {
  62. emitter.off("throw-exception");
  63. throw {
  64. toString: () => "foo",
  65. stack: "bar",
  66. };
  67. }
  68. emitter.on("throw-exception", throwListener);
  69. emitter.emit("throw-exception");
  70. killItWhileEmitting();
  71. }
  72. function killItWhileEmitting() {
  73. function c1() {
  74. ok(true, "c1 called");
  75. }
  76. function c2() {
  77. ok(true, "c2 called");
  78. emitter.off("tick", c3);
  79. }
  80. function c3() {
  81. ok(false, "c3 should not be called");
  82. }
  83. function c4() {
  84. ok(true, "c4 called");
  85. }
  86. emitter.on("tick", c1);
  87. emitter.on("tick", c2);
  88. emitter.on("tick", c3);
  89. emitter.on("tick", c4);
  90. emitter.emit("tick");
  91. offAfterOnce();
  92. }
  93. function offAfterOnce() {
  94. let enteredC1 = false;
  95. function c1() {
  96. enteredC1 = true;
  97. }
  98. emitter.once("oao", c1);
  99. emitter.off("oao", c1);
  100. emitter.emit("oao");
  101. ok(!enteredC1, "c1 should not be called");
  102. }
  103. }
  104. function testPromise() {
  105. let emitter = new EventEmitter();
  106. let p = emitter.once("thing");
  107. // Check that the promise is only resolved once event though we
  108. // emit("thing") more than once
  109. let firstCallbackCalled = false;
  110. let check1 = p.then(arg => {
  111. is(firstCallbackCalled, false, "first callback called only once");
  112. firstCallbackCalled = true;
  113. is(arg, "happened", "correct arg in promise");
  114. return "rval from c1";
  115. });
  116. emitter.emit("thing", "happened", "ignored");
  117. // Check that the promise is resolved asynchronously
  118. let secondCallbackCalled = false;
  119. let check2 = p.then(arg => {
  120. ok(true, "second callback called");
  121. is(arg, "happened", "correct arg in promise");
  122. secondCallbackCalled = true;
  123. is(arg, "happened", "correct arg in promise (a second time)");
  124. return "rval from c2";
  125. });
  126. // Shouldn't call any of the above listeners
  127. emitter.emit("thing", "trashinate");
  128. // Check that we can still separate events with different names
  129. // and that it works with no parameters
  130. let pfoo = emitter.once("foo");
  131. let pbar = emitter.once("bar");
  132. let check3 = pfoo.then(arg => {
  133. ok(arg === undefined, "no arg for foo event");
  134. return "rval from c3";
  135. });
  136. pbar.then(() => {
  137. ok(false, "pbar should not be called");
  138. });
  139. emitter.emit("foo");
  140. is(secondCallbackCalled, false, "second callback not called yet");
  141. return promise.all([ check1, check2, check3 ]).then(args => {
  142. is(args[0], "rval from c1", "callback 1 done good");
  143. is(args[1], "rval from c2", "callback 2 done good");
  144. is(args[2], "rval from c3", "callback 3 done good");
  145. });
  146. }
  147. </script>
  148. </body>
  149. </html>