package org.jooby.caffeine; import static java.util.Objects.requireNonNull; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.fail; import javax.inject.Inject; import org.jooby.Env; import org.jooby.test.MockUnit; import org.junit.Test; import com.github.benmanes.caffeine.cache.AsyncLoadingCache; import com.github.benmanes.caffeine.cache.Cache; import com.github.benmanes.caffeine.cache.CacheLoader; import com.github.benmanes.caffeine.cache.LoadingCache; import com.google.inject.ConfigurationException; import com.google.inject.Guice; import com.google.inject.Injector; import com.google.inject.Key; import com.google.inject.name.Names; import com.typesafe.config.Config; import com.typesafe.config.ConfigFactory; import com.typesafe.config.ConfigValueFactory; public class CaffeineCacheTest { public static class RequireCache { @Inject public RequireCache(final Cache<String, Object> cache) { requireNonNull(cache, "The cache is required."); } } public static class RequireLoadingCache { @Inject public RequireLoadingCache(final LoadingCache<String, Object> cache) { requireNonNull(cache, "The cache is required."); } } public static class RequireAsyncLoadingCache { @Inject public RequireAsyncLoadingCache(final AsyncLoadingCache<String, Object> cache) { requireNonNull(cache, "The cache is required."); } } public static class RequireTypeSafeCache { @Inject public RequireTypeSafeCache(final Cache<Integer, String> cache) { requireNonNull(cache, "The cache is required."); } } @Test public void defaults() throws Exception { Config conf = ConfigFactory.empty() .withValue("caffeine.cache", ConfigValueFactory.fromAnyRef("")) .withValue("caffeine.session", ConfigValueFactory.fromAnyRef("")); new MockUnit(Env.class) .run(unit -> { Injector injector = Guice.createInjector(binder -> { CaffeineCache.newCache().configure(unit.get(Env.class), conf, binder); }); injector.getInstance(RequireCache.class); injector.getInstance(CaffeineSessionStore.class); }); } @Test public void loadingCache() throws Exception { Config conf = ConfigFactory.empty() .withValue("caffeine.cache", ConfigValueFactory.fromAnyRef("")) .withValue("caffeine.session", ConfigValueFactory.fromAnyRef("")); new MockUnit(Env.class) .run(unit -> { Injector injector = Guice.createInjector(binder -> { new CaffeineCache<String, Object>(){}.doWith((n, b) ->{ return b.build(new CacheLoader<String, Object>() { @Override public Object load(final String key) throws Exception { return null; } }); }).configure(unit.get(Env.class), conf, binder); }); injector.getInstance(RequireCache.class); injector.getInstance(RequireLoadingCache.class); injector.getInstance(CaffeineSessionStore.class); }); } @Test public void ayncLoadingCache() throws Exception { Config conf = ConfigFactory.empty() .withValue("caffeine.cache", ConfigValueFactory.fromAnyRef("")) .withValue("caffeine.session", ConfigValueFactory.fromAnyRef("")); new MockUnit(Env.class) .run(unit -> { Injector injector = Guice.createInjector(binder -> { new CaffeineCache<String, Object>(){}.doWithAsync((n, b) ->{ return b.buildAsync(new CacheLoader<String, Object>() { @Override public Object load(final String key) throws Exception { return null; } }); }).configure(unit.get(Env.class), conf, binder); }); injector.getInstance(RequireAsyncLoadingCache.class); }); } @SuppressWarnings("rawtypes") @Test public void defaultsNoSpec() throws Exception { Config conf = ConfigFactory.empty(); new MockUnit(Env.class) .run(unit -> { Injector injector = Guice.createInjector(binder -> { new CaffeineCache() { }.configure(unit.get(Env.class), conf, binder); }); injector.getInstance(RequireCache.class); }); } @SuppressWarnings("rawtypes") @Test public void oneCache() throws Exception { Config conf = ConfigFactory.empty() .withValue("caffeine.cache", ConfigValueFactory.fromAnyRef("")); new MockUnit(Env.class) .run(unit -> { Injector injector = Guice.createInjector(binder -> { new CaffeineCache() { }.configure(unit.get(Env.class), conf, binder); }); injector.getInstance(RequireCache.class); try { injector.getInstance(CaffeineSessionStore.class); fail("No session found"); } catch (ConfigurationException ex) { // OK } }); } @SuppressWarnings("rawtypes") @Test public void cacheWithObjectSpec() throws Exception { Config conf = ConfigFactory.empty() .withValue("caffeine.cache.maximumSize", ConfigValueFactory.fromAnyRef(10)); new MockUnit(Env.class) .run(unit -> { Injector injector = Guice.createInjector(binder -> { new CaffeineCache() { }.configure(unit.get(Env.class), conf, binder); }); injector.getInstance(RequireCache.class); try { injector.getInstance(CaffeineSessionStore.class); fail("No session found"); } catch (ConfigurationException ex) { // OK } }); } @Test public void typeSafeCache() throws Exception { Config conf = ConfigFactory.empty() .withValue("caffeine.cache", ConfigValueFactory.fromAnyRef("")) .withValue("caffeine.session", ConfigValueFactory.fromAnyRef("")); new MockUnit(Env.class) .run(unit -> { Injector injector = Guice.createInjector(binder -> { new CaffeineCache<Integer, String>() { } .configure(unit.get(Env.class), conf, binder); }); injector.getInstance(RequireTypeSafeCache.class); // raw cache injector.getInstance(Cache.class); // raw cache for session injector.getInstance(Key.get(Cache.class, Names.named("session"))); }); } @Test public void withCallback() throws Exception { Config conf = ConfigFactory.empty() .withValue("caffeine.cache", ConfigValueFactory.fromAnyRef("maximumSize=10")); new MockUnit(Env.class) .run(unit -> { Injector injector = Guice.createInjector(binder -> { new CaffeineCache<Integer, String>() { }.doWith((n, builder) -> { assertEquals("cache", n); assertNotNull(builder); return builder.build(); }) .configure(unit.get(Env.class), conf, binder); }); injector.getInstance(RequireTypeSafeCache.class); }); } }