77 assertExceptionMatch(cr3, |
81 assertExceptionMatch(cr3, |
78 new ExceptionInfo(RuntimeException.class, message, |
82 new ExceptionInfo(RuntimeException.class, message, |
79 newStackTraceElement("", "f", s1, 1), |
83 newStackTraceElement("", "f", s1, 1), |
80 newStackTraceElement("A", "g", s2, 1), |
84 newStackTraceElement("A", "g", s2, 1), |
81 newStackTraceElement("", "", cr3.snippet(), 1))); |
85 newStackTraceElement("", "", cr3.snippet(), 1))); |
|
86 } |
|
87 |
|
88 public void throwChained() { |
|
89 String message1 = "error_message1"; |
|
90 String message2 = "error_message2"; |
|
91 Snippet s1 = methodKey(assertEval("void p() throws Exception { ((String) null).toString(); }")); |
|
92 Snippet s2 = methodKey(assertEval("void n() throws Exception { try { p(); } catch (Exception ex) { throw new java.io.IOException(\"" + message2 + "\", ex); }}")); |
|
93 Snippet s3 = methodKey(assertEval("void m() {\n" |
|
94 + "try { n(); }\n" |
|
95 + "catch (Exception ex) {\n" |
|
96 + " throw new RuntimeException(\"" + message1 + "\", ex);\n" |
|
97 + "}}")); |
|
98 SnippetEvent cr4 = assertEvalException("m();"); |
|
99 assertExceptionMatch(cr4, |
|
100 new ExceptionInfo(RuntimeException.class, message1, |
|
101 new ExceptionInfo(IOException.class, message2, |
|
102 new ExceptionInfo(NullPointerException.class, null, |
|
103 newStackTraceElement("", "p", s1, 1), |
|
104 newStackTraceElement("", "n", s2, 1), |
|
105 newStackTraceElement("", "m", s3, 2), |
|
106 newStackTraceElement("", "", cr4.snippet(), 1)), |
|
107 newStackTraceElement("", "n", s2, 1), |
|
108 newStackTraceElement("", "m", s3, 2), |
|
109 newStackTraceElement("", "", cr4.snippet(), 1)), |
|
110 newStackTraceElement("", "m", s3, 4), |
|
111 newStackTraceElement("", "", cr4.snippet(), 1))); |
|
112 } |
|
113 |
|
114 public void throwChainedUnresolved() { |
|
115 String message1 = "error_message1"; |
|
116 String message2 = "error_message2"; |
|
117 Snippet s1 = methodKey(assertEval("void p() throws Exception { ((String) null).toString(); }")); |
|
118 Snippet s2 = methodKey(assertEval("void n() throws Exception { try { p(); } catch (Exception ex) { throw new java.io.IOException(\"" + message2 + "\", ex); }}")); |
|
119 Snippet s3 = methodKey(assertEval("void m() {\n" |
|
120 + "try { n(); }\n" |
|
121 + "catch (Exception ex) {\n" |
|
122 + " throw new RuntimeException(\"" + message1 + "\", ex);\n" |
|
123 + "}}")); |
|
124 getState().drop(s1); |
|
125 SnippetEvent cr4 = assertEvalException("m();"); |
|
126 assertExceptionMatch(cr4, |
|
127 new ExceptionInfo(RuntimeException.class, message1, |
|
128 new UnresolvedExceptionInfo(s2, |
|
129 newStackTraceElement("", "n", s2, 1), |
|
130 newStackTraceElement("", "m", s3, 2), |
|
131 newStackTraceElement("", "", cr4.snippet(), 1)), |
|
132 newStackTraceElement("", "m", s3, 4), |
|
133 newStackTraceElement("", "", cr4.snippet(), 1))); |
82 } |
134 } |
83 |
135 |
84 public void throwFromConstructor() { |
136 public void throwFromConstructor() { |
85 String message = "error_message"; |
137 String message = "error_message"; |
86 Snippet s1 = methodKey(assertEval("void f() { throw new RuntimeException(\"" + message + "\"); }")); |
138 Snippet s1 = methodKey(assertEval("void f() { throw new RuntimeException(\"" + message + "\"); }")); |
169 |
221 |
170 private StackTraceElement newStackTraceElement(String className, String methodName, Snippet key, int lineNumber) { |
222 private StackTraceElement newStackTraceElement(String className, String methodName, Snippet key, int lineNumber) { |
171 return new StackTraceElement(className, methodName, "#" + key.id(), lineNumber); |
223 return new StackTraceElement(className, methodName, "#" + key.id(), lineNumber); |
172 } |
224 } |
173 |
225 |
174 private static class ExceptionInfo { |
226 private static class AnyExceptionInfo { |
|
227 |
|
228 public final StackTraceElement[] stackTraceElements; |
|
229 |
|
230 public AnyExceptionInfo(StackTraceElement... stackTraceElements) { |
|
231 this.stackTraceElements = stackTraceElements.length == 0 ? null : stackTraceElements; |
|
232 } |
|
233 } |
|
234 |
|
235 private static class UnresolvedExceptionInfo extends AnyExceptionInfo { |
|
236 |
|
237 public final Snippet sn; |
|
238 |
|
239 public UnresolvedExceptionInfo(Snippet sn, StackTraceElement... stackTraceElements) { |
|
240 super(stackTraceElements); |
|
241 this.sn = sn; |
|
242 } |
|
243 } |
|
244 |
|
245 private static class ExceptionInfo extends AnyExceptionInfo { |
|
246 |
175 public final Class<? extends Throwable> exception; |
247 public final Class<? extends Throwable> exception; |
176 public final String message; |
248 public final String message; |
177 public final StackTraceElement[] stackTraceElements; |
249 public final AnyExceptionInfo cause; |
178 |
250 |
179 public ExceptionInfo(Class<? extends Throwable> exception, String message, StackTraceElement...stackTraceElements) { |
251 public ExceptionInfo(Class<? extends Throwable> exception, String message, |
|
252 StackTraceElement... stackTraceElements) { |
|
253 this(exception, message, null, stackTraceElements); |
|
254 } |
|
255 |
|
256 public ExceptionInfo(Class<? extends Throwable> exception, String message, |
|
257 AnyExceptionInfo cause, StackTraceElement... stackTraceElements) { |
|
258 super(stackTraceElements); |
180 this.exception = exception; |
259 this.exception = exception; |
181 this.message = message; |
260 this.message = message; |
182 this.stackTraceElements = stackTraceElements.length == 0 ? null : stackTraceElements; |
261 this.cause = cause; |
183 } |
262 } |
184 } |
263 } |
185 |
264 |
186 private void assertExecuteException(String input, Class<? extends Throwable> exception) { |
265 private void assertExecuteException(String input, Class<? extends Throwable> exception) { |
187 assertExceptionMatch(assertEvalException(input), new ExceptionInfo(exception, null)); |
266 assertExceptionMatch(assertEvalException(input), new ExceptionInfo(exception, null)); |
188 } |
267 } |
189 |
268 |
190 private void assertExceptionMatch(SnippetEvent cr, ExceptionInfo exceptionInfo) { |
269 private void assertExceptionMatch(SnippetEvent cr, ExceptionInfo exceptionInfo) { |
191 assertNotNull(cr.exception(), "Expected exception was not thrown: " + exceptionInfo.exception); |
270 assertExceptionMatch(cr.exception(), cr.snippet().source(), exceptionInfo); |
192 if (cr.exception() instanceof EvalException) { |
271 } |
193 EvalException ex = (EvalException) cr.exception(); |
272 |
|
273 private void assertExceptionMatch(Throwable exception, String source, ExceptionInfo exceptionInfo) { |
|
274 assertNotNull(exception, "Expected exception was not thrown: " + exceptionInfo.exception); |
|
275 if (exception instanceof EvalException) { |
|
276 EvalException ex = (EvalException) exception; |
194 String actualException = ex.getExceptionClassName(); |
277 String actualException = ex.getExceptionClassName(); |
195 String expectedException = exceptionInfo.exception.getCanonicalName(); |
278 String expectedException = exceptionInfo.exception.getCanonicalName(); |
196 String stackTrace = getStackTrace(ex); |
|
197 String source = cr.snippet().source(); |
|
198 assertEquals(actualException, expectedException, |
279 assertEquals(actualException, expectedException, |
199 String.format("Given \"%s\" expected exception: %s, got: %s%nStack trace:%n%s", |
280 String.format("Given \"%s\" expected exception: %s, got: %s%nStack trace:%n%s", |
200 source, expectedException, actualException, stackTrace)); |
281 source, expectedException, actualException, getStackTrace(ex))); |
201 if (exceptionInfo.message != null) { |
282 if (exceptionInfo.message != null) { |
202 assertEquals(ex.getMessage(), exceptionInfo.message, |
283 assertEquals(ex.getMessage(), exceptionInfo.message, |
203 String.format("Given \"%s\" expected message: %s, got: %s", |
284 String.format("Given \"%s\" expected message: %s, got: %s", |
204 source, exceptionInfo.message, ex.getMessage())); |
285 source, exceptionInfo.message, ex.getMessage())); |
205 } |
286 } |
206 if (exceptionInfo.stackTraceElements != null) { |
287 assertStackMatch(ex, source, exceptionInfo); |
207 assertStackTrace(ex.getStackTrace(), exceptionInfo.stackTraceElements, |
288 if (exceptionInfo.cause != null) { |
208 String.format("Given \"%s\"%nStack trace:%n%s%n", |
289 assertAnyExceptionMatch(exception.getCause(), exceptionInfo.cause); |
209 source, stackTrace)); |
|
210 } |
290 } |
211 } else { |
291 } else { |
212 fail("Unexpected execution exceptionInfo: " + cr.exception()); |
292 fail("Unexpected exception: " + exception + " or exceptionInfo: " + exceptionInfo); |
|
293 } |
|
294 } |
|
295 |
|
296 private void assertStackMatch(JShellException exception, String source, AnyExceptionInfo exceptionInfo) { |
|
297 if (exceptionInfo.stackTraceElements != null) { |
|
298 assertStackTrace(exception.getStackTrace(), exceptionInfo.stackTraceElements, |
|
299 String.format("Given \"%s\"%nStack trace:%n%s%n", |
|
300 source, getStackTrace(exception))); |
|
301 } |
|
302 } |
|
303 |
|
304 private void assertAnyExceptionMatch(Throwable exception, AnyExceptionInfo exceptionInfo) { |
|
305 if (exceptionInfo instanceof ExceptionInfo) { |
|
306 assertExceptionMatch(exception, "", (ExceptionInfo) exceptionInfo); |
|
307 } else { |
|
308 assertTrue(exceptionInfo instanceof UnresolvedExceptionInfo, "Bad exceptionInfo: " + exceptionInfo); |
|
309 assertTrue(exception instanceof UnresolvedReferenceException, |
|
310 "Expected UnresolvedReferenceException: " + exception); |
|
311 UnresolvedExceptionInfo uei = (UnresolvedExceptionInfo) exceptionInfo; |
|
312 UnresolvedReferenceException ure = (UnresolvedReferenceException) exception; |
|
313 assertEquals(ure.getSnippet(), uei.sn); |
|
314 assertStackMatch(ure, "", exceptionInfo); |
213 } |
315 } |
214 } |
316 } |
215 |
317 |
216 private void assertStackTrace(StackTraceElement[] actual, StackTraceElement[] expected, String message) { |
318 private void assertStackTrace(StackTraceElement[] actual, StackTraceElement[] expected, String message) { |
217 if (actual != expected) { |
319 if (actual != expected) { |