1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/toolkit/devtools/tests/mochitest/test_eventemitter_basic.html Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,179 @@ 1.4 +<!DOCTYPE html> 1.5 +<!-- 1.6 + Any copyright is dedicated to the Public Domain. 1.7 + http://creativecommons.org/publicdomain/zero/1.0/ 1.8 +--> 1.9 + 1.10 +<html> 1.11 + 1.12 + <head> 1.13 + <meta charset="utf8"> 1.14 + <title></title> 1.15 + 1.16 + <script type="application/javascript" 1.17 + src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> 1.18 + <link rel="stylesheet" type="text/css" 1.19 + href="chrome://mochikit/content/tests/SimpleTest/test.css"> 1.20 + </head> 1.21 + 1.22 + <body> 1.23 + 1.24 + <script type="application/javascript;version=1.8"> 1.25 + "use strict"; 1.26 + 1.27 + const { utils: Cu } = Components; 1.28 + const { Promise: promise } = 1.29 + Cu.import("resource://gre/modules/devtools/deprecated-sync-thenables.js", {}); 1.30 + const { EventEmitter } = 1.31 + Cu.import("resource://gre/modules/devtools/event-emitter.js", {}); 1.32 + const { Task } = Cu.import("resource://gre/modules/Task.jsm", {}); 1.33 + 1.34 + SimpleTest.waitForExplicitFinish(); 1.35 + 1.36 + testEmitter(); 1.37 + testEmitter({}); 1.38 + 1.39 + Task.spawn(testPromise) 1.40 + .then(null, ok.bind(null, false)) 1.41 + .then(SimpleTest.finish); 1.42 + 1.43 + function testEmitter(aObject) { 1.44 + let emitter; 1.45 + 1.46 + if (aObject) { 1.47 + emitter = aObject; 1.48 + EventEmitter.decorate(emitter); 1.49 + } else { 1.50 + emitter = new EventEmitter(); 1.51 + } 1.52 + 1.53 + ok(emitter, "We have an event emitter"); 1.54 + 1.55 + emitter.on("next", next); 1.56 + emitter.emit("next", "abc", "def"); 1.57 + 1.58 + let beenHere1 = false; 1.59 + function next(eventName, str1, str2) { 1.60 + is(eventName, "next", "Got event"); 1.61 + is(str1, "abc", "Argument 1 is correct"); 1.62 + is(str2, "def", "Argument 2 is correct"); 1.63 + 1.64 + ok(!beenHere1, "first time in next callback"); 1.65 + beenHere1 = true; 1.66 + 1.67 + emitter.off("next", next); 1.68 + 1.69 + emitter.emit("next"); 1.70 + 1.71 + emitter.once("onlyonce", onlyOnce); 1.72 + 1.73 + emitter.emit("onlyonce"); 1.74 + emitter.emit("onlyonce"); 1.75 + } 1.76 + 1.77 + let beenHere2 = false; 1.78 + function onlyOnce() { 1.79 + ok(!beenHere2, "\"once\" listner has been called once"); 1.80 + beenHere2 = true; 1.81 + emitter.emit("onlyonce"); 1.82 + 1.83 + killItWhileEmitting(); 1.84 + } 1.85 + 1.86 + function killItWhileEmitting() { 1.87 + function c1() { 1.88 + ok(true, "c1 called"); 1.89 + } 1.90 + function c2() { 1.91 + ok(true, "c2 called"); 1.92 + emitter.off("tick", c3); 1.93 + } 1.94 + function c3() { 1.95 + ok(false, "c3 should not be called"); 1.96 + } 1.97 + function c4() { 1.98 + ok(true, "c4 called"); 1.99 + } 1.100 + 1.101 + emitter.on("tick", c1); 1.102 + emitter.on("tick", c2); 1.103 + emitter.on("tick", c3); 1.104 + emitter.on("tick", c4); 1.105 + 1.106 + emitter.emit("tick"); 1.107 + 1.108 + offAfterOnce(); 1.109 + } 1.110 + 1.111 + function offAfterOnce() { 1.112 + let enteredC1 = false; 1.113 + 1.114 + function c1() { 1.115 + enteredC1 = true; 1.116 + } 1.117 + 1.118 + emitter.once("oao", c1); 1.119 + emitter.off("oao", c1); 1.120 + 1.121 + emitter.emit("oao"); 1.122 + 1.123 + ok(!enteredC1, "c1 should not be called"); 1.124 + } 1.125 + } 1.126 + 1.127 + function testPromise() { 1.128 + let emitter = new EventEmitter(); 1.129 + let p = emitter.once("thing"); 1.130 + 1.131 + // Check that the promise is only resolved once event though we 1.132 + // emit("thing") more than once 1.133 + let firstCallbackCalled = false; 1.134 + let check1 = p.then(arg => { 1.135 + is(firstCallbackCalled, false, "first callback called only once"); 1.136 + firstCallbackCalled = true; 1.137 + is(arg, "happened", "correct arg in promise"); 1.138 + return "rval from c1"; 1.139 + }); 1.140 + 1.141 + emitter.emit("thing", "happened", "ignored"); 1.142 + 1.143 + // Check that the promise is resolved asynchronously 1.144 + let secondCallbackCalled = false; 1.145 + let check2 = p.then(arg => { 1.146 + ok(true, "second callback called"); 1.147 + is(arg, "happened", "correct arg in promise"); 1.148 + secondCallbackCalled = true; 1.149 + is(arg, "happened", "correct arg in promise (a second time)"); 1.150 + return "rval from c2"; 1.151 + }); 1.152 + 1.153 + // Shouldn't call any of the above listeners 1.154 + emitter.emit("thing", "trashinate"); 1.155 + 1.156 + // Check that we can still separate events with different names 1.157 + // and that it works with no parameters 1.158 + let pfoo = emitter.once("foo"); 1.159 + let pbar = emitter.once("bar"); 1.160 + 1.161 + let check3 = pfoo.then(arg => { 1.162 + ok(arg === undefined, "no arg for foo event"); 1.163 + return "rval from c3"; 1.164 + }); 1.165 + 1.166 + pbar.then(() => { 1.167 + ok(false, "pbar should not be called"); 1.168 + }); 1.169 + 1.170 + emitter.emit("foo"); 1.171 + 1.172 + is(secondCallbackCalled, false, "second callback not called yet"); 1.173 + 1.174 + return promise.all([ check1, check2, check3 ]).then(args => { 1.175 + is(args[0], "rval from c1", "callback 1 done good"); 1.176 + is(args[1], "rval from c2", "callback 2 done good"); 1.177 + is(args[2], "rval from c3", "callback 3 done good"); 1.178 + }); 1.179 + } 1.180 + </script> 1.181 + </body> 1.182 +</html>