| /* |
| * 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.js; |
| |
| /** |
| * Tests the JsStaticEval optimizer. |
| */ |
| public class JsStaticEvalTest extends OptimizerTestBase { |
| |
| public void testAddLiterals() throws Exception { |
| assertEquals("alert(42);", optimize("alert(21+21);")); |
| assertEquals("alert('Hello World');", optimize("alert('Hello '+'World');")); |
| assertEquals("alert('Hello 42');", optimize("alert('Hello ' + 42);")); |
| assertEquals("alert('42 Hello');", optimize("alert(42 + ' Hello');")); |
| assertEquals("alert('42 Hello');", optimize("alert(42.0 + ' Hello');")); |
| assertEquals("alert('42.2 Hello');", optimize("alert(42.2 + ' Hello');")); |
| assertEquals("alert('Hello 42.2');", optimize("alert('Hello ' + 42.2);")); |
| } |
| |
| public void testAssociativity() throws Exception { |
| // Simple test |
| assertEquals("alert(a||b||c||d);", optimize("alert((a||b)||(c||d));")); |
| assertEquals("alert(a&&b&&c&&d);", optimize("alert((a&&b)&&(c&&d));")); |
| |
| // Preserve precedence |
| assertEquals("alert((a||b)&&(c||d));", |
| optimize("alert((a || b) && (c || d));")); |
| assertEquals("alert(a&&b||c&&d);", |
| optimize("alert((a && b) || ( c && d));")); |
| assertEquals("a(),b&&c();", optimize("a(), b && c()")); |
| assertEquals("a()&&b,c();", optimize("a() && b, c()")); |
| |
| // Don't damage math expressions |
| assertEquals("alert(seconds/(60*60));", |
| optimize("alert(seconds / (60 * 60))")); |
| assertEquals("alert(1-(1-foo));", optimize("alert(1 - (1 - foo))")); |
| |
| // Don't damage assignments |
| assertEquals("alert((a=0,b=foo));", |
| optimize("alert((a = 0, b = (bar, foo)))")); |
| assertEquals("alert(1+(a='2')+3+4);", |
| optimize("alert(1 + (a = '2') + 3 + 4);")); |
| assertEquals("alert(1+(a='2')+7);", |
| optimize("alert(1 + (a = '2') + (3 + 4));")); |
| |
| // Break comma expressions up |
| assertEquals("alert((a(),b(),c(),d));", |
| optimize("alert(((a(),b()),(c(),d)));")); |
| // and remove expressions without side effects |
| assertEquals("alert(d);", optimize("alert(((a,b),(c,d)));")); |
| |
| // Pattern of coercing a numeric add operation to a string |
| assertEquals("alert(''+(a+b));", optimize("alert('' + (a + b))")); |
| assertEquals("alert('foo'+(a+b));", |
| optimize("alert('foo' + ('' + (a + b)))")); |
| |
| // Tests involving numeric and string literals and identifiers |
| assertEquals("alert(21+(1+$foo));", |
| optimize("alert((20 + 1) + (1 + $foo));")); |
| assertEquals("alert('211'+$foo);", |
| optimize("alert((20 + 1) + ('1' + $foo));")); |
| assertEquals("alert('2011'+$foo);", |
| optimize("alert((20 + '1') + ('1' + $foo));")); |
| assertEquals("alert('2011'+$foo);", |
| optimize("alert(('20' + 1) + ('1' + $foo));")); |
| assertEquals("alert('2011'+$foo);", |
| optimize("alert(('20' + '1') + ('1' + $foo));")); |
| |
| // These are also tricky, because $foo could be non-numeric |
| assertEquals("alert($foo+1+21);", optimize("alert(($foo + 1) + (20 + 1));")); |
| assertEquals("alert($bar+13+7+(2+$foo));", |
| optimize("alert((($bar + (10 + 3)) + (2 + 5)) + (2 + $foo));")); |
| |
| // Without type info, there's nothing that can be done for this expr |
| assertEquals("alert($foo+($bar+($baz+$quux)));", |
| optimize("alert($foo + ($bar + ($baz + $quux)));")); |
| } |
| |
| public void testIfWithEmptyThen() throws Exception { |
| assertEquals("a();", optimize("if (a()) { }")); |
| } |
| |
| public void testIfWithEmptyThenAndElseExpression() throws Exception { |
| assertEquals("a()||b();", optimize("if (a()) { } else { b(); }")); |
| } |
| |
| public void testIfWithEmptyThenAndElse() throws Exception { |
| assertEquals("if(!a()){throw 1}", |
| optimize("if (a()) { } else { throw 1; }")); |
| } |
| |
| public void testIfWithEmptyThenAndEmptyElse() throws Exception { |
| assertEquals("a();", optimize("if (a()) { } else { }")); |
| } |
| |
| public void testIfWithThenAndEmptyElse() throws Exception { |
| assertEquals("if(a()){throw 1}", optimize("if (a()) { throw 1; } else { }")); |
| } |
| |
| public void testIfWithThenExpressionAndEmptyElse() throws Exception { |
| assertEquals("a()&&b();", optimize("if (a()) { b() } else { }")); |
| } |
| |
| public void testIfWithThenExpressionAndElseExpression() throws Exception { |
| assertEquals("a()?b():c();", optimize("if (a()) { b() } else { c(); }")); |
| } |
| |
| public void testIfWithThenExpressionAndElseStatement() throws Exception { |
| // This can't be optimized further |
| assertEquals("if(a()){b()}else{throw 1}", |
| optimize("if (a()) { b() } else { throw 1; }")); |
| } |
| |
| public void testLiteralEqNull() throws Exception { |
| assertEquals("alert(false);", optimize("alert('test' == null)")); |
| } |
| |
| public void testLiteralNeNull() throws Exception { |
| assertEquals("alert(true);", optimize("alert('test' != null)")); |
| } |
| |
| public void testNullEqNull() throws Exception { |
| assertEquals("alert(true);", optimize("alert(null == null)")); |
| } |
| |
| public void testNullNeNull() throws Exception { |
| assertEquals("alert(false);", optimize("alert(null != null)")); |
| } |
| |
| private String optimize(String js) throws Exception { |
| return optimize(js, JsStaticEval.class); |
| } |
| } |