Home | History | Annotate | Download | only in mjsunit
      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 
     28 function MjsUnitAssertionError(message) {
     29   this.message = message;
     30 }
     31 
     32 MjsUnitAssertionError.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 
     42 function 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 
     54 function 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 
     73 function 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 
    105 function assertEquals(expected, found, name_opt) {
    106   if (!deepEquals(found, expected)) {
    107     fail(expected, found, name_opt);
    108   }
    109 }
    110 
    111 
    112 function 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 
    126 function assertTrue(value, name_opt) {
    127   assertEquals(true, value, name_opt);
    128 }
    129 
    130 
    131 function assertFalse(value, name_opt) {
    132   assertEquals(false, value, name_opt);
    133 }
    134 
    135 
    136 function assertNaN(value, name_opt) {
    137   if (!isNaN(value)) {
    138     fail("NaN", value, name_opt);
    139   }
    140 }
    141 
    142 
    143 function assertNull(value, name_opt) {
    144   if (value !== null) {
    145     fail("null", value, name_opt);
    146   }
    147 }
    148 
    149 
    150 function assertNotNull(value, name_opt) {
    151   if (value === null) {
    152     fail("not null", value, name_opt);
    153   }
    154 }
    155 
    156 
    157 function 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 
    177 function assertInstanceof(obj, type) {
    178   if (!(obj instanceof type)) {
    179     assertTrue(false, "Object <" + obj + "> is not an instance of <" + type + ">");
    180   }
    181 }
    182 
    183 
    184 function 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 
    197 function 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