From 2889ee8692d04703f4f0f2de8748815c1f2dbf79 Mon Sep 17 00:00:00 2001 From: Yoryos Valotasios Date: Tue, 5 Mar 2013 21:54:29 +0100 Subject: [PATCH] Added standard Mustache specs tests suite. The groups with failing tests are currently commented out (everything except interpolation). The main reason for failures are due to the requirement that standalone lines that contain nothing but whitespace be stripped from the output. --- .gitmodules | 3 + pom.xml | 6 ++ .../com/samskivert/mustache/Template.java | 1 - .../com/samskivert/mustache/specs/Spec.java | 47 ++++++++++ .../specs/SpecAwareTemplateLoader.java | 26 ++++++ .../mustache/specs/SpecFrameworkTest.java | 33 +++++++ .../samskivert/mustache/specs/SpecRunner.java | 91 +++++++++++++++++++ .../samskivert/mustache/specs/SpecTest.java | 39 ++++++++ src/test/resources/specs | 1 + 9 files changed, 246 insertions(+), 1 deletion(-) create mode 100644 .gitmodules create mode 100644 src/test/java/com/samskivert/mustache/specs/Spec.java create mode 100644 src/test/java/com/samskivert/mustache/specs/SpecAwareTemplateLoader.java create mode 100644 src/test/java/com/samskivert/mustache/specs/SpecFrameworkTest.java create mode 100644 src/test/java/com/samskivert/mustache/specs/SpecRunner.java create mode 100644 src/test/java/com/samskivert/mustache/specs/SpecTest.java create mode 160000 src/test/resources/specs diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..bd84223 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "src/test/resources/specs"] + path = src/test/resources/specs + url = git://github.com/mustache/spec.git diff --git a/pom.xml b/pom.xml index dbbe8e1..f56d303 100644 --- a/pom.xml +++ b/pom.xml @@ -54,6 +54,12 @@ 4.8.1 test + + org.yaml + snakeyaml + 1.11 + test + diff --git a/src/main/java/com/samskivert/mustache/Template.java b/src/main/java/com/samskivert/mustache/Template.java index c5c4186..637335a 100644 --- a/src/main/java/com/samskivert/mustache/Template.java +++ b/src/main/java/com/samskivert/mustache/Template.java @@ -8,7 +8,6 @@ import java.io.IOException; import java.io.StringWriter; import java.io.Writer; import java.util.Collections; -import java.util.HashMap; import java.util.Iterator; import java.util.Map; diff --git a/src/test/java/com/samskivert/mustache/specs/Spec.java b/src/test/java/com/samskivert/mustache/specs/Spec.java new file mode 100644 index 0000000..eb548fb --- /dev/null +++ b/src/test/java/com/samskivert/mustache/specs/Spec.java @@ -0,0 +1,47 @@ +// +// JMustache - A Java implementation of the Mustache templating language +// http://github.com/samskivert/jmustache/blob/master/LICENSE + +package com.samskivert.mustache.specs; + +import java.util.Map; + +/** + * @author Yoryos Valotasios + */ +public class Spec +{ + private final Map map; + private final Map partials; + + public Spec (Map map) { + this.map = map; + @SuppressWarnings("unchecked") Map partials = + (Map) map.get("partials"); + this.partials = partials; + } + + public String getName () { + return (String) map.get("name"); + } + + public String getDescription () { + return (String) map.get("descr"); + } + + public String getTemplate () { + return (String) map.get("template"); + } + + public String getExpectedOutput () { + return (String) map.get("expected"); + } + + public Object getData () { + return map.get("data"); + } + + public String getPartial (String name) { + return partials == null ? null : partials.get(name); + } +} diff --git a/src/test/java/com/samskivert/mustache/specs/SpecAwareTemplateLoader.java b/src/test/java/com/samskivert/mustache/specs/SpecAwareTemplateLoader.java new file mode 100644 index 0000000..2e01f13 --- /dev/null +++ b/src/test/java/com/samskivert/mustache/specs/SpecAwareTemplateLoader.java @@ -0,0 +1,26 @@ +// +// JMustache - A Java implementation of the Mustache templating language +// http://github.com/samskivert/jmustache/blob/master/LICENSE + +package com.samskivert.mustache.specs; + +import java.io.Reader; +import java.io.StringReader; + +import com.samskivert.mustache.Mustache; + +public class SpecAwareTemplateLoader implements Mustache.TemplateLoader +{ + private static final String EMPTY_STRING = ""; + private Spec spec; + + public void setSpec (Spec spec) { + this.spec = spec; + } + + @Override public Reader getTemplate (String name) throws Exception { + if (spec == null) return new StringReader(EMPTY_STRING); + String partial = spec.getPartial(name); + return new StringReader(partial == null ? EMPTY_STRING : partial); + } +} diff --git a/src/test/java/com/samskivert/mustache/specs/SpecFrameworkTest.java b/src/test/java/com/samskivert/mustache/specs/SpecFrameworkTest.java new file mode 100644 index 0000000..824eda7 --- /dev/null +++ b/src/test/java/com/samskivert/mustache/specs/SpecFrameworkTest.java @@ -0,0 +1,33 @@ +// +// JMustache - A Java implementation of the Mustache templating language +// http://github.com/samskivert/jmustache/blob/master/LICENSE + +package com.samskivert.mustache.specs; + +import java.lang.reflect.Method; +import org.junit.runners.model.FrameworkMethod; + +/** + * @author Yoryos Valotasios + */ +public class SpecFrameworkTest extends FrameworkMethod +{ + private final String group; + private final Spec spec; + + public SpecFrameworkTest (Method method, String group, Spec spec) { + super(method); + this.group = group; + this.spec = spec; + } + + @Override + public Object invokeExplosively (Object target, Object... params) throws Throwable { + return super.invokeExplosively(target, spec); + } + + @Override + public String getName () { + return group + ": " + spec.getName(); + } +} diff --git a/src/test/java/com/samskivert/mustache/specs/SpecRunner.java b/src/test/java/com/samskivert/mustache/specs/SpecRunner.java new file mode 100644 index 0000000..db60a8a --- /dev/null +++ b/src/test/java/com/samskivert/mustache/specs/SpecRunner.java @@ -0,0 +1,91 @@ +// +// JMustache - A Java implementation of the Mustache templating language +// http://github.com/samskivert/jmustache/blob/master/LICENSE + +package com.samskivert.mustache.specs; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.Map; + +import org.junit.After; +import org.junit.Before; +import org.junit.runners.BlockJUnit4ClassRunner; +import org.junit.runners.model.FrameworkMethod; +import org.junit.runners.model.InitializationError; + +import org.yaml.snakeyaml.Yaml; + +/** + * @author Yoryos Valotasios + */ +public class SpecRunner extends BlockJUnit4ClassRunner +{ + private final Yaml yaml = new Yaml(); + private final List tests; + + public SpecRunner (Class klass) throws InitializationError { + super(klass); + if (klass != SpecTest.class) throw new IllegalArgumentException( + SpecRunner.class.getSimpleName() + " should only be used with classes of type " + + SpecTest.class.getName()); + this.tests = computeTests(); + } + + @Override + protected List computeTestMethods () { + return tests; + } + + @Override + protected void validateInstanceMethods (List errors) { + validatePublicVoidNoArgMethods(After.class, false, errors); + validatePublicVoidNoArgMethods(Before.class, false, errors); + validateTestMethods(errors); + } + + private List computeTests () throws InitializationError { + String[] groups = new String[] { + // "comments", + // "delimiters", + "interpolation", + // "inverted", + // "sections", + // "partials" + }; + Method m = getTestClassMethod("test", Spec.class); + List tests = new ArrayList(); + for (String name : groups) { + for (Map test: getTestsForGroup(name)) { + tests.add(new SpecFrameworkTest(m, name, new Spec(test))); + } + } + return tests; + } + + private Method getTestClassMethod (String name, Class... paramTypes) + throws InitializationError { + try { + return getTestClass().getJavaClass().getDeclaredMethod(name, paramTypes); + } catch (NoSuchMethodException ex) { + throw new InitializationError("Could not find " + name + " " + + getTestClass().getJavaClass()); + } catch (SecurityException ex) { + throw new InitializationError("Could not find " + name + " " + + getTestClass().getJavaClass()); + } + } + + private Iterable> getTestsForGroup (String name) { + @SuppressWarnings("unchecked") Map map = (Map) + yaml.load(getClass().getResourceAsStream("/specs/specs/" + name + ".yml")); + @SuppressWarnings("unchecked") List> tests = (List>) + map.get("tests"); + return tests; + } +} diff --git a/src/test/java/com/samskivert/mustache/specs/SpecTest.java b/src/test/java/com/samskivert/mustache/specs/SpecTest.java new file mode 100644 index 0000000..04968df --- /dev/null +++ b/src/test/java/com/samskivert/mustache/specs/SpecTest.java @@ -0,0 +1,39 @@ +// +// JMustache - A Java implementation of the Mustache templating language +// http://github.com/samskivert/jmustache/blob/master/LICENSE + +package com.samskivert.mustache.specs; + +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.runner.RunWith; + +import com.samskivert.mustache.Mustache; +import com.samskivert.mustache.Template; + +/** + * @author Yoryos Valotasios + */ +@RunWith(SpecRunner.class) +public class SpecTest +{ + private static Mustache.Compiler compiler; + private static SpecAwareTemplateLoader loader; + + @BeforeClass + public static void setUp () { + loader = new SpecAwareTemplateLoader(); + compiler = Mustache.compiler().defaultValue("").withLoader(loader); + } + + public void test (Spec spec) { + loader.setSpec(spec); + String tmpl = spec.getTemplate(); + Template t = compiler.compile(spec.getTemplate()); + String out = t.execute(spec.getData()); + Assert.assertEquals(String.format("When rendering '''%s''' with '%s'", + tmpl.replaceAll("\n", "\\\\n"), + spec.getData().toString().replaceAll("\n", "\\\\n")), + spec.getExpectedOutput(), out); + } +} diff --git a/src/test/resources/specs b/src/test/resources/specs new file mode 160000 index 0000000..72233f3 --- /dev/null +++ b/src/test/resources/specs @@ -0,0 +1 @@ +Subproject commit 72233f3ffda9e33915fd3022d0a9ebbcce265acd