| /* |
| * Copyright 2009 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.dev.jjs.test.singlejso; |
| |
| import com.google.gwt.core.client.JavaScriptObject; |
| import com.google.gwt.junit.client.GWTTestCase; |
| |
| /** |
| * Tests SingleJso semantics in non-trivial type hierarchies. |
| */ |
| public class TypeHierarchyTest extends GWTTestCase { |
| |
| /** |
| * Used with PlainJso and PlainJsoWithInterface to mix interfaces into |
| * existing base classes. |
| */ |
| interface Arrayish { |
| int getLength(); |
| |
| JavaScriptObject getObject(int i); |
| |
| /** |
| * Used to test virtual override where the implementation has a narrower |
| * return type. |
| */ |
| Wide wide(); |
| } |
| |
| /** |
| * The bottom type for a non-trivial diamond-shaped inheritance pattern. |
| */ |
| static class DiamondImpl extends JavaScriptObject implements IDiamond2A, |
| IDiamond2B { |
| public static native DiamondImpl create() /*-{ |
| return {size : 42}; |
| }-*/; |
| |
| protected DiamondImpl() { |
| } |
| |
| @Override |
| public final native int size() /*-{ |
| return this.size; |
| }-*/; |
| } |
| |
| /** |
| * The root type for a non-trivial diamond-shaped inheritance pattern. |
| */ |
| interface IDiamond1 { |
| int size(); |
| } |
| |
| /** |
| * The left type for a non-trivial diamond-shaped inheritance pattern. |
| */ |
| interface IDiamond2A extends IDiamond1 { |
| } |
| |
| /** |
| * The right type for a non-trivial diamond-shaped inheritance pattern. |
| */ |
| interface IDiamond2B extends IDiamond1 { |
| } |
| |
| /** |
| * Used for testing virtual overrides. |
| */ |
| static class Narrow extends Wide { |
| @Override |
| public String toString() { |
| return "Narrow"; |
| } |
| } |
| |
| /** |
| * This is a base class that is used to test adding interfaces to a JSO via a |
| * subclass. |
| */ |
| static class PlainJso extends JavaScriptObject { |
| protected PlainJso() { |
| } |
| |
| public final native int getLength()/*-{ |
| return this.length; |
| }-*/; |
| |
| public final native JavaScriptObject getObject(int i) /*-{ |
| return this[i]; |
| }-*/; |
| |
| public final Narrow wide() { |
| return new Narrow(); |
| } |
| } |
| |
| /** |
| * We'll mix in an interface into PlainJso. |
| */ |
| static class PlainJsoWithInterface extends PlainJso implements Arrayish { |
| public static PlainJsoWithInterface create() { |
| return JavaScriptObject.createArray().cast(); |
| } |
| |
| protected PlainJsoWithInterface() { |
| } |
| } |
| |
| /** |
| * Used for testing virtual overrides. |
| */ |
| static class Wide { |
| } |
| |
| private interface Element extends Node { |
| } |
| |
| private static class JvmNode implements Node { |
| @Override |
| public JvmNode appendChild(Node node) { |
| return (JvmNode) node; |
| } |
| } |
| |
| private final static class JvmElement extends JvmNode implements Element { |
| static Element create() { |
| return new JvmElement(); |
| } |
| } |
| |
| private final static class JsElement extends JsNode implements Element { |
| static Element create() { |
| return (Element) JavaScriptObject.createObject(); |
| } |
| |
| protected JsElement() { |
| } |
| } |
| |
| private static class JsNode extends JavaScriptObject implements Node { |
| @Override |
| public final native JsNode appendChild(Node node) /*-{ |
| return node; |
| }-*/; |
| |
| protected JsNode() { |
| } |
| } |
| |
| private interface Node { |
| Node appendChild(Node node); |
| } |
| |
| @Override |
| public String getModuleName() { |
| return "com.google.gwt.dev.jjs.CompilerSuite"; |
| } |
| |
| public void testCase1() { |
| A a = A.create(); |
| assertEquals("A", a.whoAmI()); |
| |
| B1 b1 = new B1(); |
| assertEquals("B1", b1.whoAmI()); |
| |
| B2 b2 = new B2(); |
| assertEquals("B2", b2.whoAmI()); |
| } |
| |
| public void testCase2() { |
| IA a = A.create(); |
| assertEquals("A", a.whoAmI()); |
| |
| IA b1 = new B1(); |
| assertEquals("B1", b1.whoAmI()); |
| |
| IA b2 = new B2(); |
| assertEquals("B2", b2.whoAmI()); |
| } |
| |
| public void testCase3() { |
| IA a = A.create(); |
| assertEquals("A", a.whoAmI()); |
| |
| IB b1 = new B1(); |
| assertEquals("B1", b1.whoAmI()); |
| |
| IB b2 = new B2(); |
| assertEquals("B2", b2.whoAmI()); |
| } |
| |
| public void testDiamond() { |
| IDiamond1 d1 = DiamondImpl.create(); |
| assertEquals(42, d1.size()); |
| |
| IDiamond2A d2a = DiamondImpl.create(); |
| assertEquals(42, d2a.size()); |
| |
| IDiamond2B d2b = DiamondImpl.create(); |
| assertEquals(42, d2b.size()); |
| } |
| |
| /** |
| * Tests that dispatches through a hierarchy of interfaces works properly. |
| */ |
| public void testInterfaceHierarchyDispatch() { |
| Element jsElement = JsElement.create(); |
| assertEquals(jsElement, jsElement.appendChild(jsElement)); |
| |
| Element jvmElement = JvmElement.create(); |
| assertEquals(jvmElement, jvmElement.appendChild(jvmElement)); |
| } |
| |
| public void testVirtualOverrides() { |
| Arrayish array = PlainJsoWithInterface.create(); |
| assertEquals(0, array.getLength()); |
| assertNull(array.getObject(0)); |
| assertEquals("Narrow", array.wide().toString()); |
| } |
| } |