addon-sdk/source/test/test-unload.js

Thu, 15 Jan 2015 15:59:08 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 15 Jan 2015 15:59:08 +0100
branch
TOR_BUG_9701
changeset 10
ac0c01689b40
permissions
-rw-r--r--

Implement a real Private Browsing Mode condition by changing the API/ABI;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

michael@0 1 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 2 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 4 "use strict";
michael@0 5
michael@0 6 var unload = require("sdk/system/unload");
michael@0 7 var { Loader, LoaderWithHookedConsole } = require("sdk/test/loader");
michael@0 8
michael@0 9 exports.testUnloading = function(assert) {
michael@0 10 let { loader, messages } = LoaderWithHookedConsole(module);
michael@0 11 var ul = loader.require("sdk/system/unload");
michael@0 12 var unloadCalled = 0;
michael@0 13 function unload() {
michael@0 14 unloadCalled++;
michael@0 15 throw new Error("error");
michael@0 16 }
michael@0 17 ul.when(unload);
michael@0 18
michael@0 19 // This should be ignored, as we already registered it
michael@0 20 ul.when(unload);
michael@0 21
michael@0 22 function unload2() { unloadCalled++; }
michael@0 23 ul.when(unload2);
michael@0 24 loader.unload();
michael@0 25 assert.equal(unloadCalled, 2,
michael@0 26 "Unloader functions are called on unload.");
michael@0 27 assert.equal(messages.length, 1,
michael@0 28 "One unload handler threw exception 1/2");
michael@0 29 assert.equal(messages[0].type, "exception",
michael@0 30 "One unload handler threw exception 2/2");
michael@0 31 };
michael@0 32
michael@0 33 exports.testEnsure = function(assert) {
michael@0 34 assert.throws(function() { unload.ensure({}); },
michael@0 35 /object has no 'unload' property/,
michael@0 36 "passing obj with no unload prop should fail");
michael@0 37 assert.throws(function() { unload.ensure({}, "destroy"); },
michael@0 38 /object has no 'destroy' property/,
michael@0 39 "passing obj with no custom unload prop should fail");
michael@0 40
michael@0 41 var called = 0;
michael@0 42 var obj = {unload: function() { called++; }};
michael@0 43
michael@0 44 unload.ensure(obj);
michael@0 45 obj.unload();
michael@0 46 assert.equal(called, 1,
michael@0 47 "unload() should be called");
michael@0 48 obj.unload();
michael@0 49 assert.equal(called, 1,
michael@0 50 "unload() should be called only once");
michael@0 51 };
michael@0 52
michael@0 53 /**
michael@0 54 * Check that destructors are called only once with Traits.
michael@0 55 * - check that public API is calling the destructor and unregister it,
michael@0 56 * - check that composed traits with multiple ensure calls, leads to only
michael@0 57 * one destructor call.
michael@0 58 */
michael@0 59 exports.testEnsureWithTraits = function(assert) {
michael@0 60 let { Trait } = require("sdk/deprecated/traits");
michael@0 61 let loader = Loader(module);
michael@0 62 let ul = loader.require("sdk/system/unload");
michael@0 63
michael@0 64 let called = 0;
michael@0 65 let composedCalled = 0;
michael@0 66 let composedTrait = Trait.compose({
michael@0 67 constructor: function () {
michael@0 68 // We have to give "public interface" of this trait, as we want to
michael@0 69 // call public `unload` method and ensure that we call it only once,
michael@0 70 // either when we call this public function manually or on add-on unload
michael@0 71 ul.ensure(this._public);
michael@0 72 },
michael@0 73 unload: function unload() {
michael@0 74 composedCalled++;
michael@0 75 }
michael@0 76 });
michael@0 77 let obj = Trait.compose(
michael@0 78 composedTrait.resolve({
michael@0 79 constructor: "_constructor",
michael@0 80 unload : "_unload"
michael@0 81 }), {
michael@0 82 constructor: function constructor() {
michael@0 83 // Same thing applies here, we need to pass public interface
michael@0 84 ul.ensure(this._public);
michael@0 85 this._constructor();
michael@0 86 },
michael@0 87 unload: function unload() {
michael@0 88 called++;
michael@0 89 this._unload();
michael@0 90 }
michael@0 91 })();
michael@0 92
michael@0 93 obj.unload();
michael@0 94 assert.equal(called, 1,
michael@0 95 "unload() should be called");
michael@0 96
michael@0 97 assert.equal(composedCalled, 1,
michael@0 98 "composed object unload() should be called");
michael@0 99
michael@0 100 obj.unload();
michael@0 101 assert.equal(called, 1,
michael@0 102 "unload() should be called only once");
michael@0 103 assert.equal(composedCalled, 1,
michael@0 104 "composed object unload() should be called only once");
michael@0 105
michael@0 106 loader.unload();
michael@0 107 assert.equal(called, 1,
michael@0 108 "unload() should be called only once, after addon unload");
michael@0 109 assert.equal(composedCalled, 1,
michael@0 110 "composed object unload() should be called only once, " +
michael@0 111 "after addon unload");
michael@0 112 };
michael@0 113
michael@0 114 exports.testEnsureWithTraitsPrivate = function(assert) {
michael@0 115 let { Trait } = require("sdk/deprecated/traits");
michael@0 116 let loader = Loader(module);
michael@0 117 let ul = loader.require("sdk/system/unload");
michael@0 118
michael@0 119 let called = 0;
michael@0 120 let privateObj = null;
michael@0 121 let obj = Trait.compose({
michael@0 122 constructor: function constructor() {
michael@0 123 // This time wa don't have to give public interface,
michael@0 124 // as we want to call a private method:
michael@0 125 ul.ensure(this, "_unload");
michael@0 126 privateObj = this;
michael@0 127 },
michael@0 128 _unload: function unload() {
michael@0 129 called++;
michael@0 130 this._unload();
michael@0 131 }
michael@0 132 })();
michael@0 133
michael@0 134 loader.unload();
michael@0 135 assert.equal(called, 1,
michael@0 136 "unload() should be called");
michael@0 137
michael@0 138 privateObj._unload();
michael@0 139 assert.equal(called, 1,
michael@0 140 "_unload() should be called only once, after addon unload");
michael@0 141 };
michael@0 142
michael@0 143 exports.testReason = function (assert) {
michael@0 144 var reason = "Reason doesn't actually have to be anything in particular.";
michael@0 145 var loader = Loader(module);
michael@0 146 var ul = loader.require("sdk/system/unload");
michael@0 147 ul.when(function (rsn) {
michael@0 148 assert.equal(rsn, reason,
michael@0 149 "when() reason should be reason given to loader");
michael@0 150 });
michael@0 151 var obj = {
michael@0 152 unload: function (rsn) {
michael@0 153 assert.equal(rsn, reason,
michael@0 154 "ensure() reason should be reason given to loader");
michael@0 155 }
michael@0 156 };
michael@0 157 ul.ensure(obj);
michael@0 158 loader.unload(reason);
michael@0 159 };
michael@0 160
michael@0 161 require("sdk/test").run(exports);

mercurial