Improve test infrastructure
This commit is contained in:
@@ -4,16 +4,34 @@
|
||||
|
||||
package com.samskivert.mustache;
|
||||
|
||||
import static java.util.Map.entry;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
import java.io.StringReader;
|
||||
import java.io.Writer;
|
||||
import java.util.*;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
import org.junit.rules.TestRule;
|
||||
import org.junit.rules.TestWatcher;
|
||||
import org.junit.runner.Description;
|
||||
|
||||
import com.samskivert.mustache.specs.SpecTest;
|
||||
|
||||
/**
|
||||
* Vestige from when JMustache supported both GWT and JVM.
|
||||
@@ -210,17 +228,25 @@ public abstract class SharedTests
|
||||
fail();
|
||||
} catch (UnsupportedOperationException uoe) {} // expected
|
||||
}
|
||||
|
||||
|
||||
Map<String,String> partials = new LinkedHashMap<>();
|
||||
|
||||
@SafeVarargs
|
||||
protected final Mustache.TemplateLoader partials(Map.Entry<String, String> ... entries) {
|
||||
Map<String,String> templates = new LinkedHashMap<>();
|
||||
for (Entry<String, String> e : entries) {
|
||||
templates.put(e.getKey(), e.getValue());
|
||||
}
|
||||
partials = templates;
|
||||
return name -> new StringReader(templates.get(name));
|
||||
}
|
||||
|
||||
@Test public void testPartial () {
|
||||
test(Mustache.compiler().withLoader(new Mustache.TemplateLoader() {
|
||||
public Reader getTemplate (String name) {
|
||||
if (name.equals("foo")) {
|
||||
return new StringReader("inside:{{bar}}");
|
||||
} else {
|
||||
return new StringReader("nonfoo");
|
||||
}
|
||||
}
|
||||
}), "foo inside:foo nonfoo foo", "{{bar}} {{>foo}} {{>baz}} {{bar}}", context("bar", "foo"));
|
||||
test(Mustache.compiler().withLoader(
|
||||
partials(entry("foo", "inside:{{bar}}"),
|
||||
entry("baz", "nonfoo")))
|
||||
, "foo inside:foo nonfoo foo", "{{bar}} {{>foo}} {{>baz}} {{bar}}", context("bar", "foo"));
|
||||
}
|
||||
|
||||
@Test public void testPartialIndent () {
|
||||
@@ -231,7 +257,7 @@ public abstract class SharedTests
|
||||
}), "\\\n |\n <\n->\n |\n/\n", "\\\n {{>partial}}\n/\n", context("content", "<\n->"));
|
||||
}
|
||||
|
||||
/* @Test */ public void testPartialBlankLines () {
|
||||
@Ignore @Test public void testPartialBlankLines () {
|
||||
test(Mustache.compiler().withLoader(new Mustache.TemplateLoader() {
|
||||
public Reader getTemplate (String name) {
|
||||
return new StringReader("|\na\n\nb\n|\n");
|
||||
@@ -239,7 +265,7 @@ public abstract class SharedTests
|
||||
}), "\\\n\t|\n\ta\n\n\tb\n\t|\n/\n", "\\\n\t{{>partial}}\n/\n", context());
|
||||
}
|
||||
|
||||
/* @Test */ public void testNestedPartialBlankLines () {
|
||||
@Ignore @Test public void testNestedPartialBlankLines () {
|
||||
test(Mustache.compiler().withLoader(new Mustache.TemplateLoader() {
|
||||
public Reader getTemplate (String name) {
|
||||
if (name.equals("partial")) {
|
||||
@@ -251,7 +277,7 @@ public abstract class SharedTests
|
||||
}), "\\\n\t1\n\t\t2\n\t\ta\n\n\t\tb\n\t\t2\n\t1\n/\n", "\\\n\t{{>partial}}\n/\n", context());
|
||||
}
|
||||
|
||||
/* @Test */ public void testNestedPartialBlankLinesCRLF () {
|
||||
@Ignore @Test public void testNestedPartialBlankLinesCRLF () {
|
||||
test(Mustache.compiler().withLoader(new Mustache.TemplateLoader() {
|
||||
public Reader getTemplate (String name) {
|
||||
if (name.equals("partial")) {
|
||||
@@ -263,16 +289,11 @@ public abstract class SharedTests
|
||||
}), "\\\r\n\t1\r\n\t\t2\r\n\t\ta\r\n\r\n\t\tb\r\n\t\t2\r\n\t1\r\n/\r\n", "\\\r\n\t{{>partial}}\r\n/\r\n", context());
|
||||
}
|
||||
|
||||
/* @Test */ public void testNestedPartialIndent () {
|
||||
test(Mustache.compiler().withLoader(new Mustache.TemplateLoader() {
|
||||
public Reader getTemplate (String name) {
|
||||
if (name.equals("partial")) {
|
||||
return new StringReader("1\n {{>nest}}\n1\n");
|
||||
} else {
|
||||
return new StringReader("2\n{{{content}}}\n2\n");
|
||||
}
|
||||
}
|
||||
}), "|\n 1\n 2\n <\n->\n 2\n 1\n|\n", "|\n {{>partial}}\n|\n", context("content", "<\n->"));
|
||||
/* @Ignore */ @Test public void testNestedPartialIndent () {
|
||||
Mustache.TemplateLoader loader = partials(entry("partial", "1\n {{>nest}}\n1\n"), entry("nest", "2\n{{{content}}}\n2\n"));
|
||||
test(Mustache.compiler().withLoader(loader),
|
||||
"|\n 1\n 2\n <\n->\n 2\n 1\n|\n",
|
||||
"|\n {{>partial}}\n|\n", context("content", "<\n->"));
|
||||
}
|
||||
|
||||
@Test public void testPartialIndentWithVariableAtTheStart () {
|
||||
@@ -826,12 +847,40 @@ public abstract class SharedTests
|
||||
test(Mustache.compiler().withDelims("<% %>"), "bar", "<%foo%>", context("foo", "bar"));
|
||||
}
|
||||
|
||||
protected void test (Mustache.Compiler compiler, String expected, String template, Object ctx) {
|
||||
check(expected, compiler.compile(template).execute(ctx));
|
||||
protected String name;
|
||||
|
||||
@Rule public TestRule watcher = new TestWatcher() {
|
||||
protected void starting(Description description) {
|
||||
name = description.getDisplayName();
|
||||
}
|
||||
};
|
||||
|
||||
protected void test(Mustache.Compiler compiler, String expected, String template, Object ctx) {
|
||||
String actual = compiler.compile(template).execute(ctx);
|
||||
if (! Objects.equals(expected, actual)) {
|
||||
System.out.println("");
|
||||
System.out.println("----------------------------------------");
|
||||
System.out.println("");
|
||||
System.out.println("Failed: " + name);
|
||||
System.out.println("Template : \"" + SpecTest.showWhitespace(template) + "\"");
|
||||
if (! partials.isEmpty()) {
|
||||
System.out.println("Partials : ");
|
||||
for (Entry<String, String> e : partials.entrySet()) {
|
||||
System.out.println("\t" + e.getKey() + ": \"" + SpecTest.showWhitespace(e.getValue()) + "\"");
|
||||
}
|
||||
}
|
||||
System.out.println("Expected : \"" + SpecTest.showWhitespace(expected) + "\"");
|
||||
System.out.println("Result : \"" + SpecTest.showWhitespace(actual) + "\"");
|
||||
System.out.println("----------------------------------------");
|
||||
System.out.println("");
|
||||
}
|
||||
check(expected, actual);
|
||||
}
|
||||
|
||||
protected void check (String expected, String output) {
|
||||
assertEquals(uncrlf(expected), uncrlf(output));
|
||||
//assertEquals(uncrlf(expected), uncrlf(output));
|
||||
assertEquals(SpecTest.showWhitespace(expected), SpecTest.showWhitespace(output));
|
||||
|
||||
}
|
||||
|
||||
protected void test (String expected, String template, Object ctx) {
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.samskivert.mustache.specs;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Parameterized;
|
||||
import org.junit.runners.Parameterized.Parameters;
|
||||
|
||||
@RunWith(Parameterized.class)
|
||||
public class CustomSpecTest extends SpecTest {
|
||||
|
||||
public CustomSpecTest(Spec spec, String name) {
|
||||
super(spec, name);
|
||||
}
|
||||
|
||||
@Parameters(name = "{1}")
|
||||
public static Collection<Object[]> data () {
|
||||
String[] groups = new String[] {
|
||||
"partials"
|
||||
};
|
||||
return SpecTest.data("/custom/specs/", groups);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package com.samskivert.mustache.specs;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Parameterized;
|
||||
import org.junit.runners.Parameterized.Parameters;
|
||||
|
||||
@RunWith(Parameterized.class)
|
||||
public class OfficialSpecTest extends SpecTest {
|
||||
|
||||
public OfficialSpecTest(Spec spec, String name) {
|
||||
super(spec, name);
|
||||
}
|
||||
|
||||
@Parameters(name = "{1}")
|
||||
public static Collection<Object[]> data () {
|
||||
String[] groups = new String[] {
|
||||
"comments",
|
||||
"delimiters",
|
||||
"interpolation",
|
||||
"inverted",
|
||||
"sections",
|
||||
"partials"
|
||||
};
|
||||
return SpecTest.data("/specs/specs/", groups);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -5,6 +5,7 @@
|
||||
package com.samskivert.mustache.specs;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* @author Yoryos Valotasios
|
||||
@@ -26,7 +27,7 @@ public class Spec
|
||||
}
|
||||
|
||||
public String getDescription () {
|
||||
return (String) map.get("descr");
|
||||
return (String) map.get("desc");
|
||||
}
|
||||
|
||||
public String getTemplate () {
|
||||
@@ -44,4 +45,20 @@ public class Spec
|
||||
public String getPartial (String name) {
|
||||
return partials == null ? null : partials.get(name);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
Consumer<String> value = s -> sb.append("\"").append(s).append("\"").append("\n");
|
||||
Consumer<String> label = s -> sb.append("").append(s).append(": ");
|
||||
label.accept("name");
|
||||
value.accept(getName());
|
||||
label.accept("desc");
|
||||
value.accept(getDescription());
|
||||
label.accept("template");
|
||||
value.accept(getTemplate());
|
||||
label.accept("expected");
|
||||
value.accept(getExpectedOutput());
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
@@ -12,9 +12,10 @@ import com.samskivert.mustache.Mustache;
|
||||
public class SpecAwareTemplateLoader implements Mustache.TemplateLoader
|
||||
{
|
||||
private static final String EMPTY_STRING = "";
|
||||
private Spec spec;
|
||||
private final Spec spec;
|
||||
|
||||
public void setSpec (Spec spec) {
|
||||
public SpecAwareTemplateLoader(Spec spec) {
|
||||
super();
|
||||
this.spec = spec;
|
||||
}
|
||||
|
||||
|
||||
@@ -7,19 +7,14 @@ import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Parameterized;
|
||||
import org.junit.runners.Parameterized.Parameters;
|
||||
import org.yaml.snakeyaml.Yaml;
|
||||
import org.yaml.snakeyaml.error.YAMLException;
|
||||
|
||||
import com.samskivert.mustache.Mustache;
|
||||
import com.samskivert.mustache.Template;
|
||||
|
||||
@RunWith(Parameterized.class)
|
||||
public class SpecTest {
|
||||
public abstract class SpecTest {
|
||||
|
||||
private static final Yaml yaml = new Yaml();
|
||||
|
||||
@@ -32,19 +27,11 @@ public class SpecTest {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
private static Mustache.Compiler compiler;
|
||||
private static SpecAwareTemplateLoader loader;
|
||||
|
||||
@BeforeClass
|
||||
public static void setUp () {
|
||||
loader = new SpecAwareTemplateLoader();
|
||||
compiler = Mustache.compiler().defaultValue("").withLoader(loader);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test () throws Exception {
|
||||
//System.out.println("Testing: " + name);
|
||||
loader.setSpec(spec);
|
||||
SpecAwareTemplateLoader loader = new SpecAwareTemplateLoader(spec);
|
||||
Mustache.Compiler compiler = Mustache.compiler().defaultValue("").withLoader(loader);
|
||||
String tmpl = spec.getTemplate();
|
||||
String desc = String.format("Template: '''%s'''\nData: '%s'\n",
|
||||
uncrlf(tmpl), uncrlf(spec.getData().toString()));
|
||||
@@ -75,7 +62,7 @@ public class SpecTest {
|
||||
}
|
||||
}
|
||||
|
||||
private static String showWhitespace (String s) {
|
||||
public static String showWhitespace (String s) {
|
||||
s = s.replace("\r\n", "\u240D");
|
||||
s = s.replace('\t', '\u21E5');
|
||||
s = s.replace("\n", "\u21B5\n");
|
||||
@@ -88,20 +75,12 @@ public class SpecTest {
|
||||
return (text == null) ? null : text.replace("\r", "\\r").replace("\n", "\\n");
|
||||
}
|
||||
|
||||
@Parameters(name = "{1}")
|
||||
public static Collection<Object[]> data () {
|
||||
String[] groups = new String[] {
|
||||
"comments",
|
||||
"delimiters",
|
||||
"interpolation",
|
||||
"inverted",
|
||||
"sections",
|
||||
"partials"
|
||||
};
|
||||
|
||||
public static Collection<Object[]> data (String specPath, String[] groups) {
|
||||
List<Object[]> tuples = new ArrayList<>();
|
||||
int i = 0;
|
||||
for (String g : groups) {
|
||||
Iterable<Spec> specs = getTestsForGroup(g);
|
||||
Iterable<Spec> specs = getTestsForGroup(specPath, g);
|
||||
for (Spec s : specs) {
|
||||
Object[] tuple = new Object[] {s, g + "-" + s.getName() + "-" + i++};
|
||||
tuples.add(tuple);
|
||||
@@ -110,8 +89,13 @@ public class SpecTest {
|
||||
return tuples;
|
||||
}
|
||||
|
||||
private static Iterable<Spec> getTestsForGroup (String name) {
|
||||
String ymlPath = "/specs/specs/" + name + ".yml";
|
||||
private static Iterable<Spec> getTestsForGroup (String specPath, String name) {
|
||||
//String ymlPath = "/specs/specs/" + name + ".yml";
|
||||
String ymlPath = specPath + name + ".yml";
|
||||
return getTestsFromYaml(name, ymlPath);
|
||||
}
|
||||
|
||||
private static Iterable<Spec> getTestsFromYaml(String name, String ymlPath) {
|
||||
try {
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, Object> map = (Map<String, Object>) yaml.load(SpecTest.class.getResourceAsStream(ymlPath));
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
overview: |
|
||||
Partial tags are used to expand an external template into the current
|
||||
template.
|
||||
|
||||
The tag's content MUST be a non-whitespace character sequence NOT containing
|
||||
the current closing delimiter.
|
||||
|
||||
This tag's content names the partial to inject. Set Delimiter tags MUST NOT
|
||||
affect the parsing of a partial. The partial MUST be rendered against the
|
||||
context stack local to the tag. If the named partial cannot be found, the
|
||||
empty string SHOULD be used instead, as in interpolations.
|
||||
|
||||
Partial tags SHOULD be treated as standalone when appropriate. If this tag
|
||||
is used standalone, any whitespace preceding the tag should treated as
|
||||
indentation, and prepended to each line of the partial before rendering.
|
||||
tests:
|
||||
|
||||
- name: Nested Partial Indent
|
||||
desc: "Nested partials should including the parent partials indent"
|
||||
data: { content: "<\n->" }
|
||||
template: "|\n {{>partial}}\n|\n"
|
||||
partials:
|
||||
partial: "1\n {{>nest}}\n1\n"
|
||||
nest: "2\n{{{content}}}\n2\n"
|
||||
expected: "|\n 1\n 2\n <\n->\n 2\n 1\n|\n"
|
||||
|
||||
- name: Standalone Indentation
|
||||
desc: Each line of the partial should be indented before rendering.
|
||||
data: { content: "<\n->" }
|
||||
template: |
|
||||
\
|
||||
{{>partial}}
|
||||
/
|
||||
partials:
|
||||
partial: |
|
||||
|
|
||||
{{{content}}}
|
||||
|
|
||||
expected: |
|
||||
\
|
||||
|
|
||||
<
|
||||
->
|
||||
|
|
||||
/
|
||||
Reference in New Issue
Block a user