package com.github.mustachejava;
import com.github.mustachejava.reflect.ReflectionObjectHandler;
import org.junit.Test;
import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
import java.lang.reflect.Array;
import java.util.AbstractMap;
import java.util.Iterator;
import java.util.Set;
import static org.junit.Assert.assertEquals;
/**
* Shows a simple way to add indexes for arrays.
* <p/>
* User: sam
* Date: 4/7/13
* Time: 11:12 AM
*/
public class ArraysIndexesTest {
@Test
public void testArrayIndexExtension() throws IOException {
String template = "<ol>\n" +
" <li>{{test.1}}</li>\n" +
" <li>{{test.0}}</li>\n" +
" <li>{{test.3}}</li>\n" +
"</ol>\n" +
"<ol>\n" +
"{{#test}}\n" +
" <li>{{.}}</li>\n" +
"{{/test}}\n" +
"</ol>";
String result = "<ol>\n" +
" <li>1</li>\n" +
" <li>0</li>\n" +
" <li>3</li>\n" +
"</ol>\n" +
"<ol>\n" +
" <li>0</li>\n" +
" <li>1</li>\n" +
" <li>2</li>\n" +
" <li>3</li>\n" +
"</ol>";
Object scope = new Object() {
int[] test = { 0, 1, 2, 3 };
};
ReflectionObjectHandler oh = new ReflectionObjectHandler() {
@Override
public Object coerce(final Object object) {
if (object != null && object.getClass().isArray()) {
return new ArrayMap(object);
}
return super.coerce(object);
}
};
DefaultMustacheFactory mf = new DefaultMustacheFactory();
mf.setObjectHandler(oh);
Mustache m = mf.compile(new StringReader(template), "template");
StringWriter writer = new StringWriter();
m.execute(writer, scope).flush();
assertEquals(result, writer.toString());
}
private static class ArrayMap extends AbstractMap<Object, Object> implements Iterable<Object> {
private final Object object;
public ArrayMap(Object object) {
this.object = object;
}
@Override
public Object get(Object key) {
try {
int index = Integer.parseInt(key.toString());
return Array.get(object, index);
} catch (NumberFormatException nfe) {
return null;
}
}
@Override
public boolean containsKey(Object key) {
return get(key) != null;
}
@Override
public Set<Entry<Object, Object>> entrySet() {
throw new UnsupportedOperationException();
}
/**
* Returns an iterator over a set of elements of type T.
*
* @return an Iterator.
*/
@Override
public Iterator<Object> iterator() {
return new Iterator<Object>() {
int index = 0;
int length = Array.getLength(object);
@Override
public boolean hasNext() {
return index < length;
}
@Override
public Object next() {
return Array.get(object, index++);
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
};
}
}
}