package com.github.mustachejava;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
import com.fasterxml.jackson.dataformat.yaml.YAMLMapper;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;
import static junit.framework.Assert.assertFalse;
/**
* Specification tests
*/
public class SpecTest {
@Test
public void interpolations() throws IOException {
run(getSpec("interpolation.yml"));
}
@Test
public void sections() throws IOException {
run(getSpec("sections.yml"));
}
@Test
public void delimiters() throws IOException {
run(getSpec("delimiters.yml"));
}
@Test
public void inverted() throws IOException {
run(getSpec("inverted.yml"));
}
@Test
public void partials() throws IOException {
run(getSpec("partials.yml"));
}
@Test
public void lambdas() throws IOException {
run(getSpec("~lambdas.yml"));
}
// @Test — need this to appear in the spec repository to enable
public void inheritance() throws IOException {
run(getSpec("inheritance.yml"));
}
private void run(JsonNode spec) {
int fail = 0;
int success = 0;
int whitespace = 0;
Map<String, Object> functionMap = new HashMap<String, Object>() {{
put("Interpolation", new Object() {
Function lambda() {
return input -> "world";
}
});
put("Interpolation - Expansion", new Object() {
Function lambda() {
return input -> "{{planet}}";
}
});
put("Interpolation - Alternate Delimiters", new Object() {
Function lambda() {
return input -> "|planet| => {{planet}}";
}
});
put("Interpolation - Multiple Calls", new Object() {
int calls = 0;
Function lambda() {
return input -> String.valueOf(++calls);
}
});
put("Escaping", new Object() {
Function lambda() {
return input -> ">";
}
});
put("Section", new Object() {
Function lambda() {
return new TemplateFunction() {
@Override
public String apply(String input) {
return input.equals("{{x}}") ? "yes" : "no";
}
};
}
});
put("Section - Expansion", new Object() {
Function lambda() {
return new TemplateFunction() {
@Override
public String apply(String input) {
return input + "{{planet}}" + input;
}
};
}
});
put("Section - Alternate Delimiters", new Object() {
Function lambda() {
return new TemplateFunction() {
@Override
public String apply(String input) {
return input + "{{planet}} => |planet|" + input;
}
};
}
});
put("Section - Multiple Calls", new Object() {
Function lambda() {
return new Function<String, String>() {
@Override
public String apply(String input) {
return "__" + input + "__";
}
};
}
});
put("Inverted Section", new Object() {
Function lambda() {
return input -> false;
}
});
}};
for (final JsonNode test : spec.get("tests")) {
boolean failed = false;
final DefaultMustacheFactory CF = createMustacheFactory(test);
String file = test.get("name").asText();
System.out.print("Running " + file + " - " + test.get("desc").asText());
StringReader template = new StringReader(test.get("template").asText());
JsonNode data = test.get("data");
try {
Mustache compile = CF.compile(template, file);
StringWriter writer = new StringWriter();
compile.execute(writer, new Object[]{new ObjectMapper().readValue(data.toString(), Map.class), functionMap.get(file)});
String expected = test.get("expected").asText();
if (writer.toString().replaceAll("\\s+", "").equals(expected.replaceAll("\\s+", ""))) {
System.out.print(": success");
if (writer.toString().equals(expected)) {
System.out.println("!");
} else {
whitespace++;
System.out.println(", whitespace differences.");
}
} else {
System.out.println(": failed!");
System.out.println(expected + " != " + writer.toString());
System.out.println(test);
failed = true;
}
} catch (Throwable e) {
System.out.println(": exception");
e.printStackTrace();
System.out.println(test);
failed = true;
}
if (failed) fail++;
else success++;
}
System.out.println("Success: " + success + " Whitespace: " + whitespace + " Fail: " + fail);
assertFalse(fail > 0);
}
protected DefaultMustacheFactory createMustacheFactory(final JsonNode test) {
return new DefaultMustacheFactory("/spec/specs") {
@Override
public Reader getReader(String resourceName) {
JsonNode partial = test.get("partials").get(resourceName);
return new StringReader(partial == null ? "" : partial.asText());
}
};
}
private JsonNode getSpec(String spec) throws IOException {
return new YAMLFactory(new YAMLMapper()).createParser(new InputStreamReader(
SpecTest.class.getResourceAsStream(
"/spec/specs/" + spec))).readValueAsTree();
}
}