blob: 558282f52bb39126003503fac3aedeb94f27ecff [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
44function fail(expected, found, name_opt) {
45 var start;
46 if (name_opt) {
47 // Fix this when we ditch the old test runner.
48 start = "Fail" + "ure (" + name_opt + "): ";
49 } else {
50 start = "Fail" + "ure:";
51 }
52 throw new MjsUnitAssertionError(start + " expected <" + expected + "> found <" + found + ">");
53}
54
55
56function deepObjectEquals(a, b) {
57 var aProps = [];
58 for (var key in a)
59 aProps.push(key);
60 var bProps = [];
61 for (var key in b)
62 bProps.push(key);
63 aProps.sort();
64 bProps.sort();
65 if (!deepEquals(aProps, bProps))
66 return false;
67 for (var i = 0; i < aProps.length; i++) {
68 if (!deepEquals(a[aProps[i]], b[aProps[i]]))
69 return false;
70 }
71 return true;
72}
73
74
75function deepEquals(a, b) {
76 if (a == b) return true;
77 if (typeof a == "number" && typeof b == "number" && isNaN(a) && isNaN(b)) {
78 return true;
79 }
Leon Clarke4515c472010-02-03 11:58:03 +000080 if (a == null || b == null) return false;
Steve Blockd0582a62009-12-15 09:54:21 +000081 if (a.constructor === RegExp || b.constructor === RegExp) {
82 return (a.constructor === b.constructor) && (a.toString === b.toString);
83 }
Steve Blocka7e24c12009-10-30 11:49:00 +000084 if ((typeof a) !== 'object' || (typeof b) !== 'object' ||
85 (a === null) || (b === null))
86 return false;
87 if (a.constructor === Array) {
88 if (b.constructor !== Array)
89 return false;
90 if (a.length != b.length)
91 return false;
92 for (var i = 0; i < a.length; i++) {
93 if (i in a) {
94 if (!(i in b) || !(deepEquals(a[i], b[i])))
95 return false;
96 } else if (i in b) {
97 return false;
98 }
99 }
100 return true;
101 } else {
102 return deepObjectEquals(a, b);
103 }
104}
105
106
107function assertEquals(expected, found, name_opt) {
108 if (!deepEquals(found, expected)) {
109 fail(expected, found, name_opt);
110 }
111}
112
113
114function assertArrayEquals(expected, found, name_opt) {
115 var start = "";
116 if (name_opt) {
117 start = name_opt + " - ";
118 }
119 assertEquals(expected.length, found.length, start + "array length");
120 if (expected.length == found.length) {
121 for (var i = 0; i < expected.length; ++i) {
122 assertEquals(expected[i], found[i], start + "array element at index " + i);
123 }
124 }
125}
126
127
128function assertTrue(value, name_opt) {
129 assertEquals(true, value, name_opt);
130}
131
132
133function assertFalse(value, name_opt) {
134 assertEquals(false, value, name_opt);
135}
136
137
138function assertNaN(value, name_opt) {
139 if (!isNaN(value)) {
140 fail("NaN", value, name_opt);
141 }
142}
143
144
145function assertNull(value, name_opt) {
146 if (value !== null) {
147 fail("null", value, name_opt);
148 }
149}
150
151
152function assertNotNull(value, name_opt) {
153 if (value === null) {
154 fail("not null", value, name_opt);
155 }
156}
157
158
159function assertThrows(code, type_opt, cause_opt) {
160 var threwException = true;
161 try {
162 if (typeof code == 'function') {
163 code();
164 } else {
165 eval(code);
166 }
167 threwException = false;
168 } catch (e) {
169 if (typeof type_opt == 'function')
170 assertInstanceof(e, type_opt);
171 if (arguments.length >= 3)
172 assertEquals(e.type, cause_opt);
173 // Do nothing.
174 }
175 if (!threwException) assertTrue(false, "did not throw exception");
176}
177
178
179function assertInstanceof(obj, type) {
180 if (!(obj instanceof type)) {
181 assertTrue(false, "Object <" + obj + "> is not an instance of <" + type + ">");
182 }
183}
184
185
186function assertDoesNotThrow(code) {
187 try {
188 if (typeof code == 'function') {
189 code();
190 } else {
191 eval(code);
192 }
193 } catch (e) {
194 assertTrue(false, "threw an exception: " + (e.message || e));
195 }
196}
197
198
199function assertUnreachable(name_opt) {
200 // Fix this when we ditch the old test runner.
201 var message = "Fail" + "ure: unreachable"
202 if (name_opt) {
203 message += " - " + name_opt;
204 }
205 throw new MjsUnitAssertionError(message);
206}