package org.stringtemplate.v4.test;
import org.junit.*;
import org.stringtemplate.v4.*;
import org.stringtemplate.v4.misc.STNoSuchPropertyException;
import org.stringtemplate.v4.misc.STRuntimeMessage;
import static org.junit.Assert.assertEquals;
public class TestModelAdaptors extends BaseTest {
static class UserAdaptor implements ModelAdaptor {
@Override
public Object getProperty(Interpreter interp, ST self, Object o, Object property, String propertyName)
throws STNoSuchPropertyException
{
if ( propertyName.equals("id") ) return ((User)o).id;
if ( propertyName.equals("name") ) return ((User)o).getName();
throw new STNoSuchPropertyException(null, o, "User."+propertyName);
}
}
static class UserAdaptorConst implements ModelAdaptor {
@Override
public Object getProperty(Interpreter interp, ST self, Object o, Object property, String propertyName)
throws STNoSuchPropertyException
{
if ( propertyName.equals("id") ) return "const id value";
if ( propertyName.equals("name") ) return "const name value";
throw new STNoSuchPropertyException(null, o, "User."+propertyName);
}
}
static class SuperUser extends User {
int bitmask;
public SuperUser(int id, String name) {
super(id, name);
bitmask = 0x8080;
}
@Override
public String getName() {
return "super "+super.getName();
}
}
@Test public void testSimpleAdaptor() throws Exception {
String templates =
"foo(x) ::= \"<x.id>: <x.name>\"\n";
writeFile(tmpdir, "foo.stg", templates);
STGroup group = new STGroupFile(tmpdir+"/foo.stg");
group.registerModelAdaptor(User.class, new UserAdaptor());
ST st = group.getInstanceOf("foo");
st.add("x", new User(100, "parrt"));
String expecting = "100: parrt";
String result = st.render();
assertEquals(expecting, result);
}
@Test public void testAdaptorAndBadProp() throws Exception {
ErrorBufferAllErrors errors = new ErrorBufferAllErrors();
String templates =
"foo(x) ::= \"<x.qqq>\"\n";
writeFile(tmpdir, "foo.stg", templates);
STGroup group = new STGroupFile(tmpdir+"/foo.stg");
group.setListener(errors);
group.registerModelAdaptor(User.class, new UserAdaptor());
ST st = group.getInstanceOf("foo");
st.add("x", new User(100, "parrt"));
String expecting = "";
String result = st.render();
assertEquals(expecting, result);
STRuntimeMessage msg = (STRuntimeMessage)errors.errors.get(0);
STNoSuchPropertyException e = (STNoSuchPropertyException)msg.cause;
assertEquals("User.qqq", e.propertyName);
}
@Test public void testAdaptorCoversSubclass() throws Exception {
String templates =
"foo(x) ::= \"<x.id>: <x.name>\"\n";
writeFile(tmpdir, "foo.stg", templates);
STGroup group = new STGroupFile(tmpdir+"/foo.stg");
group.registerModelAdaptor(User.class, new UserAdaptor());
ST st = group.getInstanceOf("foo");
st.add("x", new SuperUser(100, "parrt")); // create subclass of User
String expecting = "100: super parrt";
String result = st.render();
assertEquals(expecting, result);
}
@Test public void testWeCanResetAdaptorCacheInvalidatedUponAdaptorReset() throws Exception {
String templates =
"foo(x) ::= \"<x.id>: <x.name>\"\n";
writeFile(tmpdir, "foo.stg", templates);
STGroup group = new STGroupFile(tmpdir+"/foo.stg");
group.registerModelAdaptor(User.class, new UserAdaptor());
group.getModelAdaptor(User.class); // get User, SuperUser into cache
group.getModelAdaptor(SuperUser.class);
group.registerModelAdaptor(User.class, new UserAdaptorConst());
// cache should be reset so we see new adaptor
ST st = group.getInstanceOf("foo");
st.add("x", new User(100, "parrt"));
String expecting = "const id value: const name value"; // sees UserAdaptorConst
String result = st.render();
assertEquals(expecting, result);
}
@Test public void testSeesMostSpecificAdaptor() throws Exception {
String templates =
"foo(x) ::= \"<x.id>: <x.name>\"\n";
writeFile(tmpdir, "foo.stg", templates);
STGroup group = new STGroupFile(tmpdir+"/foo.stg");
group.registerModelAdaptor(User.class, new UserAdaptor());
group.registerModelAdaptor(SuperUser.class, new UserAdaptorConst()); // most specific
ST st = group.getInstanceOf("foo");
st.add("x", new User(100, "parrt"));
String expecting = "100: parrt";
String result = st.render();
assertEquals(expecting, result);
st.remove("x");
st.add("x", new SuperUser(100, "parrt"));
expecting = "const id value: const name value"; // sees UserAdaptorConst
result = st.render();
assertEquals(expecting, result);
}
}