package org.trimou.handlebars;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
import org.junit.Test;
import org.trimou.AbstractTest;
import org.trimou.ExceptionAssert;
import org.trimou.Hammer;
import org.trimou.MustacheExceptionAssert;
import org.trimou.engine.MustacheEngine;
import org.trimou.engine.MustacheEngineBuilder;
import org.trimou.engine.MustacheTagInfo;
import org.trimou.engine.MustacheTagType;
import org.trimou.engine.locator.MapTemplateLocator;
import org.trimou.engine.resolver.AbstractResolver;
import org.trimou.engine.resolver.ResolutionContext;
import org.trimou.exception.MustacheProblem;
import org.trimou.util.ImmutableMap;
/**
*
* @author Martin Kouba
*/
public class OptionsTest extends AbstractTest {
@Test
public void testParametes() {
MustacheEngine engine = MustacheEngineBuilder.newBuilder()
.registerHelper("test", new AbstractHelper() {
@Override
public void execute(Options options) {
List<Object> params = options.getParameters();
assertEquals(3, params.size());
assertEquals("1", params.get(0));
assertEquals(10, params.get(1));
assertNull(params.get(2));
}
}).build();
engine.compileMustache("helper_params",
"{{test \"1\" this.age nonexisting}}").render(new Hammer());
}
@Test
public void testHash() {
MustacheEngine engine = MustacheEngineBuilder.newBuilder()
.registerHelper("test", new AbstractHelper() {
@Override
public void execute(Options options) {
final Map<String, Object> hash = options.getHash();
assertEquals(3, hash.size());
assertEquals("1", hash.get("first"));
assertEquals(10, hash.get("second"));
assertNull(hash.get("third"));
ExceptionAssert
.expect(UnsupportedOperationException.class)
.check(() -> hash.remove("first"));
}
}).build();
engine.compileMustache("helper_params",
"{{test first=\"1\" second=this.age third=nonexisting}}")
.render(new Hammer());
}
@Test
public void testPush() {
MustacheEngine engine = MustacheEngineBuilder.newBuilder()
.registerHelper("test", new AbstractHelper() {
@Override
public void execute(Options options) {
options.push("OK");
options.fn();
}
}).build();
assertEquals("OK|HAMMER",
engine.compileMustache("helper_params",
"{{#test}}{{this}}{{/test}}|{{this}}")
.render(new Hammer()));
}
@Test
public void testPop() {
final MustacheEngine engine = MustacheEngineBuilder.newBuilder()
.registerHelper("test", new AbstractHelper() {
@Override
public void execute(Options options) {
options.pop();
}
}).build();
MustacheExceptionAssert
.expect(MustacheProblem.RENDER_HELPER_INVALID_POP_OPERATION)
.check(() -> engine.compileMustache("helper_params", "{{test}}")
.render(new Hammer()));
}
@Test
public void testPartial() {
final MustacheEngine engine = MustacheEngineBuilder.newBuilder()
.addTemplateLocator(new MapTemplateLocator(
ImmutableMap.of("foo", "{{this}}")))
.registerHelper("test", new AbstractHelper() {
@Override
public void execute(Options options) {
options.partial(
options.getParameters().get(0).toString());
}
}).build();
assertEquals("HELLO",
engine.compileMustache("helper_partial01", "{{test 'foo'}}")
.render("HELLO"));
MustacheExceptionAssert
.expect(MustacheProblem.RENDER_INVALID_PARTIAL_KEY)
.check(() -> engine
.compileMustache("helper_partial02", "{{test 'bar'}}")
.render("HELLO"));
}
@Test
public void testPeek() {
MustacheEngine engine = MustacheEngineBuilder.newBuilder()
.registerHelper("test", new AbstractHelper() {
@Override
public void execute(Options options) {
options.append(options.peek().toString());
}
}).build();
assertEquals("HELLO", engine.compileMustache("helper_peek", "{{test}}")
.render("HELLO"));
}
@Test
public void testGetAppendable() {
MustacheEngine engine = MustacheEngineBuilder.newBuilder()
.registerHelper("test", new AbstractHelper() {
@Override
public void execute(Options options) {
try {
options.getAppendable()
.append(options.peek().toString());
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}).build();
assertEquals("HELLO",
engine.compileMustache("helper_getappendable", "{{test}}")
.render("HELLO"));
}
@Test
public void testGetContentLiteralBlock() {
final StringBuilder builder = new StringBuilder();
MustacheEngine engine = MustacheEngineBuilder.newBuilder()
.registerHelper("test", new AbstractHelper() {
@Override
public void execute(Options options) {
builder.append(options.getContentLiteralBlock());
}
}).build();
String literal = "This is /n a {{foo bar='ok'}}{{#each this}}{{.}}{{/each}}/n/n {{join 'foo' 'bar' delimiter=' : '}}";
engine.compileMustache("helper_getcontentliteralblock",
"{{#test}}" + literal + "{{/test}}").render(null);
assertEquals(literal, builder.toString());
}
@Test
public void testGetTagInfo() {
final AtomicReference<MustacheTagInfo> reference = new AtomicReference<>();
MustacheEngine engine = MustacheEngineBuilder.newBuilder()
.registerHelper("test", new AbstractHelper() {
@Override
public void execute(Options options) {
reference.set(options.getTagInfo());
}
}).build();
engine.compileMustache("helper_gettaginfo",
"{{#test}}This is {{foo}} and {{^bar}}{{/bar}}{{/test}}")
.render(null);
assertEquals(MustacheTagType.SECTION, reference.get().getType());
assertEquals("test", reference.get().getText());
List<MustacheTagInfo> children = reference.get().getChildTags();
assertEquals(2, children.size());
assertEquals(MustacheTagType.VARIABLE,
reference.get().getChildTags().get(0).getType());
assertEquals(MustacheTagType.INVERTED_SECTION,
reference.get().getChildTags().get(1).getType());
}
@Test
public void testFnAppendable() {
final StringBuilder builder = new StringBuilder();
MustacheEngine engine = MustacheEngineBuilder.newBuilder()
.registerHelper("test", new AbstractHelper() {
@Override
public void execute(Options options) {
options.fn(builder);
}
}).build();
String literal = "This is /n a foo";
assertEquals(
"", engine
.compileMustache("helper_fnappendable",
"{{#test}}" + literal + "{{/test}}")
.render(null));
assertEquals(literal, builder.toString());
}
@Test
public void testGetValue() {
final AtomicBoolean released = new AtomicBoolean(false);
MustacheEngine engine = MustacheEngineBuilder.newBuilder()
.omitServiceLoaderConfigurationExtensions()
.addResolver(new AbstractResolver(1) {
@Override
public Object resolve(Object contextObject, String name,
ResolutionContext context) {
context.registerReleaseCallback(
() -> released.set(true));
return "foo";
}
}).registerHelper("test", new AbstractHelper() {
@Override
public void execute(Options options) {
options.append(options.getValue("key").toString());
}
}).build();
assertEquals("foo", engine
.compileMustache("helper_getvalue", "{{test}}").render("bar"));
assertTrue(released.get());
}
@Test
public void testAsyncExecution() {
MustacheEngine engine = MustacheEngineBuilder.newBuilder()
.setExecutorService(Executors.newFixedThreadPool(
Runtime.getRuntime().availableProcessors()))
.omitServiceLoaderConfigurationExtensions()
.registerHelper("async", new AbstractHelper() {
@Override
public void execute(Options options) {
options.executeAsync(o -> {
try {
Thread.sleep(50);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
o.append("done");
});
}
}).build();
assertEquals("done my friend",
engine.compileMustache("helper_asynexec", "{{async}} my friend")
.render("bar"));
}
@Test
public void testSource() {
final MustacheEngine engine = MustacheEngineBuilder.newBuilder()
.addTemplateLocator(new MapTemplateLocator(
ImmutableMap.of("foo", "{{this}}")))
.registerHelper("test", new AbstractHelper() {
@Override
public void execute(Options options) {
append(options, options.source(
options.getParameters().get(0).toString()));
}
}).build();
assertEquals("{{this}}",
engine.compileMustache("helper_source01", "{{test 'foo'}}")
.render(null));
MustacheExceptionAssert
.expect(MustacheProblem.RENDER_INVALID_PARTIAL_KEY)
.check(() -> engine
.compileMustache("helper_source02", "{{test 'bar'}}")
.render(null));
}
}