Sat, 03 Jan 2015 20:18:00 +0100
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.
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";
6 module.metadata = {
7 "stability": "unstable"
8 };
10 const { isFunction, isNull, isObject, isString,
11 isRegExp, isArray, isDate, isPrimitive,
12 isUndefined, instanceOf, source } = require("../lang/type");
14 /**
15 * The `AssertionError` is defined in assert.
16 * @extends Error
17 * @example
18 * new assert.AssertionError({
19 * message: message,
20 * actual: actual,
21 * expected: expected
22 * })
23 */
24 function AssertionError(options) {
25 let assertionError = Object.create(AssertionError.prototype);
27 if (isString(options))
28 options = { message: options };
29 if ("actual" in options)
30 assertionError.actual = options.actual;
31 if ("expected" in options)
32 assertionError.expected = options.expected;
33 if ("operator" in options)
34 assertionError.operator = options.operator;
36 assertionError.message = options.message;
37 assertionError.stack = new Error().stack;
38 return assertionError;
39 }
40 AssertionError.prototype = Object.create(Error.prototype, {
41 constructor: { value: AssertionError },
42 name: { value: "AssertionError", enumerable: true },
43 toString: { value: function toString() {
44 let value;
45 if (this.message) {
46 value = this.name + " : " + this.message;
47 }
48 else {
49 value = [
50 this.name + " : ",
51 source(this.expected),
52 this.operator,
53 source(this.actual)
54 ].join(" ");
55 }
56 return value;
57 }}
58 });
59 exports.AssertionError = AssertionError;
61 function Assert(logger) {
62 let assert = Object.create(Assert.prototype, { _log: { value: logger }});
64 assert.fail = assert.fail.bind(assert);
65 assert.pass = assert.pass.bind(assert);
67 return assert;
68 }
70 Assert.prototype = {
71 fail: function fail(e) {
72 if (!e || typeof(e) !== 'object') {
73 this._log.fail(e);
74 return;
75 }
76 let message = e.message;
77 try {
78 if ('operator' in e) {
79 message += [
80 " -",
81 source(e.expected),
82 e.operator,
83 source(e.actual)
84 ].join(" ");
85 }
86 }
87 catch(e) {}
88 this._log.fail(message);
89 },
90 pass: function pass(message) {
91 this._log.pass(message);
92 },
93 error: function error(e) {
94 this._log.exception(e);
95 },
96 ok: function ok(value, message) {
97 if (!!!value) {
98 this.fail({
99 actual: value,
100 expected: true,
101 message: message,
102 operator: "=="
103 });
104 }
105 else {
106 this.pass(message);
107 }
108 },
110 /**
111 * The equality assertion tests shallow, coercive equality with `==`.
112 * @example
113 * assert.equal(1, 1, "one is one");
114 */
115 equal: function equal(actual, expected, message) {
116 if (actual == expected) {
117 this.pass(message);
118 }
119 else {
120 this.fail({
121 actual: actual,
122 expected: expected,
123 message: message,
124 operator: "=="
125 });
126 }
127 },
129 /**
130 * The non-equality assertion tests for whether two objects are not equal
131 * with `!=`.
132 * @example
133 * assert.notEqual(1, 2, "one is not two");
134 */
135 notEqual: function notEqual(actual, expected, message) {
136 if (actual != expected) {
137 this.pass(message);
138 }
139 else {
140 this.fail({
141 actual: actual,
142 expected: expected,
143 message: message,
144 operator: "!=",
145 });
146 }
147 },
149 /**
150 * The equivalence assertion tests a deep (with `===`) equality relation.
151 * @example
152 * assert.deepEqual({ a: "foo" }, { a: "foo" }, "equivalent objects")
153 */
154 deepEqual: function deepEqual(actual, expected, message) {
155 if (isDeepEqual(actual, expected)) {
156 this.pass(message);
157 }
158 else {
159 this.fail({
160 actual: actual,
161 expected: expected,
162 message: message,
163 operator: "deepEqual"
164 });
165 }
166 },
168 /**
169 * The non-equivalence assertion tests for any deep (with `===`) inequality.
170 * @example
171 * assert.notDeepEqual({ a: "foo" }, Object.create({ a: "foo" }),
172 * "object's inherit from different prototypes");
173 */
174 notDeepEqual: function notDeepEqual(actual, expected, message) {
175 if (!isDeepEqual(actual, expected)) {
176 this.pass(message);
177 }
178 else {
179 this.fail({
180 actual: actual,
181 expected: expected,
182 message: message,
183 operator: "notDeepEqual"
184 });
185 }
186 },
188 /**
189 * The strict equality assertion tests strict equality, as determined by
190 * `===`.
191 * @example
192 * assert.strictEqual(null, null, "`null` is `null`")
193 */
194 strictEqual: function strictEqual(actual, expected, message) {
195 if (actual === expected) {
196 this.pass(message);
197 }
198 else {
199 this.fail({
200 actual: actual,
201 expected: expected,
202 message: message,
203 operator: "==="
204 });
205 }
206 },
208 /**
209 * The strict non-equality assertion tests for strict inequality, as
210 * determined by `!==`.
211 * @example
212 * assert.notStrictEqual(null, undefined, "`null` is not `undefined`");
213 */
214 notStrictEqual: function notStrictEqual(actual, expected, message) {
215 if (actual !== expected) {
216 this.pass(message);
217 }
218 else {
219 this.fail({
220 actual: actual,
221 expected: expected,
222 message: message,
223 operator: "!=="
224 })
225 }
226 },
228 /**
229 * The assertion whether or not given `block` throws an exception. If optional
230 * `Error` argument is provided and it's type of function thrown error is
231 * asserted to be an instance of it, if type of `Error` is string then message
232 * of throw exception is asserted to contain it.
233 * @param {Function} block
234 * Function that is expected to throw.
235 * @param {Error|RegExp} [Error]
236 * Error constructor that is expected to be thrown or a string that
237 * must be contained by a message of the thrown exception, or a RegExp
238 * matching a message of the thrown exception.
239 * @param {String} message
240 * Description message
241 *
242 * @examples
243 *
244 * assert.throws(function block() {
245 * doSomething(4)
246 * }, "Object is expected", "Incorrect argument is passed");
247 *
248 * assert.throws(function block() {
249 * Object.create(5)
250 * }, TypeError, "TypeError is thrown");
251 */
252 throws: function throws(block, Error, message) {
253 let threw = false;
254 let exception = null;
256 // If third argument is not provided and second argument is a string it
257 // means that optional `Error` argument was not passed, so we shift
258 // arguments.
259 if (isString(Error) && isUndefined(message)) {
260 message = Error;
261 Error = undefined;
262 }
264 // Executing given `block`.
265 try {
266 block();
267 }
268 catch (e) {
269 threw = true;
270 exception = e;
271 }
273 // If exception was thrown and `Error` argument was not passed assert is
274 // passed.
275 if (threw && (isUndefined(Error) ||
276 // If passed `Error` is RegExp using it's test method to
277 // assert thrown exception message.
278 (isRegExp(Error) && Error.test(exception.message)) ||
279 // If passed `Error` is a constructor function testing if
280 // thrown exception is an instance of it.
281 (isFunction(Error) && instanceOf(exception, Error))))
282 {
283 this.pass(message);
284 }
286 // Otherwise we report assertion failure.
287 else {
288 let failure = {
289 message: message,
290 operator: "throws"
291 };
293 if (exception)
294 failure.actual = exception;
296 if (Error)
297 failure.expected = Error;
299 this.fail(failure);
300 }
301 }
302 };
303 exports.Assert = Assert;
305 function isDeepEqual(actual, expected) {
307 // 7.1. All identical values are equivalent, as determined by ===.
308 if (actual === expected) {
309 return true;
310 }
312 // 7.2. If the expected value is a Date object, the actual value is
313 // equivalent if it is also a Date object that refers to the same time.
314 else if (isDate(actual) && isDate(expected)) {
315 return actual.getTime() === expected.getTime();
316 }
318 // XXX specification bug: this should be specified
319 else if (isPrimitive(actual) || isPrimitive(expected)) {
320 return expected === actual;
321 }
323 // 7.3. Other pairs that do not both pass typeof value == "object",
324 // equivalence is determined by ==.
325 else if (!isObject(actual) && !isObject(expected)) {
326 return actual == expected;
327 }
329 // 7.4. For all other Object pairs, including Array objects, equivalence is
330 // determined by having the same number of owned properties (as verified
331 // with Object.prototype.hasOwnProperty.call), the same set of keys
332 // (although not necessarily the same order), equivalent values for every
333 // corresponding key, and an identical "prototype" property. Note: this
334 // accounts for both named and indexed properties on Arrays.
335 else {
336 return actual.prototype === expected.prototype &&
337 isEquivalent(actual, expected);
338 }
339 }
341 function isEquivalent(a, b, stack) {
342 let aKeys = Object.keys(a);
343 let bKeys = Object.keys(b);
345 return aKeys.length === bKeys.length &&
346 isArrayEquivalent(aKeys.sort(), bKeys.sort()) &&
347 aKeys.every(function(key) {
348 return isDeepEqual(a[key], b[key], stack)
349 });
350 }
352 function isArrayEquivalent(a, b, stack) {
353 return isArray(a) && isArray(b) &&
354 a.every(function(value, index) {
355 return isDeepEqual(value, b[index]);
356 });
357 }