| /* |
| * Copyright 2008 Google Inc. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); you may not |
| * use this file except in compliance with the License. You may obtain a copy of |
| * the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
| * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
| * License for the specific language governing permissions and limitations under |
| * the License. |
| */ |
| package com.google.gwt.core.client; |
| |
| import com.google.gwt.junit.client.GWTTestCase; |
| import com.google.gwt.junit.client.WithProperties; |
| import com.google.gwt.junit.client.WithProperties.Property; |
| |
| /** |
| * Any JavaScript exceptions occurring within JSNI methods are wrapped as this |
| * class when caught in Java code. The wrapping does not occur until the |
| * exception passes out of JSNI into Java. Before that, the thrown object |
| * remains a native JavaScript exception object, and can be caught in JSNI as |
| * normal. |
| */ |
| public class JavaScriptExceptionTest extends GWTTestCase { |
| |
| static native JavaScriptObject makeJSO() /*-{ |
| return { |
| toString:function() { |
| return "jso"; |
| }, |
| name: "myName", |
| message: "myDescription", |
| extraField: "extraData" |
| }; |
| }-*/; |
| |
| static void throwJava(Throwable t) throws Throwable { |
| throw t; |
| } |
| |
| static native void throwNative(Object e) /*-{ |
| throw e; |
| }-*/; |
| |
| static void throwSandwichJava(Object e) { |
| throwNative(e); |
| } |
| |
| static native void throwSandwichNative(Throwable t) /*-{ |
| @com.google.gwt.core.client.JavaScriptExceptionTest::throwJava(Ljava/lang/Throwable;)(t); |
| }-*/; |
| |
| public void assertJsoProperties(boolean extraPropertiesShouldBePresent) { |
| JavaScriptObject jso = makeJSO(); |
| try { |
| throwNative(jso); |
| fail(); |
| } catch (JavaScriptException e) { |
| assertEquals("myName", e.getName()); |
| assertEquals("myDescription", e.getDescription()); |
| assertSame(jso, e.getException()); |
| assertTrue(e.getMessage().contains("myName")); |
| assertTrue(e.getMessage().contains("myDescription")); |
| if (extraPropertiesShouldBePresent) { |
| assertTrue( |
| "message does not contain 'extraField', but should: " |
| + e.getMessage(), e.getMessage().contains("extraField")); |
| assertTrue( |
| "message does not contain 'extraData', but should:" |
| + e.getMessage(), e.getMessage().contains("extraData")); |
| } else { |
| assertFalse( |
| "message contains 'extraField', but shouldn't: " + e.getMessage(), |
| e.getMessage().contains("extraField")); |
| // CHECKSTYLE_OFF |
| assertFalse( |
| "message contains 'extraData', but shouldn't:" + e.getMessage(), |
| e.getMessage().contains("extraData")); |
| // CHECKSTYLE_ON |
| } |
| } |
| } |
| |
| /** |
| * This test doesn't work in Development Mode yet; we'd need a way to throw |
| * true native objects as exceptions. Windows/IE is the deal killer right now |
| * on really making this work since there's no way to raise an exception of a |
| * true JS value. We could use JS lambdas around Java calls to get around this |
| * restriction. |
| */ |
| public native void disabledTestJsExceptionSandwich() /*-{ |
| var e = { }; |
| try { |
| @com.google.gwt.core.client.JavaScriptExceptionTest::throwSandwichJava(Ljava/lang/Object;)(e); |
| } catch (t) { |
| @junit.framework.Assert::assertSame(Ljava/lang/Object;Ljava/lang/Object;)(e, t); |
| } |
| }-*/; |
| |
| @Override |
| public String getModuleName() { |
| return "com.google.gwt.core.Core"; |
| } |
| |
| public void testJavaExceptionSandwich() { |
| RuntimeException e = new RuntimeException(); |
| try { |
| throwSandwichNative(e); |
| } catch (Throwable t) { |
| assertSame(e, t); |
| } |
| } |
| |
| @WithProperties({ |
| @Property(name = "compiler.stackMode", value = "emulated") |
| }) |
| public void testJsoStackModeEmulated() { |
| /** |
| * Whether we're in Development Mode, or in Production Mode with |
| * compiler.stackMode = emulated, extra properties should not be present. |
| * |
| * @see StackTraceCreator#getProperties(JavaScriptObject) |
| */ |
| assertJsoProperties(false); |
| } |
| |
| @WithProperties({ |
| @Property(name = "compiler.stackMode", value = "native") |
| }) |
| public void testJsoStackModeNative() { |
| /** |
| * In Production Mode with compiler.stackMode = native, extra properties |
| * should be present. In Development Mode, extra properties should not be |
| * present. |
| * |
| * @see StackTraceCreator#getProperties(JavaScriptObject) |
| */ |
| assertJsoProperties(GWT.isScript()); |
| } |
| |
| @WithProperties({ |
| @Property(name = "compiler.stackMode", value = "strip") |
| }) |
| public void testJsoStackModeStrip() { |
| /** |
| * In Production Mode with compiler.stackMode = strip, extra properties |
| * should be present. In Development Mode, extra properties should not be |
| * present. |
| * |
| * @see StackTraceCreator#getProperties(JavaScriptObject) |
| */ |
| assertJsoProperties(GWT.isScript()); |
| } |
| |
| public void testNull() { |
| try { |
| throwNative(null); |
| fail(); |
| } catch (JavaScriptException e) { |
| assertEquals("null", e.getName()); |
| assertEquals("null", e.getDescription()); |
| assertEquals(null, e.getException()); |
| assertTrue(e.getMessage().contains("null")); |
| } |
| } |
| |
| public void testObject() { |
| Object o = new Object() { |
| @Override |
| public String toString() { |
| return "myLameObject"; |
| } |
| }; |
| try { |
| throwNative(o); |
| fail(); |
| } catch (JavaScriptException e) { |
| assertEquals(o.getClass().getName(), e.getName()); |
| assertEquals("myLameObject", e.getDescription()); |
| assertEquals(null, e.getException()); |
| assertTrue(e.getMessage().contains(o.getClass().getName())); |
| assertTrue(e.getMessage().contains("myLameObject")); |
| } |
| } |
| |
| public void testString() { |
| try { |
| throwNative("foobarbaz"); |
| fail(); |
| } catch (JavaScriptException e) { |
| assertEquals("String", e.getName()); |
| assertEquals("foobarbaz", e.getDescription()); |
| assertEquals(null, e.getException()); |
| assertTrue(e.getMessage().contains("foobarbaz")); |
| } |
| } |
| } |