blob: 436bdc8184957fcf3a85f50f77d2a110a9980096 [file] [log] [blame]
Steve Blocka7e24c12009-10-30 11:49:00 +00001// Copyright 2008 the V8 project authors. All rights reserved.
2// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6// * Redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer.
8// * Redistributions in binary form must reproduce the above
9// copyright notice, this list of conditions and the following
10// disclaimer in the documentation and/or other materials provided
11// with the distribution.
12// * Neither the name of Google Inc. nor the names of its
13// contributors may be used to endorse or promote products derived
14// from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28function MjsUnitAssertionError(message) {
29 this.message = message;
Kristian Monsen25f61362010-05-21 11:50:48 +010030 // This allows fetching the stack trace using TryCatch::StackTrace.
31 this.stack = new Error("").stack;
Steve Blocka7e24c12009-10-30 11:49:00 +000032}
33
34MjsUnitAssertionError.prototype.toString = function () {
35 return this.message;
36}
37
38/*
39 * This file is included in all mini jsunit test cases. The test
40 * framework expects lines that signal failed tests to start with
41 * the f-word and ignore all other lines.
42 */
43
Steve Block44f0eee2011-05-26 01:26:41 +010044function MjsUnitToString(value) {
45 switch (typeof value) {
46 case "string":
47 return JSON.stringify(value);
48 case "number":
49 if (value === 0 && (1 / value) < 0) return "-0";
50 case "boolean":
51 case "null":
52 case "undefined":
53 case "function":
54 return String(value);
55 case "object":
56 if (value === null) return "null";
57 var clazz = Object.prototype.toString.call(value);
58 clazz = clazz.substring(8, clazz.length - 1);
59 switch (clazz) {
60 case "Number":
61 case "String":
62 case "Boolean":
63 case "Date":
64 return clazz + "(" + MjsUnitToString(value.valueOf()) + ")";
65 case "RegExp":
66 return value.toString();
67 case "Array":
68 return "[" + value.map(MjsUnitArrayElementToString).join(",") + "]";
69 case "Object":
70 break;
71 default:
72 return clazz + "()";
73 }
74 // [[Class]] is "Object".
75 var constructor = value.constructor.name;
76 if (name) return name + "()";
77 return "Object()";
78 default:
79 return "-- unknown value --";
80 }
81}
82
83
84function MjsUnitArrayElementToString(value, index, array) {
85 if (value === undefined && !(index in array)) return "";
86 return MjsUnitToString(value);
87}
88
89
Steve Blocka7e24c12009-10-30 11:49:00 +000090function fail(expected, found, name_opt) {
Steve Block44f0eee2011-05-26 01:26:41 +010091 var message = "Fail" + "ure";
Steve Blocka7e24c12009-10-30 11:49:00 +000092 if (name_opt) {
93 // Fix this when we ditch the old test runner.
Steve Block44f0eee2011-05-26 01:26:41 +010094 message += " (" + name_opt + ")";
Steve Blocka7e24c12009-10-30 11:49:00 +000095 }
Steve Block44f0eee2011-05-26 01:26:41 +010096
97 message += ": expected <" + MjsUnitToString(expected) +
98 "> found <" + MjsUnitToString(found) + ">";
99 throw new MjsUnitAssertionError(message);
Steve Blocka7e24c12009-10-30 11:49:00 +0000100}
101
102
103function deepObjectEquals(a, b) {
104 var aProps = [];
105 for (var key in a)
106 aProps.push(key);
107 var bProps = [];
108 for (var key in b)
109 bProps.push(key);
110 aProps.sort();
111 bProps.sort();
112 if (!deepEquals(aProps, bProps))
113 return false;
114 for (var i = 0; i < aProps.length; i++) {
115 if (!deepEquals(a[aProps[i]], b[aProps[i]]))
116 return false;
117 }
118 return true;
119}
120
121
122function deepEquals(a, b) {
Steve Block44f0eee2011-05-26 01:26:41 +0100123 if (a == b) {
124 // Check for -0.
125 if (a === 0 && b === 0) return (1 / a) === (1 / b);
126 return true;
127 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000128 if (typeof a == "number" && typeof b == "number" && isNaN(a) && isNaN(b)) {
129 return true;
130 }
Leon Clarke4515c472010-02-03 11:58:03 +0000131 if (a == null || b == null) return false;
Steve Blockd0582a62009-12-15 09:54:21 +0000132 if (a.constructor === RegExp || b.constructor === RegExp) {
Steve Block44f0eee2011-05-26 01:26:41 +0100133 return (a.constructor === b.constructor) && (a.toString() === b.toString());
Steve Blockd0582a62009-12-15 09:54:21 +0000134 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000135 if ((typeof a) !== 'object' || (typeof b) !== 'object' ||
136 (a === null) || (b === null))
137 return false;
138 if (a.constructor === Array) {
139 if (b.constructor !== Array)
140 return false;
141 if (a.length != b.length)
142 return false;
143 for (var i = 0; i < a.length; i++) {
144 if (i in a) {
145 if (!(i in b) || !(deepEquals(a[i], b[i])))
146 return false;
147 } else if (i in b) {
148 return false;
149 }
150 }
151 return true;
152 } else {
153 return deepObjectEquals(a, b);
154 }
155}
156
157
Ben Murdoche0cee9b2011-05-25 10:26:03 +0100158function assertSame(expected, found, name_opt) {
159 if (found !== expected) {
160 fail(expected, found, name_opt);
161 }
162}
163
164
Steve Blocka7e24c12009-10-30 11:49:00 +0000165function assertEquals(expected, found, name_opt) {
166 if (!deepEquals(found, expected)) {
167 fail(expected, found, name_opt);
168 }
169}
170
171
172function assertArrayEquals(expected, found, name_opt) {
173 var start = "";
174 if (name_opt) {
175 start = name_opt + " - ";
176 }
177 assertEquals(expected.length, found.length, start + "array length");
178 if (expected.length == found.length) {
179 for (var i = 0; i < expected.length; ++i) {
180 assertEquals(expected[i], found[i], start + "array element at index " + i);
181 }
182 }
183}
184
185
186function assertTrue(value, name_opt) {
187 assertEquals(true, value, name_opt);
188}
189
190
191function assertFalse(value, name_opt) {
192 assertEquals(false, value, name_opt);
193}
194
195
196function assertNaN(value, name_opt) {
197 if (!isNaN(value)) {
198 fail("NaN", value, name_opt);
199 }
200}
201
202
203function assertNull(value, name_opt) {
204 if (value !== null) {
205 fail("null", value, name_opt);
206 }
207}
208
209
210function assertNotNull(value, name_opt) {
211 if (value === null) {
212 fail("not null", value, name_opt);
213 }
214}
215
216
217function assertThrows(code, type_opt, cause_opt) {
218 var threwException = true;
219 try {
220 if (typeof code == 'function') {
221 code();
222 } else {
223 eval(code);
224 }
225 threwException = false;
226 } catch (e) {
227 if (typeof type_opt == 'function')
228 assertInstanceof(e, type_opt);
229 if (arguments.length >= 3)
230 assertEquals(e.type, cause_opt);
231 // Do nothing.
232 }
233 if (!threwException) assertTrue(false, "did not throw exception");
234}
235
236
237function assertInstanceof(obj, type) {
238 if (!(obj instanceof type)) {
239 assertTrue(false, "Object <" + obj + "> is not an instance of <" + type + ">");
240 }
241}
242
243
244function assertDoesNotThrow(code) {
245 try {
246 if (typeof code == 'function') {
247 code();
248 } else {
249 eval(code);
250 }
251 } catch (e) {
252 assertTrue(false, "threw an exception: " + (e.message || e));
253 }
254}
255
256
257function assertUnreachable(name_opt) {
258 // Fix this when we ditch the old test runner.
Steve Block44f0eee2011-05-26 01:26:41 +0100259 var message = "Fail" + "ure: unreachable";
Steve Blocka7e24c12009-10-30 11:49:00 +0000260 if (name_opt) {
261 message += " - " + name_opt;
262 }
263 throw new MjsUnitAssertionError(message);
264}