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