Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
3 /*
4 * Any copyright is dedicated to the Public Domain.
5 * http://creativecommons.org/licenses/publicdomain/
6 */
9 /*
10 * Return true if both of these return true:
11 * - LENIENT_PRED applied to CODE
12 * - STRICT_PRED applied to CODE with a use strict directive added to the front
13 *
14 * Run STRICT_PRED first, for testing code that affects the global environment
15 * in loose mode, but fails in strict mode.
16 */
17 function testLenientAndStrict(code, lenient_pred, strict_pred) {
18 return (strict_pred("'use strict'; " + code) &&
19 lenient_pred(code));
20 }
22 /*
23 * completesNormally(CODE) returns true if evaluating CODE (as eval
24 * code) completes normally (rather than throwing an exception).
25 */
26 function completesNormally(code) {
27 try {
28 eval(code);
29 return true;
30 } catch (exception) {
31 return false;
32 }
33 }
35 /*
36 * returns(VALUE)(CODE) returns true if evaluating CODE (as eval code)
37 * completes normally (rather than throwing an exception), yielding a value
38 * strictly equal to VALUE.
39 */
40 function returns(value) {
41 return function(code) {
42 try {
43 return eval(code) === value;
44 } catch (exception) {
45 return false;
46 }
47 }
48 }
50 /*
51 * returnsCopyOf(VALUE)(CODE) returns true if evaluating CODE (as eval code)
52 * completes normally (rather than throwing an exception), yielding a value
53 * that is deepEqual to VALUE.
54 */
55 function returnsCopyOf(value) {
56 return function(code) {
57 try {
58 return deepEqual(eval(code), value);
59 } catch (exception) {
60 return false;
61 }
62 }
63 }
65 /*
66 * raisesException(EXCEPTION)(CODE) returns true if evaluating CODE (as
67 * eval code) throws an exception object that is an instance of EXCEPTION,
68 * and returns false if it throws any other error or evaluates
69 * successfully. For example: raises(TypeError)("0()") == true.
70 */
71 function raisesException(exception) {
72 return function (code) {
73 try {
74 eval(code);
75 return false;
76 } catch (actual) {
77 return actual instanceof exception;
78 }
79 };
80 };
82 /*
83 * parsesSuccessfully(CODE) returns true if CODE parses as function
84 * code without an error.
85 */
86 function parsesSuccessfully(code) {
87 try {
88 Function(code);
89 return true;
90 } catch (exception) {
91 return false;
92 }
93 };
95 /*
96 * parseRaisesException(EXCEPTION)(CODE) returns true if parsing CODE
97 * as function code raises EXCEPTION.
98 */
99 function parseRaisesException(exception) {
100 return function (code) {
101 try {
102 Function(code);
103 return false;
104 } catch (actual) {
105 return actual instanceof exception;
106 }
107 };
108 };
110 /*
111 * Return the result of applying uneval to VAL, and replacing all runs
112 * of whitespace with a single horizontal space (poor man's
113 * tokenization).
114 */
115 function clean_uneval(val) {
116 return uneval(val).replace(/\s+/g, ' ');
117 }
119 /*
120 * Return true if A is equal to B, where equality on arrays and objects
121 * means that they have the same set of enumerable properties, the values
122 * of each property are deep_equal, and their 'length' properties are
123 * equal. Equality on other types is ==.
124 */
125 function deepEqual(a, b) {
126 if (typeof a != typeof b)
127 return false;
129 if (typeof a == 'object') {
130 var props = {};
131 // For every property of a, does b have that property with an equal value?
132 for (var prop in a) {
133 if (!deepEqual(a[prop], b[prop]))
134 return false;
135 props[prop] = true;
136 }
137 // Are all of b's properties present on a?
138 for (var prop in b)
139 if (!props[prop])
140 return false;
141 // length isn't enumerable, but we want to check it, too.
142 return a.length == b.length;
143 }
145 if (a === b) {
146 // Distinguish 0 from -0, even though they are ===.
147 return a !== 0 || 1/a === 1/b;
148 }
150 // Treat NaNs as equal, even though NaN !== NaN.
151 // NaNs are the only non-reflexive values, i.e., if a !== a, then a is a NaN.
152 // isNaN is broken: it converts its argument to number, so isNaN("foo") => true
153 return a !== a && b !== b;
154 }