mjsunit.js 5.55 KB
Newer Older
1
// Copyright 2008 the V8 project authors. All rights reserved.
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
//       copyright notice, this list of conditions and the following
//       disclaimer in the documentation and/or other materials provided
//       with the distribution.
//     * Neither the name of Google Inc. nor the names of its
//       contributors may be used to endorse or promote products derived
//       from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

28 29
function MjsUnitAssertionError(message) {
  this.message = message;
30 31
  // This allows fetching the stack trace using TryCatch::StackTrace.
  this.stack = new Error("").stack;
32 33 34 35 36 37
}

MjsUnitAssertionError.prototype.toString = function () {
  return this.message;
}

38 39 40 41 42 43 44 45 46
/*
 * This file is included in all mini jsunit test cases.  The test
 * framework expects lines that signal failed tests to start with
 * the f-word and ignore all other lines.
 */

function fail(expected, found, name_opt) {
  var start;
  if (name_opt) {
47 48
    // Fix this when we ditch the old test runner.
    start = "Fail" + "ure (" + name_opt + "): ";
49
  } else {
50
    start = "Fail" + "ure:";
51
  }
52
  throw new MjsUnitAssertionError(start + " expected <" + expected + "> found <" + found + ">");
53 54 55
}


56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
function deepObjectEquals(a, b) {
  var aProps = [];
  for (var key in a)
    aProps.push(key);
  var bProps = [];
  for (var key in b)
    bProps.push(key);
  aProps.sort();
  bProps.sort();
  if (!deepEquals(aProps, bProps))
    return false;
  for (var i = 0; i < aProps.length; i++) {
    if (!deepEquals(a[aProps[i]], b[aProps[i]]))
      return false;
  }
  return true;
}


75 76
function deepEquals(a, b) {
  if (a == b) return true;
77 78 79
  if (typeof a == "number" && typeof b == "number" && isNaN(a) && isNaN(b)) {
    return true;
  }
80
  if (a == null || b == null) return false;
81 82 83
  if (a.constructor === RegExp || b.constructor === RegExp) {
    return (a.constructor === b.constructor) && (a.toString === b.toString);
  }
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
  if ((typeof a) !== 'object' || (typeof b) !== 'object' ||
      (a === null) || (b === null))
    return false;
  if (a.constructor === Array) {
    if (b.constructor !== Array)
      return false;
    if (a.length != b.length)
      return false;
    for (var i = 0; i < a.length; i++) {
      if (i in a) {
        if (!(i in b) || !(deepEquals(a[i], b[i])))
          return false;
      } else if (i in b) {
        return false;
      }
    }
    return true;
101 102
  } else {
    return deepObjectEquals(a, b);
103 104 105 106
  }
}


107
function assertEquals(expected, found, name_opt) {
108
  if (!deepEquals(found, expected)) {
109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
    fail(expected, found, name_opt);
  }
}


function assertArrayEquals(expected, found, name_opt) {
  var start = "";
  if (name_opt) {
    start = name_opt + " - ";
  }
  assertEquals(expected.length, found.length, start + "array length");
  if (expected.length == found.length) {
    for (var i = 0; i < expected.length; ++i) {
      assertEquals(expected[i], found[i], start + "array element at index " + i);
    }
  }
}


function assertTrue(value, name_opt) {
  assertEquals(true, value, name_opt);
}


function assertFalse(value, name_opt) {
  assertEquals(false, value, name_opt);
}


function assertNaN(value, name_opt) {
  if (!isNaN(value)) {
    fail("NaN", value, name_opt);
  }
}


145 146 147 148 149 150 151 152 153 154 155 156 157 158
function assertNull(value, name_opt) {
  if (value !== null) {
    fail("null", value, name_opt);
  }
}


function assertNotNull(value, name_opt) {
  if (value === null) {
    fail("not null", value, name_opt);
  }
}


159
function assertThrows(code, type_opt, cause_opt) {
160
  var threwException = true;
161
  try {
162 163 164 165 166
    if (typeof code == 'function') {
      code();
    } else {
      eval(code);
    }
167
    threwException = false;
168
  } catch (e) {
169 170 171 172
    if (typeof type_opt == 'function')
      assertInstanceof(e, type_opt);
    if (arguments.length >= 3)
      assertEquals(e.type, cause_opt);
173 174
    // Do nothing.
  }
175
  if (!threwException) assertTrue(false, "did not throw exception");
176 177 178 179 180 181 182 183 184 185 186 187
}


function assertInstanceof(obj, type) {
  if (!(obj instanceof type)) {
    assertTrue(false, "Object <" + obj + "> is not an instance of <" + type + ">");
  }
}


function assertDoesNotThrow(code) {
  try {
188 189 190 191 192
    if (typeof code == 'function') {
      code();
    } else {
      eval(code);
    }
193
  } catch (e) {
194
    assertTrue(false, "threw an exception: " + (e.message || e));
195 196 197 198 199
  }
}


function assertUnreachable(name_opt) {
200 201
  // Fix this when we ditch the old test runner.
  var message = "Fail" + "ure: unreachable"
202 203 204
  if (name_opt) {
    message += " - " + name_opt;
  }
205
  throw new MjsUnitAssertionError(message);
206
}