michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: 'use strict'; michael@0: michael@0: const { on, emit } = require("sdk/event/core"); michael@0: const { filter, map, merge, expand, pipe, stripListeners } = require("sdk/event/utils"); michael@0: const $ = require("./event/helpers"); michael@0: michael@0: function isEven(x) !(x % 2) michael@0: function inc(x) x + 1 michael@0: michael@0: exports["test filter events"] = function(assert) { michael@0: let input = {}; michael@0: let evens = filter(input, isEven); michael@0: let actual = []; michael@0: on(evens, "data", function(e) actual.push(e)); michael@0: michael@0: [1, 2, 3, 4, 5, 6, 7].forEach(function(x) emit(input, "data", x)); michael@0: michael@0: assert.deepEqual(actual, [2, 4, 6], "only even numbers passed through"); michael@0: }; michael@0: michael@0: exports["test filter emits"] = $.emits(function(input, assert) { michael@0: let output = filter(input, isEven); michael@0: assert(output, [1, 2, 3, 4, 5], [2, 4], "this is `output` & evens passed"); michael@0: });; michael@0: michael@0: exports["test filter reg once"] = $.registerOnce(function(input, assert) { michael@0: assert(filter(input, isEven), [1, 2, 3, 4, 5, 6], [2, 4, 6], michael@0: "listener can be registered only once"); michael@0: }); michael@0: michael@0: exports["test filter ignores new"] = $.ignoreNew(function(input, assert) { michael@0: assert(filter(input, isEven), [1, 2, 3], [2], michael@0: "new listener is ignored") michael@0: }); michael@0: michael@0: exports["test filter is FIFO"] = $.FIFO(function(input, assert) { michael@0: assert(filter(input, isEven), [1, 2, 3, 4], [2, 4], michael@0: "listeners are invoked in fifo order") michael@0: }); michael@0: michael@0: exports["test map events"] = function(assert) { michael@0: let input = {}; michael@0: let incs = map(input, inc); michael@0: let actual = []; michael@0: on(incs, "data", function(e) actual.push(e)); michael@0: michael@0: [1, 2, 3, 4].forEach(function(x) emit(input, "data", x)); michael@0: michael@0: assert.deepEqual(actual, [2, 3, 4, 5], "all numbers were incremented"); michael@0: }; michael@0: michael@0: exports["test map emits"] = $.emits(function(input, assert) { michael@0: let output = map(input, inc); michael@0: assert(output, [1, 2, 3], [2, 3, 4], "this is `output` & evens passed"); michael@0: });; michael@0: michael@0: exports["test map reg once"] = $.registerOnce(function(input, assert) { michael@0: assert(map(input, inc), [1, 2, 3], [2, 3, 4], michael@0: "listener can be registered only once"); michael@0: }); michael@0: michael@0: exports["test map ignores new"] = $.ignoreNew(function(input, assert) { michael@0: assert(map(input, inc), [1], [2], michael@0: "new listener is ignored") michael@0: }); michael@0: michael@0: exports["test map is FIFO"] = $.FIFO(function(input, assert) { michael@0: assert(map(input, inc), [1, 2, 3, 4], [2, 3, 4, 5], michael@0: "listeners are invoked in fifo order") michael@0: }); michael@0: michael@0: exports["test merge stream[stream]"] = function(assert) { michael@0: let a = {}, b = {}, c = {}; michael@0: let inputs = {}; michael@0: let actual = []; michael@0: michael@0: on(merge(inputs), "data", function($) actual.push($)) michael@0: michael@0: emit(inputs, "data", a); michael@0: emit(a, "data", "a1"); michael@0: emit(inputs, "data", b); michael@0: emit(b, "data", "b1"); michael@0: emit(a, "data", "a2"); michael@0: emit(inputs, "data", c); michael@0: emit(c, "data", "c1"); michael@0: emit(c, "data", "c2"); michael@0: emit(b, "data", "b2"); michael@0: emit(a, "data", "a3"); michael@0: michael@0: assert.deepEqual(actual, ["a1", "b1", "a2", "c1", "c2", "b2", "a3"], michael@0: "all inputs data merged into one"); michael@0: }; michael@0: michael@0: exports["test merge array[stream]"] = function(assert) { michael@0: let a = {}, b = {}, c = {}; michael@0: let inputs = {}; michael@0: let actual = []; michael@0: michael@0: on(merge([a, b, c]), "data", function($) actual.push($)) michael@0: michael@0: emit(a, "data", "a1"); michael@0: emit(b, "data", "b1"); michael@0: emit(a, "data", "a2"); michael@0: emit(c, "data", "c1"); michael@0: emit(c, "data", "c2"); michael@0: emit(b, "data", "b2"); michael@0: emit(a, "data", "a3"); michael@0: michael@0: assert.deepEqual(actual, ["a1", "b1", "a2", "c1", "c2", "b2", "a3"], michael@0: "all inputs data merged into one"); michael@0: }; michael@0: michael@0: exports["test merge emits"] = $.emits(function(input, assert) { michael@0: let evens = filter(input, isEven) michael@0: let output = merge([evens, input]); michael@0: assert(output, [1, 2, 3], [1, 2, 2, 3], "this is `output` & evens passed"); michael@0: }); michael@0: michael@0: michael@0: exports["test merge reg once"] = $.registerOnce(function(input, assert) { michael@0: let evens = filter(input, isEven) michael@0: let output = merge([input, evens]); michael@0: assert(output, [1, 2, 3, 4], [1, 2, 2, 3, 4, 4], michael@0: "listener can be registered only once"); michael@0: }); michael@0: michael@0: exports["test merge ignores new"] = $.ignoreNew(function(input, assert) { michael@0: let evens = filter(input, isEven) michael@0: let output = merge([input, evens]) michael@0: assert(output, [1], [1], michael@0: "new listener is ignored") michael@0: }); michael@0: michael@0: exports["test marge is FIFO"] = $.FIFO(function(input, assert) { michael@0: let evens = filter(input, isEven) michael@0: let output = merge([input, evens]) michael@0: michael@0: assert(output, [1, 2, 3, 4], [1, 2, 2, 3, 4, 4], michael@0: "listeners are invoked in fifo order") michael@0: }); michael@0: michael@0: exports["test expand"] = function(assert) { michael@0: let a = {}, b = {}, c = {}; michael@0: let inputs = {}; michael@0: let actual = []; michael@0: michael@0: on(expand(inputs, function($) $()), "data", function($) actual.push($)) michael@0: michael@0: emit(inputs, "data", function() a); michael@0: emit(a, "data", "a1"); michael@0: emit(inputs, "data", function() b); michael@0: emit(b, "data", "b1"); michael@0: emit(a, "data", "a2"); michael@0: emit(inputs, "data", function() c); michael@0: emit(c, "data", "c1"); michael@0: emit(c, "data", "c2"); michael@0: emit(b, "data", "b2"); michael@0: emit(a, "data", "a3"); michael@0: michael@0: assert.deepEqual(actual, ["a1", "b1", "a2", "c1", "c2", "b2", "a3"], michael@0: "all inputs data merged into one"); michael@0: }; michael@0: michael@0: exports["test pipe"] = function (assert, done) { michael@0: let src = {}; michael@0: let dest = {}; michael@0: michael@0: let aneventCount = 0, multiargsCount = 0; michael@0: let wildcardCount = {}; michael@0: michael@0: on(dest, 'an-event', arg => { michael@0: assert.equal(arg, 'my-arg', 'piped argument to event'); michael@0: ++aneventCount; michael@0: check(); michael@0: }); michael@0: on(dest, 'multiargs', (...data) => { michael@0: assert.equal(data[0], 'a', 'multiple arguments passed via pipe'); michael@0: assert.equal(data[1], 'b', 'multiple arguments passed via pipe'); michael@0: assert.equal(data[2], 'c', 'multiple arguments passed via pipe'); michael@0: ++multiargsCount; michael@0: check(); michael@0: }); michael@0: michael@0: on(dest, '*', (name, ...data) => { michael@0: wildcardCount[name] = (wildcardCount[name] || 0) + 1; michael@0: if (name === 'multiargs') { michael@0: assert.equal(data[0], 'a', 'multiple arguments passed via pipe, wildcard'); michael@0: assert.equal(data[1], 'b', 'multiple arguments passed via pipe, wildcard'); michael@0: assert.equal(data[2], 'c', 'multiple arguments passed via pipe, wildcard'); michael@0: } michael@0: if (name === 'an-event') michael@0: assert.equal(data[0], 'my-arg', 'argument passed via pipe, wildcard'); michael@0: check(); michael@0: }); michael@0: michael@0: pipe(src, dest); michael@0: michael@0: for (let i = 0; i < 3; i++) michael@0: emit(src, 'an-event', 'my-arg'); michael@0: michael@0: emit(src, 'multiargs', 'a', 'b', 'c'); michael@0: michael@0: function check () { michael@0: if (aneventCount === 3 && multiargsCount === 1 && michael@0: wildcardCount['an-event'] === 3 && michael@0: wildcardCount['multiargs'] === 1) michael@0: done(); michael@0: } michael@0: }; michael@0: michael@0: exports["test pipe multiple targets"] = function (assert) { michael@0: let src1 = {}; michael@0: let src2 = {}; michael@0: let middle = {}; michael@0: let dest = {}; michael@0: michael@0: pipe(src1, middle); michael@0: pipe(src2, middle); michael@0: pipe(middle, dest); michael@0: michael@0: let middleFired = 0; michael@0: let destFired = 0; michael@0: let src1Fired = 0; michael@0: let src2Fired = 0; michael@0: michael@0: on(src1, '*', () => src1Fired++); michael@0: on(src2, '*', () => src2Fired++); michael@0: on(middle, '*', () => middleFired++); michael@0: on(dest, '*', () => destFired++); michael@0: michael@0: emit(src1, 'ev'); michael@0: assert.equal(src1Fired, 1, 'event triggers in source in pipe chain'); michael@0: assert.equal(middleFired, 1, 'event passes through the middle of pipe chain'); michael@0: assert.equal(destFired, 1, 'event propagates to end of pipe chain'); michael@0: assert.equal(src2Fired, 0, 'event does not fire on alternative chain routes'); michael@0: michael@0: emit(src2, 'ev'); michael@0: assert.equal(src2Fired, 1, 'event triggers in source in pipe chain'); michael@0: assert.equal(middleFired, 2, michael@0: 'event passes through the middle of pipe chain from different src'); michael@0: assert.equal(destFired, 2, michael@0: 'event propagates to end of pipe chain from different src'); michael@0: assert.equal(src1Fired, 1, 'event does not fire on alternative chain routes'); michael@0: michael@0: emit(middle, 'ev'); michael@0: assert.equal(middleFired, 3, michael@0: 'event triggers in source of pipe chain'); michael@0: assert.equal(destFired, 3, michael@0: 'event propagates to end of pipe chain from middle src'); michael@0: assert.equal(src1Fired, 1, 'event does not fire on alternative chain routes'); michael@0: assert.equal(src2Fired, 1, 'event does not fire on alternative chain routes'); michael@0: }; michael@0: michael@0: exports['test stripListeners'] = function (assert) { michael@0: var options = { michael@0: onAnEvent: noop1, michael@0: onMessage: noop2, michael@0: verb: noop1, michael@0: value: 100 michael@0: }; michael@0: michael@0: var stripped = stripListeners(options); michael@0: assert.ok(stripped !== options, 'stripListeners should return a new object'); michael@0: assert.equal(options.onAnEvent, noop1, 'stripListeners does not affect original'); michael@0: assert.equal(options.onMessage, noop2, 'stripListeners does not affect original'); michael@0: assert.equal(options.verb, noop1, 'stripListeners does not affect original'); michael@0: assert.equal(options.value, 100, 'stripListeners does not affect original'); michael@0: michael@0: assert.ok(!stripped.onAnEvent, 'stripListeners removes `on*` values'); michael@0: assert.ok(!stripped.onMessage, 'stripListeners removes `on*` values'); michael@0: assert.equal(stripped.verb, noop1, 'stripListeners leaves not `on*` values'); michael@0: assert.equal(stripped.value, 100, 'stripListeners leaves not `on*` values'); michael@0: michael@0: function noop1 () {} michael@0: function noop2 () {} michael@0: }; michael@0: michael@0: require('test').run(exports);