addon-sdk/source/lib/method/test/common.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 "use strict";
michael@0 2
michael@0 3 var Method = require("../core")
michael@0 4
michael@0 5 function type(value) {
michael@0 6 return Object.prototype.toString.call(value).
michael@0 7 split(" ").
michael@0 8 pop().
michael@0 9 split("]").
michael@0 10 shift().
michael@0 11 toLowerCase()
michael@0 12 }
michael@0 13
michael@0 14 var values = [
michael@0 15 null, // 0
michael@0 16 undefined, // 1
michael@0 17 Infinity, // 2
michael@0 18 NaN, // 3
michael@0 19 5, // 4
michael@0 20 {}, // 5
michael@0 21 Object.create({}), // 6
michael@0 22 Object.create(null), // 7
michael@0 23 [], // 8
michael@0 24 /foo/, // 9
michael@0 25 new Date(), // 10
michael@0 26 Function, // 11
michael@0 27 function() {}, // 12
michael@0 28 true, // 13
michael@0 29 false, // 14
michael@0 30 "string" // 15
michael@0 31 ]
michael@0 32
michael@0 33 function True() { return true }
michael@0 34 function False() { return false }
michael@0 35
michael@0 36 var trues = values.map(True)
michael@0 37 var falses = values.map(False)
michael@0 38
michael@0 39 exports["test throws if not implemented"] = function(assert) {
michael@0 40 var method = Method("nope")
michael@0 41
michael@0 42 assert.throws(function() {
michael@0 43 method({})
michael@0 44 }, /not implement/i, "method throws if not implemented")
michael@0 45
michael@0 46 assert.throws(function() {
michael@0 47 method(null)
michael@0 48 }, /not implement/i, "method throws on null")
michael@0 49 }
michael@0 50
michael@0 51 exports["test all types inherit from default"] = function(assert) {
michael@0 52 var isImplemented = Method("isImplemented")
michael@0 53 isImplemented.define(function() { return true })
michael@0 54
michael@0 55 values.forEach(function(value) {
michael@0 56 assert.ok(isImplemented(value),
michael@0 57 type(value) + " inherits deafult implementation")
michael@0 58 })
michael@0 59 }
michael@0 60
michael@0 61 exports["test default can be implemented later"] = function(assert) {
michael@0 62 var isImplemented = Method("isImplemented")
michael@0 63 isImplemented.define(function() {
michael@0 64 return true
michael@0 65 })
michael@0 66
michael@0 67 values.forEach(function(value) {
michael@0 68 assert.ok(isImplemented(value),
michael@0 69 type(value) + " inherits deafult implementation")
michael@0 70 })
michael@0 71 }
michael@0 72
michael@0 73 exports["test dispatch not-implemented"] = function(assert) {
michael@0 74 var isDefault = Method("isDefault")
michael@0 75 values.forEach(function(value) {
michael@0 76 assert.throws(function() {
michael@0 77 isDefault(value)
michael@0 78 }, /not implement/, type(value) + " throws if not implemented")
michael@0 79 })
michael@0 80 }
michael@0 81
michael@0 82 exports["test dispatch default"] = function(assert) {
michael@0 83 var isDefault = Method("isDefault")
michael@0 84
michael@0 85 // Implement default
michael@0 86 isDefault.define(True)
michael@0 87 assert.deepEqual(values.map(isDefault), trues,
michael@0 88 "all implementation inherit from default")
michael@0 89
michael@0 90 }
michael@0 91
michael@0 92 exports["test dispatch null"] = function(assert) {
michael@0 93 var isNull = Method("isNull")
michael@0 94
michael@0 95 // Implement default
michael@0 96 isNull.define(False)
michael@0 97 isNull.define(null, True)
michael@0 98 assert.deepEqual(values.map(isNull),
michael@0 99 [ true ].
michael@0 100 concat(falses.slice(1)),
michael@0 101 "only null gets methods defined for null")
michael@0 102 }
michael@0 103
michael@0 104 exports["test dispatch undefined"] = function(assert) {
michael@0 105 var isUndefined = Method("isUndefined")
michael@0 106
michael@0 107 // Implement default
michael@0 108 isUndefined.define(False)
michael@0 109 isUndefined.define(undefined, True)
michael@0 110 assert.deepEqual(values.map(isUndefined),
michael@0 111 [ false, true ].
michael@0 112 concat(falses.slice(2)),
michael@0 113 "only undefined gets methods defined for undefined")
michael@0 114 }
michael@0 115
michael@0 116 exports["test dispatch object"] = function(assert) {
michael@0 117 var isObject = Method("isObject")
michael@0 118
michael@0 119 // Implement default
michael@0 120 isObject.define(False)
michael@0 121 isObject.define(Object, True)
michael@0 122 assert.deepEqual(values.map(isObject),
michael@0 123 [ false, false, false, false, false ].
michael@0 124 concat(trues.slice(5, 13)).
michael@0 125 concat([false, false, false]),
michael@0 126 "all values except primitives inherit Object methods")
michael@0 127
michael@0 128 }
michael@0 129
michael@0 130 exports["test dispatch number"] = function(assert) {
michael@0 131 var isNumber = Method("isNumber")
michael@0 132 isNumber.define(False)
michael@0 133 isNumber.define(Number, True)
michael@0 134
michael@0 135 assert.deepEqual(values.map(isNumber),
michael@0 136 falses.slice(0, 2).
michael@0 137 concat(true, true, true).
michael@0 138 concat(falses.slice(5)),
michael@0 139 "all numbers inherit from Number method")
michael@0 140 }
michael@0 141
michael@0 142 exports["test dispatch string"] = function(assert) {
michael@0 143 var isString = Method("isString")
michael@0 144 isString.define(False)
michael@0 145 isString.define(String, True)
michael@0 146
michael@0 147 assert.deepEqual(values.map(isString),
michael@0 148 falses.slice(0, 15).
michael@0 149 concat(true),
michael@0 150 "all strings inherit from String method")
michael@0 151 }
michael@0 152
michael@0 153 exports["test dispatch function"] = function(assert) {
michael@0 154 var isFunction = Method("isFunction")
michael@0 155 isFunction.define(False)
michael@0 156 isFunction.define(Function, True)
michael@0 157
michael@0 158 assert.deepEqual(values.map(isFunction),
michael@0 159 falses.slice(0, 11).
michael@0 160 concat(true, true).
michael@0 161 concat(falses.slice(13)),
michael@0 162 "all functions inherit from Function method")
michael@0 163 }
michael@0 164
michael@0 165 exports["test dispatch date"] = function(assert) {
michael@0 166 var isDate = Method("isDate")
michael@0 167 isDate.define(False)
michael@0 168 isDate.define(Date, True)
michael@0 169
michael@0 170 assert.deepEqual(values.map(isDate),
michael@0 171 falses.slice(0, 10).
michael@0 172 concat(true).
michael@0 173 concat(falses.slice(11)),
michael@0 174 "all dates inherit from Date method")
michael@0 175 }
michael@0 176
michael@0 177 exports["test dispatch RegExp"] = function(assert) {
michael@0 178 var isRegExp = Method("isRegExp")
michael@0 179 isRegExp.define(False)
michael@0 180 isRegExp.define(RegExp, True)
michael@0 181
michael@0 182 assert.deepEqual(values.map(isRegExp),
michael@0 183 falses.slice(0, 9).
michael@0 184 concat(true).
michael@0 185 concat(falses.slice(10)),
michael@0 186 "all regexps inherit from RegExp method")
michael@0 187 }
michael@0 188
michael@0 189 exports["test redefine for descendant"] = function(assert) {
michael@0 190 var isFoo = Method("isFoo")
michael@0 191 var ancestor = {}
michael@0 192 isFoo.implement(ancestor, function() { return true })
michael@0 193 var descendant = Object.create(ancestor)
michael@0 194 isFoo.implement(descendant, function() { return false })
michael@0 195
michael@0 196 assert.ok(isFoo(ancestor), "defined on ancestor")
michael@0 197 assert.ok(!isFoo(descendant), "overrided for descendant")
michael@0 198 }
michael@0 199
michael@0 200 exports["test on custom types"] = function(assert) {
michael@0 201 function Bar() {}
michael@0 202 var isBar = Method("isBar")
michael@0 203
michael@0 204 isBar.define(function() { return false })
michael@0 205 isBar.define(Bar, function() { return true })
michael@0 206
michael@0 207 assert.ok(!isBar({}), "object is get's default implementation")
michael@0 208 assert.ok(isBar(new Bar()), "Foo type objects get own implementation")
michael@0 209
michael@0 210 var isObject = Method("isObject")
michael@0 211 isObject.define(function() { return false })
michael@0 212 isObject.define(Object, function() { return true })
michael@0 213
michael@0 214 assert.ok(isObject(new Bar()), "foo inherits implementation from object")
michael@0 215
michael@0 216
michael@0 217 isObject.define(Bar, function() { return false })
michael@0 218
michael@0 219 assert.ok(!isObject(new Bar()),
michael@0 220 "implementation inherited form object can be overrided")
michael@0 221 }
michael@0 222
michael@0 223
michael@0 224 exports["test error types"] = function(assert) {
michael@0 225 var isError = Method("isError")
michael@0 226 isError.define(function() { return false })
michael@0 227 isError.define(Error, function() { return true })
michael@0 228
michael@0 229 assert.ok(isError(Error("boom")), "error is error")
michael@0 230 assert.ok(isError(TypeError("boom")), "type error is an error")
michael@0 231 assert.ok(isError(EvalError("boom")), "eval error is an error")
michael@0 232 assert.ok(isError(RangeError("boom")), "range error is an error")
michael@0 233 assert.ok(isError(ReferenceError("boom")), "reference error is an error")
michael@0 234 assert.ok(isError(SyntaxError("boom")), "syntax error is an error")
michael@0 235 assert.ok(isError(URIError("boom")), "URI error is an error")
michael@0 236 }
michael@0 237
michael@0 238 exports["test override define polymorphic method"] = function(assert) {
michael@0 239 var define = Method.define
michael@0 240 var implement = Method.implement
michael@0 241
michael@0 242 var fn = Method("fn")
michael@0 243 var methods = {}
michael@0 244 implement(define, fn, function(method, label, implementation) {
michael@0 245 methods[label] = implementation
michael@0 246 })
michael@0 247
michael@0 248 function foo() {}
michael@0 249
michael@0 250 define(fn, "foo-case", foo)
michael@0 251
michael@0 252 assert.equal(methods["foo-case"], foo, "define set property")
michael@0 253 }
michael@0 254
michael@0 255 exports["test override define via method API"] = function(assert) {
michael@0 256 var define = Method.define
michael@0 257 var implement = Method.implement
michael@0 258
michael@0 259 var fn = Method("fn")
michael@0 260 var methods = {}
michael@0 261 define.implement(fn, function(method, label, implementation) {
michael@0 262 methods[label] = implementation
michael@0 263 })
michael@0 264
michael@0 265 function foo() {}
michael@0 266
michael@0 267 define(fn, "foo-case", foo)
michael@0 268
michael@0 269 assert.equal(methods["foo-case"], foo, "define set property")
michael@0 270 }
michael@0 271
michael@0 272 require("test").run(exports)

mercurial