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: "use strict"; michael@0: michael@0: const { Loader } = require("sdk/test/loader"); michael@0: const { isWeak, WeakReference } = require("sdk/core/reference"); michael@0: const { subscribe, unsubscribe, michael@0: observe, Observer } = require("sdk/core/observer"); michael@0: const { Class } = require("sdk/core/heritage"); michael@0: michael@0: const { Cc, Ci, Cu } = require("chrome"); michael@0: const { notifyObservers } = Cc["@mozilla.org/observer-service;1"]. michael@0: getService(Ci.nsIObserverService); michael@0: michael@0: const message = x => ({wrappedJSObject: x}); michael@0: michael@0: exports["test subscribe unsubscribe"] = assert => { michael@0: const topic = Date.now().toString(32); michael@0: const Subscriber = Class({ michael@0: extends: Observer, michael@0: initialize: function(observe) { michael@0: this.observe = observe; michael@0: } michael@0: }); michael@0: observe.define(Subscriber, (x, subject, _, data) => michael@0: x.observe(subject.wrappedJSObject.x)); michael@0: michael@0: let xs = []; michael@0: const x = Subscriber((...rest) => xs.push(...rest)); michael@0: michael@0: let ys = []; michael@0: const y = Subscriber((...rest) => ys.push(...rest)); michael@0: michael@0: const publish = (topic, data) => michael@0: notifyObservers(message(data), topic, null); michael@0: michael@0: publish({x:0}); michael@0: michael@0: subscribe(x, topic); michael@0: michael@0: publish(topic, {x:1}); michael@0: michael@0: subscribe(y, topic); michael@0: michael@0: publish(topic, {x:2}); michael@0: publish(topic + "!", {x: 2.5}); michael@0: michael@0: unsubscribe(x, topic); michael@0: michael@0: publish(topic, {x:3}); michael@0: michael@0: subscribe(y, topic); michael@0: michael@0: publish(topic, {x:4}); michael@0: michael@0: subscribe(x, topic); michael@0: michael@0: publish(topic, {x:5}); michael@0: michael@0: unsubscribe(x, topic); michael@0: unsubscribe(y, topic); michael@0: michael@0: publish(topic, {x:6}); michael@0: michael@0: assert.deepEqual(xs, [1, 2, 5]); michael@0: assert.deepEqual(ys, [2, 3, 4, 5]); michael@0: } michael@0: michael@0: exports["test weak observers are GC-ed on unload"] = (assert, end) => { michael@0: const topic = Date.now().toString(32); michael@0: const loader = Loader(module); michael@0: const { Observer, observe, michael@0: subscribe, unsubscribe } = loader.require("sdk/core/observer"); michael@0: const { isWeak, WeakReference } = loader.require("sdk/core/reference"); michael@0: michael@0: const MyObserver = Class({ michael@0: extends: Observer, michael@0: initialize: function(observe) { michael@0: this.observe = observe; michael@0: } michael@0: }); michael@0: observe.define(MyObserver, (x, ...rest) => x.observe(...rest)); michael@0: michael@0: const MyWeakObserver = Class({ michael@0: extends: MyObserver, michael@0: implements: [WeakReference] michael@0: }); michael@0: michael@0: let xs = []; michael@0: let ys = []; michael@0: let x = new MyObserver((subject, topic, data) => { michael@0: xs.push(subject.wrappedJSObject, topic, data); michael@0: }); michael@0: let y = new MyWeakObserver((subject, topic, data) => { michael@0: ys.push(subject.wrappedJSObject, topic, data); michael@0: }); michael@0: michael@0: subscribe(x, topic); michael@0: subscribe(y, topic); michael@0: michael@0: michael@0: notifyObservers(message({ foo: 1 }), topic, null); michael@0: x = null; michael@0: y = null; michael@0: loader.unload(); michael@0: michael@0: Cu.schedulePreciseGC(() => { michael@0: michael@0: notifyObservers(message({ bar: 2 }), topic, ":)"); michael@0: michael@0: assert.deepEqual(xs, [{ foo: 1 }, topic, null, michael@0: { bar: 2 }, topic, ":)"], michael@0: "non week observer is kept"); michael@0: michael@0: assert.deepEqual(ys, [{ foo: 1 }, topic, null], michael@0: "week observer was GC-ed"); michael@0: michael@0: end(); michael@0: }); michael@0: }; michael@0: michael@0: require("sdk/test").run(exports);