/* * Copyright 2015 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.template.soy.jssrc.restricted; import static com.google.common.truth.Truth.assertThat; import com.google.common.collect.ImmutableList; import com.google.template.soy.data.SanitizedContent.ContentKind; import com.google.template.soy.exprtree.Operator; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; /** * Unit tests for JsExprUtils. * */ @RunWith(JUnit4.class) public class JsExprUtilsTest { @Test public void testConcatJsExprs() { JsExpr concatResult = JsExprUtils.concatJsExprs( ImmutableList.of( new JsExpr("'blah' + 'blah'", Operator.MINUS.getPrecedence()), new JsExpr("'bleh' + 'bleh'", Operator.MINUS.getPrecedence()), new JsExpr("2 * 8", Operator.TIMES.getPrecedence()))); assertThat(concatResult.getText()).isEqualTo("'blah' + 'blah' + ('bleh' + 'bleh') + 2 * 8"); assertThat(concatResult.getPrecedence()).isEqualTo(Operator.PLUS.getPrecedence()); } @Test public void testIsStringLiteral() { assertThat(JsExprUtils.isStringLiteral(new JsExpr("''", Integer.MAX_VALUE))).isTrue(); assertThat(JsExprUtils.isStringLiteral(new JsExpr("'a'", Integer.MAX_VALUE))).isTrue(); assertThat(JsExprUtils.isStringLiteral(new JsExpr("'abc'", Integer.MAX_VALUE))).isTrue(); assertThat(JsExprUtils.isStringLiteral(new JsExpr("'ab\\nc'", Integer.MAX_VALUE))).isTrue(); assertThat(JsExprUtils.isStringLiteral(new JsExpr("'ab\\'c'", Integer.MAX_VALUE))).isTrue(); assertThat(JsExprUtils.isStringLiteral(new JsExpr("'\\'abc\\''", Integer.MAX_VALUE))).isTrue(); assertThat(JsExprUtils.isStringLiteral(new JsExpr("'\\u1234'", Integer.MAX_VALUE))).isTrue(); assertThat(JsExprUtils.isStringLiteral(new JsExpr("abc", Integer.MAX_VALUE))).isFalse(); assertThat(JsExprUtils.isStringLiteral(new JsExpr("123", Integer.MAX_VALUE))).isFalse(); assertThat(JsExprUtils.isStringLiteral(new JsExpr("foo()", Integer.MAX_VALUE))).isFalse(); assertThat(JsExprUtils.isStringLiteral(new JsExpr("'a' + 1", Operator.MINUS.getPrecedence()))) .isFalse(); assertThat(JsExprUtils.isStringLiteral(new JsExpr("1 + 'a'", Operator.MINUS.getPrecedence()))) .isFalse(); assertThat(JsExprUtils.isStringLiteral(new JsExpr("foo('a')", Integer.MAX_VALUE))).isFalse(); } @Test public void testWrapWithFunction() { JsExpr expr = new JsExpr("'foo' + 'bar'", Operator.PLUS.getPrecedence()); assertThat(JsExprUtils.wrapWithFunction("new Frob", expr).getText()) .isEqualTo("new Frob('foo' + 'bar')"); assertThat(JsExprUtils.maybeWrapAsSanitizedContent(ContentKind.HTML, expr).getText()) .isEqualTo("soydata.VERY_UNSAFE.ordainSanitizedHtml('foo' + 'bar')"); assertThat(JsExprUtils.maybeWrapAsSanitizedContent(null, expr).getText()) .isEqualTo("'foo' + 'bar'"); } /** * This test shows the inherent error-prone nature of JsExpr. Nothing checks that the precedence * passed to the JsExpr ctor corresponds to the topmost operator in the text passed in to the * JsExpr ctor. Passing in the wrong precedence bypasses the parenthesization logic and lead to * incorrect gencode. TODO(user): consolidate JS code generation under CodeChunk and eliminate * JsExpr. */ @Test public void testJsExprGarbageInGarbageOut() { JsExpr lhs = new JsExpr("a", Integer.MAX_VALUE); JsExpr wrongPrecedence = new JsExpr("b < c", Integer.MAX_VALUE /* should be Operator.LESS_THAN.getPrecedence() */); assertThat(JsExprUtils.concatJsExprs(ImmutableList.of(lhs, wrongPrecedence)).getText()) .isEqualTo("a + b < c"); // wrong! should be a + (b < c) JsExpr rightPrecedence = new JsExpr("b < c", Operator.LESS_THAN.getPrecedence()); assertThat(JsExprUtils.concatJsExprs(ImmutableList.of(lhs, rightPrecedence)).getText()) .isEqualTo("a + (b < c)"); } }