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

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

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
michael@0 5 "use strict";
michael@0 6
michael@0 7 const { Class, extend, mix, obscure } = require('sdk/core/heritage');
michael@0 8
michael@0 9 exports['test extend'] = function(assert) {
michael@0 10 let ancestor = { a: 1 };
michael@0 11 let descendant = extend(ancestor, {
michael@0 12 b: 2,
michael@0 13 get c() { return 3 },
michael@0 14 d: function() { return 4 }
michael@0 15 });
michael@0 16
michael@0 17 assert.ok(ancestor.isPrototypeOf(descendant),
michael@0 18 'descendant inherits from ancestor');
michael@0 19 assert.ok(descendant.b, 2, 'proprety was implemented');
michael@0 20 assert.ok(descendant.c, 3, 'getter was implemented');
michael@0 21 assert.ok(descendant.d(), 4, 'method was implemented');
michael@0 22
michael@0 23 /* Will be fixed once Bug 674195 is shipped.
michael@0 24 assert.ok(Object.isFrozen(descendant),
michael@0 25 'extend returns frozen objects');
michael@0 26 */
michael@0 27 };
michael@0 28
michael@0 29 exports['test mix'] = function(assert) {
michael@0 30 let ancestor = { a: 1 }
michael@0 31 let mixed = mix(extend(ancestor, { b: 1, c: 1 }), { c: 2 }, { d: 3 });
michael@0 32
michael@0 33 assert.deepEqual(JSON.parse(JSON.stringify(mixed)), { b: 1, c: 2, d: 3 },
michael@0 34 'properties mixed as expected');
michael@0 35 assert.ok(ancestor.isPrototypeOf(mixed),
michael@0 36 'first arguments ancestor is ancestor of result');
michael@0 37 };
michael@0 38
michael@0 39 exports['test obscure'] = function(assert) {
michael@0 40 let fixture = mix({ a: 1 }, obscure({ b: 2 }));
michael@0 41
michael@0 42 assert.equal(fixture.a, 1, 'a property is included');
michael@0 43 assert.equal(fixture.b, 2, 'b proprety is included');
michael@0 44 assert.ok(!Object.getOwnPropertyDescriptor(fixture, 'b').enumerable,
michael@0 45 'obscured properties are non-enumerable');
michael@0 46 };
michael@0 47
michael@0 48 exports['test inheritance'] = function(assert) {
michael@0 49 let Ancestor = Class({
michael@0 50 name: 'ancestor',
michael@0 51 method: function () {
michael@0 52 return 'hello ' + this.name;
michael@0 53 }
michael@0 54 });
michael@0 55
michael@0 56 assert.ok(Ancestor() instanceof Ancestor,
michael@0 57 'can be instantiated without new');
michael@0 58 assert.ok(new Ancestor() instanceof Ancestor,
michael@0 59 'can also be instantiated with new');
michael@0 60 assert.ok(Ancestor() instanceof Class,
michael@0 61 'if ancestor not specified than defaults to Class');
michael@0 62 assert.ok(Ancestor.prototype.extends, Class.prototype,
michael@0 63 'extends of prototype points to ancestors prototype');
michael@0 64
michael@0 65
michael@0 66 assert.equal(Ancestor().method(), 'hello ancestor',
michael@0 67 'instance inherits defined properties');
michael@0 68
michael@0 69 let Descendant = Class({
michael@0 70 extends: Ancestor,
michael@0 71 name: 'descendant'
michael@0 72 });
michael@0 73
michael@0 74 assert.ok(Descendant() instanceof Descendant,
michael@0 75 'instantiates correctly');
michael@0 76 assert.ok(Descendant() instanceof Ancestor,
michael@0 77 'Inherits for passed `extends`');
michael@0 78 assert.equal(Descendant().method(), 'hello descendant',
michael@0 79 'propreties inherited');
michael@0 80 };
michael@0 81
michael@0 82 exports['test immunity against __proto__'] = function(assert) {
michael@0 83 let Foo = Class({ name: 'foo', hacked: false });
michael@0 84
michael@0 85 let Bar = Class({ extends: Foo, name: 'bar' });
michael@0 86
michael@0 87 assert.throws(function() {
michael@0 88 Foo.prototype.__proto__ = { hacked: true };
michael@0 89 if (Foo() instanceof Base && !Foo().hacked)
michael@0 90 throw Error('can not change prototype chain');
michael@0 91 }, 'prototype chain is immune to __proto__ hacks');
michael@0 92
michael@0 93 assert.throws(function() {
michael@0 94 Foo.prototype.__proto__ = { hacked: true };
michael@0 95 if (Bar() instanceof Foo && !Bar().hacked)
michael@0 96 throw Error('can not change prototype chain');
michael@0 97 }, 'prototype chain of decedants immune to __proto__ hacks');
michael@0 98 };
michael@0 99
michael@0 100 exports['test super'] = function(assert) {
michael@0 101 var Foo = Class({
michael@0 102 initialize: function initialize(options) {
michael@0 103 this.name = options.name;
michael@0 104 }
michael@0 105 });
michael@0 106
michael@0 107 var Bar = Class({
michael@0 108 extends: Foo,
michael@0 109 initialize: function Bar(options) {
michael@0 110 Foo.prototype.initialize.call(this, options);
michael@0 111 this.type = 'bar';
michael@0 112 }
michael@0 113 });
michael@0 114
michael@0 115 var bar = Bar({ name: 'test' });
michael@0 116
michael@0 117 assert.equal(bar.type, 'bar', 'bar initializer was called');
michael@0 118 assert.equal(bar.name, 'test', 'bar initializer called Foo initializer');
michael@0 119 };
michael@0 120
michael@0 121 exports['test initialize'] = function(assert) {
michael@0 122 var Dog = Class({
michael@0 123 initialize: function initialize(name) {
michael@0 124 this.name = name;
michael@0 125 },
michael@0 126 type: 'dog',
michael@0 127 bark: function bark() {
michael@0 128 return 'Ruff! Ruff!'
michael@0 129 }
michael@0 130 });
michael@0 131
michael@0 132 var fluffy = Dog('Fluffy'); // instatiation
michael@0 133 assert.ok(fluffy instanceof Dog,
michael@0 134 'instanceof works as expected');
michael@0 135 assert.ok(fluffy instanceof Class,
michael@0 136 'inherits form Class if not specified otherwise');
michael@0 137 assert.ok(fluffy.name, 'fluffy',
michael@0 138 'initialize unless specified otherwise');
michael@0 139 };
michael@0 140
michael@0 141 exports['test complements regular inheritace'] = function(assert) {
michael@0 142 let Base = Class({ name: 'base' });
michael@0 143
michael@0 144 function Type() {
michael@0 145 // ...
michael@0 146 }
michael@0 147 Type.prototype = Object.create(Base.prototype);
michael@0 148 Type.prototype.run = function() {
michael@0 149 // ...
michael@0 150 };
michael@0 151
michael@0 152 let value = new Type();
michael@0 153
michael@0 154 assert.ok(value instanceof Type, 'creates instance of Type');
michael@0 155 assert.ok(value instanceof Base, 'inherits from Base');
michael@0 156 assert.equal(value.name, 'base', 'inherits properties from Base');
michael@0 157
michael@0 158
michael@0 159 let SubType = Class({
michael@0 160 extends: Type,
michael@0 161 sub: 'type'
michael@0 162 });
michael@0 163
michael@0 164 let fixture = SubType();
michael@0 165
michael@0 166 assert.ok(fixture instanceof Base, 'is instance of Base');
michael@0 167 assert.ok(fixture instanceof Type, 'is instance of Type');
michael@0 168 assert.ok(fixture instanceof SubType, 'is instance of SubType');
michael@0 169
michael@0 170 assert.equal(fixture.sub, 'type', 'proprety is defined');
michael@0 171 assert.equal(fixture.run, Type.prototype.run, 'proprety is inherited');
michael@0 172 assert.equal(fixture.name, 'base', 'inherits base properties');
michael@0 173 };
michael@0 174
michael@0 175 exports['test extends object'] = function(assert) {
michael@0 176 let prototype = { constructor: function() { return this; }, name: 'me' };
michael@0 177 let Foo = Class({
michael@0 178 extends: prototype,
michael@0 179 value: 2
michael@0 180 });
michael@0 181 let foo = new Foo();
michael@0 182
michael@0 183 assert.ok(foo instanceof Foo, 'instance of Foo');
michael@0 184 assert.ok(!(foo instanceof Class), 'is not instance of Class');
michael@0 185 assert.ok(prototype.isPrototypeOf(foo), 'inherits from given prototype');
michael@0 186 assert.equal(Object.getPrototypeOf(Foo.prototype), prototype,
michael@0 187 'contsructor prototype inherits from extends option');
michael@0 188 assert.equal(foo.value, 2, 'property is defined');
michael@0 189 assert.equal(foo.name, 'me', 'prototype proprety is inherited');
michael@0 190 };
michael@0 191
michael@0 192
michael@0 193 var HEX = Class({
michael@0 194 hex: function hex() {
michael@0 195 return '#' + this.color;
michael@0 196 }
michael@0 197 });
michael@0 198
michael@0 199 var RGB = Class({
michael@0 200 red: function red() {
michael@0 201 return parseInt(this.color.substr(0, 2), 16);
michael@0 202 },
michael@0 203 green: function green() {
michael@0 204 return parseInt(this.color.substr(2, 2), 16);
michael@0 205 },
michael@0 206 blue: function blue() {
michael@0 207 return parseInt(this.color.substr(4, 2), 16);
michael@0 208 }
michael@0 209 });
michael@0 210
michael@0 211 var CMYK = Class({
michael@0 212 black: function black() {
michael@0 213 var color = Math.max(Math.max(this.red(), this.green()), this.blue());
michael@0 214 return (1 - color / 255).toFixed(4);
michael@0 215 },
michael@0 216 magenta: function magenta() {
michael@0 217 var K = this.black();
michael@0 218 return (((1 - this.green() / 255).toFixed(4) - K) / (1 - K)).toFixed(4);
michael@0 219 },
michael@0 220 yellow: function yellow() {
michael@0 221 var K = this.black();
michael@0 222 return (((1 - this.blue() / 255).toFixed(4) - K) / (1 - K)).toFixed(4);
michael@0 223 },
michael@0 224 cyan: function cyan() {
michael@0 225 var K = this.black();
michael@0 226 return (((1 - this.red() / 255).toFixed(4) - K) / (1 - K)).toFixed(4);
michael@0 227 }
michael@0 228 });
michael@0 229
michael@0 230 var Color = Class({
michael@0 231 implements: [ HEX, RGB, CMYK ],
michael@0 232 initialize: function initialize(color) {
michael@0 233 this.color = color;
michael@0 234 }
michael@0 235 });
michael@0 236
michael@0 237 exports['test composition'] = function(assert) {
michael@0 238 var pink = Color('FFC0CB');
michael@0 239
michael@0 240 assert.equal(pink.red(), 255, 'red() works');
michael@0 241 assert.equal(pink.green(), 192, 'green() works');
michael@0 242 assert.equal(pink.blue(), 203, 'blue() works');
michael@0 243
michael@0 244 assert.equal(pink.magenta(), 0.2471, 'magenta() works');
michael@0 245 assert.equal(pink.yellow(), 0.2039, 'yellow() works');
michael@0 246 assert.equal(pink.cyan(), 0.0000, 'cyan() works');
michael@0 247
michael@0 248 assert.ok(pink instanceof Color, 'is instance of Color');
michael@0 249 assert.ok(pink instanceof Class, 'is instance of Class');
michael@0 250 };
michael@0 251
michael@0 252 var Point = Class({
michael@0 253 initialize: function initialize(x, y) {
michael@0 254 this.x = x;
michael@0 255 this.y = y;
michael@0 256 },
michael@0 257 toString: function toString() {
michael@0 258 return this.x + ':' + this.y;
michael@0 259 }
michael@0 260 })
michael@0 261
michael@0 262 var Pixel = Class({
michael@0 263 extends: Point,
michael@0 264 implements: [ Color ],
michael@0 265 initialize: function initialize(x, y, color) {
michael@0 266 Color.prototype.initialize.call(this, color);
michael@0 267 Point.prototype.initialize.call(this, x, y);
michael@0 268 },
michael@0 269 toString: function toString() {
michael@0 270 return this.hex() + '@' + Point.prototype.toString.call(this)
michael@0 271 }
michael@0 272 });
michael@0 273
michael@0 274 exports['test compostion with inheritance'] = function(assert) {
michael@0 275 var pixel = Pixel(11, 23, 'CC3399');
michael@0 276
michael@0 277 assert.equal(pixel.toString(), '#CC3399@11:23', 'stringifies correctly');
michael@0 278 assert.ok(pixel instanceof Pixel, 'instance of Pixel');
michael@0 279 assert.ok(pixel instanceof Point, 'instance of Point');
michael@0 280 };
michael@0 281
michael@0 282 exports['test composition with objects'] = function(assert) {
michael@0 283 var A = { a: 1, b: 1 };
michael@0 284 var B = Class({ b: 2, c: 2 });
michael@0 285 var C = { c: 3 };
michael@0 286 var D = { d: 4 };
michael@0 287
michael@0 288 var ABCD = Class({
michael@0 289 implements: [ A, B, C, D ],
michael@0 290 e: 5
michael@0 291 });
michael@0 292
michael@0 293 var f = ABCD();
michael@0 294
michael@0 295 assert.equal(f.a, 1, 'inherits A.a');
michael@0 296 assert.equal(f.b, 2, 'inherits B.b overrides A.b');
michael@0 297 assert.equal(f.c, 3, 'inherits C.c overrides B.c');
michael@0 298 assert.equal(f.d, 4, 'inherits D.d');
michael@0 299 assert.equal(f.e, 5, 'implements e');
michael@0 300 };
michael@0 301
michael@0 302 require("test").run(exports);

mercurial