event_utils_spec.js 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  1. /* Copyright 2017 Mozilla Foundation
  2. *
  3. * Licensed under the Apache License, Version 2.0 (the "License");
  4. * you may not use this file except in compliance with the License.
  5. * You may obtain a copy of the License at
  6. *
  7. * http://www.apache.org/licenses/LICENSE-2.0
  8. *
  9. * Unless required by applicable law or agreed to in writing, software
  10. * distributed under the License is distributed on an "AS IS" BASIS,
  11. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. * See the License for the specific language governing permissions and
  13. * limitations under the License.
  14. */
  15. import {
  16. EventBus,
  17. waitOnEventOrTimeout,
  18. WaitOnType,
  19. } from "../../web/event_utils.js";
  20. import { isNodeJS } from "../../src/shared/is_node.js";
  21. describe("event_utils", function () {
  22. describe("EventBus", function () {
  23. it("dispatch event", function () {
  24. const eventBus = new EventBus();
  25. let count = 0;
  26. eventBus.on("test", function (evt) {
  27. expect(evt).toEqual(undefined);
  28. count++;
  29. });
  30. eventBus.dispatch("test");
  31. expect(count).toEqual(1);
  32. });
  33. it("dispatch event with arguments", function () {
  34. const eventBus = new EventBus();
  35. let count = 0;
  36. eventBus.on("test", function (evt) {
  37. expect(evt).toEqual({ abc: 123 });
  38. count++;
  39. });
  40. eventBus.dispatch("test", {
  41. abc: 123,
  42. });
  43. expect(count).toEqual(1);
  44. });
  45. it("dispatch different event", function () {
  46. const eventBus = new EventBus();
  47. let count = 0;
  48. eventBus.on("test", function () {
  49. count++;
  50. });
  51. eventBus.dispatch("nottest");
  52. expect(count).toEqual(0);
  53. });
  54. it("dispatch event multiple times", function () {
  55. const eventBus = new EventBus();
  56. let count = 0;
  57. eventBus.dispatch("test");
  58. eventBus.on("test", function () {
  59. count++;
  60. });
  61. eventBus.dispatch("test");
  62. eventBus.dispatch("test");
  63. expect(count).toEqual(2);
  64. });
  65. it("dispatch event to multiple handlers", function () {
  66. const eventBus = new EventBus();
  67. let count = 0;
  68. eventBus.on("test", function () {
  69. count++;
  70. });
  71. eventBus.on("test", function () {
  72. count++;
  73. });
  74. eventBus.dispatch("test");
  75. expect(count).toEqual(2);
  76. });
  77. it("dispatch to detached", function () {
  78. const eventBus = new EventBus();
  79. let count = 0;
  80. const listener = function () {
  81. count++;
  82. };
  83. eventBus.on("test", listener);
  84. eventBus.dispatch("test");
  85. eventBus.off("test", listener);
  86. eventBus.dispatch("test");
  87. expect(count).toEqual(1);
  88. });
  89. it("dispatch to wrong detached", function () {
  90. const eventBus = new EventBus();
  91. let count = 0;
  92. eventBus.on("test", function () {
  93. count++;
  94. });
  95. eventBus.dispatch("test");
  96. eventBus.off("test", function () {
  97. count++;
  98. });
  99. eventBus.dispatch("test");
  100. expect(count).toEqual(2);
  101. });
  102. it("dispatch to detached during handling", function () {
  103. const eventBus = new EventBus();
  104. let count = 0;
  105. const listener1 = function () {
  106. eventBus.off("test", listener2);
  107. count++;
  108. };
  109. const listener2 = function () {
  110. eventBus.off("test", listener1);
  111. count++;
  112. };
  113. eventBus.on("test", listener1);
  114. eventBus.on("test", listener2);
  115. eventBus.dispatch("test");
  116. eventBus.dispatch("test");
  117. expect(count).toEqual(2);
  118. });
  119. it("dispatch event to handlers with/without 'once' option", function () {
  120. const eventBus = new EventBus();
  121. let multipleCount = 0,
  122. onceCount = 0;
  123. eventBus.on("test", function () {
  124. multipleCount++;
  125. });
  126. eventBus.on(
  127. "test",
  128. function () {
  129. onceCount++;
  130. },
  131. { once: true }
  132. );
  133. eventBus.dispatch("test");
  134. eventBus.dispatch("test");
  135. eventBus.dispatch("test");
  136. expect(multipleCount).toEqual(3);
  137. expect(onceCount).toEqual(1);
  138. });
  139. it("should not re-dispatch to DOM", async function () {
  140. if (isNodeJS) {
  141. pending("Document is not supported in Node.js.");
  142. }
  143. const eventBus = new EventBus();
  144. let count = 0;
  145. eventBus.on("test", function (evt) {
  146. expect(evt).toEqual(undefined);
  147. count++;
  148. });
  149. function domEventListener() {
  150. // Shouldn't get here.
  151. expect(false).toEqual(true);
  152. }
  153. document.addEventListener("test", domEventListener);
  154. eventBus.dispatch("test");
  155. await Promise.resolve();
  156. expect(count).toEqual(1);
  157. document.removeEventListener("test", domEventListener);
  158. });
  159. });
  160. describe("waitOnEventOrTimeout", function () {
  161. let eventBus;
  162. beforeAll(function () {
  163. eventBus = new EventBus();
  164. });
  165. afterAll(function () {
  166. eventBus = null;
  167. });
  168. it("should reject invalid parameters", async function () {
  169. const invalidTarget = waitOnEventOrTimeout({
  170. target: "window",
  171. name: "DOMContentLoaded",
  172. }).then(
  173. function () {
  174. // Shouldn't get here.
  175. expect(false).toEqual(true);
  176. },
  177. function (reason) {
  178. expect(reason instanceof Error).toEqual(true);
  179. }
  180. );
  181. const invalidName = waitOnEventOrTimeout({
  182. target: eventBus,
  183. name: "",
  184. }).then(
  185. function () {
  186. // Shouldn't get here.
  187. expect(false).toEqual(true);
  188. },
  189. function (reason) {
  190. expect(reason instanceof Error).toEqual(true);
  191. }
  192. );
  193. const invalidDelay = waitOnEventOrTimeout({
  194. target: eventBus,
  195. name: "pagerendered",
  196. delay: -1000,
  197. }).then(
  198. function () {
  199. // Shouldn't get here.
  200. expect(false).toEqual(true);
  201. },
  202. function (reason) {
  203. expect(reason instanceof Error).toEqual(true);
  204. }
  205. );
  206. await Promise.all([invalidTarget, invalidName, invalidDelay]);
  207. });
  208. it("should resolve on event, using the DOM", async function () {
  209. if (isNodeJS) {
  210. pending("Document is not supported in Node.js.");
  211. }
  212. const button = document.createElement("button");
  213. const buttonClicked = waitOnEventOrTimeout({
  214. target: button,
  215. name: "click",
  216. delay: 10000,
  217. });
  218. // Immediately dispatch the expected event.
  219. button.click();
  220. const type = await buttonClicked;
  221. expect(type).toEqual(WaitOnType.EVENT);
  222. });
  223. it("should resolve on timeout, using the DOM", async function () {
  224. if (isNodeJS) {
  225. pending("Document is not supported in Node.js.");
  226. }
  227. const button = document.createElement("button");
  228. const buttonClicked = waitOnEventOrTimeout({
  229. target: button,
  230. name: "click",
  231. delay: 10,
  232. });
  233. // Do *not* dispatch the event, and wait for the timeout.
  234. const type = await buttonClicked;
  235. expect(type).toEqual(WaitOnType.TIMEOUT);
  236. });
  237. it("should resolve on event, using the EventBus", async function () {
  238. const pageRendered = waitOnEventOrTimeout({
  239. target: eventBus,
  240. name: "pagerendered",
  241. delay: 10000,
  242. });
  243. // Immediately dispatch the expected event.
  244. eventBus.dispatch("pagerendered");
  245. const type = await pageRendered;
  246. expect(type).toEqual(WaitOnType.EVENT);
  247. });
  248. it("should resolve on timeout, using the EventBus", async function () {
  249. const pageRendered = waitOnEventOrTimeout({
  250. target: eventBus,
  251. name: "pagerendered",
  252. delay: 10,
  253. });
  254. // Do *not* dispatch the event, and wait for the timeout.
  255. const type = await pageRendered;
  256. expect(type).toEqual(WaitOnType.TIMEOUT);
  257. });
  258. });
  259. });