package org.jooby.jade;
import static org.easymock.EasyMock.eq;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.isA;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.fail;
import java.io.FileNotFoundException;
import java.io.Reader;
import java.util.HashMap;
import java.util.Map;
import org.jooby.Env;
import org.jooby.Renderer;
import org.jooby.test.MockUnit;
import org.jooby.test.MockUnit.Block;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import com.google.inject.Binder;
import com.google.inject.binder.AnnotatedBindingBuilder;
import com.google.inject.binder.LinkedBindingBuilder;
import com.google.inject.multibindings.Multibinder;
import com.typesafe.config.Config;
import de.neuland.jade4j.JadeConfiguration;
import de.neuland.jade4j.template.ClasspathTemplateLoader;
import de.neuland.jade4j.template.TemplateLoader;
@RunWith(PowerMockRunner.class)
@PrepareForTest({Jade.class, JadeConfiguration.class, Multibinder.class, HashMap.class })
public class JadeTest {
@Test
public void defaults() throws Exception {
new MockUnit(Env.class, Config.class, Binder.class)
.expect(env("dev"))
.expect(conf(".jade", false, false))
.expect(jade(".jade", false, true))
.run(unit -> {
new Jade()
.configure(unit.get(Env.class), unit.get(Config.class), unit.get(Binder.class));
});
}
@Test
public void testConfigurableSuffix() throws Exception {
new MockUnit(Env.class, Config.class, Binder.class)
.expect(env("dev"))
.expect(conf(".html", false, false))
.expect(jade(".html", false, true))
.run(unit -> {
new Jade(".html")
.configure(unit.get(Env.class), unit.get(Config.class), unit.get(Binder.class));
});
}
@Test
public void testCachingOn() throws Exception {
new MockUnit(Env.class, Config.class, Binder.class)
.expect(env("prod"))
.expect(conf(".jade", true, false))
.expect(jade(".jade", true, false))
.run(unit -> {
new Jade()
.configure(unit.get(Env.class), unit.get(Config.class), unit.get(Binder.class));
});
}
@Test
public void testCachingOnInProduction() throws Exception {
new MockUnit(Env.class, Config.class, Binder.class)
.expect(env("prod"))
.expect(conf(".jade", false, false))
.expect(jade(".jade", true, false))
.run(unit -> {
new Jade()
.configure(unit.get(Env.class), unit.get(Config.class), unit.get(Binder.class));
});
}
@Test
public void testPrettyPrinting() throws Exception {
new MockUnit(Env.class, Config.class, Binder.class)
.expect(env("dev"))
.expect(conf(".jade", false, true))
.expect(unit -> {
Config config = unit.get(Config.class);
expect(config.getBoolean("jade.prettyprint")).andReturn(true);
})
.expect(jade(".jade", false, true))
.run(unit -> {
new Jade()
.configure(unit.get(Env.class), unit.get(Config.class), unit.get(Binder.class));
});
}
@Test
public void doWith() throws Exception {
new MockUnit(Env.class, Config.class, Binder.class)
.expect(env("dev"))
.expect(conf(".jade", false, false))
.expect(jade(".jade", false, true))
.run(unit -> {
new Jade()
.doWith(jade -> assertNotNull(jade))
.configure(unit.get(Env.class), unit.get(Config.class), unit.get(Binder.class));
});
}
@Test
public void safeTemplateLoader() throws Exception {
new MockUnit(TemplateLoader.class, Reader.class)
.expect(unit -> {
TemplateLoader tl = unit.get(TemplateLoader.class);
expect(tl.getLastModified("x")).andReturn(678L);
expect(tl.getReader("foo")).andReturn(unit.get(Reader.class));
expect(tl.getReader("fnf")).andThrow(new NullPointerException());
})
.run(unit -> {
TemplateLoader tl = new Jade.IOTemplateLoader(unit.get(TemplateLoader.class));
assertEquals(678L, tl.getLastModified("x"));
assertEquals(unit.get(Reader.class), tl.getReader("foo"));
try {
assertEquals(unit.get(Reader.class), tl.getReader("fnf"));
fail("expecting fnf");
} catch (FileNotFoundException x) {
}
});
}
@SuppressWarnings("unchecked")
private Block jade(final String suffix, final boolean caching, final boolean prettyPrint) {
return unit -> {
JadeConfiguration jadeConfiguration = unit.mockConstructor(JadeConfiguration.class);
jadeConfiguration.setCaching(caching);
jadeConfiguration.setPrettyPrint(prettyPrint);
Env env = unit.get(Env.class);
Map<String, Object> sharedVariables = unit.constructor(HashMap.class)
.build(2);
expect(sharedVariables.put(eq( "env"), eq(env))).andReturn(null);
expect(sharedVariables.put(eq( "xss"), isA(XssHelper.class))).andReturn(null);
jadeConfiguration.setSharedVariables(sharedVariables);
ClasspathTemplateLoader classpathTemplateLoader = unit
.mockConstructor(ClasspathTemplateLoader.class);
jadeConfiguration.setTemplateLoader(classpathTemplateLoader);
expect(jadeConfiguration.getTemplateLoader()).andReturn(classpathTemplateLoader);
Jade.IOTemplateLoader safetl = unit
.constructor(Jade.IOTemplateLoader.class)
.build(classpathTemplateLoader);
jadeConfiguration.setTemplateLoader(safetl);
AnnotatedBindingBuilder<JadeConfiguration> configBB = unit
.mock(AnnotatedBindingBuilder.class);
configBB.toInstance(jadeConfiguration);
Binder binder = unit.get(Binder.class);
expect(binder.bind(JadeConfiguration.class)).andReturn(configBB);
Engine engine = unit.mockConstructor(
Engine.class, new Class[]{JadeConfiguration.class, String.class },
jadeConfiguration, suffix);
LinkedBindingBuilder<Renderer> ffLBB = unit.mock(LinkedBindingBuilder.class);
ffLBB.toInstance(engine);
Multibinder<Renderer> formatter = unit.mock(Multibinder.class);
expect(formatter.addBinding()).andReturn(ffLBB);
unit.mockStatic(Multibinder.class);
expect(Multibinder.newSetBinder(binder, Renderer.class)).andReturn(formatter);
};
}
private Block env(final String name) {
return unit -> {
Env env = unit.get(Env.class);
expect(env.name()).andReturn(name);
};
}
private Block conf(final String suffix, final boolean caching, final boolean prettyprint) {
return unit -> {
Config config = unit.get(Config.class);
expect(config.hasPath("jade.caching")).andReturn(caching);
if (caching) {
expect(config.getBoolean("jade.caching")).andReturn(caching);
}
expect(config.hasPath("jade.prettyprint")).andReturn(prettyprint);
};
}
}