blob: d7ece2c6f2b57c34a494d2d7cc418fd52479f011 [file] [log] [blame]
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00001// 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
kasperl@chromium.org2abc4502009-07-02 07:00:29 +000028function testMethodNameInference() {
29 function Foo() { }
30 Foo.prototype.bar = function () { FAIL; };
31 (new Foo).bar();
32}
33
34function testNested() {
35 function one() {
36 function two() {
37 function three() {
38 FAIL;
39 }
40 three();
41 }
42 two();
43 }
44 one();
45}
46
47function testArrayNative() {
48 [1, 2, 3].map(function () { FAIL; });
49}
50
51function testImplicitConversion() {
52 function Nirk() { }
53 Nirk.prototype.valueOf = function () { FAIL; };
54 return 1 + (new Nirk);
55}
56
57function testEval() {
58 eval("function Doo() { FAIL; }; Doo();");
59}
60
61function testNestedEval() {
62 var x = "FAIL";
63 eval("function Outer() { eval('function Inner() { eval(x); }'); Inner(); }; Outer();");
64}
65
66function testValue() {
67 Number.prototype.causeError = function () { FAIL; };
68 (1).causeError();
69}
70
71function testConstructor() {
72 function Plonk() { FAIL; }
73 new Plonk();
74}
75
kasperl@chromium.org86f77b72009-07-06 08:21:57 +000076function 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
83function testAnonymousMethod() {
84 (function () { FAIL }).call([1, 2, 3]);
85}
86
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +000087function CustomError(message, stripPoint) {
88 this.message = message;
89 Error.captureStackTrace(this, stripPoint);
90}
91
92CustomError.prototype.toString = function () {
93 return "CustomError: " + this.message;
94};
95
96function testDefaultCustomError() {
97 throw new CustomError("hep-hey", undefined);
98}
99
100function testStrippedCustomError() {
101 throw new CustomError("hep-hey", CustomError);
102}
103
kasperl@chromium.org2abc4502009-07-02 07:00:29 +0000104// Utility function for testing that the expected strings occur
105// in the stack trace produced when running the given function.
sgjesse@chromium.org911335c2009-08-19 12:59:44 +0000106function testTrace(name, fun, expected, unexpected) {
kasperl@chromium.org2abc4502009-07-02 07:00:29 +0000107 var threw = false;
108 try {
109 fun();
110 } catch (e) {
111 for (var i = 0; i < expected.length; i++) {
sgjesse@chromium.org911335c2009-08-19 12:59:44 +0000112 assertTrue(e.stack.indexOf(expected[i]) != -1,
113 name + " doesn't contain expected[" + i + "]");
kasperl@chromium.org2abc4502009-07-02 07:00:29 +0000114 }
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +0000115 if (unexpected) {
116 for (var i = 0; i < unexpected.length; i++) {
sgjesse@chromium.org911335c2009-08-19 12:59:44 +0000117 assertEquals(e.stack.indexOf(unexpected[i]), -1,
118 name + " contains unexpected[" + i + "]");
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +0000119 }
120 }
kasperl@chromium.org2abc4502009-07-02 07:00:29 +0000121 threw = true;
122 }
sgjesse@chromium.org911335c2009-08-19 12:59:44 +0000123 assertTrue(threw, name + " didn't throw");
kasperl@chromium.org2abc4502009-07-02 07:00:29 +0000124}
125
126// Test that the error constructor is not shown in the trace
127function testCallerCensorship() {
128 var threw = false;
129 try {
130 FAIL;
131 } catch (e) {
sgjesse@chromium.org911335c2009-08-19 12:59:44 +0000132 assertEquals(-1, e.stack.indexOf('at new ReferenceError'),
133 "CallerCensorship contained new ReferenceError");
kasperl@chromium.org2abc4502009-07-02 07:00:29 +0000134 threw = true;
135 }
sgjesse@chromium.org911335c2009-08-19 12:59:44 +0000136 assertTrue(threw, "CallerCensorship didn't throw");
kasperl@chromium.org2abc4502009-07-02 07:00:29 +0000137}
138
139// Test that the explicit constructor call is shown in the trace
140function testUnintendedCallerCensorship() {
141 var threw = false;
142 try {
143 new ReferenceError({
144 toString: function () {
145 FAIL;
146 }
147 });
148 } catch (e) {
sgjesse@chromium.org911335c2009-08-19 12:59:44 +0000149 assertTrue(e.stack.indexOf('at new ReferenceError') != -1,
150 "UnintendedCallerCensorship didn't contain new ReferenceError");
kasperl@chromium.org2abc4502009-07-02 07:00:29 +0000151 threw = true;
152 }
sgjesse@chromium.org911335c2009-08-19 12:59:44 +0000153 assertTrue(threw, "UnintendedCallerCensorship didn't throw");
kasperl@chromium.org2abc4502009-07-02 07:00:29 +0000154}
155
156// If an error occurs while the stack trace is being formatted it should
157// be handled gracefully.
158function 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;
sgjesse@chromium.org911335c2009-08-19 12:59:44 +0000168 assertTrue(e.stack.indexOf('<error: ReferenceError') != -1,
169 "ErrorsDuringFormatting didn't contain error: ReferenceError");
kasperl@chromium.org2abc4502009-07-02 07:00:29 +0000170 }
sgjesse@chromium.org911335c2009-08-19 12:59:44 +0000171 assertTrue(threw, "ErrorsDuringFormatting didn't throw");
kasperl@chromium.org2abc4502009-07-02 07:00:29 +0000172 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;
sgjesse@chromium.org911335c2009-08-19 12:59:44 +0000180 assertTrue(e.stack.indexOf('<error>') != -1,
181 "ErrorsDuringFormatting didn't contain <error>");
kasperl@chromium.org2abc4502009-07-02 07:00:29 +0000182 }
sgjesse@chromium.org911335c2009-08-19 12:59:44 +0000183 assertTrue(threw, "ErrorsDuringFormatting didnt' throw (2)");
kasperl@chromium.org2abc4502009-07-02 07:00:29 +0000184}
185
kasperl@chromium.org2abc4502009-07-02 07:00:29 +0000186
sgjesse@chromium.org911335c2009-08-19 12:59:44 +0000187testTrace("testArrayNative", testArrayNative, ["Array.map (native)"]);
188testTrace("testNested", testNested, ["at one", "at two", "at three"]);
189testTrace("testMethodNameInference", testMethodNameInference, ["at Foo.bar"]);
190testTrace("testImplicitConversion", testImplicitConversion, ["at Nirk.valueOf"]);
191testTrace("testEval", testEval, ["at Doo (eval at testEval"]);
192testTrace("testNestedEval", testNestedEval, ["eval at Inner (eval at Outer"]);
193testTrace("testValue", testValue, ["at Number.causeError"]);
194testTrace("testConstructor", testConstructor, ["new Plonk"]);
195testTrace("testRenamedMethod", testRenamedMethod, ["Wookie.a$b$c$d [as d]"]);
196testTrace("testAnonymousMethod", testAnonymousMethod, ["Array.<anonymous>"]);
197testTrace("testDefaultCustomError", testDefaultCustomError,
198 ["hep-hey", "new CustomError"],
199 ["collectStackTrace"]);
200testTrace("testStrippedCustomError", testStrippedCustomError, ["hep-hey"],
201 ["new CustomError", "collectStackTrace"]);
kasperl@chromium.org2abc4502009-07-02 07:00:29 +0000202testCallerCensorship();
203testUnintendedCallerCensorship();
204testErrorsDuringFormatting();