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