/*
* 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.SoyFileSetParser.ParseResult;
import com.google.template.soy.SoyFileSetParserBuilder;
import com.google.template.soy.SoyModule;
import com.google.template.soy.sharedpasses.render.RenderException;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
/**
* Unit tests for PrerenderVisitor.
*
*/
@RunWith(JUnit4.class)
public class PrerenderVisitorTest {
@Test
public void testPrerenderBasic() throws Exception {
String templateBody =
"{let $boo: 8 /}\n"
+ "{$boo}\n"
+ "{if $boo > 4}\n"
+ " {sp}+ 7 equals {$boo + 7}.\n"
+ "{/if}\n";
assertEquals("8 + 7 equals 15.", prerender(templateBody));
}
@Test
public void testPrerenderWithDirectives() throws Exception {
String printNodesSource =
"{let $boo: 8 /}\n"
+ "{'<b>&</b>' |escapeHtml} {sp}\n"
+ "{'aaa+bbb = ccc' |escapeUri} {sp}\n"
+ "{'0123456789' |truncate:5,true} {sp}\n"
+ "{'0123456789' |truncate:$boo,false} {sp}\n"
+ "{'0123456789' |escapeHtml |insertWordBreaks:5} {sp}\n"
+ "{'0123456789' |insertWordBreaks:$boo |escapeHtml} {sp}\n";
String expectedResult =
"<b>&</b> "
+ "aaa%2Bbbb%20%3D%20ccc "
+ "01... "
+ "01234567 "
+ "01234<wbr>56789 "
+ "01234567<wbr>89 ";
assertEquals(expectedResult, prerender(printNodesSource));
}
@Test
public void testPrerenderWithUnsupportedNode() throws Exception {
// Cannot prerender MsgFallbackGroupNode.
String templateBody = "{msg desc=\"\"}\n" + " Hello world.\n" + "{/msg}\n";
try {
prerender(templateBody);
fail();
} catch (RenderException re) {
assertTrue(re.getMessage().contains("Cannot prerender MsgFallbackGroupNode."));
}
// Cannot prerender CssNode.
templateBody =
"{let $boo: 8 /}\n"
+ "{if $boo > 4}\n"
+ " <div class=\"{css foo}\">blah</div>\n"
+ "{/if}\n";
try {
prerender(templateBody);
fail();
} catch (RenderException re) {
assertTrue(re.getMessage().contains("Cannot prerender CssNode."));
}
// This should work because the if-condition is false, thus skipping the CssNode.
templateBody =
"{let $boo: 8 /}\n"
+ "{$boo}\n"
+ "{if $boo < 4}\n"
+ " <div class=\"{css foo}\">blah</div>\n"
+ "{/if}\n";
assertEquals("8", prerender(templateBody));
}
@Test
public void testPrerenderWithUndefinedData() throws Exception {
String templateBody =
"{@param foo : ? }\n" + "{let $boo: 8 /}\n" + "{if $boo > 4}\n" + " {$foo}\n" + "{/if}\n";
try {
prerender(templateBody);
fail();
} catch (RenderException re) {
// Test passes.
}
// This should work because the if-condition is false, thus skipping the undefined data.
templateBody =
"{@param foo : ? }\n"
+ "{let $boo: 8 /}\n"
+ "{$boo}\n"
+ "{if $boo < 4}\n"
+ " {$foo}\n"
+ "{/if}\n";
assertEquals("8", prerender(templateBody));
}
@Test
public void testPrerenderWithDirectiveError() throws Exception {
try {
prerender(" {'blah' |bidiSpanWrap}\n");
fail();
} catch (Exception e) {
assertTrue(
e instanceof RenderException
&& e.getMessage()
.contains("Cannot prerender a node with some impure print directive."));
}
}
// -----------------------------------------------------------------------------------------------
// Helpers.
private static final Injector INJECTOR = Guice.createInjector(new SoyModule());
/**
* Renders the given input string (should be a template body) and returns the result.
*
* @param input The input string to prerender.
* @return The rendered result.
* @throws Exception If there's an error.
*/
private static String prerender(String input) throws Exception {
ParseResult result = SoyFileSetParserBuilder.forTemplateContents(input).parse();
StringBuilder outputSb = new StringBuilder();
PrerenderVisitor prerenderVisitor =
INJECTOR.getInstance(PrerenderVisitorFactory.class).create(outputSb, result.registry());
prerenderVisitor.exec(result.fileSet().getChild(0).getChild(0));
return outputSb.toString();
}
}