blob: f95e50fa383f4374cc1d6249de2cb92d1023fba4 [file] [log] [blame]
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001// Copyright 2012 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// Return the stack frames of an Error object.
29
30Error.prepareStackTrace = function(error, frames) {
31 return frames;
32}
33
34Error.prototype.getFrames = function() {
35 var frames = this.stack;
36 return frames;
37}
38
39String.prototype.contains = function(pattern) {
40 return this.indexOf(pattern) > -1;
41}
42
43// Check for every frame that a certain method returns the
44// expected value for every frame.
45Array.prototype.verifyEquals = function(frames, func_name) {
46 this.forEach(
47 function(element, index) {
48 var frame = frames[index];
49 if (element === null) return;
50 assertEquals(element, (frame[func_name])());
51 }
52 );
53}
54
55// Check for every frame that a certain method has a return value
56// that contains the expected pattern for every frame.
57Array.prototype.verifyContains = function(frames, func_name) {
58 this.forEach(
59 function(element, index) {
60 var frame = frames[index];
61 if (element === null) return;
62 assertTrue((frame[func_name])().contains(element));
63 }
64 );
65}
66
67// Check for every frame that a certain method returns undefined
68// when expected.
69Array.prototype.verifyUndefined = function(frames, func_name) {
70 this.forEach(
71 function(element, index) {
72 var frame = frames[index];
73 if (element === null) return;
74 assertEquals(element, (frame[func_name])() === undefined);
75 }
76 );
77}
78
79
80// Simple eval.
81var code1 = "function f() { \n" +
82 " throw new Error(3); \n" + // Line 2
83 "} \n" +
84 "f(); \n"; // Line 4
85
86function g() {
87 eval(code1);
88}
89
90try {
91 g();
92} catch (e) {
93 // We expect something like
94 // f (eval at g (eval-stack.js:87:8), <anonymous>:2:9)
95 // eval (eval at g (eval-stack.js:87:8), <anonymous>:4:1)
96 // g (eval-stack.js:87:3)
97 // eval-stack.js:94:3
98 var frames = e.getFrames();
99 assertEquals(4, frames.length);
100 ["f", "eval", "g"]
101 .verifyEquals(frames, "getFunctionName");
102 [2, 4]
103 .verifyEquals(frames, "getLineNumber");
104 ["<anonymous>:2:", "<anonymous>:4:"]
105 .verifyContains(frames, "toString");
106 [true, true, false, false]
107 .verifyUndefined(frames, "getFileName");
108 ["eval at g", "eval at g"]
109 .verifyContains(frames, "getEvalOrigin");
110}
111
112
113// Nested eval.
114var code2 = "function h() { \n" +
115 " // Empty \n" +
116 " eval(code1); \n" + // Line 3
117 "} \n" +
118 "h(); \n"; // Line 5
119
120try {
121 eval(code2);
122} catch (e) {
123 // We expect something like
124 // f (eval at h (eval at <anonymous> (eval-stack.js:116:8)),
125 // <anonymous>:2:9)
126 // eval (eval at h (eval at <anonymous> (eval-stack.js:116:8)),
127 // <anonymous>:4:1)
128 // h (eval at <anonymous> (eval-stack.js:116:8), <anonymous>:3:3)
129 // eval (eval at <anonymous> (eval-stack.js:116:8), <anonymous>:5:1)
130 // eval-stack.js:116:3
131 var frames = e.getFrames();
132 assertEquals(5, frames.length);
133 ["f", "eval", "h", "eval"]
134 .verifyEquals(frames, "getFunctionName");
135 [2, 4, 3, 5]
136 .verifyEquals(frames, "getLineNumber");
137 ["<anonymous>:2:", "<anonymous>:4:", "<anonymous>:3:", "<anonymous>:5:"]
138 .verifyContains(frames, "toString");
139 [true, true, true, true, false]
140 .verifyUndefined(frames, "getFileName");
141 ["eval at h (eval at <anonymous> (",
142 "eval at h (eval at <anonymous> (",
143 "eval at <anonymous> (",
144 "eval at <anonymous> ("]
145 .verifyContains(frames, "getEvalOrigin");
146}
147
148
149// Nested eval calling through non-eval defined function.
150var code3 = "function h() { \n" +
151 " // Empty \n" +
152 " g(); \n" + // Line 3
153 "} \n" +
154 "h(); \n"; // Line 5
155
156try {
157 eval(code3);
158} catch (e) {
159 // We expect something like
160 // f (eval at g (test.js:83:8), <anonymous>:2:9)
161 // eval (eval at g (test.js:83:8), <anonymous>:4:1)
162 // g (test.js:83:3)
163 // h (eval at <anonymous> (test.js:149:8), <anonymous>:3:3)
164 // eval (eval at <anonymous> (test.js:149:8), <anonymous>:5:1)
165 // test.js:149:3
166 var frames = e.getFrames();
167 assertEquals(6, frames.length);
168 ["f", "eval", "g", "h", "eval"]
169 .verifyEquals(frames, "getFunctionName");
170 [2, 4, null, 3, 5]
171 .verifyEquals(frames, "getLineNumber");
172 ["<anonymous>:2:", "<anonymous>:4:", null, "<anonymous>:3:", "<anonymous>:5:"]
173 .verifyContains(frames, "toString");
174 [true, true, false, true, true, false]
175 .verifyUndefined(frames, "getFileName");
176 ["eval at g (",
177 "eval at g (",
178 null,
179 "eval at <anonymous> (",
180 "eval at <anonymous> ("]
181 .verifyContains(frames, "getEvalOrigin");
182}
183
184
185// Calling function defined in eval.
186eval("function f() { \n" +
187 " throw new Error(3); \n" +
188 "} \n");
189
190try {
191 f();
192} catch (e) {
193 // We expect something like
194 // f (eval at <anonymous> (test.js:182:40), <anonymous>:2:9)
195 // test.js:186:3
196 var frames = e.getFrames();
197 assertEquals(2, frames.length);
198 ["f"].verifyEquals(frames, "getFunctionName");
199 [2].verifyEquals(frames, "getLineNumber");
200 ["<anonymous>:2:"].verifyContains(frames, "toString");
201 [true, false].verifyUndefined(frames, "getFileName");
202 ["eval at <anonymous> ("].verifyContains(frames, "getEvalOrigin");
203}