Thu, 15 Jan 2015 15:59:08 +0100
Implement a real Private Browsing Mode condition by changing the API/ABI;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.
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';
6 const { LoaderWithHookedConsole } = require("sdk/test/loader");
8 // Exposing private methods as public in order to test
9 const EventEmitter = require('sdk/deprecated/events').EventEmitter.compose({
10 listeners: function(type) this._listeners(type),
11 emit: function() this._emit.apply(this, arguments),
12 emitOnObject: function() this._emitOnObject.apply(this, arguments),
13 removeAllListeners: function(type) this._removeAllListeners(type)
14 });
16 exports['test:add listeners'] = function(assert) {
17 let e = new EventEmitter();
19 let events_new_listener_emited = [];
20 let times_hello_emited = 0;
22 e.on("newListener", function (event, listener) {
23 events_new_listener_emited.push(event)
24 })
26 e.on("hello", function (a, b) {
27 times_hello_emited += 1
28 assert.equal("a", a)
29 assert.equal("b", b)
30 assert.equal(this, e, '`this` pseudo-variable is bound to instance');
31 })
33 e.emit("hello", "a", "b")
34 };
36 exports['test:removeListener'] = function(assert) {
37 let count = 0;
39 function listener1 () {
40 count++;
41 }
42 function listener2 () {
43 count++;
44 }
46 // test adding and removing listener
47 let e1 = new EventEmitter();
48 assert.equal(0, e1.listeners('hello').length);
49 e1.on("hello", listener1);
50 assert.equal(1, e1.listeners('hello').length);
51 assert.equal(listener1, e1.listeners('hello')[0]);
52 e1.removeListener("hello", listener1);
53 assert.equal(0, e1.listeners('hello').length);
54 e1.emit("hello", "");
55 assert.equal(0, count);
57 // test adding one listener and removing another which was not added
58 let e2 = new EventEmitter();
59 assert.equal(0, e2.listeners('hello').length);
60 e2.on("hello", listener1);
61 assert.equal(1, e2.listeners('hello').length);
62 e2.removeListener("hello", listener2);
63 assert.equal(1, e2.listeners('hello').length);
64 assert.equal(listener1, e2.listeners('hello')[0]);
65 e2.emit("hello", "");
66 assert.equal(1, count);
68 // test adding 2 listeners, and removing one
69 let e3 = new EventEmitter();
70 assert.equal(0, e3.listeners('hello').length);
71 e3.on("hello", listener1);
72 assert.equal(1, e3.listeners('hello').length);
73 e3.on("hello", listener2);
74 assert.equal(2, e3.listeners('hello').length);
75 e3.removeListener("hello", listener1);
76 assert.equal(1, e3.listeners('hello').length);
77 assert.equal(listener2, e3.listeners('hello')[0]);
78 e3.emit("hello", "");
79 assert.equal(2, count);
80 };
82 exports['test:removeAllListeners'] = function(assert) {
83 let count = 0;
85 function listener1 () {
86 count++;
87 }
88 function listener2 () {
89 count++;
90 }
92 // test adding a listener and removing all of that type
93 let e1 = new EventEmitter();
94 e1.on("hello", listener1);
95 assert.equal(1, e1.listeners('hello').length);
96 e1.removeAllListeners("hello");
97 assert.equal(0, e1.listeners('hello').length);
98 e1.emit("hello", "");
99 assert.equal(0, count);
101 // test adding a listener and removing all of another type
102 let e2 = new EventEmitter();
103 e2.on("hello", listener1);
104 assert.equal(1, e2.listeners('hello').length);
105 e2.removeAllListeners('goodbye');
106 assert.equal(1, e2.listeners('hello').length);
107 e2.emit("hello", "");
108 assert.equal(1, count);
110 // test adding 1+ listeners and removing all of that type
111 let e3 = new EventEmitter();
112 e3.on("hello", listener1);
113 assert.equal(1, e3.listeners('hello').length);
114 e3.on("hello", listener2);
115 assert.equal(2, e3.listeners('hello').length);
116 e3.removeAllListeners("hello");
117 assert.equal(0, e3.listeners('hello').length);
118 e3.emit("hello", "");
119 assert.equal(1, count);
121 // test adding 2 listeners for 2 types and removing all listeners
122 let e4 = new EventEmitter();
123 e4.on("hello", listener1);
124 assert.equal(1, e4.listeners('hello').length);
125 e4.on('goodbye', listener2);
126 assert.equal(1, e4.listeners('goodbye').length);
127 e4.emit("goodbye", "");
128 e4.removeAllListeners();
129 assert.equal(0, e4.listeners('hello').length);
130 assert.equal(0, e4.listeners('goodbye').length);
131 e4.emit("hello", "");
132 e4.emit("goodbye", "");
133 assert.equal(2, count);
134 };
136 exports['test: modify in emit'] = function(assert) {
137 let callbacks_called = [ ];
138 let e = new EventEmitter();
140 function callback1() {
141 callbacks_called.push("callback1");
142 e.on("foo", callback2);
143 e.on("foo", callback3);
144 e.removeListener("foo", callback1);
145 }
146 function callback2() {
147 callbacks_called.push("callback2");
148 e.removeListener("foo", callback2);
149 }
150 function callback3() {
151 callbacks_called.push("callback3");
152 e.removeListener("foo", callback3);
153 }
155 e.on("foo", callback1);
156 assert.equal(1, e.listeners("foo").length);
158 e.emit("foo");
159 assert.equal(2, e.listeners("foo").length);
160 assert.equal(1, callbacks_called.length);
161 assert.equal('callback1', callbacks_called[0]);
163 e.emit("foo");
164 assert.equal(0, e.listeners("foo").length);
165 assert.equal(3, callbacks_called.length);
166 assert.equal('callback1', callbacks_called[0]);
167 assert.equal('callback2', callbacks_called[1]);
168 assert.equal('callback3', callbacks_called[2]);
170 e.emit("foo");
171 assert.equal(0, e.listeners("foo").length);
172 assert.equal(3, callbacks_called.length);
173 assert.equal('callback1', callbacks_called[0]);
174 assert.equal('callback2', callbacks_called[1]);
175 assert.equal('callback3', callbacks_called[2]);
177 e.on("foo", callback1);
178 e.on("foo", callback2);
179 assert.equal(2, e.listeners("foo").length);
180 e.removeAllListeners("foo");
181 assert.equal(0, e.listeners("foo").length);
183 // Verify that removing callbacks while in emit allows emits to propagate to
184 // all listeners
185 callbacks_called = [ ];
187 e.on("foo", callback2);
188 e.on("foo", callback3);
189 assert.equal(2, e.listeners("foo").length);
190 e.emit("foo");
191 assert.equal(2, callbacks_called.length);
192 assert.equal('callback2', callbacks_called[0]);
193 assert.equal('callback3', callbacks_called[1]);
194 assert.equal(0, e.listeners("foo").length);
195 };
197 exports['test:adding same listener'] = function(assert) {
198 function foo() {}
199 let e = new EventEmitter();
200 e.on("foo", foo);
201 e.on("foo", foo);
202 assert.equal(
203 1,
204 e.listeners("foo").length,
205 "listener reregistration is ignored"
206 );
207 }
209 exports['test:errors are reported if listener throws'] = function(assert) {
210 let e = new EventEmitter(),
211 reported = false;
212 e.on('error', function(e) reported = true)
213 e.on('boom', function() { throw new Error('Boom!') });
214 e.emit('boom', 3);
215 assert.ok(reported, 'error should be reported through event');
216 };
218 exports['test:emitOnObject'] = function(assert) {
219 let e = new EventEmitter();
221 e.on("foo", function() {
222 assert.equal(this, e, "`this` should be emitter");
223 });
224 e.emitOnObject(e, "foo");
226 e.on("bar", function() {
227 assert.equal(this, obj, "`this` should be other object");
228 });
229 let obj = {};
230 e.emitOnObject(obj, "bar");
231 };
233 exports['test:once'] = function(assert) {
234 let e = new EventEmitter();
235 let called = false;
237 e.once('foo', function(value) {
238 assert.ok(!called, "listener called only once");
239 assert.equal(value, "bar", "correct argument was passed");
240 });
242 e.emit('foo', 'bar');
243 e.emit('foo', 'baz');
244 };
246 exports["test:removing once"] = function(assert) {
247 let e = require("sdk/deprecated/events").EventEmitterTrait.create();
248 e.once("foo", function() { assert.pass("listener was called"); });
249 e.once("error", function() { assert.fail("error event was emitted"); });
250 e._emit("foo", "bug-656684");
251 };
253 // Bug 726967: Ensure that `emit` doesn't do an infinite loop when `error`
254 // listener throws an exception
255 exports['test:emitLoop'] = function(assert) {
256 // Override the console for this test so it doesn't log the exception to the
257 // test output
258 let { loader } = LoaderWithHookedConsole(module);
260 let EventEmitter = loader.require('sdk/deprecated/events').EventEmitter.compose({
261 listeners: function(type) this._listeners(type),
262 emit: function() this._emit.apply(this, arguments),
263 emitOnObject: function() this._emitOnObject.apply(this, arguments),
264 removeAllListeners: function(type) this._removeAllListeners(type)
265 });
267 let e = new EventEmitter();
269 e.on("foo", function() {
270 throw new Error("foo");
271 });
273 e.on("error", function() {
274 throw new Error("error");
275 });
276 e.emit("foo");
278 assert.pass("emit didn't looped");
279 };
281 require('sdk/test').run(exports);