123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722 |
- // Copyright 2007 The Closure Library Authors. All Rights Reserved.
- //
- // Licensed 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.
- goog.provide('goog.pubsub.PubSubTest');
- goog.setTestOnly('goog.pubsub.PubSubTest');
- goog.require('goog.array');
- goog.require('goog.pubsub.PubSub');
- goog.require('goog.testing.MockClock');
- goog.require('goog.testing.jsunit');
- var pubsub;
- var asyncPubsub;
- var mockClock;
- function setUp() {
- pubsub = new goog.pubsub.PubSub();
- asyncPubsub = new goog.pubsub.PubSub(true);
- mockClock = new goog.testing.MockClock(true);
- }
- function tearDown() {
- mockClock.uninstall();
- asyncPubsub.dispose();
- pubsub.dispose();
- }
- function testConstructor() {
- assertNotNull('PubSub instance must not be null', pubsub);
- assertTrue(
- 'PubSub instance must have the expected type',
- pubsub instanceof goog.pubsub.PubSub);
- }
- function testDispose() {
- assertFalse(
- 'PubSub instance must not have been disposed of', pubsub.isDisposed());
- pubsub.dispose();
- assertTrue('PubSub instance must have been disposed of', pubsub.isDisposed());
- }
- function testSubscribeUnsubscribe() {
- function foo1() {}
- function bar1() {}
- function foo2() {}
- function bar2() {}
- assertEquals(
- 'Topic "foo" must not have any subscribers', 0, pubsub.getCount('foo'));
- assertEquals(
- 'Topic "bar" must not have any subscribers', 0, pubsub.getCount('bar'));
- pubsub.subscribe('foo', foo1);
- assertEquals('Topic "foo" must have 1 subscriber', 1, pubsub.getCount('foo'));
- assertEquals(
- 'Topic "bar" must not have any subscribers', 0, pubsub.getCount('bar'));
- pubsub.subscribe('bar', bar1);
- assertEquals('Topic "foo" must have 1 subscriber', 1, pubsub.getCount('foo'));
- assertEquals('Topic "bar" must have 1 subscriber', 1, pubsub.getCount('bar'));
- pubsub.subscribe('foo', foo2);
- assertEquals(
- 'Topic "foo" must have 2 subscribers', 2, pubsub.getCount('foo'));
- assertEquals('Topic "bar" must have 1 subscriber', 1, pubsub.getCount('bar'));
- pubsub.subscribe('bar', bar2);
- assertEquals(
- 'Topic "foo" must have 2 subscribers', 2, pubsub.getCount('foo'));
- assertEquals(
- 'Topic "bar" must have 2 subscribers', 2, pubsub.getCount('bar'));
- assertTrue(pubsub.unsubscribe('foo', foo1));
- assertEquals('Topic "foo" must have 1 subscriber', 1, pubsub.getCount('foo'));
- assertEquals(
- 'Topic "bar" must have 2 subscribers', 2, pubsub.getCount('bar'));
- assertTrue(pubsub.unsubscribe('foo', foo2));
- assertEquals(
- 'Topic "foo" must have no subscribers', 0, pubsub.getCount('foo'));
- assertEquals(
- 'Topic "bar" must have 2 subscribers', 2, pubsub.getCount('bar'));
- assertTrue(pubsub.unsubscribe('bar', bar1));
- assertEquals(
- 'Topic "foo" must have no subscribers', 0, pubsub.getCount('foo'));
- assertEquals('Topic "bar" must have 1 subscriber', 1, pubsub.getCount('bar'));
- assertTrue(pubsub.unsubscribe('bar', bar2));
- assertEquals(
- 'Topic "foo" must have no subscribers', 0, pubsub.getCount('foo'));
- assertEquals(
- 'Topic "bar" must have no subscribers', 0, pubsub.getCount('bar'));
- assertFalse(
- 'Unsubscribing a nonexistent topic must return false',
- pubsub.unsubscribe('baz', foo1));
- assertFalse(
- 'Unsubscribing a nonexistent function must return false',
- pubsub.unsubscribe('foo', function() {}));
- }
- function testSubscribeUnsubscribeWithContext() {
- function foo() {}
- function bar() {}
- var contextA = {};
- var contextB = {};
- assertEquals(
- 'Topic "X" must not have any subscribers', 0, pubsub.getCount('X'));
- pubsub.subscribe('X', foo, contextA);
- assertEquals('Topic "X" must have 1 subscriber', 1, pubsub.getCount('X'));
- pubsub.subscribe('X', bar);
- assertEquals('Topic "X" must have 2 subscribers', 2, pubsub.getCount('X'));
- pubsub.subscribe('X', bar, contextB);
- assertEquals('Topic "X" must have 3 subscribers', 3, pubsub.getCount('X'));
- assertFalse(
- 'Unknown function/context combination return false',
- pubsub.unsubscribe('X', foo, contextB));
- assertTrue(pubsub.unsubscribe('X', foo, contextA));
- assertEquals('Topic "X" must have 2 subscribers', 2, pubsub.getCount('X'));
- assertTrue(pubsub.unsubscribe('X', bar));
- assertEquals('Topic "X" must have 1 subscriber', 1, pubsub.getCount('X'));
- assertTrue(pubsub.unsubscribe('X', bar, contextB));
- assertEquals('Topic "X" must have no subscribers', 0, pubsub.getCount('X'));
- }
- function testSubscribeOnce() {
- var called, context;
- called = false;
- pubsub.subscribeOnce('someTopic', function() { called = true; });
- assertEquals(
- 'Topic must have one subscriber', 1, pubsub.getCount('someTopic'));
- assertFalse('Subscriber must not have been called yet', called);
- pubsub.publish('someTopic');
- assertEquals(
- 'Topic must have no subscribers', 0, pubsub.getCount('someTopic'));
- assertTrue('Subscriber must have been called', called);
- context = {called: false};
- pubsub.subscribeOnce(
- 'someTopic', function() { this.called = true; }, context);
- assertEquals(
- 'Topic must have one subscriber', 1, pubsub.getCount('someTopic'));
- assertFalse('Subscriber must not have been called yet', context.called);
- pubsub.publish('someTopic');
- assertEquals(
- 'Topic must have no subscribers', 0, pubsub.getCount('someTopic'));
- assertTrue('Subscriber must have been called', context.called);
- context = {called: false, value: 0};
- pubsub.subscribeOnce('someTopic', function(value) {
- this.called = true;
- this.value = value;
- }, context);
- assertEquals(
- 'Topic must have one subscriber', 1, pubsub.getCount('someTopic'));
- assertFalse('Subscriber must not have been called yet', context.called);
- assertEquals('Value must have expected value', 0, context.value);
- pubsub.publish('someTopic', 17);
- assertEquals(
- 'Topic must have no subscribers', 0, pubsub.getCount('someTopic'));
- assertTrue('Subscriber must have been called', context.called);
- assertEquals('Value must have been updated', 17, context.value);
- }
- function testAsyncSubscribeOnce() {
- var callCount = 0;
- asyncPubsub.subscribeOnce('someTopic', function() { callCount++; });
- assertEquals(
- 'Topic must have one subscriber', 1, asyncPubsub.getCount('someTopic'));
- mockClock.tick();
- assertEquals('Subscriber must not have been called yet', 0, callCount);
- asyncPubsub.publish('someTopic');
- asyncPubsub.publish('someTopic');
- mockClock.tick();
- assertEquals(
- 'Topic must have no subscribers', 0, asyncPubsub.getCount('someTopic'));
- assertEquals('Subscriber must have been called once', 1, callCount);
- }
- function testAsyncSubscribeOnceWithContext() {
- var context = {callCount: 0};
- asyncPubsub.subscribeOnce(
- 'someTopic', function() { this.callCount++; }, context);
- assertEquals(
- 'Topic must have one subscriber', 1, asyncPubsub.getCount('someTopic'));
- mockClock.tick();
- assertEquals(
- 'Subscriber must not have been called yet', 0, context.callCount);
- asyncPubsub.publish('someTopic');
- asyncPubsub.publish('someTopic');
- mockClock.tick();
- assertEquals(
- 'Topic must have no subscribers', 0, asyncPubsub.getCount('someTopic'));
- assertEquals('Subscriber must have been called once', 1, context.callCount);
- }
- function testAsyncSubscribeOnceWithContextAndValue() {
- var context = {callCount: 0, value: 0};
- asyncPubsub.subscribeOnce('someTopic', function(value) {
- this.callCount++;
- this.value = value;
- }, context);
- assertEquals(
- 'Topic must have one subscriber', 1, asyncPubsub.getCount('someTopic'));
- mockClock.tick();
- assertEquals(
- 'Subscriber must not have been called yet', 0, context.callCount);
- assertEquals('Value must have expected value', 0, context.value);
- asyncPubsub.publish('someTopic', 17);
- asyncPubsub.publish('someTopic', 42);
- mockClock.tick();
- assertEquals(
- 'Topic must have no subscribers', 0, asyncPubsub.getCount('someTopic'));
- assertEquals('Subscriber must have been called once', 1, context.callCount);
- assertEquals('Value must have been updated', 17, context.value);
- }
- function testSubscribeOnce_boundFn() {
- var context = {called: false, value: 0};
- function subscriber(value) {
- this.called = true;
- this.value = value;
- }
- pubsub.subscribeOnce('someTopic', goog.bind(subscriber, context));
- assertEquals(
- 'Topic must have one subscriber', 1, pubsub.getCount('someTopic'));
- assertFalse('Subscriber must not have been called yet', context.called);
- assertEquals('Value must have expected value', 0, context.value);
- pubsub.publish('someTopic', 17);
- assertEquals(
- 'Topic must have no subscribers', 0, pubsub.getCount('someTopic'));
- assertTrue('Subscriber must have been called', context.called);
- assertEquals('Value must have been updated', 17, context.value);
- }
- function testSubscribeOnce_partialFn() {
- var called = false;
- var value = 0;
- function subscriber(hasBeenCalled, newValue) {
- called = hasBeenCalled;
- value = newValue;
- }
- pubsub.subscribeOnce('someTopic', goog.partial(subscriber, true));
- assertEquals(
- 'Topic must have one subscriber', 1, pubsub.getCount('someTopic'));
- assertFalse('Subscriber must not have been called yet', called);
- assertEquals('Value must have expected value', 0, value);
- pubsub.publish('someTopic', 17);
- assertEquals(
- 'Topic must have no subscribers', 0, pubsub.getCount('someTopic'));
- assertTrue('Subscriber must have been called', called);
- assertEquals('Value must have been updated', 17, value);
- }
- function testSelfResubscribe() {
- var value = null;
- function resubscribe(iteration, newValue) {
- pubsub.subscribeOnce('someTopic', goog.partial(resubscribe, iteration + 1));
- value = newValue + ':' + iteration;
- }
- pubsub.subscribeOnce('someTopic', goog.partial(resubscribe, 0));
- assertEquals('Topic must have 1 subscriber', 1, pubsub.getCount('someTopic'));
- assertNull('Value must be null', value);
- pubsub.publish('someTopic', 'foo');
- assertEquals('Topic must have 1 subscriber', 1, pubsub.getCount('someTopic'));
- assertEquals(
- 'Pubsub must not have any pending unsubscribe keys', 0,
- pubsub.pendingKeys_.length);
- assertEquals('Value be as expected', 'foo:0', value);
- pubsub.publish('someTopic', 'bar');
- assertEquals('Topic must have 1 subscriber', 1, pubsub.getCount('someTopic'));
- assertEquals(
- 'Pubsub must not have any pending unsubscribe keys', 0,
- pubsub.pendingKeys_.length);
- assertEquals('Value be as expected', 'bar:1', value);
- pubsub.publish('someTopic', 'baz');
- assertEquals('Topic must have 1 subscriber', 1, pubsub.getCount('someTopic'));
- assertEquals(
- 'Pubsub must not have any pending unsubscribe keys', 0,
- pubsub.pendingKeys_.length);
- assertEquals('Value be as expected', 'baz:2', value);
- }
- function testUnsubscribeByKey() {
- var key1, key2, key3;
- key1 = pubsub.subscribe('X', function() {});
- key2 = pubsub.subscribe('Y', function() {});
- assertEquals('Topic "X" must have 1 subscriber', 1, pubsub.getCount('X'));
- assertEquals('Topic "Y" must have 1 subscriber', 1, pubsub.getCount('Y'));
- assertNotEquals('Subscription keys must be distinct', key1, key2);
- pubsub.unsubscribeByKey(key1);
- assertEquals('Topic "X" must have no subscribers', 0, pubsub.getCount('X'));
- assertEquals('Topic "Y" must have 1 subscriber', 1, pubsub.getCount('Y'));
- key3 = pubsub.subscribe('X', function() {});
- assertEquals('Topic "X" must have 1 subscriber', 1, pubsub.getCount('X'));
- assertEquals('Topic "Y" must have 1 subscriber', 1, pubsub.getCount('Y'));
- assertNotEquals('Subscription keys must be distinct', key1, key3);
- assertNotEquals('Subscription keys must be distinct', key2, key3);
- pubsub.unsubscribeByKey(key1); // Obsolete key; should be no-op.
- assertEquals('Topic "X" must have 1 subscriber', 1, pubsub.getCount('X'));
- assertEquals('Topic "Y" must have 1 subscriber', 1, pubsub.getCount('Y'));
- pubsub.unsubscribeByKey(key2);
- assertEquals('Topic "X" must have 1 subscriber', 1, pubsub.getCount('X'));
- assertEquals('Topic "Y" must have no subscribers', 0, pubsub.getCount('Y'));
- pubsub.unsubscribeByKey(key3);
- assertEquals('Topic "X" must have no subscribers', 0, pubsub.getCount('X'));
- assertEquals('Topic "Y" must have no subscribers', 0, pubsub.getCount('Y'));
- }
- function testSubscribeUnsubscribeMultiple() {
- function foo() {}
- function bar() {}
- var context = {};
- assertEquals(
- 'Pubsub channel must not have any subscribers', 0, pubsub.getCount());
- assertEquals(
- 'Topic "X" must not have any subscribers', 0, pubsub.getCount('X'));
- assertEquals(
- 'Topic "Y" must not have any subscribers', 0, pubsub.getCount('Y'));
- assertEquals(
- 'Topic "Z" must not have any subscribers', 0, pubsub.getCount('Z'));
- goog.array.forEach(
- ['X', 'Y', 'Z'], function(topic) { pubsub.subscribe(topic, foo); });
- assertEquals('Topic "X" must have 1 subscriber', 1, pubsub.getCount('X'));
- assertEquals('Topic "Y" must have 1 subscriber', 1, pubsub.getCount('Y'));
- assertEquals('Topic "Z" must have 1 subscriber', 1, pubsub.getCount('Z'));
- goog.array.forEach(['X', 'Y', 'Z'], function(topic) {
- pubsub.subscribe(topic, bar, context);
- });
- assertEquals('Topic "X" must have 2 subscribers', 2, pubsub.getCount('X'));
- assertEquals('Topic "Y" must have 2 subscribers', 2, pubsub.getCount('Y'));
- assertEquals('Topic "Z" must have 2 subscribers', 2, pubsub.getCount('Z'));
- assertEquals(
- 'Pubsub channel must have a total of 6 subscribers', 6,
- pubsub.getCount());
- goog.array.forEach(
- ['X', 'Y', 'Z'], function(topic) { pubsub.unsubscribe(topic, foo); });
- assertEquals('Topic "X" must have 1 subscriber', 1, pubsub.getCount('X'));
- assertEquals('Topic "Y" must have 1 subscriber', 1, pubsub.getCount('Y'));
- assertEquals('Topic "Z" must have 1 subscriber', 1, pubsub.getCount('Z'));
- goog.array.forEach(['X', 'Y', 'Z'], function(topic) {
- pubsub.unsubscribe(topic, bar, context);
- });
- assertEquals(
- 'Topic "X" must not have any subscribers', 0, pubsub.getCount('X'));
- assertEquals(
- 'Topic "Y" must not have any subscribers', 0, pubsub.getCount('Y'));
- assertEquals(
- 'Topic "Z" must not have any subscribers', 0, pubsub.getCount('Z'));
- assertEquals(
- 'Pubsub channel must not have any subscribers', 0, pubsub.getCount());
- }
- function testPublish() {
- var context = {};
- var fooCalled = false;
- var barCalled = false;
- function foo(x, y) {
- fooCalled = true;
- assertEquals('x must have expected value', 'x', x);
- assertEquals('y must have expected value', 'y', y);
- }
- function bar(x, y) {
- barCalled = true;
- assertEquals('Context must have expected value', context, this);
- assertEquals('x must have expected value', 'x', x);
- assertEquals('y must have expected value', 'y', y);
- }
- pubsub.subscribe('someTopic', foo);
- pubsub.subscribe('someTopic', bar, context);
- assertTrue(pubsub.publish('someTopic', 'x', 'y'));
- assertTrue('foo() must have been called', fooCalled);
- assertTrue('bar() must have been called', barCalled);
- fooCalled = false;
- barCalled = false;
- assertTrue(pubsub.unsubscribe('someTopic', foo));
- assertTrue(pubsub.publish('someTopic', 'x', 'y'));
- assertFalse('foo() must not have been called', fooCalled);
- assertTrue('bar() must have been called', barCalled);
- fooCalled = false;
- barCalled = false;
- pubsub.subscribe('differentTopic', foo);
- assertTrue(pubsub.publish('someTopic', 'x', 'y'));
- assertFalse('foo() must not have been called', fooCalled);
- assertTrue('bar() must have been called', barCalled);
- }
- function testAsyncPublish() {
- var context = {};
- var fooCallCount = 0;
- var barCallCount = 0;
- function foo(x, y) {
- fooCallCount++;
- assertEquals('x must have expected value', 'x', x);
- assertEquals('y must have expected value', 'y', y);
- }
- function bar(x, y) {
- barCallCount++;
- assertEquals('Context must have expected value', context, this);
- assertEquals('x must have expected value', 'x', x);
- assertEquals('y must have expected value', 'y', y);
- }
- asyncPubsub.subscribe('someTopic', foo);
- asyncPubsub.subscribe('someTopic', bar, context);
- assertTrue(asyncPubsub.publish('someTopic', 'x', 'y'));
- assertEquals('foo() must not have been called', 0, fooCallCount);
- assertEquals('bar() must not have been called', 0, barCallCount);
- mockClock.tick();
- assertEquals('foo() must have been called once', 1, fooCallCount);
- assertEquals('bar() must have been called once', 1, barCallCount);
- fooCallCount = 0;
- barCallCount = 0;
- assertTrue(asyncPubsub.unsubscribe('someTopic', foo));
- assertTrue(asyncPubsub.publish('someTopic', 'x', 'y'));
- assertEquals('foo() must not have been called', 0, fooCallCount);
- assertEquals('bar() must not have been called', 0, barCallCount);
- mockClock.tick();
- assertEquals('foo() must not have been called', 0, fooCallCount);
- assertEquals('bar() must have been called once', 1, barCallCount);
- fooCallCount = 0;
- barCallCount = 0;
- asyncPubsub.subscribe('differentTopic', foo);
- assertTrue(asyncPubsub.publish('someTopic', 'x', 'y'));
- assertEquals('foo() must not have been called', 0, fooCallCount);
- assertEquals('bar() must not have been called', 0, barCallCount);
- mockClock.tick();
- assertEquals('foo() must not have been called', 0, fooCallCount);
- assertEquals('bar() must have been called once', 1, barCallCount);
- }
- function testPublishEmptyTopic() {
- var fooCalled = false;
- function foo() { fooCalled = true; }
- assertFalse(
- 'Publishing to nonexistent topic must return false',
- pubsub.publish('someTopic'));
- pubsub.subscribe('someTopic', foo);
- assertTrue(
- 'Publishing to topic with subscriber must return true',
- pubsub.publish('someTopic'));
- assertTrue('Foo must have been called', fooCalled);
- pubsub.unsubscribe('someTopic', foo);
- fooCalled = false;
- assertFalse(
- 'Publishing to topic without subscribers must return false',
- pubsub.publish('someTopic'));
- assertFalse('Foo must nothave been called', fooCalled);
- }
- function testSubscribeWhilePublishing() {
- // It's OK for a subscriber to add a new subscriber to its own topic,
- // but the newly added subscriber shouldn't be called until the next
- // publish cycle.
- var firstCalled = false;
- var secondCalled = false;
- pubsub.subscribe('someTopic', function() {
- pubsub.subscribe('someTopic', function() { secondCalled = true; });
- firstCalled = true;
- });
- assertEquals(
- 'Topic must have one subscriber', 1, pubsub.getCount('someTopic'));
- assertFalse(
- 'No subscriber must have been called yet', firstCalled || secondCalled);
- pubsub.publish('someTopic');
- assertEquals(
- 'Topic must have two subscribers', 2, pubsub.getCount('someTopic'));
- assertTrue('The first subscriber must have been called', firstCalled);
- assertFalse(
- 'The second subscriber must not have been called yet', secondCalled);
- pubsub.publish('someTopic');
- assertEquals(
- 'Topic must have three subscribers', 3, pubsub.getCount('someTopic'));
- assertTrue('The first subscriber must have been called', firstCalled);
- assertTrue('The second subscriber must also have been called', secondCalled);
- }
- function testUnsubscribeWhilePublishing() {
- // It's OK for a subscriber to unsubscribe another subscriber from its
- // own topic, but the subscriber in question won't actually be removed
- // until after publishing is complete.
- var firstCalled = false;
- var secondCalled = false;
- var thirdCalled = false;
- function first() {
- assertTrue(
- 'unsubscribe() must return true when unsubscribing',
- pubsub.unsubscribe('X', second));
- assertEquals(
- 'Topic "X" must still have 3 subscribers', 3, pubsub.getCount('X'));
- firstCalled = true;
- }
- pubsub.subscribe('X', first);
- function second() { secondCalled = true; }
- pubsub.subscribe('X', second);
- function third() {
- assertTrue(
- 'unsubscribe() must return true when unsubscribing',
- pubsub.unsubscribe('X', first));
- assertEquals(
- 'Topic "X" must still have 3 subscribers', 3, pubsub.getCount('X'));
- thirdCalled = true;
- }
- pubsub.subscribe('X', third);
- assertEquals('Topic "X" must have 3 subscribers', 3, pubsub.getCount('X'));
- assertFalse(
- 'No subscribers must have been called yet',
- firstCalled || secondCalled || thirdCalled);
- assertTrue(pubsub.publish('X'));
- assertTrue('First function must have been called', firstCalled);
- assertFalse('Second function must not have been called', secondCalled);
- assertTrue('Third function must have been called', thirdCalled);
- assertEquals(
- 'Topic "X" must have 1 subscriber after publishing', 1,
- pubsub.getCount('X'));
- assertEquals(
- 'PubSub must not have any subscriptions pending removal', 0,
- pubsub.pendingKeys_.length);
- }
- function testUnsubscribeSelfWhilePublishing() {
- // It's OK for a subscriber to unsubscribe itself, but it won't actually
- // be removed until after publishing is complete.
- var selfDestructCalled = false;
- function selfDestruct() {
- assertTrue(
- 'unsubscribe() must return true when unsubscribing',
- pubsub.unsubscribe('someTopic', arguments.callee));
- assertEquals(
- 'Topic must still have 1 subscriber', 1, pubsub.getCount('someTopic'));
- selfDestructCalled = true;
- }
- pubsub.subscribe('someTopic', selfDestruct);
- assertEquals('Topic must have 1 subscriber', 1, pubsub.getCount('someTopic'));
- assertFalse(
- 'selfDestruct() must not have been called yet', selfDestructCalled);
- pubsub.publish('someTopic');
- assertTrue('selfDestruct() must have been called', selfDestructCalled);
- assertEquals(
- 'Topic must have no subscribers after publishing', 0,
- pubsub.getCount('someTopic'));
- assertEquals(
- 'PubSub must not have any subscriptions pending removal', 0,
- pubsub.pendingKeys_.length);
- }
- function testPublishReturnValue() {
- pubsub.subscribe(
- 'X', function() { pubsub.unsubscribe('X', arguments.callee); });
- assertTrue(
- 'publish() must return true even if the only subscriber ' +
- 'removes itself during publishing',
- pubsub.publish('X'));
- }
- function testNestedPublish() {
- var x1 = false;
- var x2 = false;
- var y1 = false;
- var y2 = false;
- pubsub.subscribe('X', function() {
- pubsub.publish('Y');
- pubsub.unsubscribe('X', arguments.callee);
- x1 = true;
- });
- pubsub.subscribe('X', function() { x2 = true; });
- pubsub.subscribe('Y', function() {
- pubsub.unsubscribe('Y', arguments.callee);
- y1 = true;
- });
- pubsub.subscribe('Y', function() { y2 = true; });
- pubsub.publish('X');
- assertTrue('x1 must be true', x1);
- assertTrue('x2 must be true', x2);
- assertTrue('y1 must be true', y1);
- assertTrue('y2 must be true', y2);
- }
- function testClear() {
- function fn() {}
- goog.array.forEach(
- ['W', 'X', 'Y', 'Z'], function(topic) { pubsub.subscribe(topic, fn); });
- assertEquals('Pubsub channel must have 4 subscribers', 4, pubsub.getCount());
- pubsub.clear('W');
- assertEquals('Pubsub channel must have 3 subscribers', 3, pubsub.getCount());
- goog.array.forEach(['X', 'Y'], function(topic) { pubsub.clear(topic); });
- assertEquals('Pubsub channel must have 1 subscriber', 1, pubsub.getCount());
- pubsub.clear();
- assertEquals('Pubsub channel must have no subscribers', 0, pubsub.getCount());
- }
- function testSubscriberExceptionUnlocksSubscriptions() {
- var key1 = pubsub.subscribe('X', function() {});
- pubsub.subscribe('X', function() {
- // Pushes "key1" onto queue to be unsubscribed after subscriptions are
- // processed.
- pubsub.unsubscribeByKey(key1);
- });
- pubsub.subscribe('X', function() { throw 'Oh no!'; });
- var key2 = pubsub.subscribe('X', function() {});
- assertThrows(function() { pubsub.publish('X'); });
- assertTrue(pubsub.unsubscribeByKey(key2));
- // "key1" should've been successfully removed already;
- assertFalse(pubsub.unsubscribeByKey(key1));
- }
- function testNestedSubscribeOnce() {
- var calls = 0;
- pubsub.subscribeOnce('X', function() { calls++; });
- pubsub.subscribe('Y', function() {
- pubsub.publish('X');
- pubsub.publish('X');
- });
- pubsub.publish('Y');
- assertEquals('X must be called once', 1, calls);
- }
|