|
1 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
2 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
4 "use strict"; |
|
5 |
|
6 const { Loader } = require("sdk/test/loader"); |
|
7 const { isWeak, WeakReference } = require("sdk/core/reference"); |
|
8 const { subscribe, unsubscribe, |
|
9 observe, Observer } = require("sdk/core/observer"); |
|
10 const { Class } = require("sdk/core/heritage"); |
|
11 |
|
12 const { Cc, Ci, Cu } = require("chrome"); |
|
13 const { notifyObservers } = Cc["@mozilla.org/observer-service;1"]. |
|
14 getService(Ci.nsIObserverService); |
|
15 |
|
16 const message = x => ({wrappedJSObject: x}); |
|
17 |
|
18 exports["test subscribe unsubscribe"] = assert => { |
|
19 const topic = Date.now().toString(32); |
|
20 const Subscriber = Class({ |
|
21 extends: Observer, |
|
22 initialize: function(observe) { |
|
23 this.observe = observe; |
|
24 } |
|
25 }); |
|
26 observe.define(Subscriber, (x, subject, _, data) => |
|
27 x.observe(subject.wrappedJSObject.x)); |
|
28 |
|
29 let xs = []; |
|
30 const x = Subscriber((...rest) => xs.push(...rest)); |
|
31 |
|
32 let ys = []; |
|
33 const y = Subscriber((...rest) => ys.push(...rest)); |
|
34 |
|
35 const publish = (topic, data) => |
|
36 notifyObservers(message(data), topic, null); |
|
37 |
|
38 publish({x:0}); |
|
39 |
|
40 subscribe(x, topic); |
|
41 |
|
42 publish(topic, {x:1}); |
|
43 |
|
44 subscribe(y, topic); |
|
45 |
|
46 publish(topic, {x:2}); |
|
47 publish(topic + "!", {x: 2.5}); |
|
48 |
|
49 unsubscribe(x, topic); |
|
50 |
|
51 publish(topic, {x:3}); |
|
52 |
|
53 subscribe(y, topic); |
|
54 |
|
55 publish(topic, {x:4}); |
|
56 |
|
57 subscribe(x, topic); |
|
58 |
|
59 publish(topic, {x:5}); |
|
60 |
|
61 unsubscribe(x, topic); |
|
62 unsubscribe(y, topic); |
|
63 |
|
64 publish(topic, {x:6}); |
|
65 |
|
66 assert.deepEqual(xs, [1, 2, 5]); |
|
67 assert.deepEqual(ys, [2, 3, 4, 5]); |
|
68 } |
|
69 |
|
70 exports["test weak observers are GC-ed on unload"] = (assert, end) => { |
|
71 const topic = Date.now().toString(32); |
|
72 const loader = Loader(module); |
|
73 const { Observer, observe, |
|
74 subscribe, unsubscribe } = loader.require("sdk/core/observer"); |
|
75 const { isWeak, WeakReference } = loader.require("sdk/core/reference"); |
|
76 |
|
77 const MyObserver = Class({ |
|
78 extends: Observer, |
|
79 initialize: function(observe) { |
|
80 this.observe = observe; |
|
81 } |
|
82 }); |
|
83 observe.define(MyObserver, (x, ...rest) => x.observe(...rest)); |
|
84 |
|
85 const MyWeakObserver = Class({ |
|
86 extends: MyObserver, |
|
87 implements: [WeakReference] |
|
88 }); |
|
89 |
|
90 let xs = []; |
|
91 let ys = []; |
|
92 let x = new MyObserver((subject, topic, data) => { |
|
93 xs.push(subject.wrappedJSObject, topic, data); |
|
94 }); |
|
95 let y = new MyWeakObserver((subject, topic, data) => { |
|
96 ys.push(subject.wrappedJSObject, topic, data); |
|
97 }); |
|
98 |
|
99 subscribe(x, topic); |
|
100 subscribe(y, topic); |
|
101 |
|
102 |
|
103 notifyObservers(message({ foo: 1 }), topic, null); |
|
104 x = null; |
|
105 y = null; |
|
106 loader.unload(); |
|
107 |
|
108 Cu.schedulePreciseGC(() => { |
|
109 |
|
110 notifyObservers(message({ bar: 2 }), topic, ":)"); |
|
111 |
|
112 assert.deepEqual(xs, [{ foo: 1 }, topic, null, |
|
113 { bar: 2 }, topic, ":)"], |
|
114 "non week observer is kept"); |
|
115 |
|
116 assert.deepEqual(ys, [{ foo: 1 }, topic, null], |
|
117 "week observer was GC-ed"); |
|
118 |
|
119 end(); |
|
120 }); |
|
121 }; |
|
122 |
|
123 require("sdk/test").run(exports); |