aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/test/java/com/google/devtools/build/lib/analysis/stringtemplate/TemplateExpanderTest.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/java/com/google/devtools/build/lib/analysis/stringtemplate/TemplateExpanderTest.java')
-rw-r--r--src/test/java/com/google/devtools/build/lib/analysis/stringtemplate/TemplateExpanderTest.java219
1 files changed, 140 insertions, 79 deletions
diff --git a/src/test/java/com/google/devtools/build/lib/analysis/stringtemplate/TemplateExpanderTest.java b/src/test/java/com/google/devtools/build/lib/analysis/stringtemplate/TemplateExpanderTest.java
index fa61f091b3..d2740b6465 100644
--- a/src/test/java/com/google/devtools/build/lib/analysis/stringtemplate/TemplateExpanderTest.java
+++ b/src/test/java/com/google/devtools/build/lib/analysis/stringtemplate/TemplateExpanderTest.java
@@ -18,132 +18,193 @@ import static org.junit.Assert.fail;
import java.util.HashMap;
import java.util.Map;
+import java.util.function.Function;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
/**
- * Unit tests for the {@link
- * com.google.devtools.build.lib.analysis.stringtemplate.TemplateExpander}, which expands variable
- * references of the form <code>"$x"</code> and <code>"$(foo)"</code> into their corresponding
- * values.
+ * Unit tests for the {@link TemplateExpander}.
*/
@RunWith(JUnit4.class)
public class TemplateExpanderTest {
+ private static final class TemplateContextImpl implements TemplateContext {
+ private final Map<String, String> vars = new HashMap<>();
+ private final Map<String, Function<String, String>> functions = new HashMap<>();
+
+ @Override
+ public String lookupVariable(String name)
+ throws ExpansionException {
+ // Not a Make variable. Let the shell handle the expansion.
+ if (name.startsWith("$")) {
+ return name;
+ }
+ if (!vars.containsKey(name)) {
+ throw new ExpansionException(String.format("$(%s) not defined", name));
+ }
+ return vars.get(name);
+ }
- private TemplateContext context;
+ @Override
+ public String lookupFunction(String name, String param) throws ExpansionException {
+ if (!functions.containsKey(name)) {
+ throw new ExpansionException(String.format("$(%s) not defined", name));
+ }
+ return functions.get(name).apply(param);
+ }
+ }
- private Map<String, String> vars = new HashMap<>();
+ private TemplateContextImpl context;
@Before
public final void createContext() throws Exception {
- context = new TemplateContext() {
- @Override
- public String lookupVariable(String name)
- throws ExpansionException {
- // Not a Make variable. Let the shell handle the expansion.
- if (name.startsWith("$")) {
- return name;
- }
- if (!vars.containsKey(name)) {
- throw new ExpansionException(String.format("$(%s) not defined", name));
- }
- return vars.get(name);
- }
- };
-
- vars.put("SRCS", "src1 src2");
+ context = new TemplateContextImpl();
}
- private void assertExpansionEquals(String expected, String cmd)
- throws ExpansionException {
- assertThat(TemplateExpander.expand(cmd, context)).isEqualTo(expected);
+ private String expand(String value) throws ExpansionException {
+ return TemplateExpander.expand(value, context);
}
- private void assertExpansionFails(String expectedErrorSuffix, String cmd) {
+ private ExpansionException expansionFailure(String cmd) {
try {
- TemplateExpander.expand(cmd, context);
+ expand(cmd);
fail("Expansion of " + cmd + " didn't fail as expected");
- } catch (Exception e) {
- assertThat(e).hasMessageThat().isEqualTo(expectedErrorSuffix);
+ throw new AssertionError();
+ } catch (ExpansionException e) {
+ return e;
}
}
@Test
- public void testExpansion() throws Exception {
- vars.put("<", "src1");
- vars.put("OUTS", "out1 out2");
- vars.put("@", "out1");
- vars.put("^", "src1 src2 dep1 dep2");
- vars.put("@D", "outdir");
- vars.put("BINDIR", "bindir");
-
- assertExpansionEquals("src1 src2", "$(SRCS)");
- assertExpansionEquals("src1", "$<");
- assertExpansionEquals("out1 out2", "$(OUTS)");
- assertExpansionEquals("out1", "$(@)");
- assertExpansionEquals("out1", "$@");
- assertExpansionEquals("out1,", "$@,");
-
- assertExpansionEquals("src1 src2 out1 out2", "$(SRCS) $(OUTS)");
-
- assertExpansionEquals("cmd", "cmd");
- assertExpansionEquals("cmd src1 src2,", "cmd $(SRCS),");
- assertExpansionEquals("label1 src1 src2,", "label1 $(SRCS),");
- assertExpansionEquals(":label1 src1 src2,", ":label1 $(SRCS),");
+ public void testVariableExpansion() throws Exception {
+ context.vars.put("SRCS", "src1 src2");
+ context.vars.put("<", "src1");
+ context.vars.put("OUTS", "out1 out2");
+ context.vars.put("@", "out1");
+ context.vars.put("^", "src1 src2 dep1 dep2");
+ context.vars.put("@D", "outdir");
+ context.vars.put("BINDIR", "bindir");
+
+ assertThat(expand("$(SRCS)")).isEqualTo("src1 src2");
+ assertThat(expand("$<")).isEqualTo("src1");
+ assertThat(expand("$(OUTS)")).isEqualTo("out1 out2");
+ assertThat(expand("$(@)")).isEqualTo("out1");
+ assertThat(expand("$@")).isEqualTo("out1");
+ assertThat(expand("$@,")).isEqualTo("out1,");
+
+ assertThat(expand("$(SRCS) $(OUTS)")).isEqualTo("src1 src2 out1 out2");
+
+ assertThat(expand("cmd")).isEqualTo("cmd");
+ assertThat(expand("cmd $(SRCS),")).isEqualTo("cmd src1 src2,");
+ assertThat(expand("label1 $(SRCS),")).isEqualTo("label1 src1 src2,");
+ assertThat(expand(":label1 $(SRCS),")).isEqualTo(":label1 src1 src2,");
+ }
+
+ @Test
+ public void testUndefinedVariableExpansion() throws Exception {
+ assertThat(expansionFailure("$(foo)"))
+ .hasMessageThat().isEqualTo("$(foo) not defined");
+ }
+
+ @Test
+ public void testFunctionExpansion() throws Exception {
+ context.functions.put("foo", (String p) -> "FOO(" + p + ")");
+ context.vars.put("bar", "bar");
+
+ assertThat(expand("$(foo baz)")).isEqualTo("FOO(baz)");
+ assertThat(expand("$(bar) $(foo baz)")).isEqualTo("bar FOO(baz)");
+ assertThat(expand("xyz$(foo baz)zyx")).isEqualTo("xyzFOO(baz)zyx");
+ }
+
+ @Test
+ public void testFunctionExpansionThrows() throws Exception {
+ try {
+ TemplateExpander.expand("$(foo baz)", new TemplateContext() {
+ @Override
+ public String lookupVariable(String name) throws ExpansionException {
+ throw new ExpansionException(name);
+ }
+
+ @Override
+ public String lookupFunction(String name, String param) throws ExpansionException {
+ throw new ExpansionException(name + "(" + param + ")");
+ }
+ });
+ fail();
+ } catch (ExpansionException e) {
+ assertThat(e).hasMessageThat().isEqualTo("foo(baz)");
+ }
+ }
+ @Test
+ public void testUndefinedFunctionExpansion() throws Exception {
// Note: $(location x) is considered an undefined variable;
- assertExpansionFails("$(location label1) not defined",
- "$(location label1), $(SRCS),");
+ assertThat(expansionFailure("$(location label1), $(SRCS),"))
+ .hasMessageThat().isEqualTo("$(location) not defined");
+ assertThat(expansionFailure("$(basename file)"))
+ .hasMessageThat().isEqualTo("$(basename) not defined");
}
@Test
public void testRecursiveExpansion() throws Exception {
// Expansion is recursive: $(recursive) -> $(SRCS) -> "src1 src2"
- vars.put("recursive", "$(SRCS)");
- assertExpansionEquals("src1 src2", "$(recursive)");
+ context.vars.put("SRCS", "src1 src2");
+ context.vars.put("recursive", "$(SRCS)");
+ assertThat(expand("$(recursive)")).isEqualTo("src1 src2");
+ }
+ @Test
+ public void testRecursiveExpansionDoesNotSpanExpansionBoundaries() throws Exception {
// Recursion does not span expansion boundaries:
// $(recur2a)$(recur2b) --> "$" + "(SRCS)" --/--> "src1 src2"
- vars.put("recur2a", "$$");
- vars.put("recur2b", "(SRCS)");
- assertExpansionEquals("$(SRCS)", "$(recur2a)$(recur2b)");
+ context.vars.put("SRCS", "src1 src2");
+ context.vars.put("recur2a", "$$");
+ context.vars.put("recur2b", "(SRCS)");
+ assertThat(expand("$(recur2a)$(recur2b)")).isEqualTo("$(SRCS)");
}
@Test
- public void testInfiniteRecursionFailsGracefully() throws Exception {
- vars.put("infinite", "$(infinite)");
- assertExpansionFails("potentially unbounded recursion during expansion "
- + "of '$(infinite)'",
- "$(infinite)");
+ public void testSelfInfiniteExpansionFailsGracefully() throws Exception {
+ context.vars.put("infinite", "$(infinite)");
+ assertThat(expansionFailure("$(infinite)")).hasMessageThat()
+ .isEqualTo("potentially unbounded recursion during expansion of '$(infinite)'");
+ }
- vars.put("black", "$(white)");
- vars.put("white", "$(black)");
- assertExpansionFails("potentially unbounded recursion during expansion "
- + "of '$(black)'",
- "$(white) is the new $(black)");
+ @Test
+ public void testMutuallyInfiniteExpansionFailsGracefully() throws Exception {
+ context.vars.put("black", "$(white)");
+ context.vars.put("white", "$(black)");
+ assertThat(expansionFailure("$(white) is the new $(black)")).hasMessageThat()
+ .isEqualTo("potentially unbounded recursion during expansion of '$(black)'");
}
@Test
public void testErrors() throws Exception {
- assertExpansionFails("unterminated variable reference", "$(SRCS");
- assertExpansionFails("unterminated $", "$");
+ assertThat(expansionFailure("$(SRCS")).hasMessageThat()
+ .isEqualTo("unterminated variable reference");
+ assertThat(expansionFailure("$")).hasMessageThat().isEqualTo("unterminated $");
String suffix = "instead for \"Make\" variables, or escape the '$' as '$$' if you intended "
+ "this for the shell";
- assertExpansionFails("'$file' syntax is not supported; use '$(file)' " + suffix,
- "for file in a b c;do echo $file;done");
- assertExpansionFails("'${file%:.*8}' syntax is not supported; use '$(file%:.*8)' " + suffix,
- "${file%:.*8}");
+ assertThat(expansionFailure("for file in a b c;do echo $file;done")).hasMessageThat()
+ .isEqualTo("'$file' syntax is not supported; use '$(file)' " + suffix);
+ assertThat(expansionFailure("${file%:.*8}")).hasMessageThat()
+ .isEqualTo("'${file%:.*8}' syntax is not supported; use '$(file%:.*8)' " + suffix);
+ }
+
+ @Test
+ public void testDollarDollar() throws Exception {
+ assertThat(expand("for file in a b c;do echo $$file;done"))
+ .isEqualTo("for file in a b c;do echo $file;done");
+ assertThat(expand("$${file%:.*8}")).isEqualTo("${file%:.*8}");
+ assertThat(expand("$$(basename file)")).isEqualTo("$(basename file)");
}
+ // Regression test: check that the parameter is trimmed before expanding.
@Test
- public void testShellVariables() throws Exception {
- assertExpansionEquals("for file in a b c;do echo $file;done",
- "for file in a b c;do echo $$file;done");
- assertExpansionEquals("${file%:.*8}", "$${file%:.*8}");
- assertExpansionFails("$(basename file) not defined", "$(basename file)");
- assertExpansionEquals("$(basename file)", "$$(basename file)");
+ public void testFunctionExpansionIsTrimmed() throws Exception {
+ context.functions.put("foo", (String p) -> "FOO(" + p + ")");
+ assertThat(expand("$(foo baz )")).isEqualTo("FOO(baz)");
}
}