/*
 * 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;

import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.dev.jjs.test.SingleJsoImplTest.JsoHasInnerJsoType.InnerType;
import com.google.gwt.dev.jjs.test.jsointfs.JsoInterfaceWithUnreferencedImpl;
import com.google.gwt.junit.client.GWTTestCase;
import com.google.gwt.user.client.rpc.AsyncCallback;

import java.io.IOException;

/**
 * Ensures that JavaScriptObjects may implement interfaces with methods.
 */
public class SingleJsoImplTest extends GWTTestCase {

  interface Adder {
    int ADDER_CONST = 6;

    /**
     * @see SameDescriptors#SAME_NAME
     */
    String SAME_NAME = "Same Name";

    Object DIFFERENT_OBJECT = new Object();
    Object SAME_OBJECT = new Object();
    Object SAME_OBJECT2 = SAME_OBJECT;

    /*
     * NB: Picking a mix of double and int because doubles have size 2 on the
     * stack, so this ensures that we're handling that case correctly.
     */
    double add(double a, int b);

    /*
     * Ensure that we can return types whose sizes are larger than the size of
     * the arguments.
     */
    long returnLong();
  }

  interface CallsMethodInInnerType {
    interface InnerInterface {
      void call(int a);

      int get();
    }

    InnerInterface call(InnerInterface o, int a);
  }

  interface CallsStaticMethodInSubclass {
    String call(int a, int b);
  }

  interface CreatedWithCast {
    String foo();
  }

  interface CreatedWithCastToTag {
  }

  interface CreatedWithCastToTagSub extends CreatedWithCastToTag {
    String foo();
  }

  interface Divider extends Multiplier {
    int divide(int a, int b);
  }

  static class JavaAdder implements Adder {
    @Override
    public double add(double a, int b) {
      return a + b;
    }

    @Override
    public long returnLong() {
      return 5L;
    }
  }

  /**
   * Even though this type is never instantiated, it's necessary to ensure that
   * the CreatedWithCast test isn't short-circuited due to type tightening.
   */
  static class JavaCreatedWithCast implements CreatedWithCast {
    @Override
    public String foo() {
      return "foo";
    }
  }

  static class JavaCreatedWithCastToTag implements CreatedWithCastToTagSub {
    @Override
    public String foo() {
      return "foo";
    }
  }

  /**
   * The extra declaration of implementing Multiplier should still be legal.
   */
  static class JavaDivider extends JavaMultiplier implements Divider,
      Multiplier, Tag {
    @Override
    public int divide(int a, int b) {
      return a / b;
    }
  }

  /**
   * Ensure that SingleJsoImpl interfaces can be extended and implemented by
   * regular Java types.
   */
  static class JavaLog2 extends JavaDivider implements Log2 {
    @Override
    public double log2(int a) {
      return Math.log(a) / Math.log(2);
    }
  }

  static class JavaMultiplier implements Multiplier {
    @Override
    public int multiply(int a, int b) {
      return a * b;
    }
  }

  static class JavaUsesArrays implements UsesArrays {
    @Override
    public void acceptInt3Array(int[][][] arr) {
      assertTrue(arr.length == 3);
    }

    @Override
    public void acceptIntArray(int[] arr) {
      assertTrue(arr.length == 1);
    }

    @Override
    public void acceptObject3Array(Object[][][] arr) {
      assertTrue(arr.length == 3);
    }

    @Override
    public void acceptObjectArray(Object[] arr) {
      assertTrue(arr.length == 1);
    }

    @Override
    public void acceptString3Array(String[][][] arr) {
      assertTrue(arr.length == 3);
    }

    @Override
    public void acceptStringArray(String[] arr) {
      assertTrue(arr.length == 1);
    }

    @Override
    public int[][][] returnInt3Array() {
      return new int[3][2][1];
    }

    @Override
    public int[] returnIntArray() {
      return new int[1];
    }

    @Override
    public Object[][][] returnObject3Array() {
      return new Object[3][2][1];
    }

    @Override
    public Object[] returnObjectArray() {
      return new Object[1];
    }

    @Override
    public String[][][] returnString3Array() {
      return new String[3][2][1];
    }

    @Override
    public String[] returnStringArray() {
      return new String[1];
    }
  }

  static class JsoAdder extends JavaScriptObject implements Adder {
    protected JsoAdder() {
    }

    @Override
    public final native double add(double a, int b) /*-{
      return this.offset * (a + b);
    }-*/;

    @Override
    public final long returnLong() {
      return 5L;
    }
  }

  static class JsoCallsStaticMethodInSubclass extends JavaScriptObject
      implements CallsStaticMethodInSubclass {
    protected JsoCallsStaticMethodInSubclass() {
    }

    @Override
    public final native String call(int a, int b) /*-{
      return "foo" + @com.google.gwt.dev.jjs.test.SingleJsoImplTest.JsoCallsStaticMethodInSubclassSubclass::actual(II)(a, b);
    }-*/;
  }

  static class JsoCallsStaticMethodInSubclassSubclass extends
      JsoCallsStaticMethodInSubclass {
    public static String actual(int a, int b) {
      return String.valueOf(a + b);
    }

    protected JsoCallsStaticMethodInSubclassSubclass() {
    }
  }

  static class JsoCreatedWithCast extends JavaScriptObject implements
      CreatedWithCast {
    protected JsoCreatedWithCast() {
    }

    @Override
    public final String foo() {
      return "foo";
    }
  }

  static class JsoCreatedWithCastToTag extends JavaScriptObject implements
      CreatedWithCastToTagSub {
    protected JsoCreatedWithCastToTag() {
    }

    @Override
    public final String foo() {
      return "foo";
    }
  }

  static class JsoDivider extends JsoMultiplier implements Divider, Tag {
    protected JsoDivider() {
    }

    @Override
    public final native int divide(int a, int b) /*-{
      return this.offset * a / b;
    }-*/;
  }

  static class JsoHasInnerJsoType extends JavaScriptObject implements
      CallsMethodInInnerType {
    static class InnerType extends JavaScriptObject implements InnerInterface {
      protected InnerType() {
      }

      @Override
      public final native void call(int a) /*-{
        this.foo = a;
      }-*/;

      @Override
      public final native int get() /*-{
        return this.foo;
      }-*/;
    }

    protected JsoHasInnerJsoType() {
    }

    @Override
    public final InnerInterface call(InnerInterface o, int a) {
      o.call(a);
      return o;
    }
  }

  static class JsoMultiplier extends JavaScriptObject implements Multiplier {
    protected JsoMultiplier() {
    }

    @Override
    public final native int multiply(int a, int b) /*-{
      return this.offset * a * b;
    }-*/;
  }

  /**
   * Just a random JSO type for testing cross-casting.
   */
  final static class JsoRandom extends JavaScriptObject implements
      SameDescriptors, Tag {
    protected JsoRandom() {
    }

    @Override
    public int add(int a, int b) {
      return -1;
    }

    @Override
    public int divide(int a, int b) {
      return -1;
    }

    @Override
    public int multiply(int a, int b) {
      return -1;
    }

    String b() {
      return "b";
    }
  }

  final static class JsoSimple extends JavaScriptObject implements Simple {
    protected JsoSimple() {
    }

    @Override
    public String a() {
      return "a";
    }

    @Override
    public String a(boolean overload) {
      return overload ? "Kaboom!" : "OK";
    }

    @Override
    public String ex() throws IOException {
      throw new IOException();
    }

    @Override
    public String rte() {
      throw new IllegalArgumentException();
    }
  }

  static final class JsoUsesArrays extends JavaScriptObject implements
      UsesArrays {
    protected JsoUsesArrays() {
    }

    @Override
    public void acceptInt3Array(int[][][] arr) {
      assertTrue(arr.length == 3);
    }

    @Override
    public void acceptIntArray(int[] arr) {
      assertTrue(arr.length == 1);
    }

    @Override
    public void acceptObject3Array(Object[][][] arr) {
      assertTrue(arr.length == 3);
    }

    @Override
    public void acceptObjectArray(Object[] arr) {
      assertTrue(arr.length == 1);
    }

    @Override
    public void acceptString3Array(String[][][] arr) {
      assertTrue(arr.length == 3);
    }

    @Override
    public void acceptStringArray(String[] arr) {
      assertTrue(arr.length == 1);
    }

    @Override
    public int[][][] returnInt3Array() {
      return new int[3][2][1];
    }

    @Override
    public int[] returnIntArray() {
      return new int[1];
    }

    @Override
    public Object[][][] returnObject3Array() {
      return new Object[3][2][1];
    }

    @Override
    public Object[] returnObjectArray() {
      return new Object[1];
    }

    @Override
    public String[][][] returnString3Array() {
      return new String[3][2][1];
    }

    @Override
    public String[] returnStringArray() {
      return new String[1];
    }
  }

  static class JsoUsesGeneric extends JavaScriptObject implements UsesGenerics {
    public static native <T extends CharSequence> JsoUsesGeneric create() /*-{
      return {suffix : "42"};
    }-*/;

    protected JsoUsesGeneric() {
    }

    @Override
    public final native <T> String acceptsGeneric(T chars) /*-{
      return chars + this.suffix;
    }-*/;

    @Override
    public final native <T> void callback(AsyncCallback<T> callback, T chars) /*-{
      callback.@com.google.gwt.user.client.rpc.AsyncCallback::onSuccess(Ljava/lang/Object;)(chars + this.suffix);
    }-*/;

    /**
     * What you're seeing here is would be achieved by an unsafe (T) cast and
     * would break with a ClassCastException if accessed via JsoIsGenericFinal
     * in normal Java.
     */
    @Override
    public final native <T> T returnsGeneric(String chars) /*-{
      return chars + this.suffix;
    }-*/;
  }

  /**
   * Ensure that SingleJsoImpl interfaces can be extended and implemented by
   * regular Java types.
   */
  interface Log2 extends Divider {
    double log2(int a);
  }

  interface Multiplier {
    int multiply(int a, int b);
  }

  /**
   * This interface makes sure that types with identical method signatures will
   * still dispatch correctly.
   */
  interface SameDescriptors {
    int SAME_NAME = 6;

    int add(int a, int b);

    int divide(int a, int b);

    int multiply(int a, int b);
  }

  interface Simple {
    String a();

    String a(boolean overload);

    String ex() throws IOException;

    String rte();
  }

  /**
   * An interface that has dual JSO and non-JSO implementations.
   */
  interface DualSimple {
    String a();
  }

  static class JavaDualSimple implements DualSimple {
    @Override
    public String a() {
      return "object";
    }
  }

  static final class JsoDualSimple extends JavaScriptObject implements DualSimple {
    protected JsoDualSimple() {
    }

    @Override
    public String a() {
      return "jso";
    }
  }

  /**
   * Ensure that a Java-only implementation of a SingleJsoImpl interface works.
   */
  static class SimpleOnlyJava implements SimpleOnlyJavaInterface {
    @Override
    public String simpleOnlyJava() {
      return "simpleOnlyJava";
    }
  }

  interface SimpleOnlyJavaInterface {
    String simpleOnlyJava();
  }
  interface Tag {
  }

  /**
   * Ensure that arrays are valid return and parameter types.
   */
  interface UsesArrays {
    void acceptInt3Array(int[][][] arr);

    void acceptIntArray(int[] arr);

    void acceptObject3Array(Object[][][] arr);

    void acceptObjectArray(Object[] arr);

    void acceptString3Array(String[][][] arr);

    void acceptStringArray(String[] arr);

    int[][][] returnInt3Array();

    int[] returnIntArray();

    Object[][][] returnObject3Array();

    Object[] returnObjectArray();

    String[][][] returnString3Array();

    String[] returnStringArray();
  }

  interface UsesGenerics {
    <T extends Object> String acceptsGeneric(T chars);

    <T> void callback(AsyncCallback<T> callback, T chars);

    <T> T returnsGeneric(String chars);
  }

  private static native JsoAdder makeAdder(int offset) /*-{
    return {offset:offset};
  }-*/;

  private static native JsoDivider makeDivider(int offset) /*-{
    return {offset:offset};
  }-*/;

  private static native JsoMultiplier makeMultiplier(int offset) /*-{
    return {offset:offset};
  }-*/;

  private static native JsoSimple makeSimple() /*-{
    return {};
  }-*/;

  interface JsFunction {
    int call();
  }

  final static class JsFunctionImpl extends JavaScriptObject implements JsFunction {
    protected JsFunctionImpl() {
    }

    static native JsFunction makeFunc() /*-{
      return function() { return 42; };
    }-*/;

    public native int call() /*-{
      return this();
    }-*/;
  }

  @Override
  public String getModuleName() {
    return "com.google.gwt.dev.jjs.CompilerSuite";
  }

  /*
   * These "testAssign*" tests below are inspired by the issue reported here:
   * 
   * @see http://code.google.com/p/google-web-toolkit/issues/detail?id=6448
   */
  public void testAssignToDualJavaJsoImplInterfaceArray() {
    int i = 0;
    DualSimple[] dualSimples = new DualSimple[10];

    DualSimple dualSimple = (DualSimple) JavaScriptObject.createObject();
    dualSimples[i] = dualSimple;
    assertEquals("jso", dualSimples[i++].a());

    JsoDualSimple jsoDualSimple = (JsoDualSimple) JavaScriptObject.createObject();
    dualSimples[i] = jsoDualSimple;
    assertEquals("jso", dualSimples[i++].a());

    DualSimple javaDualSimple = new JavaDualSimple();
    dualSimples[i] = javaDualSimple;
    assertEquals("object", dualSimples[i++].a());

    Object[] objects = dualSimples;
    objects[i++] = dualSimple;
    objects[i++] = jsoDualSimple;
    objects[i++] = javaDualSimple;
    try {
      objects[i++] = new Object();
      fail("ArrayStoreException expected");
    } catch (ArrayStoreException expected) {
    }
  }

  public void testAssignToJsoArray() {
    int i = 0;
    JsoDualSimple[] jsoDualSimples = new JsoDualSimple[10];

    JsoDualSimple jsoDualSimple = (JsoDualSimple) JavaScriptObject.createObject();
    jsoDualSimples[i] = jsoDualSimple;
    assertEquals("jso", jsoDualSimples[i++].a());

    DualSimple dualSimple = (DualSimple) JavaScriptObject.createObject();
    jsoDualSimples[i] = (JsoDualSimple) dualSimple;
    assertEquals("jso", jsoDualSimples[i++].a());

    DualSimple[] dualSimples = jsoDualSimples;
    try {
      DualSimple javaDualSimple = new JavaDualSimple();
      dualSimples[i++] = javaDualSimple;
      fail("ArrayStoreException expected");
    } catch (ArrayStoreException expected) {
    }
  }

  public void testAssignToJavaArray() {
    int i = 0;
    JavaDualSimple[] javaDualSimples = new JavaDualSimple[10];

    JavaDualSimple javaDualSimple = new JavaDualSimple();
    javaDualSimples[i] = javaDualSimple;
    assertEquals("object", javaDualSimples[i++].a());

    DualSimple[] dualSimples = javaDualSimples;
    try {
      DualSimple jsoDualSimple = (DualSimple) JavaScriptObject.createObject();
      dualSimples[i++] = jsoDualSimple;
      fail("ArrayStoreException expected");
    } catch (ArrayStoreException expected) {
    }
  }

  public void testAssignToObjectArray() {
    int i = 0;
    Object[] objects = new Object[10];

    Simple simple = (Simple) JavaScriptObject.createObject();
    objects[i++] = simple;

    JsoSimple jsoSimple = (JsoSimple) JavaScriptObject.createObject();
    objects[i++] = jsoSimple;

    JavaScriptObject jso = JavaScriptObject.createObject();
    objects[i++] = jso;

    Object object = new Object();
    objects[i++] = object;

    Integer integer = new Integer(1);
    objects[i++] = integer;
  }

  public void testAssignToSingleJsoImplInterfaceArray() {
    int i = 0;
    Simple[] simples = new Simple[10];
    Simple simple = (Simple) JavaScriptObject.createObject();
    simples[i] = simple;
    assertEquals("a", simples[i++].a());

    Simple jsoSimple = (JsoSimple) JavaScriptObject.createObject();
    simples[i] = jsoSimple;
    assertEquals("a", simples[i++].a());

    Object[] objects = simples;
    try {
      objects[i++] = new Object();
      fail("ArrayStoreException expected");
    } catch (ArrayStoreException expected) {
    }
  }

  public void testCallsToInnerTypes() {
    CallsMethodInInnerType a = (CallsMethodInInnerType) JavaScriptObject.createObject();
    InnerType i = (InnerType) JavaScriptObject.createObject();
    assertEquals(5, a.call(i, 5).get());
    assertEquals(5, i.get());
  }

  public void testCallsWithArrays() {
    UsesArrays a = JavaScriptObject.createObject().<JsoUsesArrays> cast();
    a.acceptIntArray(a.returnIntArray());
    a.acceptInt3Array(a.returnInt3Array());
    a.acceptStringArray(a.returnStringArray());
    a.acceptString3Array(a.returnString3Array());
    a.acceptObjectArray(a.returnStringArray());
    a.acceptObject3Array(a.returnString3Array());

    a = new JavaUsesArrays();
    a.acceptIntArray(a.returnIntArray());
    a.acceptInt3Array(a.returnInt3Array());
    a.acceptStringArray(a.returnStringArray());
    a.acceptString3Array(a.returnString3Array());
    a.acceptObjectArray(a.returnStringArray());
    a.acceptObject3Array(a.returnString3Array());
  }

  /**
   * Ensure that SingleJSO types that are referred to only via a cast to the
   * interface type are retained. If the JsoCreatedWithCast type isn't rescued
   * correctly, the cast in this test will throw a ClassCastException since the
   * compiler would assume there are types that implement the interface.
   */
  public void testCreatedWithCast() {
    try {
      Object a = (CreatedWithCast) JavaScriptObject.createObject();
    } catch (ClassCastException e) {
      fail("a");
    }
    try {
      Object b = (CreatedWithCastToTag) JavaScriptObject.createObject();
    } catch (ClassCastException e) {
      fail("b");
    }
  }

  public void testDualCase() {
    // Direct dispatch
    {
      JavaAdder java = new JavaAdder();
      assertEquals(2.0, java.add(1, 1));

      JsoAdder jso = makeAdder(2);
      assertEquals(4.0, jso.add(1, 1));
      assertEquals(5L, jso.returnLong());
    }

    // Just check dispatch via the interface
    {
      Adder a = new JavaAdder();
      assertEquals(2.0, a.add(1, 1));

      a = makeAdder(2);
      assertEquals(4.0, a.add(1, 1));
      assertEquals(5L, a.returnLong());
    }

    // Check casting
    {
      Object a = new JavaAdder();
      assertEquals(2.0, ((Adder) a).add(1, 1));
      assertEquals(2.0, ((JavaAdder) a).add(1, 1));
      assertEquals(5L, ((Adder) a).returnLong());
      assertEquals(5L, ((JavaAdder) a).returnLong());
      assertTrue(a instanceof JavaAdder);
      assertFalse(a instanceof JsoAdder);
      assertFalse(a instanceof Tag);
      try {
        ((JsoAdder) a).add(1, 1);
        fail("Should have thrown CCE");
      } catch (ClassCastException e) {
        // OK
      }

      a = makeAdder(2);
      assertEquals(4.0, ((Adder) a).add(1, 1));
      assertEquals(4.0, ((JsoAdder) a).add(1, 1));
      assertEquals(5L, ((Adder) a).returnLong());
      assertEquals(5L, ((JsoAdder) a).returnLong());
      assertTrue(a instanceof JsoAdder);
      assertFalse(a instanceof JavaAdder);
      // NB: This is unexpected until you consider JSO$ as a roll-up type
      assertTrue(a instanceof Tag);
      try {
        ((JavaAdder) a).add(1, 1);
        fail("Should have thrown CCE");
      } catch (ClassCastException e) {
        // OK
      }
    }
  }

  public void testFields() {
    assertEquals(6, Adder.ADDER_CONST);
    assertEquals("Same Name", Adder.SAME_NAME);
    assertEquals(6, SameDescriptors.SAME_NAME);
    assertSame(Adder.SAME_OBJECT, Adder.SAME_OBJECT2);
    assertNotSame(Adder.DIFFERENT_OBJECT, Adder.SAME_OBJECT);
  }

  public void testGenerics() {
    UsesGenerics j = JsoUsesGeneric.create();
    assertEquals("Hello42", j.acceptsGeneric("Hello"));
    assertEquals("Hello42", j.returnsGeneric("Hello"));
    j.callback(new AsyncCallback<CharSequence>() {
      @Override
      public void onFailure(Throwable caught) {
      }

      @Override
      public void onSuccess(CharSequence result) {
        assertEquals("Hello42", result);
      }
    }, "Hello");
  }

  @SuppressWarnings("cast")
  public void testSimpleCase() {
    {
      JsoSimple asJso = makeSimple();
      assertTrue(asJso instanceof Object);
      assertTrue(asJso instanceof Simple);
      assertEquals("a", asJso.a());
      assertEquals("OK", asJso.a(false));
      try {
        asJso.ex();
        fail("Should have thrown IOException");
      } catch (IOException e) {
        // OK
      }
      try {
        asJso.rte();
        fail("Should have thrown IllegalArgumentException");
      } catch (IllegalArgumentException e) {
        // OK
      }
    }

    {
      Simple asSimple = makeSimple();
      assertTrue(asSimple instanceof Object);
      assertTrue(asSimple instanceof JavaScriptObject);
      assertTrue(asSimple instanceof JsoSimple);
      assertEquals("a", asSimple.a());
      assertEquals("OK", asSimple.a(false));
      assertEquals("a", ((JsoSimple) asSimple).a());
      assertEquals("OK", ((JsoSimple) asSimple).a(false));
      try {
        asSimple.ex();
        fail("Should have thrown IOException");
      } catch (IOException e) {
        // OK
      }
      try {
        asSimple.rte();
        fail("Should have thrown IllegalArgumentException");
      } catch (IllegalArgumentException e) {
        // OK
      }
    }

    {
      Object asObject = "Defeat type-tightening";
      assertTrue(asObject instanceof String);

      asObject = makeSimple();
      assertTrue(asObject instanceof Object);
      assertTrue(asObject instanceof JavaScriptObject);
      assertTrue(asObject instanceof JsoSimple);
      assertTrue(asObject instanceof Simple);
      assertEquals("a", ((Simple) asObject).a());
      assertEquals("a", ((JsoSimple) asObject).a());
      assertEquals("OK", ((Simple) asObject).a(false));
      assertEquals("OK", ((JsoSimple) asObject).a(false));

      // Test a cross-cast that's normally not allowed by the type system
      assertTrue(asObject instanceof JsoRandom);
      assertEquals("b", ((JsoRandom) asObject).b());
      assertEquals(-1, ((JsoRandom) asObject).add(1, 1));
    }

    {
      Object o = "Defeat type-tightening";
      assertTrue(o instanceof String);
      o = new SimpleOnlyJava();
      assertTrue(o instanceof SimpleOnlyJavaInterface);
      assertEquals("simpleOnlyJava", ((SimpleOnlyJava) o).simpleOnlyJava());
    }
  }

  public void testStaticCallsToSubclasses() {
    Object o = "String";
    assertEquals(String.class, o.getClass());
    o = JavaScriptObject.createObject();
    assertTrue(o instanceof CallsStaticMethodInSubclass);
    assertEquals("foo5", ((CallsStaticMethodInSubclass) o).call(2, 3));
  }

  @SuppressWarnings("cast")
  public void testSubclassing() {
    {
      JsoDivider d = makeDivider(1);
      assertTrue(d instanceof Divider);
      assertTrue(d instanceof Multiplier);
      assertTrue(d instanceof Tag);
      assertEquals(5, d.divide(10, 2));
      assertEquals(10, d.multiply(5, 2));
      assertEquals(10, ((JsoMultiplier) d).multiply(5, 2));
    }

    {
      Object d = makeDivider(1);
      assertTrue(d instanceof Divider);
      assertTrue(d instanceof Multiplier);
      assertTrue(d instanceof JsoDivider);
      assertTrue(d instanceof JsoMultiplier);
      assertFalse(d instanceof JavaDivider);
      assertFalse(d instanceof JavaMultiplier);
      assertTrue(d instanceof Tag);

      assertEquals(5, ((Divider) d).divide(10, 2));
      assertEquals(10, ((Divider) d).multiply(5, 2));
      assertEquals(10, ((Multiplier) d).multiply(5, 2));
      assertEquals(5, ((JsoDivider) d).divide(10, 2));
      assertEquals(10, ((JsoMultiplier) d).multiply(5, 2));

      d = new JavaDivider();
      assertTrue(d instanceof Divider);
      assertTrue(d instanceof Multiplier);
      assertTrue(d instanceof JavaDivider);
      assertTrue(d instanceof JavaMultiplier);
      assertFalse(d instanceof JsoDivider);
      assertFalse(d instanceof JsoMultiplier);
      assertTrue(d instanceof Tag);

      assertEquals(5, ((Divider) d).divide(10, 2));
      assertEquals(10, ((Divider) d).multiply(5, 2));
      assertEquals(10, ((Multiplier) d).multiply(5, 2));
      assertEquals(5, ((JavaDivider) d).divide(10, 2));
      assertEquals(10, ((JavaMultiplier) d).multiply(5, 2));
    }

    {
      Object m = makeMultiplier(1);
      // This only works because JSO$ implements every SingleJsoImpl interface
      assertTrue(m instanceof Divider);
      assertEquals(2, ((Divider) m).divide(10, 5));

      m = new JavaMultiplier();
      // but this should fail, since there's proper type information
      assertFalse(m instanceof Divider);
      try {
        assertEquals(2, ((Divider) m).divide(10, 5));
        fail("Should have thrown CCE");
      } catch (ClassCastException e) {
        // OK
      }
    }

    {
      Object l2 = "Prevent type-tightening";
      assertTrue(l2 instanceof String);

      l2 = new JavaLog2();
      assertTrue(l2 instanceof Log2);
      assertTrue(l2 instanceof Multiplier);
      assertTrue(l2 instanceof Divider);
      assertEquals(4.0, ((Log2) l2).log2(16));
    }
  }

  public void testUnreferencedType() {
    JsoInterfaceWithUnreferencedImpl o = (JsoInterfaceWithUnreferencedImpl) JavaScriptObject.createObject();
    assertNotNull(o);
    assertTrue(o.isOk());
  }

  public void testJsFunctionCastsAsJso() {
    JsFunction func = JsFunctionImpl.makeFunc();
    assertTrue(func instanceof JavaScriptObject);
    JavaScriptObject jso = (JavaScriptObject) func;
    JsFunction func2 = (JsFunction) jso;
    if (func2 instanceof JavaScriptObject) {
      assertEquals(42, func2.call());
    } else {
      fail("Function should return true for instanceof JSO");
    }
  }
}
