Added support for obtaining variable values from fields and methods. Added a

template-local variable fetching cache that avoids reresolving the source of a
variable when it remains monomorphic (e.g. it's always a field of class
Foo.class or always a method named getFoo(), etc.).
This commit is contained in:
Michael Bayne
2010-10-21 19:26:40 +00:00
parent 3eea40d1d4
commit 1e89b87cb0
3 changed files with 227 additions and 45 deletions
@@ -17,57 +17,98 @@ import static org.junit.Assert.*;
public class MustacheTest
{
@Test public void testSimpleVariable () {
test("bar", "{{foo}}", "foo", "bar");
test("bar", "{{foo}}", context("foo", "bar"));
}
@Test public void testFieldVariable () {
test("bar", "{{foo}}", new Object() {
String foo = "bar";
});
}
@Test public void testMethodVariable () {
test("bar", "{{foo}}", new Object() {
String foo () { return "bar"; }
});
}
@Test public void testPropertyVariable () {
test("bar", "{{foo}}", new Object() {
String getFoo () { return "bar"; }
});
}
@Test public void testCallSiteReuse () {
Template tmpl = Mustache.compile("{{foo}}");
Object ctx = new Object() {
String getFoo () { return "bar"; }
};
for (int ii = 0; ii < 50; ii++) {
assertEquals("bar", tmpl.execute(ctx));
}
}
@Test public void testCallSiteChange () {
Template tmpl = Mustache.compile("{{foo}}");
assertEquals("bar", tmpl.execute(new Object() {
String getFoo () { return "bar"; }
}));
assertEquals("bar", tmpl.execute(new Object() {
String foo = "bar";
}));
}
@Test public void testOneShotSection () {
test("baz", "{{#foo}}{{bar}}{{/foo}}", "foo", context("bar", "baz"));
test("baz", "{{#foo}}{{bar}}{{/foo}}", context("foo", context("bar", "baz")));
}
@Test public void testListSection () {
test("bazbif", "{{#foo}}{{bar}}{{/foo}}", "foo",
Arrays.asList(context("bar", "baz"), context("bar", "bif")));
test("bazbif", "{{#foo}}{{bar}}{{/foo}}", context(
"foo", Arrays.asList(context("bar", "baz"), context("bar", "bif"))));
}
@Test public void testArraySection () {
test("bazbif", "{{#foo}}{{bar}}{{/foo}}", "foo",
new Object[] { context("bar", "baz"), context("bar", "bif") });
test("bazbif", "{{#foo}}{{bar}}{{/foo}}",
context("foo", new Object[] {
context("bar", "baz"), context("bar", "bif") }));
}
@Test public void testIteratorSection () {
test("bazbif", "{{#foo}}{{bar}}{{/foo}}", "foo",
Arrays.asList(context("bar", "baz"), context("bar", "bif")).iterator());
test("bazbif", "{{#foo}}{{bar}}{{/foo}}",
context("foo", Arrays.asList(context("bar", "baz"),
context("bar", "bif")).iterator()));
}
@Test public void testEmptyListSection () {
test("", "{{#foo}}{{bar}}{{/foo}}", "foo", Collections.emptyList());
test("", "{{#foo}}{{bar}}{{/foo}}", context("foo", Collections.emptyList()));
}
@Test public void testEmptyArraySection () {
test("", "{{#foo}}{{bar}}{{/foo}}", "foo", new Object[0]);
test("", "{{#foo}}{{bar}}{{/foo}}", context("foo", new Object[0]));
}
@Test public void testEmptyIteratorSection () {
test("", "{{#foo}}{{bar}}{{/foo}}", "foo", Collections.emptyList().iterator());
test("", "{{#foo}}{{bar}}{{/foo}}", context("foo", Collections.emptyList().iterator()));
}
@Test public void testFalseSection () {
test("", "{{#foo}}{{bar}}{{/foo}}", "foo", false);
test("", "{{#foo}}{{bar}}{{/foo}}", context("foo", false));
}
@Test public void testNestedListSection () {
test("1234", "{{#a}}{{#b}}{{c}}{{/b}}{{#d}}{{e}}{{/d}}{{/a}}", "a",
new Object[] { context("b", new Object[] { context("c", "1"), context("c", "2") }),
context("d", new Object[] { context("e", "3"), context("e", "4") }) });
test("1234", "{{#a}}{{#b}}{{c}}{{/b}}{{#d}}{{e}}{{/d}}{{/a}}",
context("a", new Object[] {
context("b", new Object[] { context("c", "1"), context("c", "2") }),
context("d", new Object[] { context("e", "3"), context("e", "4") }) }));
}
@Test public void testComment () {
test("foobar", "foo{{! nothing to see here}}bar");
test("foobar", "foo{{! nothing to see here}}bar", new Object());
}
protected void test (String expected, String template, Object... data)
protected void test (String expected, String template, Object ctx)
{
assertEquals(expected, Mustache.compile(template).execute(context(data)));
assertEquals(expected, Mustache.compile(template).execute(ctx));
}
protected static Object context (Object... data)