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 ((typeof a) !== 'object' || (typeof b) !== 'object' || 79 (a === null) || (b === null)) 80 return false; 81 if (a.constructor === Array) { 82 if (b.constructor !== Array) 83 return false; 84 if (a.length != b.length) 85 return false; 86 for (var i = 0; i < a.length; i++) { 87 if (i in a) { 88 if (!(i in b) || !(deepEquals(a[i], b[i]))) 89 return false; 90 } else if (i in b) { 91 return false; 92 } 93 } 94 return true; 95 } else { 96 return deepObjectEquals(a, b); 97 } 98} 99 100 101function assertEquals(expected, found, name_opt) { 102 if (!deepEquals(found, expected)) { 103 fail(expected, found, name_opt); 104 } 105} 106 107 108function assertArrayEquals(expected, found, name_opt) { 109 var start = ""; 110 if (name_opt) { 111 start = name_opt + " - "; 112 } 113 assertEquals(expected.length, found.length, start + "array length"); 114 if (expected.length == found.length) { 115 for (var i = 0; i < expected.length; ++i) { 116 assertEquals(expected[i], found[i], start + "array element at index " + i); 117 } 118 } 119} 120 121 122function assertTrue(value, name_opt) { 123 assertEquals(true, value, name_opt); 124} 125 126 127function assertFalse(value, name_opt) { 128 assertEquals(false, value, name_opt); 129} 130 131 132function assertNaN(value, name_opt) { 133 if (!isNaN(value)) { 134 fail("NaN", value, name_opt); 135 } 136} 137 138 139function assertNull(value, name_opt) { 140 if (value !== null) { 141 fail("null", value, name_opt); 142 } 143} 144 145 146function assertNotNull(value, name_opt) { 147 if (value === null) { 148 fail("not null", value, name_opt); 149 } 150} 151 152 153function assertThrows(code, type_opt, cause_opt) { 154 var threwException = true; 155 try { 156 if (typeof code == 'function') { 157 code(); 158 } else { 159 eval(code); 160 } 161 threwException = false; 162 } catch (e) { 163 if (typeof type_opt == 'function') 164 assertInstanceof(e, type_opt); 165 if (arguments.length >= 3) 166 assertEquals(e.type, cause_opt); 167 // Do nothing. 168 } 169 if (!threwException) assertTrue(false, "did not throw exception"); 170} 171 172 173function assertInstanceof(obj, type) { 174 if (!(obj instanceof type)) { 175 assertTrue(false, "Object <" + obj + "> is not an instance of <" + type + ">"); 176 } 177} 178 179 180function assertDoesNotThrow(code) { 181 try { 182 if (typeof code == 'function') { 183 code(); 184 } else { 185 eval(code); 186 } 187 } catch (e) { 188 assertTrue(false, "threw an exception: " + (e.message || e)); 189 } 190} 191 192 193function assertUnreachable(name_opt) { 194 // Fix this when we ditch the old test runner. 195 var message = "Fail" + "ure: unreachable" 196 if (name_opt) { 197 message += " - " + name_opt; 198 } 199 throw new MjsUnitAssertionError(message); 200} 201