1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/addon-sdk/source/test/test-event-target.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,205 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 + 1.8 +'use strict'; 1.9 + 1.10 +const { emit } = require('sdk/event/core'); 1.11 +const { EventTarget } = require('sdk/event/target'); 1.12 +const { Loader } = require('sdk/test/loader'); 1.13 + 1.14 +exports['test add a listener'] = function(assert) { 1.15 + let events = [ { name: 'event#1' }, 'event#2' ]; 1.16 + let target = EventTarget(); 1.17 + 1.18 + target.on('message', function(message) { 1.19 + assert.equal(this, target, 'this is a target object'); 1.20 + assert.equal(message, events.shift(), 'message is emitted event'); 1.21 + }); 1.22 + 1.23 + emit(target, 'message', events[0]); 1.24 + emit(target, 'message', events[0]); 1.25 +}; 1.26 + 1.27 +exports['test pass in listeners'] = function(assert) { 1.28 + let actual = [ ]; 1.29 + let target = EventTarget({ 1.30 + onMessage: function onMessage(message) { 1.31 + assert.equal(this, target, 'this is an event target'); 1.32 + actual.push(1); 1.33 + }, 1.34 + onFoo: null, 1.35 + onbla: function() { 1.36 + assert.fail('`onbla` is not supposed to be called'); 1.37 + } 1.38 + }); 1.39 + target.on('message', function(message) { 1.40 + assert.equal(this, target, 'this is an event target'); 1.41 + actual.push(2); 1.42 + }); 1.43 + 1.44 + emit(target, 'message'); 1.45 + emit(target, 'missing'); 1.46 + 1.47 + assert.deepEqual([ 1, 2 ], actual, 'all listeners trigerred in right order'); 1.48 +}; 1.49 + 1.50 +exports['test that listener is unique per type'] = function(assert) { 1.51 + let actual = [] 1.52 + let target = EventTarget(); 1.53 + function listener() { actual.push(1) } 1.54 + target.on('message', listener); 1.55 + target.on('message', listener); 1.56 + target.on('message', listener); 1.57 + target.on('foo', listener); 1.58 + target.on('foo', listener); 1.59 + 1.60 + emit(target, 'message'); 1.61 + assert.deepEqual([ 1 ], actual, 'only one message listener added'); 1.62 + emit(target, 'foo'); 1.63 + assert.deepEqual([ 1, 1 ], actual, 'same listener added for other event'); 1.64 +}; 1.65 + 1.66 +exports['test event type matters'] = function(assert) { 1.67 + let target = EventTarget(); 1.68 + target.on('message', function() { 1.69 + assert.fail('no event is expected'); 1.70 + }); 1.71 + target.on('done', function() { 1.72 + assert.pass('event is emitted'); 1.73 + }); 1.74 + 1.75 + emit(target, 'foo'); 1.76 + emit(target, 'done'); 1.77 +}; 1.78 + 1.79 +exports['test all arguments are pasesd'] = function(assert) { 1.80 + let foo = { name: 'foo' }, bar = 'bar'; 1.81 + let target = EventTarget(); 1.82 + target.on('message', function(a, b) { 1.83 + assert.equal(a, foo, 'first argument passed'); 1.84 + assert.equal(b, bar, 'second argument passed'); 1.85 + }); 1.86 + emit(target, 'message', foo, bar); 1.87 +}; 1.88 + 1.89 +exports['test no side-effects in emit'] = function(assert) { 1.90 + let target = EventTarget(); 1.91 + target.on('message', function() { 1.92 + assert.pass('first listener is called'); 1.93 + target.on('message', function() { 1.94 + assert.fail('second listener is called'); 1.95 + }); 1.96 + }); 1.97 + emit(target, 'message'); 1.98 +}; 1.99 + 1.100 +exports['test order of propagation'] = function(assert) { 1.101 + let actual = []; 1.102 + let target = EventTarget(); 1.103 + target.on('message', function() { actual.push(1); }); 1.104 + target.on('message', function() { actual.push(2); }); 1.105 + target.on('message', function() { actual.push(3); }); 1.106 + emit(target, 'message'); 1.107 + assert.deepEqual([ 1, 2, 3 ], actual, 'called in order they were added'); 1.108 +}; 1.109 + 1.110 +exports['test remove a listener'] = function(assert) { 1.111 + let target = EventTarget(); 1.112 + let actual = []; 1.113 + target.on('message', function listener() { 1.114 + actual.push(1); 1.115 + target.on('message', function() { 1.116 + target.removeListener('message', listener); 1.117 + actual.push(2); 1.118 + }) 1.119 + }); 1.120 + 1.121 + target.off('message'); // must do nothing. 1.122 + emit(target, 'message'); 1.123 + assert.deepEqual([ 1 ], actual, 'first listener called'); 1.124 + emit(target, 'message'); 1.125 + assert.deepEqual([ 1, 1, 2 ], actual, 'second listener called'); 1.126 + emit(target, 'message'); 1.127 + assert.deepEqual([ 1, 1, 2, 2, 2 ], actual, 'first listener removed'); 1.128 +}; 1.129 + 1.130 +exports['test error handling'] = function(assert) { 1.131 + let target = EventTarget(); 1.132 + let error = Error('boom!'); 1.133 + 1.134 + target.on('message', function() { throw error; }) 1.135 + target.on('error', function(boom) { 1.136 + assert.equal(boom, error, 'thrown exception causes error event'); 1.137 + }); 1.138 + emit(target, 'message'); 1.139 +}; 1.140 + 1.141 +exports['test unhandled errors'] = function(assert) { 1.142 + let exceptions = []; 1.143 + let loader = Loader(module); 1.144 + let { emit } = loader.require('sdk/event/core'); 1.145 + let { EventTarget } = loader.require('sdk/event/target'); 1.146 + Object.defineProperties(loader.sandbox('sdk/event/core'), { 1.147 + console: { value: { 1.148 + exception: function(e) { 1.149 + exceptions.push(e); 1.150 + } 1.151 + }} 1.152 + }); 1.153 + let target = EventTarget(); 1.154 + let boom = Error('Boom!'); 1.155 + let drax = Error('Draax!!'); 1.156 + 1.157 + target.on('message', function() { throw boom; }); 1.158 + 1.159 + emit(target, 'message'); 1.160 + assert.ok(~String(exceptions[0]).indexOf('Boom!'), 1.161 + 'unhandled exception is logged'); 1.162 + 1.163 + target.on('error', function() { throw drax; }); 1.164 + emit(target, 'message'); 1.165 + assert.ok(~String(exceptions[1]).indexOf('Draax!'), 1.166 + 'error in error handler is logged'); 1.167 +}; 1.168 + 1.169 +exports['test target is chainable'] = function (assert, done) { 1.170 + let loader = Loader(module); 1.171 + let exceptions = []; 1.172 + let { EventTarget } = loader.require('sdk/event/target'); 1.173 + let { emit } = loader.require('sdk/event/core'); 1.174 + Object.defineProperties(loader.sandbox('sdk/event/core'), { 1.175 + console: { value: { 1.176 + exception: function(e) { 1.177 + exceptions.push(e); 1.178 + } 1.179 + }} 1.180 + }); 1.181 + 1.182 + let emitter = EventTarget(); 1.183 + let boom = Error('Boom'); 1.184 + let onceCalled = 0; 1.185 + 1.186 + emitter.once('oneTime', function () { 1.187 + assert.equal(++onceCalled, 1, 'once event called only once'); 1.188 + }).on('data', function (message) { 1.189 + assert.equal(message, 'message', 'handles event'); 1.190 + emit(emitter, 'oneTime'); 1.191 + emit(emitter, 'data2', 'message2'); 1.192 + }).on('phony', function () { 1.193 + assert.fail('removeListener does not remove chained event'); 1.194 + }).removeListener('phony') 1.195 + .on('data2', function (message) { 1.196 + assert.equal(message, 'message2', 'handle chained event'); 1.197 + emit(emitter, 'oneTime'); 1.198 + throw boom; 1.199 + }).on('error', function (error) { 1.200 + assert.equal(error, boom, 'error handled in chained event'); 1.201 + done(); 1.202 + }); 1.203 + 1.204 + emit(emitter, 'data', 'message'); 1.205 +}; 1.206 + 1.207 +require('test').run(exports); 1.208 +