1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/addon-sdk/source/test/test-event-core.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,245 @@ 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 { on, once, off, emit, count } = require('sdk/event/core'); 1.11 +const { LoaderWithHookedConsole } = require("sdk/test/loader"); 1.12 + 1.13 +exports['test add a listener'] = function(assert) { 1.14 + let events = [ { name: 'event#1' }, 'event#2' ]; 1.15 + let target = { name: 'target' }; 1.16 + 1.17 + on(target, 'message', function(message) { 1.18 + assert.equal(this, target, 'this is a target object'); 1.19 + assert.equal(message, events.shift(), 'message is emitted event'); 1.20 + }); 1.21 + emit(target, 'message', events[0]); 1.22 + emit(target, 'message', events[0]); 1.23 +}; 1.24 + 1.25 +exports['test that listener is unique per type'] = function(assert) { 1.26 + let actual = [] 1.27 + let target = {} 1.28 + function listener() { actual.push(1) } 1.29 + on(target, 'message', listener); 1.30 + on(target, 'message', listener); 1.31 + on(target, 'message', listener); 1.32 + on(target, 'foo', listener); 1.33 + on(target, 'foo', listener); 1.34 + 1.35 + emit(target, 'message'); 1.36 + assert.deepEqual([ 1 ], actual, 'only one message listener added'); 1.37 + emit(target, 'foo'); 1.38 + assert.deepEqual([ 1, 1 ], actual, 'same listener added for other event'); 1.39 +}; 1.40 + 1.41 +exports['test event type matters'] = function(assert) { 1.42 + let target = { name: 'target' } 1.43 + on(target, 'message', function() { 1.44 + assert.fail('no event is expected'); 1.45 + }); 1.46 + on(target, 'done', function() { 1.47 + assert.pass('event is emitted'); 1.48 + }); 1.49 + emit(target, 'foo') 1.50 + emit(target, 'done'); 1.51 +}; 1.52 + 1.53 +exports['test all arguments are pasesd'] = function(assert) { 1.54 + let foo = { name: 'foo' }, bar = 'bar'; 1.55 + let target = { name: 'target' }; 1.56 + on(target, 'message', function(a, b) { 1.57 + assert.equal(a, foo, 'first argument passed'); 1.58 + assert.equal(b, bar, 'second argument passed'); 1.59 + }); 1.60 + emit(target, 'message', foo, bar); 1.61 +}; 1.62 + 1.63 +exports['test no side-effects in emit'] = function(assert) { 1.64 + let target = { name: 'target' }; 1.65 + on(target, 'message', function() { 1.66 + assert.pass('first listener is called'); 1.67 + on(target, 'message', function() { 1.68 + assert.fail('second listener is called'); 1.69 + }); 1.70 + }); 1.71 + emit(target, 'message'); 1.72 +}; 1.73 + 1.74 +exports['test can remove next listener'] = function(assert) { 1.75 + let target = { name: 'target' }; 1.76 + function fail() assert.fail('Listener should be removed'); 1.77 + 1.78 + on(target, 'data', function() { 1.79 + assert.pass('first litener called'); 1.80 + off(target, 'data', fail); 1.81 + }); 1.82 + on(target, 'data', fail); 1.83 + 1.84 + emit(target, 'data', 'hello'); 1.85 +}; 1.86 + 1.87 +exports['test order of propagation'] = function(assert) { 1.88 + let actual = []; 1.89 + let target = { name: 'target' }; 1.90 + on(target, 'message', function() { actual.push(1); }); 1.91 + on(target, 'message', function() { actual.push(2); }); 1.92 + on(target, 'message', function() { actual.push(3); }); 1.93 + emit(target, 'message'); 1.94 + assert.deepEqual([ 1, 2, 3 ], actual, 'called in order they were added'); 1.95 +}; 1.96 + 1.97 +exports['test remove a listener'] = function(assert) { 1.98 + let target = { name: 'target' }; 1.99 + let actual = []; 1.100 + on(target, 'message', function listener() { 1.101 + actual.push(1); 1.102 + on(target, 'message', function() { 1.103 + off(target, 'message', listener); 1.104 + actual.push(2); 1.105 + }) 1.106 + }); 1.107 + 1.108 + emit(target, 'message'); 1.109 + assert.deepEqual([ 1 ], actual, 'first listener called'); 1.110 + emit(target, 'message'); 1.111 + assert.deepEqual([ 1, 1, 2 ], actual, 'second listener called'); 1.112 + 1.113 + emit(target, 'message'); 1.114 + assert.deepEqual([ 1, 1, 2, 2, 2 ], actual, 'first listener removed'); 1.115 +}; 1.116 + 1.117 +exports['test remove all listeners for type'] = function(assert) { 1.118 + let actual = []; 1.119 + let target = { name: 'target' } 1.120 + on(target, 'message', function() { actual.push(1); }); 1.121 + on(target, 'message', function() { actual.push(2); }); 1.122 + on(target, 'message', function() { actual.push(3); }); 1.123 + on(target, 'bar', function() { actual.push('b') }); 1.124 + off(target, 'message'); 1.125 + 1.126 + emit(target, 'message'); 1.127 + emit(target, 'bar'); 1.128 + 1.129 + assert.deepEqual([ 'b' ], actual, 'all message listeners were removed'); 1.130 +}; 1.131 + 1.132 +exports['test remove all listeners'] = function(assert) { 1.133 + let actual = []; 1.134 + let target = { name: 'target' } 1.135 + on(target, 'message', function() { actual.push(1); }); 1.136 + on(target, 'message', function() { actual.push(2); }); 1.137 + on(target, 'message', function() { actual.push(3); }); 1.138 + on(target, 'bar', function() { actual.push('b') }); 1.139 + off(target); 1.140 + 1.141 + emit(target, 'message'); 1.142 + emit(target, 'bar'); 1.143 + 1.144 + assert.deepEqual([], actual, 'all listeners events were removed'); 1.145 +}; 1.146 + 1.147 +exports['test falsy arguments are fine'] = function(assert) { 1.148 + let type, listener, actual = []; 1.149 + let target = { name: 'target' } 1.150 + on(target, 'bar', function() { actual.push(0) }); 1.151 + 1.152 + off(target, 'bar', listener); 1.153 + emit(target, 'bar'); 1.154 + assert.deepEqual([ 0 ], actual, '3rd bad ard will keep listeners'); 1.155 + 1.156 + off(target, type); 1.157 + emit(target, 'bar'); 1.158 + assert.deepEqual([ 0, 0 ], actual, '2nd bad arg will keep listener'); 1.159 + 1.160 + off(target, type, listener); 1.161 + emit(target, 'bar'); 1.162 + assert.deepEqual([ 0, 0, 0 ], actual, '2nd&3rd bad args will keep listener'); 1.163 +}; 1.164 + 1.165 +exports['test error handling'] = function(assert) { 1.166 + let target = Object.create(null); 1.167 + let error = Error('boom!'); 1.168 + 1.169 + on(target, 'message', function() { throw error; }) 1.170 + on(target, 'error', function(boom) { 1.171 + assert.equal(boom, error, 'thrown exception causes error event'); 1.172 + }); 1.173 + emit(target, 'message'); 1.174 +}; 1.175 + 1.176 +exports['test unhandled exceptions'] = function(assert) { 1.177 + let exceptions = []; 1.178 + let { loader, messages } = LoaderWithHookedConsole(module); 1.179 + 1.180 + let { emit, on } = loader.require('sdk/event/core'); 1.181 + let target = {}; 1.182 + let boom = Error('Boom!'); 1.183 + let drax = Error('Draax!!'); 1.184 + 1.185 + on(target, 'message', function() { throw boom; }); 1.186 + 1.187 + emit(target, 'message'); 1.188 + assert.equal(messages.length, 1, 'Got the first exception'); 1.189 + assert.equal(messages[0].type, 'exception', 'The console message is exception'); 1.190 + assert.ok(~String(messages[0].msg).indexOf('Boom!'), 1.191 + 'unhandled exception is logged'); 1.192 + 1.193 + on(target, 'error', function() { throw drax; }); 1.194 + emit(target, 'message'); 1.195 + assert.equal(messages.length, 2, 'Got the second exception'); 1.196 + assert.equal(messages[1].type, 'exception', 'The console message is exception'); 1.197 + assert.ok(~String(messages[1].msg).indexOf('Draax!'), 1.198 + 'error in error handler is logged'); 1.199 +}; 1.200 + 1.201 +exports['test unhandled errors'] = function(assert) { 1.202 + let exceptions = []; 1.203 + let { loader, messages } = LoaderWithHookedConsole(module); 1.204 + 1.205 + let { emit, on } = loader.require('sdk/event/core'); 1.206 + let target = {}; 1.207 + let boom = Error('Boom!'); 1.208 + 1.209 + emit(target, 'error', boom); 1.210 + assert.equal(messages.length, 1, 'Error was logged'); 1.211 + assert.equal(messages[0].type, 'exception', 'The console message is exception'); 1.212 + assert.ok(~String(messages[0].msg).indexOf('Boom!'), 1.213 + 'unhandled exception is logged'); 1.214 +}; 1.215 + 1.216 + 1.217 +exports['test count'] = function(assert) { 1.218 + let target = {}; 1.219 + 1.220 + assert.equal(count(target, 'foo'), 0, 'no listeners for "foo" events'); 1.221 + on(target, 'foo', function() {}); 1.222 + assert.equal(count(target, 'foo'), 1, 'listener registered'); 1.223 + on(target, 'foo', function() {}, 2, 'another listener registered'); 1.224 + off(target) 1.225 + assert.equal(count(target, 'foo'), 0, 'listeners unregistered'); 1.226 +}; 1.227 + 1.228 +exports['test listen to all events'] = function(assert) { 1.229 + let actual = []; 1.230 + let target = {}; 1.231 + 1.232 + on(target, 'foo', message => actual.push(message)); 1.233 + on(target, '*', (type, ...message) => { 1.234 + actual.push([type].concat(message)); 1.235 + }); 1.236 + 1.237 + emit(target, 'foo', 'hello'); 1.238 + assert.equal(actual[0], 'hello', 1.239 + 'non-wildcard listeners still work'); 1.240 + assert.deepEqual(actual[1], ['foo', 'hello'], 1.241 + 'wildcard listener called'); 1.242 + 1.243 + emit(target, 'bar', 'goodbye'); 1.244 + assert.deepEqual(actual[2], ['bar', 'goodbye'], 1.245 + 'wildcard listener called for unbound event name'); 1.246 +}; 1.247 + 1.248 +require('test').run(exports);