blob: 5588e4c2d76070c02c92ad5133bbabb8f73e1eb4 [file] [log] [blame]
/*
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
describe('channel', function () {
var channel = cordova.require('cordova/channel');
var multiChannel;
var stickyChannel;
function expectCallCount (spy, count) {
expect(spy).toHaveBeenCalledTimes(count);
}
beforeEach(function () {
multiChannel = channel.create('multiChannel');
stickyChannel = channel.createSticky('stickyChannel');
});
describe('subscribe method', function () {
it('Test#001 : should throw an exception if no arguments are provided', function () {
expect(function () {
multiChannel.subscribe();
}).toThrow();
expect(function () {
multiChannel.subscribe(null);
}).toThrow();
expect(function () {
multiChannel.subscribe(undefined);
}).toThrow();
});
it('Test#002 : should accept a function or an EventListener object implementing the handleEvent interface', function () {
expect(function () {
multiChannel.subscribe(function () {});
}).not.toThrow();
expect(function () {
multiChannel.subscribe({ handleEvent: function () {} });
}).not.toThrow();
expect(function () {
multiChannel.subscribe({ apply: function () {}, call: function () {} });
}).toThrow();
});
it('Test#003 : should not change number of handlers if no function is provided', function () {
var initialLength = multiChannel.numHandlers;
try {
multiChannel.subscribe();
} catch (e) {}
expect(multiChannel.numHandlers).toEqual(initialLength);
try {
multiChannel.subscribe(null);
} catch (e) {}
expect(multiChannel.numHandlers).toEqual(initialLength);
});
it('Test#004 : should not change number of handlers when subscribing same function multiple times', function () {
var handler = function () {};
multiChannel.subscribe(handler);
multiChannel.subscribe(handler);
stickyChannel.subscribe(handler);
stickyChannel.subscribe(handler);
expect(multiChannel.numHandlers).toEqual(1);
expect(stickyChannel.numHandlers).toEqual(1);
});
});
describe('unsubscribe method', function () {
it('Test#005 : should throw an exception if no arguments are provided', function () {
expect(function () {
multiChannel.unsubscribe();
}).toThrow();
expect(function () {
multiChannel.unsubscribe(null);
}).toThrow();
});
it('Test#006 : should accept a function or an EventListener object implementing the handleEvent interface', function () {
expect(function () {
multiChannel.unsubscribe(function () {});
}).not.toThrow();
expect(function () {
multiChannel.unsubscribe({ handleEvent: function () {} });
}).not.toThrow();
expect(function () {
multiChannel.unsubscribe({ apply: function () {}, call: function () {} });
}).toThrow();
});
it('Test#007 : should not decrement numHandlers if unsubscribing something that does not exist', function () {
multiChannel.subscribe(function () {});
multiChannel.unsubscribe(function () {});
expect(multiChannel.numHandlers).toEqual(1);
});
it('Test#008 : should change the handlers length appropriately', function () {
var firstHandler = function () {};
var secondHandler = function () {};
var thirdHandler = function () {};
multiChannel.subscribe(firstHandler);
multiChannel.subscribe(secondHandler);
multiChannel.subscribe(thirdHandler);
expect(multiChannel.numHandlers).toEqual(3);
multiChannel.unsubscribe(thirdHandler);
expect(multiChannel.numHandlers).toEqual(2);
multiChannel.unsubscribe(firstHandler);
multiChannel.unsubscribe(secondHandler);
expect(multiChannel.numHandlers).toEqual(0);
});
it('Test#009 : should not decrement handlers length more than once if unsubscribing a single handler', function () {
var firstHandler = function () {};
multiChannel.subscribe(firstHandler);
expect(multiChannel.numHandlers).toEqual(1);
multiChannel.unsubscribe(firstHandler);
multiChannel.unsubscribe(firstHandler);
multiChannel.unsubscribe(firstHandler);
multiChannel.unsubscribe(firstHandler);
expect(multiChannel.numHandlers).toEqual(0);
});
it('Test#010 : should not unregister a function registered with a different handler', function () {
var cHandler = function () {};
var c2Handler = function () {};
var c2 = channel.create('jables');
multiChannel.subscribe(cHandler);
c2.subscribe(c2Handler);
expect(multiChannel.numHandlers).toEqual(1);
expect(c2.numHandlers).toEqual(1);
multiChannel.unsubscribe(c2Handler);
c2.unsubscribe(cHandler);
expect(multiChannel.numHandlers).toEqual(1);
expect(c2.numHandlers).toEqual(1);
});
});
function commonFireTests (multi) {
it('Test#011 : should fire all subscribed handlers', function () {
var testChannel = multi ? multiChannel : stickyChannel;
var handler = jasmine.createSpy();
var anotherOne = jasmine.createSpy();
testChannel.subscribe(handler);
testChannel.subscribe(anotherOne);
testChannel.fire();
expectCallCount(handler, 1);
expectCallCount(anotherOne, 1);
});
it('Test#012 : should pass params to handlers', function () {
var testChannel = multi ? multiChannel : stickyChannel;
var handler = jasmine.createSpy();
testChannel.subscribe(handler);
testChannel.fire(1, 2, 3);
expect(handler.calls.argsFor(0)).toEqual([1, 2, 3]);
});
it('Test#013 : should not fire a handler that was unsubscribed', function () {
var testChannel = multi ? multiChannel : stickyChannel;
var handler = jasmine.createSpy();
var anotherOne = jasmine.createSpy();
testChannel.subscribe(handler);
testChannel.subscribe(anotherOne);
testChannel.unsubscribe(handler);
testChannel.fire();
expectCallCount(handler, 0);
expectCallCount(anotherOne, 1);
});
it('Test#014 : should not fire a handler more than once if it was subscribed more than once', function () {
var testChannel = multi ? multiChannel : stickyChannel;
var handler = jasmine.createSpy();
testChannel.subscribe(handler);
testChannel.subscribe(handler);
testChannel.subscribe(handler);
testChannel.fire();
expectCallCount(handler, 1);
});
it('Test#15 : handler should be called when subscribed, removed, and subscribed again', function () {
var testChannel = multi ? multiChannel : stickyChannel;
var handler = jasmine.createSpy();
testChannel.subscribe(handler);
testChannel.unsubscribe(handler);
testChannel.subscribe(handler);
testChannel.fire();
expectCallCount(handler, 1);
});
it('Test#016 : should not prevent a callback from firing when it is removed during firing.', function () {
var testChannel = multi ? multiChannel : stickyChannel;
var handler = jasmine.createSpy().and.callFake(function () { testChannel.unsubscribe(handler2); });
var handler2 = jasmine.createSpy();
testChannel.subscribe(handler);
testChannel.subscribe(handler2);
testChannel.fire();
expectCallCount(handler, 1);
expectCallCount(handler2, 1);
});
}
describe('fire method for sticky channels', function () {
commonFireTests(false);
it('Test#017 : should instantly trigger the callback if the event has already been fired', function () {
var before = jasmine.createSpy('before');
var after = jasmine.createSpy('after');
stickyChannel.subscribe(before);
stickyChannel.fire(1, 2, 3);
stickyChannel.subscribe(after);
expectCallCount(before, 1);
expectCallCount(after, 1);
expect(after.calls.argsFor(0)).toEqual([1, 2, 3]);
});
it('Test#018 : should instantly trigger the callback if the event is currently being fired.', function () {
var handler1 = jasmine.createSpy().and.callFake(function () { stickyChannel.subscribe(handler2); });
var handler2 = jasmine.createSpy().and.callFake(function (arg1) { expect(arg1).toEqual('foo'); });
stickyChannel.subscribe(handler1);
stickyChannel.fire('foo');
expectCallCount(handler2, 1);
});
it('Test#019 : should unregister all handlers after being fired.', function () {
var handler = jasmine.createSpy();
stickyChannel.subscribe(handler);
stickyChannel.fire();
stickyChannel.fire();
expectCallCount(handler, 1);
});
});
describe('fire method for multi channels', function () {
commonFireTests(true);
it('Test#020 : should not trigger the callback if the event has already been fired', function () {
var before = jasmine.createSpy('before');
var after = jasmine.createSpy('after');
multiChannel.subscribe(before);
multiChannel.fire();
multiChannel.subscribe(after);
expectCallCount(before, 1);
expectCallCount(after, 0);
});
it('Test#021 : should not trigger the callback if the event is currently being fired.', function () {
var handler1 = jasmine.createSpy().and.callFake(function () { multiChannel.subscribe(handler2); });
var handler2 = jasmine.createSpy();
multiChannel.subscribe(handler1);
multiChannel.fire();
multiChannel.fire();
expectCallCount(handler1, 2);
expectCallCount(handler2, 1);
});
it('Test#022 : should not unregister handlers after being fired.', function () {
var handler = jasmine.createSpy();
multiChannel.subscribe(handler);
multiChannel.fire();
multiChannel.fire();
expectCallCount(handler, 2);
});
});
describe('channel.join()', function () {
it('Test#023 : should be called when all functions start unfired', function () {
var handler = jasmine.createSpy();
var stickyChannel2 = channel.createSticky('stickyChannel');
channel.join(handler, [stickyChannel, stickyChannel2]);
expectCallCount(handler, 0);
stickyChannel.fire();
expectCallCount(handler, 0);
stickyChannel2.fire();
expectCallCount(handler, 1);
});
it('Test#024 : should be called when one functions start fired', function () {
var handler = jasmine.createSpy();
var stickyChannel2 = channel.createSticky('stickyChannel');
stickyChannel.fire();
channel.join(handler, [stickyChannel, stickyChannel2]);
expectCallCount(handler, 0);
stickyChannel2.fire();
expectCallCount(handler, 1);
});
it('Test#025 : should be called when all functions start fired', function () {
var handler = jasmine.createSpy();
var stickyChannel2 = channel.createSticky('stickyChannel');
stickyChannel.fire();
stickyChannel2.fire();
channel.join(handler, [stickyChannel, stickyChannel2]);
expectCallCount(handler, 1);
});
it('Test#026 : should throw if a channel is not sticky', function () {
expect(function () {
channel.join(function () {}, [stickyChannel, multiChannel]);
}).toThrow();
});
});
describe('onHasSubscribersChange', function () {
it('Test#027 : should be called only when the first subscriber is added and last subscriber is removed.', function () {
var handler = jasmine.createSpy().and.callFake(function () {
if (handler.calls.count() === 1) {
expect(this.numHandlers).toEqual(1);
} else {
expect(this.numHandlers).toEqual(0);
}
});
multiChannel.onHasSubscribersChange = handler;
function foo1 () {}
function foo2 () {}
multiChannel.subscribe(foo1);
multiChannel.subscribe(foo2);
multiChannel.unsubscribe(foo1);
multiChannel.unsubscribe(foo2);
expectCallCount(handler, 2);
});
});
});