/*
* 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.sharedpasses.opti;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.template.soy.SoyFileSetParserBuilder;
import com.google.template.soy.SoyModule;
import com.google.template.soy.data.SoyValue;
import com.google.template.soy.data.SoyValueConverter;
import com.google.template.soy.data.SoyValueProvider;
import com.google.template.soy.exprtree.ExprRootNode;
import com.google.template.soy.sharedpasses.render.RenderException;
import com.google.template.soy.sharedpasses.render.TestingEnvironment;
import com.google.template.soy.soytree.PrintNode;
import java.util.HashMap;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
/**
* Unit tests for PreevalVisitor.
*
*/
@RunWith(JUnit4.class)
public final class PreevalVisitorTest {
@Test
public void testPreevalNoData() {
assertEquals(-210, preeval("-99+-111").integerValue());
assertEquals("-99-111", preeval("-99 + '-111'").stringValue());
assertEquals(false, preeval("false or 0 or 0.0 or ''").booleanValue());
assertEquals(true, preeval("0 <= 0").booleanValue());
assertEquals(true, preeval("'22' == 22").booleanValue());
assertEquals(true, preeval("'22' == '' + 22").booleanValue());
// With functions.
// TODO SOON: Uncomment these tests when basic functions have been changed to SoyJavaFunction.
//assertEquals(8, preeval("max(4, 8)").integerValue());
//assertEquals(3, preeval("floor(7/2)").integerValue());
// With impure function.
try {
preeval("randomInt(1000)");
fail();
} catch (RenderException re) {
assertTrue(re.getMessage().equals("Cannot preevaluate impure function."));
}
}
@Test
public void testPreevalWithData() {
assertEquals(8, preeval("$boo", "boo").integerValue());
assertEquals(2, preeval("$boo % 3", "boo").integerValue());
assertEquals(2, preeval("not $boo ? 1 : 2", "boo").integerValue());
assertEquals("8", preeval("$boo + ''", "boo").stringValue());
// With functions.
// TODO SOON: Uncomment these tests when basic functions have been changed to SoyJavaFunction.
//assertEquals(8, preeval("max(4, $boo)").integerValue());
//assertEquals(2, preeval("floor($boo / 3)").integerValue());
//assertEquals(3, preeval("round($boo / 3)").integerValue());
// With undefined data.
try {
preeval("4 + $foo", "foo");
fail();
} catch (RenderException re) {
// Test passes.
}
}
@Test
public void testPreevalWithIjData() {
try {
preeval("6 + $ij.foo");
fail();
} catch (RenderException re) {
// Test passes.
}
}
// -----------------------------------------------------------------------------------------------
// Helpers.
private static final Injector INJECTOR = Guice.createInjector(new SoyModule());
/**
* Evaluates the given expression and returns the result.
*
* @param expression The expression to preevaluate.
* @return The expression result.
*/
private static SoyValue preeval(String expression, String... params) {
String header = "";
for (String param : params) {
header += "{@param " + param + " : ?}\n";
}
PrintNode code =
(PrintNode)
SoyFileSetParserBuilder.forTemplateContents(header + "{" + expression + "}")
.parse()
.fileSet()
.getChild(0)
.getChild(0)
.getChild(0);
ExprRootNode expr = code.getExpr();
PreevalVisitor preevalVisitor =
INJECTOR
.getInstance(PreevalVisitorFactory.class)
.create(
null,
TestingEnvironment.createForTest(
SoyValueConverter.UNCUSTOMIZED_INSTANCE.newDict("boo", 8),
new HashMap<String, SoyValueProvider>()));
return preevalVisitor.exec(expr);
}
}