blob: 3bb5755aed77a0cbb2b903590917ce2645d4f49e [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.org0b6db592009-07-30 14:48:31 +0000106function testTrace(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++) {
112 assertTrue(e.stack.indexOf(expected[i]) != -1);
113 }
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +0000114 if (unexpected) {
115 for (var i = 0; i < unexpected.length; i++) {
116 assertEquals(e.stack.indexOf(unexpected[i]), -1);
117 }
118 }
kasperl@chromium.org2abc4502009-07-02 07:00:29 +0000119 threw = true;
120 }
121 assertTrue(threw);
122}
123
124// Test that the error constructor is not shown in the trace
125function testCallerCensorship() {
126 var threw = false;
127 try {
128 FAIL;
129 } catch (e) {
130 assertEquals(-1, e.stack.indexOf('at new ReferenceError'));
131 threw = true;
132 }
133 assertTrue(threw);
134}
135
136// Test that the explicit constructor call is shown in the trace
137function testUnintendedCallerCensorship() {
138 var threw = false;
139 try {
140 new ReferenceError({
141 toString: function () {
142 FAIL;
143 }
144 });
145 } catch (e) {
146 assertTrue(e.stack.indexOf('at new ReferenceError') != -1);
147 threw = true;
148 }
149 assertTrue(threw);
150}
151
152// If an error occurs while the stack trace is being formatted it should
153// be handled gracefully.
154function testErrorsDuringFormatting() {
155 function Nasty() { }
156 Nasty.prototype.foo = function () { throw new RangeError(); };
157 var n = new Nasty();
158 n.__defineGetter__('constructor', function () { CONS_FAIL; });
159 var threw = false;
160 try {
161 n.foo();
162 } catch (e) {
163 threw = true;
164 assertTrue(e.stack.indexOf('<error: ReferenceError') != -1);
165 }
166 assertTrue(threw);
167 threw = false;
168 // Now we can't even format the message saying that we couldn't format
169 // the stack frame. Put that in your pipe and smoke it!
170 ReferenceError.prototype.toString = function () { NESTED_FAIL; };
171 try {
172 n.foo();
173 } catch (e) {
174 threw = true;
175 assertTrue(e.stack.indexOf('<error>') != -1);
176 }
177 assertTrue(threw);
178}
179
180testTrace(testArrayNative, ["Array.map (native)"]);
181testTrace(testNested, ["at one", "at two", "at three"]);
182testTrace(testMethodNameInference, ["at Foo.bar"]);
183testTrace(testImplicitConversion, ["at Nirk.valueOf"]);
184testTrace(testEval, ["at Doo (eval at testEval"]);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +0000185testTrace(testNestedEval, ["eval at Inner (eval at Outer"]);
kasperl@chromium.org2abc4502009-07-02 07:00:29 +0000186testTrace(testValue, ["at Number.causeError"]);
187testTrace(testConstructor, ["new Plonk"]);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +0000188testTrace(testRenamedMethod, ["Wookie.a$b$c$d [as d]"]);
189testTrace(testAnonymousMethod, ["Array.<anonymous>"]);
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +0000190testTrace(testDefaultCustomError, ["hep-hey", "new CustomError"],
191 ["collectStackTrace"]);
192testTrace(testStrippedCustomError, ["hep-hey"], ["new CustomError",
193 "collectStackTrace"]);
kasperl@chromium.org2abc4502009-07-02 07:00:29 +0000194
195testCallerCensorship();
196testUnintendedCallerCensorship();
197testErrorsDuringFormatting();