| /* |
| * Copyright 2013 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.dev.jjs.test.overrides.package1.Caller; |
| import com.google.gwt.dev.jjs.test.overrides.package1.ClassExposingM; |
| import com.google.gwt.dev.jjs.test.overrides.package1.SomeParent; |
| import com.google.gwt.dev.jjs.test.overrides.package1.SomeParentParent; |
| import com.google.gwt.dev.jjs.test.overrides.package1.SomeParentParentParent; |
| import com.google.gwt.dev.jjs.test.overrides.package1.SubClassExposingM; |
| import com.google.gwt.dev.jjs.test.overrides.package2.SomeSubClassInAnotherPackage; |
| import com.google.gwt.dev.jjs.test.overrides.package2.SomeSubSubClassInAnotherPackage; |
| import com.google.gwt.dev.jjs.test.overrides.package3.SomeInterface; |
| import com.google.gwt.dev.jjs.test.overrides.package3.SomePackageConfusedParent; |
| import com.google.gwt.dom.client.Document; |
| import com.google.gwt.junit.client.GWTTestCase; |
| |
| import java.util.ArrayList; |
| import java.util.HashMap; |
| import java.util.List; |
| import java.util.Map; |
| |
| /** |
| * Tests Miscelaneous fixes. |
| */ |
| public class CompilerMiscRegressionTest extends GWTTestCase { |
| |
| @Override |
| public String getModuleName() { |
| return "com.google.gwt.dev.jjs.CompilerSuite"; |
| } |
| |
| native double toNumber(String value) /*-{ |
| return +value; |
| }-*/; |
| |
| native double addAndConvert(double v1, String v2) /*-{ |
| return v1 + +v2; |
| }-*/; |
| |
| native double minusAndDecrement(double val) /*-{ |
| var lhs = val; |
| return - --lhs; |
| }-*/; |
| |
| /** |
| * The array {@code map.get("one")[0]} gets normalized (by {@link ImplementCastsAndTypeChecks}) to |
| * {@code Cast.dynamicCast(map.get("one"), ...)[0]}. The expression resulting from dynamiCast |
| * would have type Object and that would not be a valid type for an array access operation. |
| */ |
| public void testOverridingReturnType() { |
| Map<String, String[]> map = new HashMap(); |
| map.put("one", new String[10]); |
| |
| map.get("one")[0] = "one"; |
| assertEquals("one", map.get("one")[0]); |
| } |
| |
| /** |
| * Test for issues 6373 and 3942. |
| */ |
| public void testUnaryPlus() { |
| // With the unary + operator stripped the first assertion only fails in |
| // dev mode, in web mode the comparison made by assertEquals masks |
| // the error; whereas the second fails in both dev and web modes. |
| assertEquals(11.0, toNumber("11")); |
| assertEquals(12.0, toNumber("10") + toNumber("2")); |
| assertEquals(12.0, addAndConvert(10, "2")); |
| assertEquals(-10.0, minusAndDecrement(11)); |
| } |
| private static float[] copy(float[] src, float[] dest) { |
| System.arraycopy(src, 0, dest, 0, Math.min(src.length, dest.length)); |
| return dest; |
| } |
| |
| private void throwE(String message) { |
| throw new RuntimeException(message); |
| } |
| |
| /** |
| * Test for issue 8243. |
| */ |
| public void testAddAllLargeNumberOfElements() { |
| |
| int dstLength = 10; |
| // Some browser have a limit on the number of parameters a function can have and 130000 barely |
| // exceeds Chrome limit (as of V34). |
| // This limit also applies when functions are called through apply(). |
| int srcLength = 130000; |
| List<String> original = new ArrayList<String>(); |
| for (int i = 0; i < dstLength; i++) { |
| original.add("foo"); |
| } |
| List<String> src = new ArrayList<String>(); |
| for (int i = 0; i < srcLength; i++) { |
| src.add("bar"); |
| } |
| |
| original.addAll(src); |
| final int totalLength = srcLength + dstLength; |
| assertEquals(totalLength, original.size()); |
| |
| // Check the result sampling as iterating through large arrays seems costly in IE. |
| for (int i = 0; i < totalLength; i += 1000) { |
| if (i < dstLength) { |
| assertEquals("foo", original.get(i)); |
| } else { |
| assertEquals("bar", original.get(i)); |
| } |
| } |
| } |
| |
| /** |
| * Test for issue 7253. |
| */ |
| public void testNestedTryFollowedByTry() { |
| try { |
| throwE("1"); |
| fail("Should have thrown RuntimeException"); |
| } catch (RuntimeException e) { |
| assertEquals("1", e.getMessage()); |
| try { |
| throwE("2"); |
| fail("Should have thrown RuntimeException"); |
| } catch (RuntimeException e2) { |
| assertEquals("2", e2.getMessage()); |
| } |
| } |
| try { |
| throwE("3"); |
| fail("Should have thrown RuntimeException"); |
| } catch (RuntimeException e) { |
| assertEquals("3", e.getMessage()); |
| } |
| } |
| |
| /** |
| * Test for issue 6638. |
| */ |
| public void testNewArrayInlining() { |
| float[] src = new float[]{1,1,1}; |
| float[] dest = copy(src, new float[3]); |
| |
| assertEqualContents(src, dest); |
| } |
| |
| @SuppressWarnings("null") |
| public void testJsoShouldNullPointerExceptionInDevMode() { |
| com.google.gwt.dom.client.Element foo = null; |
| try { |
| foo.setPropertyString("x", "y"); |
| fail("Should have thrown Exception"); |
| } catch (Exception npe) { |
| // is not yet a NullPointerException in prod mode |
| } |
| // once foo is not null, then it works |
| foo = Document.get().createDivElement(); |
| foo.setPropertyString("x", "y"); |
| assertEquals("y", foo.getPropertyString("x")); |
| } |
| |
| /** |
| * Tests complex overriding patterns involving package private methods. |
| * <p> |
| * Test for issue 8654. |
| */ |
| public void testOverride() { |
| Caller aCaller = new Caller(); |
| assertEquals("SomeParentParent", aCaller.callPackagePrivatem(new SomeParentParent())); |
| assertEquals("SomeParent", aCaller.callPackagePrivatem(new SomeParent())); |
| assertEquals("SomeParent", aCaller.callPackagePrivatem( |
| new SomeSubClassInAnotherPackage())); |
| |
| assertEquals("SomeSubClassInAnotherPackage", |
| SomeSubClassInAnotherPackage.pleaseCallm(new SomeSubClassInAnotherPackage())); |
| assertEquals("SomeSubSubClassInAnotherPackage", |
| SomeSubClassInAnotherPackage.pleaseCallm(new SomeSubSubClassInAnotherPackage())); |
| |
| assertEquals("ClassExposingM", |
| aCaller.callPackagePrivatem(new ClassExposingM())); |
| |
| SomeInterface i = new ClassExposingM(); |
| assertEquals("ClassExposingM", i.m()); |
| assertEquals("live at ClassExposingM", new ClassExposingM().f()); |
| |
| // Confirm that both calling m through SomeInterface and through SomeParentParentParent |
| // dispatch to the right implementation. |
| SomeInterface i1 = new SubClassExposingM(); |
| assertEquals("SubClassExposingM", i1.m()); |
| |
| assertEquals("SubClassExposingM", |
| SomeParentParentParent.callSomeParentParentParentM(new SubClassExposingM())); |
| |
| assertEquals("SomeParentParentParent", |
| SomeParentParentParent.callSomeParentParentParentM(new SomeParentParentParent())); |
| assertEquals("SomeParentParentParent", |
| SomeParentParentParent.callSomeParentParentParentM(new SomePackageConfusedParent())); |
| assertEquals("SomeParentParent", |
| SomeParentParentParent.callSomeParentParentParentM(new SomeParentParent())); |
| assertEquals("SomeParent", |
| SomeParentParentParent.callSomeParentParentParentM(new SomeParent())); |
| assertEquals("SomeParent", |
| SomeParentParentParent.callSomeParentParentParentM(new SomeSubClassInAnotherPackage())); |
| assertEquals("SomeParent", |
| SomeParentParentParent.callSomeParentParentParentM(new SomeSubSubClassInAnotherPackage())); |
| } |
| |
| enum MyEnum { |
| A, |
| B, |
| C; |
| |
| public final static MyEnum[] VALUES = values(); |
| |
| public int getPriority() { |
| return VALUES.length - ordinal(); |
| } |
| } |
| |
| /** |
| * Tests that enum ordinalizer does not incorrectly optimize {@code MyEnum}. |
| * <p> |
| * Test for issue 8846:. |
| */ |
| public void testMyEnum() { |
| assertEquals(2, MyEnum.B.getPriority()); |
| } |
| |
| /** |
| * Tests that regexes are not incorrectly internalized. |
| * |
| * Test for issue 8865. |
| */ |
| public native void testJavaScriptRegExps() /*-{ |
| // Make regexes large enough so that the will be interned (if regex interning was enabled). |
| var regExp1 = /this is a string where the search/g; |
| var regExp2 = /this is a string where the search/g; |
| var str = "this is a string where the search occurs"; |
| @junit.framework.Assert::assertEquals(ZZ)( |
| regExp1.test(str), regExp2.test(str)); |
| }-*/; |
| |
| private static void assertEqualContents(float[] expected, float[] actual) { |
| |
| assertEquals("Array length mismatch", expected.length, actual.length); |
| for (int i = 0; i < expected.length; i++) { |
| assertEquals("Array mismatch at element " + i , expected[i], actual[i]); |
| } |
| } |
| } |