diff options
author | Matt A. Tobin <mattatobin@localhost.localdomain> | 2018-02-02 04:16:08 -0500 |
---|---|---|
committer | Matt A. Tobin <mattatobin@localhost.localdomain> | 2018-02-02 04:16:08 -0500 |
commit | 5f8de423f190bbb79a62f804151bc24824fa32d8 (patch) | |
tree | 10027f336435511475e392454359edea8e25895d /addon-sdk/source/test/test-observers.js | |
parent | 49ee0794b5d912db1f95dce6eb52d781dc210db5 (diff) | |
download | UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.gz UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.lz UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.xz UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.zip |
Add m-esr52 at 52.6.0
Diffstat (limited to 'addon-sdk/source/test/test-observers.js')
-rw-r--r-- | addon-sdk/source/test/test-observers.js | 183 |
1 files changed, 183 insertions, 0 deletions
diff --git a/addon-sdk/source/test/test-observers.js b/addon-sdk/source/test/test-observers.js new file mode 100644 index 000000000..4f15a87f1 --- /dev/null +++ b/addon-sdk/source/test/test-observers.js @@ -0,0 +1,183 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +"use strict"; + +const { Loader } = require("sdk/test/loader"); +const { isWeak, WeakReference } = require("sdk/core/reference"); +const { subscribe, unsubscribe, + observe, Observer } = require("sdk/core/observer"); +const { Class } = require("sdk/core/heritage"); + +const { Cc, Ci, Cu } = require("chrome"); +const { notifyObservers } = Cc["@mozilla.org/observer-service;1"]. + getService(Ci.nsIObserverService); +const { defer } = require("sdk/core/promise"); + +const message = x => ({wrappedJSObject: x}); + +exports["test subscribe unsubscribe"] = assert => { + const topic = Date.now().toString(32); + const Subscriber = Class({ + extends: Observer, + initialize: function(observe) { + this.observe = observe; + } + }); + observe.define(Subscriber, (x, subject, _, data) => + x.observe(subject.wrappedJSObject.x)); + + let xs = []; + const x = Subscriber((...rest) => xs.push(...rest)); + + let ys = []; + const y = Subscriber((...rest) => ys.push(...rest)); + + const publish = (topic, data) => + notifyObservers(message(data), topic, null); + + publish({x:0}); + + subscribe(x, topic); + + publish(topic, {x:1}); + + subscribe(y, topic); + + publish(topic, {x:2}); + publish(topic + "!", {x: 2.5}); + + unsubscribe(x, topic); + + publish(topic, {x:3}); + + subscribe(y, topic); + + publish(topic, {x:4}); + + subscribe(x, topic); + + publish(topic, {x:5}); + + unsubscribe(x, topic); + unsubscribe(y, topic); + + publish(topic, {x:6}); + + assert.deepEqual(xs, [1, 2, 5]); + assert.deepEqual(ys, [2, 3, 4, 5]); +} + +exports["test weak observers are GC-ed on unload"] = (assert, end) => { + const topic = Date.now().toString(32); + const loader = Loader(module); + const { Observer, observe, + subscribe, unsubscribe } = loader.require("sdk/core/observer"); + const { isWeak, WeakReference } = loader.require("sdk/core/reference"); + + const MyObserver = Class({ + extends: Observer, + initialize: function(observe) { + this.observe = observe; + } + }); + observe.define(MyObserver, (x, ...rest) => x.observe(...rest)); + + const MyWeakObserver = Class({ + extends: MyObserver, + implements: [WeakReference] + }); + + let xs = []; + let ys = []; + let x = new MyObserver((subject, topic, data) => { + xs.push(subject.wrappedJSObject, topic, data); + }); + let y = new MyWeakObserver((subject, topic, data) => { + ys.push(subject.wrappedJSObject, topic, data); + }); + + subscribe(x, topic); + subscribe(y, topic); + + + notifyObservers(message({ foo: 1 }), topic, null); + x = null; + y = null; + loader.unload(); + + Cu.schedulePreciseGC(() => { + + notifyObservers(message({ bar: 2 }), topic, ":)"); + + assert.deepEqual(xs, [{ foo: 1 }, topic, null, + { bar: 2 }, topic, ":)"], + "non week observer is kept"); + + assert.deepEqual(ys, [{ foo: 1 }, topic, null], + "week observer was GC-ed"); + + end(); + }); +}; + +exports["test weak observer unsubscribe"] = function*(assert) { + const loader = Loader(module); + const { Observer, observe, subscribe, unsubscribe } = loader.require("sdk/core/observer"); + const { WeakReference } = loader.require("sdk/core/reference"); + + let sawNotification = false; + let firstWait = defer(); + let secondWait = defer(); + + const WeakObserver = Class({ + extends: Observer, + implements: [WeakReference], + observe: function() { + sawNotification = true; + firstWait.resolve(); + } + }); + + const StrongObserver = Class({ + extends: Observer, + observe: function() { + secondWait.resolve(); + } + }); + + observe.define(Observer, (x, ...rest) => x.observe(...rest)); + + let weakObserver = new WeakObserver; + let strongObserver = new StrongObserver(); + subscribe(weakObserver, "test-topic"); + subscribe(strongObserver, "test-wait"); + + notifyObservers(null, "test-topic", null); + yield firstWait.promise; + + assert.ok(sawNotification, "Should have seen notification before GC"); + sawNotification = false; + + yield loader.require("sdk/test/memory").gc(); + + notifyObservers(null, "test-topic", null); + notifyObservers(null, "test-wait", null); + yield secondWait.promise; + + assert.ok(sawNotification, "Should have seen notification after GC"); + sawNotification = false; + + try { + unsubscribe(weakObserver, "test-topic"); + unsubscribe(strongObserver, "test-wait"); + assert.pass("Should not have seen an exception"); + } + catch (e) { + assert.fail("Should not have seen an exception"); + } + + loader.unload(); +}; + +require("sdk/test").run(exports); |