package org.jooby.pebble; import static org.easymock.EasyMock.expect; import static org.easymock.EasyMock.isA; import static org.junit.Assert.assertNotNull; import java.util.Locale; import java.util.concurrent.CountDownLatch; 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.common.cache.Cache; import com.google.common.cache.CacheBuilder; 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.mitchellbosecke.pebble.PebbleEngine; import com.mitchellbosecke.pebble.cache.BaseTagCacheKey; import com.mitchellbosecke.pebble.loader.ClasspathLoader; import com.mitchellbosecke.pebble.template.PebbleTemplate; import com.typesafe.config.Config; @RunWith(PowerMockRunner.class) @PrepareForTest({Pebble.class, PebbleEngine.Builder.class, ClasspathLoader.class, Multibinder.class, CacheBuilder.class }) public class PebbleTest { private Block newEngine = unit -> { PebbleEngine.Builder pebble = unit.constructor(PebbleEngine.Builder.class) .build(); expect(pebble.cacheActive(true)).andReturn(pebble); expect(pebble.loader(unit.get(ClasspathLoader.class))).andReturn(pebble); expect(pebble.extension(isA(XssExt.class))).andReturn(pebble); unit.registerMock(PebbleEngine.Builder.class, pebble); }; private Block defLoader = unit -> { ClasspathLoader loader = unit.constructor(ClasspathLoader.class).build(); loader.setPrefix(null); loader.setSuffix(".html"); unit.registerMock(ClasspathLoader.class, loader); }; private Block build = unit -> { PebbleEngine.Builder pebble = unit.get(PebbleEngine.Builder.class); expect(pebble.build()).andReturn(unit.get(PebbleEngine.class)); }; @SuppressWarnings("unchecked") private Block bindEngine = unit -> { AnnotatedBindingBuilder<PebbleEngine> peABB = unit.mock(AnnotatedBindingBuilder.class); peABB.toInstance(unit.get(PebbleEngine.class)); Binder binder = unit.get(Binder.class); expect(binder.bind(PebbleEngine.class)).andReturn(peABB); }; @SuppressWarnings("unchecked") private Block renderer = unit -> { PebbleRenderer renderer = unit.constructor(PebbleRenderer.class) .args(PebbleEngine.class) .build(unit.get(PebbleEngine.class)); unit.mockStatic(Multibinder.class); LinkedBindingBuilder<Renderer> rLBB = unit.mock(LinkedBindingBuilder.class); rLBB.toInstance(renderer); Multibinder<Renderer> rmb = unit.mock(Multibinder.class); expect(rmb.addBinding()).andReturn(rLBB); expect(Multibinder.newSetBinder(unit.get(Binder.class), Renderer.class)).andReturn(rmb); }; private Block cacheStatic = unit -> { unit.mockStatic(CacheBuilder.class); }; @Test public void basic() throws Exception { Locale locale = Locale.getDefault(); new MockUnit(Env.class, Config.class, Binder.class, PebbleEngine.class) .expect(defLoader) .expect(newEngine) .expect(env("dev", locale)) .expect(cacheStatic) .expect(cache("pebble.cache", null)) .expect(cache(0)) .expect(cache("pebble.tagCache", null)) .expect(tagCache(0)) .expect(locale(locale)) .expect(build) .expect(bindEngine) .expect(renderer) .run(unit -> { new Pebble() .configure(unit.get(Env.class), unit.get(Config.class), unit.get(Binder.class)); }); } @Test public void proddef() throws Exception { Locale locale = Locale.getDefault(); new MockUnit(Env.class, Config.class, Binder.class, PebbleEngine.class) .expect(defLoader) .expect(newEngine) .expect(env("prod", locale)) .expect(cacheStatic) .expect(cache("pebble.cache", null)) .expect(cache(100)) .expect(cache("pebble.tagCache", null)) .expect(tagCache(100)) .expect(locale(locale)) .expect(build) .expect(bindEngine) .expect(renderer) .run(unit -> { new Pebble() .configure(unit.get(Env.class), unit.get(Config.class), unit.get(Binder.class)); }); } @Test public void doWithFull() throws Exception { Locale locale = Locale.getDefault(); CountDownLatch latch = new CountDownLatch(1); new MockUnit(Env.class, Config.class, Binder.class, PebbleEngine.class) .expect(defLoader) .expect(newEngine) .expect(env("dev", locale)) .expect(cacheStatic) .expect(cache("pebble.cache", null)) .expect(cache(0)) .expect(cache("pebble.tagCache", null)) .expect(tagCache(0)) .expect(locale(locale)) .expect(build) .expect(bindEngine) .expect(renderer) .run(unit -> { new Pebble(".html").doWith((b, c) -> { assertNotNull(b); assertNotNull(c); latch.countDown(); }) .configure(unit.get(Env.class), unit.get(Config.class), unit.get(Binder.class)); }); latch.await(); } @Test public void doWith1() throws Exception { Locale locale = Locale.getDefault(); CountDownLatch latch = new CountDownLatch(1); new MockUnit(Env.class, Config.class, Binder.class, PebbleEngine.class) .expect(defLoader) .expect(newEngine) .expect(env("dev", locale)) .expect(cacheStatic) .expect(cache("pebble.cache", null)) .expect(cache(0)) .expect(cache("pebble.tagCache", null)) .expect(tagCache(0)) .expect(locale(locale)) .expect(build) .expect(bindEngine) .expect(renderer) .run(unit -> { new Pebble().doWith(b -> { assertNotNull(b); latch.countDown(); }) .configure(unit.get(Env.class), unit.get(Config.class), unit.get(Binder.class)); }); latch.await(); } @SuppressWarnings({"unchecked", "rawtypes" }) @Test public void prod() throws Exception { Locale locale = Locale.getDefault(); new MockUnit(Env.class, Config.class, Binder.class, PebbleEngine.class) .expect(defLoader) .expect(newEngine) .expect(env("prod", locale)) .expect(cache("pebble.cache", "maximumSize=200")) .expect(cacheStatic) .expect(cacheBuilder(200)) .expect(cache("pebble.tagCache", "maximumSize=100")) .expect(unit -> { Cache<BaseTagCacheKey, Object> cache = unit.mock(Cache.class); CacheBuilder cachebuilder = unit.mock(CacheBuilder.class); expect(CacheBuilder.from("maximumSize=100")).andReturn(cachebuilder); expect(cachebuilder.build()).andReturn(cache); PebbleEngine.Builder pebble = unit.get(PebbleEngine.Builder.class); expect(pebble.tagCache(cache)).andReturn(pebble); }) .expect(locale(locale)) .expect(build) .expect(bindEngine) .expect(renderer) .run(unit -> { new Pebble() .configure(unit.get(Env.class), unit.get(Config.class), unit.get(Binder.class)); }); } @SuppressWarnings({"unchecked", "rawtypes" }) private Block cacheBuilder(final int maxSize) { return unit -> { Cache<Object, PebbleTemplate> cache = unit.mock(Cache.class); unit.registerMock(Cache.class, cache); CacheBuilder cachebuilder = unit.mock(CacheBuilder.class); expect(CacheBuilder.from("maximumSize=" + maxSize)).andReturn(cachebuilder); expect(cachebuilder.build()).andReturn(cache); PebbleEngine.Builder pebble = unit.get(PebbleEngine.Builder.class); expect(pebble.templateCache(cache)).andReturn(pebble); }; } private Block locale(final Locale locale) { return unit -> { PebbleEngine.Builder pebble = unit.get(PebbleEngine.Builder.class); expect(pebble.defaultLocale(locale)).andReturn(pebble); }; } private Block cache(final String path, final String value) { return unit -> { Config conf = unit.get(Config.class); boolean has = value != null; expect(conf.hasPath(path)).andReturn(has); if (has) { expect(conf.getString(path)).andReturn(value); } }; } private Block env(final String name, final Locale locale) { return unit -> { Env env = unit.get(Env.class); expect(env.name()).andReturn(name); expect(env.locale()).andReturn(locale); }; } @SuppressWarnings({"unchecked", "rawtypes" }) private Block cache(final int size) { return unit -> { Cache<Object, PebbleTemplate> cache = unit.mock(Cache.class); CacheBuilder cachebuilder = unit.mock(CacheBuilder.class); expect(CacheBuilder.newBuilder()).andReturn(cachebuilder); expect(cachebuilder.maximumSize(size)).andReturn(cachebuilder); expect(cachebuilder.build()).andReturn(cache); PebbleEngine.Builder pebble = unit.get(PebbleEngine.Builder.class); expect(pebble.templateCache(cache)).andReturn(pebble); }; } @SuppressWarnings({"unchecked", "rawtypes" }) private Block tagCache(final int size) { return unit -> { Cache<BaseTagCacheKey, Object> cache = unit.mock(Cache.class); CacheBuilder cachebuilder = unit.mock(CacheBuilder.class); expect(CacheBuilder.newBuilder()).andReturn(cachebuilder); expect(cachebuilder.maximumSize(size)).andReturn(cachebuilder); expect(cachebuilder.build()).andReturn(cache); PebbleEngine.Builder pebble = unit.get(PebbleEngine.Builder.class); expect(pebble.tagCache(cache)).andReturn(pebble); }; } }