Home | History | Annotate | Download | only in mjsunit
      1 // Copyright 2009 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 testMethodNameInference() {
     29   function Foo() { }
     30   Foo.prototype.bar = function () { FAIL; };
     31   (new Foo).bar();
     32 }
     33 
     34 function testNested() {
     35   function one() {
     36     function two() {
     37       function three() {
     38         FAIL;
     39       }
     40       three();
     41     }
     42     two();
     43   }
     44   one();
     45 }
     46 
     47 function testArrayNative() {
     48   [1, 2, 3].map(function () { FAIL; });
     49 }
     50 
     51 function testImplicitConversion() {
     52   function Nirk() { }
     53   Nirk.prototype.valueOf = function () { FAIL; };
     54   return 1 + (new Nirk);
     55 }
     56 
     57 function testEval() {
     58   eval("function Doo() { FAIL; }; Doo();");
     59 }
     60 
     61 function testNestedEval() {
     62   var x = "FAIL";
     63   eval("function Outer() { eval('function Inner() { eval(x); }'); Inner(); }; Outer();");
     64 }
     65 
     66 function testValue() {
     67   Number.prototype.causeError = function () { FAIL; };
     68   (1).causeError();
     69 }
     70 
     71 function testConstructor() {
     72   function Plonk() { FAIL; }
     73   new Plonk();
     74 }
     75 
     76 function testRenamedMethod() {
     77   function a$b$c$d() { return FAIL; }
     78   function Wookie() { }
     79   Wookie.prototype.d = a$b$c$d;
     80   (new Wookie).d();
     81 }
     82 
     83 function testAnonymousMethod() {
     84   (function () { FAIL }).call([1, 2, 3]);
     85 }
     86 
     87 function CustomError(message, stripPoint) {
     88   this.message = message;
     89   Error.captureStackTrace(this, stripPoint);
     90 }
     91 
     92 CustomError.prototype.toString = function () {
     93   return "CustomError: " + this.message;
     94 };
     95 
     96 function testDefaultCustomError() {
     97   throw new CustomError("hep-hey", undefined);
     98 }
     99 
    100 function testStrippedCustomError() {
    101   throw new CustomError("hep-hey", CustomError);
    102 }
    103 
    104 // Utility function for testing that the expected strings occur
    105 // in the stack trace produced when running the given function.
    106 function testTrace(name, fun, expected, unexpected) {
    107   var threw = false;
    108   try {
    109     fun();
    110   } catch (e) {
    111     for (var i = 0; i < expected.length; i++) {
    112       assertTrue(e.stack.indexOf(expected[i]) != -1,
    113                  name + " doesn't contain expected[" + i + "]");
    114     }
    115     if (unexpected) {
    116       for (var i = 0; i < unexpected.length; i++) {
    117         assertEquals(e.stack.indexOf(unexpected[i]), -1,
    118                      name + " contains unexpected[" + i + "]");
    119       }
    120     }
    121     threw = true;
    122   }
    123   assertTrue(threw, name + " didn't throw");
    124 }
    125 
    126 // Test that the error constructor is not shown in the trace
    127 function testCallerCensorship() {
    128   var threw = false;
    129   try {
    130     FAIL;
    131   } catch (e) {
    132     assertEquals(-1, e.stack.indexOf('at new ReferenceError'),
    133                  "CallerCensorship contained new ReferenceError");
    134     threw = true;
    135   }
    136   assertTrue(threw, "CallerCensorship didn't throw");
    137 }
    138 
    139 // Test that the explicit constructor call is shown in the trace
    140 function testUnintendedCallerCensorship() {
    141   var threw = false;
    142   try {
    143     new ReferenceError({
    144       toString: function () {
    145         FAIL;
    146       }
    147     });
    148   } catch (e) {
    149     assertTrue(e.stack.indexOf('at new ReferenceError') != -1,
    150                "UnintendedCallerCensorship didn't contain new ReferenceError");
    151     threw = true;
    152   }
    153   assertTrue(threw, "UnintendedCallerCensorship didn't throw");
    154 }
    155 
    156 // If an error occurs while the stack trace is being formatted it should
    157 // be handled gracefully.
    158 function testErrorsDuringFormatting() {
    159   function Nasty() { }
    160   Nasty.prototype.foo = function () { throw new RangeError(); };
    161   var n = new Nasty();
    162   n.__defineGetter__('constructor', function () { CONS_FAIL; });
    163   var threw = false;
    164   try {
    165     n.foo();
    166   } catch (e) {
    167     threw = true;
    168     assertTrue(e.stack.indexOf('<error: ReferenceError') != -1,
    169                "ErrorsDuringFormatting didn't contain error: ReferenceError");
    170   }
    171   assertTrue(threw, "ErrorsDuringFormatting didn't throw");
    172   threw = false;
    173   // Now we can't even format the message saying that we couldn't format
    174   // the stack frame.  Put that in your pipe and smoke it!
    175   ReferenceError.prototype.toString = function () { NESTED_FAIL; };
    176   try {
    177     n.foo();
    178   } catch (e) {
    179     threw = true;
    180     assertTrue(e.stack.indexOf('<error>') != -1,
    181                "ErrorsDuringFormatting didn't contain <error>");
    182   }
    183   assertTrue(threw, "ErrorsDuringFormatting didnt' throw (2)");
    184 }
    185 
    186 
    187 testTrace("testArrayNative", testArrayNative, ["Array.map (native)"]);
    188 testTrace("testNested", testNested, ["at one", "at two", "at three"]);
    189 testTrace("testMethodNameInference", testMethodNameInference, ["at Foo.bar"]);
    190 testTrace("testImplicitConversion", testImplicitConversion, ["at Nirk.valueOf"]);
    191 testTrace("testEval", testEval, ["at Doo (eval at testEval"]);
    192 testTrace("testNestedEval", testNestedEval, ["eval at Inner (eval at Outer"]);
    193 testTrace("testValue", testValue, ["at Number.causeError"]);
    194 testTrace("testConstructor", testConstructor, ["new Plonk"]);
    195 testTrace("testRenamedMethod", testRenamedMethod, ["Wookie.a$b$c$d [as d]"]);
    196 testTrace("testAnonymousMethod", testAnonymousMethod, ["Array.<anonymous>"]);
    197 testTrace("testDefaultCustomError", testDefaultCustomError,
    198     ["hep-hey", "new CustomError"],
    199     ["collectStackTrace"]);
    200 testTrace("testStrippedCustomError", testStrippedCustomError, ["hep-hey"],
    201     ["new CustomError", "collectStackTrace"]);
    202 testCallerCensorship();
    203 testUnintendedCallerCensorship();
    204 testErrorsDuringFormatting();
    205