Fixed bug where -last was not correctly handled on lists of a single element,

where said element is both -first and -last.
This commit is contained in:
Michael Bayne
2011-08-29 13:51:11 -07:00
parent 28978548c5
commit a3eb9e22e1
3 changed files with 22 additions and 18 deletions
@@ -571,13 +571,11 @@ public class Mustache
value = ((Iterable<?>)value).iterator(); value = ((Iterable<?>)value).iterator();
} }
if (value instanceof Iterator<?>) { if (value instanceof Iterator<?>) {
Template.Mode mode = null;
int index = 0; int index = 0;
for (Iterator<?> iter = (Iterator<?>)value; iter.hasNext(); ) { for (Iterator<?> iter = (Iterator<?>)value; iter.hasNext(); ) {
Object elem = iter.next(); Object elem = iter.next();
mode = (mode == null) ? Template.Mode.FIRST : boolean onFirst = (index == 0), onLast = !iter.hasNext();
(iter.hasNext() ? Template.Mode.OTHER : Template.Mode.LAST); executeSegs(tmpl, ctx.nest(elem, ++index, onFirst, onLast), out);
executeSegs(tmpl, ctx.nest(elem, ++index, mode), out);
} }
} else if (value instanceof Boolean) { } else if (value instanceof Boolean) {
if ((Boolean)value) { if ((Boolean)value) {
@@ -585,12 +583,11 @@ public class Mustache
} }
} else if (value.getClass().isArray()) { } else if (value.getClass().isArray()) {
for (int ii = 0, ll = Array.getLength(value); ii < ll; ii++) { for (int ii = 0, ll = Array.getLength(value); ii < ll; ii++) {
Template.Mode mode = (ii == 0) ? Template.Mode.FIRST : boolean onFirst = (ii == 0), onLast = (ii == ll-1);
((ii == ll-1) ? Template.Mode.LAST : Template.Mode.OTHER); executeSegs(tmpl, ctx.nest(Array.get(value, ii), ii+1, onFirst, onLast), out);
executeSegs(tmpl, ctx.nest(Array.get(value, ii), ii+1, mode), out);
} }
} else { } else {
executeSegs(tmpl, ctx.nest(value, 0, Template.Mode.OTHER), out); executeSegs(tmpl, ctx.nest(value, 0, false, false), out);
} }
} }
} }
@@ -55,7 +55,7 @@ public class Template
*/ */
public void execute (Object context, Writer out) throws MustacheException public void execute (Object context, Writer out) throws MustacheException
{ {
executeSegs(new Context(context, null, 0, Mode.OTHER), out); executeSegs(new Context(context, null, 0, false, false), out);
} }
protected Template (Segment[] segs, Mustache.Compiler compiler) protected Template (Segment[] segs, Mustache.Compiler compiler)
@@ -113,9 +113,9 @@ public class Template
// handle our special variables // handle our special variables
if (name == FIRST_NAME) { if (name == FIRST_NAME) {
return ctx.mode == Mode.FIRST; return ctx.onFirst;
} else if (name == LAST_NAME) { } else if (name == LAST_NAME) {
return ctx.mode == Mode.LAST; return ctx.onLast;
} else if (name == INDEX_NAME) { } else if (name == INDEX_NAME) {
return ctx.index; return ctx.index;
} }
@@ -313,24 +313,24 @@ public class Template
return null; return null;
} }
protected static enum Mode { FIRST, OTHER, LAST };
protected static class Context protected static class Context
{ {
public final Object data; public final Object data;
public final Context parent; public final Context parent;
public final int index; public final int index;
public final Mode mode; public final boolean onFirst;
public final boolean onLast;
public Context (Object data, Context parent, int index, Mode mode) { public Context (Object data, Context parent, int index, boolean onFirst, boolean onLast) {
this.data = data; this.data = data;
this.parent = parent; this.parent = parent;
this.index = index; this.index = index;
this.mode = mode; this.onFirst = onFirst;
this.onLast = onLast;
} }
public Context nest (Object data, int index, Mode mode) { public Context nest (Object data, int index, boolean onFirst, boolean onLast) {
return new Context(data, this, index, mode); return new Context(data, this, index, onFirst, onLast);
} }
} }
@@ -329,6 +329,13 @@ public class MustacheTest
context("things", Arrays.asList("foo", "bar", "baz"))); context("things", Arrays.asList("foo", "bar", "baz")));
} }
@Test public void testFirstLast () {
test("[foo]", "{{#things}}{{#-first}}[{{/-first}}{{this}}{{#-last}}]{{/-last}}{{/things}}",
context("things", Arrays.asList("foo")));
test("foo", "{{#things}}{{this}}{{^-last}}|{{/-last}}{{/things}}",
context("things", Arrays.asList("foo")));
}
@Test public void testIndex () { @Test public void testIndex () {
test("123", "{{#things}}{{-index}}{{/things}}", test("123", "{{#things}}{{-index}}{{/things}}",
context("things", Arrays.asList("foo", "bar", "baz"))); context("things", Arrays.asList("foo", "bar", "baz")));