package org.jooby.hbm;
import static com.typesafe.config.ConfigValueFactory.fromAnyRef;
import static javaslang.Predicates.instanceOf;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.isA;
import static org.junit.Assert.assertEquals;
import java.net.URL;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.stream.Collectors;
import javax.enterprise.inject.spi.BeanManager;
import javax.inject.Provider;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.boot.Metadata;
import org.hibernate.boot.MetadataBuilder;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.SessionFactoryBuilder;
import org.hibernate.boot.archive.scan.spi.ScanEnvironment;
import org.hibernate.boot.model.naming.ImplicitNamingStrategyJpaCompliantImpl;
import org.hibernate.boot.registry.BootstrapServiceRegistry;
import org.hibernate.boot.registry.BootstrapServiceRegistryBuilder;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.event.service.spi.EventListenerRegistry;
import org.hibernate.event.spi.EventType;
import org.hibernate.event.spi.PostLoadEventListener;
import org.hibernate.integrator.spi.Integrator;
import org.hibernate.jpa.event.spi.JpaIntegrator;
import org.hibernate.service.spi.ServiceRegistryImplementor;
import org.jooby.Env;
import org.jooby.Env.ServiceKey;
import org.jooby.Registry;
import org.jooby.internal.hbm.GuiceBeanManager;
import org.jooby.internal.hbm.OpenSessionInView;
import org.jooby.internal.hbm.ScanEnvImpl;
import org.jooby.internal.hbm.SessionProvider;
import org.jooby.internal.hbm.UnitOfWorkProvider;
import org.jooby.jdbc.Jdbc;
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.collect.ImmutableMap;
import com.google.inject.Binder;
import com.google.inject.Key;
import com.google.inject.binder.AnnotatedBindingBuilder;
import com.google.inject.binder.LinkedBindingBuilder;
import com.google.inject.name.Names;
import com.typesafe.config.Config;
import com.typesafe.config.ConfigFactory;
import com.typesafe.config.ConfigValueFactory;
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import hbm5.Beer;
import javaslang.concurrent.Promise;
import javaslang.control.Try.CheckedConsumer;
import javaslang.control.Try.CheckedRunnable;
@RunWith(PowerMockRunner.class)
@PrepareForTest({Hbm.class, BootstrapServiceRegistryBuilder.class, JpaIntegrator.class,
MetadataSources.class, Promise.class, GuiceBeanManager.class, SessionProvider.class,
OpenSessionInView.class })
public class HbmTest {
private Block bsrb = unit -> {
BootstrapServiceRegistryBuilder bsrb = unit.constructor(BootstrapServiceRegistryBuilder.class)
.build();
unit.registerMock(BootstrapServiceRegistryBuilder.class, bsrb);
JpaIntegrator jpa = unit.constructor(JpaIntegrator.class)
.build();
expect(bsrb.applyIntegrator(jpa)).andReturn(bsrb);
BootstrapServiceRegistry bsr = unit.mock(BootstrapServiceRegistry.class);
unit.registerMock(BootstrapServiceRegistry.class, bsr);
expect(bsrb.build()).andReturn(bsr);
};
private Block applyDataSource = unit -> {
StandardServiceRegistryBuilder ssrb = unit.get(StandardServiceRegistryBuilder.class);
expect(ssrb.applySetting(AvailableSettings.DATASOURCE, unit.get(HikariDataSource.class)))
.andReturn(ssrb);
};
@SuppressWarnings("unchecked")
private Block onStart = unit -> {
Env env = unit.get(Env.class);
expect(env.onStart(unit.capture(CheckedConsumer.class))).andReturn(env);
};
private Block onStop = unit -> {
Env env = unit.get(Env.class);
expect(env.onStop(unit.capture(CheckedRunnable.class))).andReturn(env);
expect(env.onStop(isA(CheckedRunnable.class))).andReturn(env);
};
@Test
public void shouldLoadConfigFromClasspath() {
assertEquals(ConfigFactory.parseResources(Hbm.class, "hbm.conf")
.withFallback(ConfigFactory.parseResources(Jdbc.class, "jdbc.conf")), new Hbm().config());
}
@Test
public void newHbm() throws Exception {
String url = "jdbc:h2:target/hbm";
new MockUnit(Env.class, Config.class, Binder.class)
.expect(props("org.h2.jdbcx.JdbcDataSource", url, "h2.hbm",
"sa", "", false))
.expect(hikariConfig())
.expect(hikariDataSource(url))
.expect(serviceKey("hbm"))
.expect(env("dev"))
.expect(bsrb)
.expect(ssrb("update"))
.expect(applySettins(ImmutableMap.of(
AvailableSettings.SESSION_FACTORY_NAME_IS_JNDI, false,
AvailableSettings.SCANNER_DISCOVERY, "class",
AvailableSettings.CURRENT_SESSION_CONTEXT_CLASS, "managed")))
.expect(applyDataSource)
.expect(metadataSources())
.expect(metadataBuilder())
.expect(sessionFactoryBuilder("hbm"))
.expect(beanManager())
.expect(bind(null, SessionFactory.class))
.expect(bind("hbm", SessionFactory.class))
.expect(bind(null, EntityManagerFactory.class))
.expect(bind("hbm", EntityManagerFactory.class))
.expect(sessionProvider())
.expect(bind(null, Session.class, SessionProvider.class))
.expect(bind("hbm", Session.class, SessionProvider.class))
.expect(bind(null, EntityManager.class, SessionProvider.class))
.expect(bind("hbm", EntityManager.class, SessionProvider.class))
.expect(unitOfWork())
.expect(bind(null, UnitOfWork.class, UnitOfWorkProvider.class))
.expect(bind("hbm", UnitOfWork.class, UnitOfWorkProvider.class))
.expect(onStart)
.expect(onStop)
.run(unit -> {
new Hbm()
.configure(unit.get(Env.class), config("hbm"), unit.get(Binder.class));
});
}
@SuppressWarnings({"unchecked", "rawtypes" })
@Test
public void onStart() throws Exception {
String url = "jdbc:h2:target/hbm";
new MockUnit(Env.class, Config.class, Binder.class, Registry.class)
.expect(props("org.h2.jdbcx.JdbcDataSource", url, "h2.hbm",
"sa", "", false))
.expect(hikariConfig())
.expect(hikariDataSource(url))
.expect(serviceKey("hbm"))
.expect(env("dev"))
.expect(bsrb)
.expect(ssrb("update"))
.expect(applySettins(ImmutableMap.of(
AvailableSettings.SESSION_FACTORY_NAME_IS_JNDI, false,
AvailableSettings.SCANNER_DISCOVERY, "class",
AvailableSettings.CURRENT_SESSION_CONTEXT_CLASS, "managed")))
.expect(applyDataSource)
.expect(metadataSources())
.expect(metadataBuilder())
.expect(sessionFactoryBuilder("hbm"))
.expect(beanManager())
.expect(bind(null, SessionFactory.class))
.expect(bind("hbm", SessionFactory.class))
.expect(bind(null, EntityManagerFactory.class))
.expect(bind("hbm", EntityManagerFactory.class))
.expect(sessionProvider())
.expect(bind(null, Session.class, SessionProvider.class))
.expect(bind("hbm", Session.class, SessionProvider.class))
.expect(bind(null, EntityManager.class, SessionProvider.class))
.expect(bind("hbm", EntityManager.class, SessionProvider.class))
.expect(unitOfWork())
.expect(bind(null, UnitOfWork.class, UnitOfWorkProvider.class))
.expect(bind("hbm", UnitOfWork.class, UnitOfWorkProvider.class))
.expect(onStart)
.expect(onStop)
.run(unit -> {
new Hbm()
.configure(unit.get(Env.class), config("hbm"), unit.get(Binder.class));
}, unit -> {
CheckedConsumer<Registry> onStart = unit.captured(CheckedConsumer.class).iterator()
.next();
onStart.accept(unit.get(Registry.class));
Promise promise = unit.captured(Promise.class).iterator().next();
assertEquals(unit.get(Registry.class), promise.future().get());
});
}
@Test
public void onStop() throws Exception {
String url = "jdbc:h2:target/hbm";
new MockUnit(Env.class, Config.class, Binder.class, Registry.class)
.expect(props("org.h2.jdbcx.JdbcDataSource", url, "h2.hbm",
"sa", "", false))
.expect(hikariConfig())
.expect(hikariDataSource(url))
.expect(serviceKey("hbm"))
.expect(env("dev"))
.expect(bsrb)
.expect(ssrb("update"))
.expect(applySettins(ImmutableMap.of(
AvailableSettings.SESSION_FACTORY_NAME_IS_JNDI, false,
AvailableSettings.SCANNER_DISCOVERY, "class",
AvailableSettings.CURRENT_SESSION_CONTEXT_CLASS, "managed")))
.expect(applyDataSource)
.expect(metadataSources())
.expect(metadataBuilder())
.expect(sessionFactoryBuilder("hbm"))
.expect(beanManager())
.expect(bind(null, SessionFactory.class))
.expect(bind("hbm", SessionFactory.class))
.expect(bind(null, EntityManagerFactory.class))
.expect(bind("hbm", EntityManagerFactory.class))
.expect(sessionProvider())
.expect(bind(null, Session.class, SessionProvider.class))
.expect(bind("hbm", Session.class, SessionProvider.class))
.expect(bind(null, EntityManager.class, SessionProvider.class))
.expect(bind("hbm", EntityManager.class, SessionProvider.class))
.expect(unitOfWork())
.expect(bind(null, UnitOfWork.class, UnitOfWorkProvider.class))
.expect(bind("hbm", UnitOfWork.class, UnitOfWorkProvider.class))
.expect(onStart)
.expect(onStop)
.expect(unit -> {
unit.get(SessionFactory.class).close();
})
.run(unit -> {
new Hbm()
.configure(unit.get(Env.class), config("hbm"), unit.get(Binder.class));
}, unit -> {
CheckedRunnable onStop = unit.captured(CheckedRunnable.class).iterator()
.next();
onStop.run();
});
}
@SuppressWarnings({"unchecked", "rawtypes" })
@Test
public void withEvent() throws Exception {
String url = "jdbc:h2:target/hbm";
new MockUnit(Env.class, Config.class, Binder.class, Registry.class)
.expect(props("org.h2.jdbcx.JdbcDataSource", url, "h2.hbm",
"sa", "", false))
.expect(hikariConfig())
.expect(hikariDataSource(url))
.expect(serviceKey("hbm"))
.expect(env("dev"))
.expect(bsrb)
.expect(ssrb("update"))
.expect(applySettins(ImmutableMap.of(
AvailableSettings.SESSION_FACTORY_NAME_IS_JNDI, false,
AvailableSettings.SCANNER_DISCOVERY, "class",
AvailableSettings.CURRENT_SESSION_CONTEXT_CLASS, "managed")))
.expect(applyDataSource)
.expect(metadataSources())
.expect(metadataBuilder())
.expect(sessionFactoryBuilder("hbm"))
.expect(beanManager())
.expect(bind(null, SessionFactory.class))
.expect(bind("hbm", SessionFactory.class))
.expect(bind(null, EntityManagerFactory.class))
.expect(bind("hbm", EntityManagerFactory.class))
.expect(sessionProvider())
.expect(bind(null, Session.class, SessionProvider.class))
.expect(bind("hbm", Session.class, SessionProvider.class))
.expect(bind(null, EntityManager.class, SessionProvider.class))
.expect(bind("hbm", EntityManager.class, SessionProvider.class))
.expect(unitOfWork())
.expect(bind(null, UnitOfWork.class, UnitOfWorkProvider.class))
.expect(bind("hbm", UnitOfWork.class, UnitOfWorkProvider.class))
.expect(onStart)
.expect(onStop)
.expect(unit -> {
PostLoadEventListener listener = unit.mock(PostLoadEventListener.class);
Registry registry = unit.get(Registry.class);
expect(registry.require(PostLoadEventListener.class))
.andReturn(listener);
EventListenerRegistry elr = unit.mock(EventListenerRegistry.class);
elr.appendListeners(EventType.POST_LOAD, listener);
ServiceRegistryImplementor sri = unit.mock(ServiceRegistryImplementor.class);
expect(sri.getService(EventListenerRegistry.class)).andReturn(elr);
SessionFactoryImplementor sf = unit.get(SessionFactoryImplementor.class);
expect(sf.getServiceRegistry()).andReturn(sri);
})
.expect(unit -> {
AnnotatedBindingBuilder abb = unit.mock(AnnotatedBindingBuilder.class);
abb.asEagerSingleton();
Binder binder = unit.get(Binder.class);
expect(binder.bind(PostLoadEventListener.class)).andReturn(abb);
})
.run(unit -> {
new Hbm()
.onEvent(EventType.POST_LOAD, PostLoadEventListener.class)
.configure(unit.get(Env.class), config("hbm"), unit.get(Binder.class));
}, unit -> {
CheckedConsumer<Registry> onStart = unit.captured(CheckedConsumer.class).iterator()
.next();
onStart.accept(unit.get(Registry.class));
});
}
@Test
public void addClass() throws Exception {
String url = "jdbc:h2:target/hbm";
new MockUnit(Env.class, Config.class, Binder.class)
.expect(props("org.h2.jdbcx.JdbcDataSource", url, "h2.hbm",
"sa", "", false))
.expect(hikariConfig())
.expect(hikariDataSource(url))
.expect(serviceKey("hbm"))
.expect(env("dev"))
.expect(bsrb)
.expect(ssrb("update"))
.expect(applySettins(ImmutableMap.of(
AvailableSettings.SESSION_FACTORY_NAME_IS_JNDI, false,
AvailableSettings.SCANNER_DISCOVERY, "class",
AvailableSettings.CURRENT_SESSION_CONTEXT_CLASS, "managed")))
.expect(applyDataSource)
.expect(metadataSources(Beer.class))
.expect(metadataBuilder())
.expect(sessionFactoryBuilder("hbm"))
.expect(beanManager())
.expect(bind(null, SessionFactory.class))
.expect(bind("hbm", SessionFactory.class))
.expect(bind(null, EntityManagerFactory.class))
.expect(bind("hbm", EntityManagerFactory.class))
.expect(sessionProvider())
.expect(bind(null, Session.class, SessionProvider.class))
.expect(bind("hbm", Session.class, SessionProvider.class))
.expect(bind(null, EntityManager.class, SessionProvider.class))
.expect(bind("hbm", EntityManager.class, SessionProvider.class))
.expect(unitOfWork())
.expect(bind(null, UnitOfWork.class, UnitOfWorkProvider.class))
.expect(bind("hbm", UnitOfWork.class, UnitOfWorkProvider.class))
.expect(onStart)
.expect(onStop)
.run(unit -> {
new Hbm()
.classes(Beer.class)
.configure(unit.get(Env.class), config("hbm"), unit.get(Binder.class));
});
}
@Test
public void defaultScan() throws Exception {
String url = "jdbc:h2:target/hbm";
new MockUnit(Env.class, Config.class, Binder.class)
.expect(props("org.h2.jdbcx.JdbcDataSource", url, "h2.hbm",
"sa", "", false))
.expect(hikariConfig())
.expect(hikariDataSource(url))
.expect(serviceKey("hbm"))
.expect(env("dev"))
.expect(bsrb)
.expect(ssrb("update"))
.expect(applySettins(ImmutableMap.of(
AvailableSettings.SESSION_FACTORY_NAME_IS_JNDI, false,
AvailableSettings.SCANNER_DISCOVERY, "class",
AvailableSettings.CURRENT_SESSION_CONTEXT_CLASS, "managed")))
.expect(applyDataSource)
.expect(metadataSources("my.model"))
.expect(metadataBuilder())
.expect(sessionFactoryBuilder("hbm"))
.expect(beanManager())
.expect(bind(null, SessionFactory.class))
.expect(bind("hbm", SessionFactory.class))
.expect(bind(null, EntityManagerFactory.class))
.expect(bind("hbm", EntityManagerFactory.class))
.expect(sessionProvider())
.expect(bind(null, Session.class, SessionProvider.class))
.expect(bind("hbm", Session.class, SessionProvider.class))
.expect(bind(null, EntityManager.class, SessionProvider.class))
.expect(bind("hbm", EntityManager.class, SessionProvider.class))
.expect(unitOfWork())
.expect(bind(null, UnitOfWork.class, UnitOfWorkProvider.class))
.expect(bind("hbm", UnitOfWork.class, UnitOfWorkProvider.class))
.expect(onStart)
.expect(onStop)
.run(unit -> {
new Hbm()
.scan()
.configure(unit.get(Env.class), config("hbm"), unit.get(Binder.class));
});
}
@Test
public void scan() throws Exception {
String url = "jdbc:h2:target/hbm";
new MockUnit(Env.class, Config.class, Binder.class)
.expect(props("org.h2.jdbcx.JdbcDataSource", url, "h2.hbm",
"sa", "", false))
.expect(hikariConfig())
.expect(hikariDataSource(url))
.expect(serviceKey("hbm"))
.expect(env("dev"))
.expect(bsrb)
.expect(ssrb("update"))
.expect(applySettins(ImmutableMap.of(
AvailableSettings.SESSION_FACTORY_NAME_IS_JNDI, false,
AvailableSettings.SCANNER_DISCOVERY, "class",
AvailableSettings.CURRENT_SESSION_CONTEXT_CLASS, "managed")))
.expect(applyDataSource)
.expect(metadataSources("my.model"))
.expect(metadataBuilder())
.expect(sessionFactoryBuilder("hbm"))
.expect(beanManager())
.expect(bind(null, SessionFactory.class))
.expect(bind("hbm", SessionFactory.class))
.expect(bind(null, EntityManagerFactory.class))
.expect(bind("hbm", EntityManagerFactory.class))
.expect(sessionProvider())
.expect(bind(null, Session.class, SessionProvider.class))
.expect(bind("hbm", Session.class, SessionProvider.class))
.expect(bind(null, EntityManager.class, SessionProvider.class))
.expect(bind("hbm", EntityManager.class, SessionProvider.class))
.expect(unitOfWork())
.expect(bind(null, UnitOfWork.class, UnitOfWorkProvider.class))
.expect(bind("hbm", UnitOfWork.class, UnitOfWorkProvider.class))
.expect(onStart)
.expect(onStop)
.run(unit -> {
new Hbm()
.scan("my.model")
.configure(unit.get(Env.class), config("hbm"), unit.get(Binder.class));
});
}
@Test
public void shouldPickupCustomHibernateProps() throws Exception {
String url = "jdbc:h2:target/hbm";
new MockUnit(Env.class, Config.class, Binder.class)
.expect(props("org.h2.jdbcx.JdbcDataSource", url, "h2.hbm",
"sa", "", false))
.expect(hikariConfig())
.expect(hikariDataSource(url))
.expect(serviceKey("hbm"))
.expect(env("dev"))
.expect(bsrb)
.expect(ssrb("update"))
.expect(applySettins(ImmutableMap.of(
AvailableSettings.DIALECT, "h2",
AvailableSettings.SESSION_FACTORY_NAME_IS_JNDI, false,
AvailableSettings.SCANNER_DISCOVERY, "class",
AvailableSettings.CURRENT_SESSION_CONTEXT_CLASS, "managed")))
.expect(applyDataSource)
.expect(metadataSources())
.expect(metadataBuilder())
.expect(sessionFactoryBuilder("hbm"))
.expect(beanManager())
.expect(bind(null, SessionFactory.class))
.expect(bind("hbm", SessionFactory.class))
.expect(bind(null, EntityManagerFactory.class))
.expect(bind("hbm", EntityManagerFactory.class))
.expect(sessionProvider())
.expect(bind(null, Session.class, SessionProvider.class))
.expect(bind("hbm", Session.class, SessionProvider.class))
.expect(bind(null, EntityManager.class, SessionProvider.class))
.expect(bind("hbm", EntityManager.class, SessionProvider.class))
.expect(unitOfWork())
.expect(bind(null, UnitOfWork.class, UnitOfWorkProvider.class))
.expect(bind("hbm", UnitOfWork.class, UnitOfWorkProvider.class))
.expect(onStart)
.expect(onStop)
.run(unit -> {
new Hbm()
.configure(unit.get(Env.class),
config("hbm").withValue("hibernate.dialect", ConfigValueFactory.fromAnyRef("h2")),
unit.get(Binder.class));
});
}
@Test
public void ddlAutoIsNoneOnProd() throws Exception {
String url = "jdbc:h2:target/hbm";
new MockUnit(Env.class, Config.class, Binder.class)
.expect(props("org.h2.jdbcx.JdbcDataSource", url, "h2.hbm",
"sa", "", false))
.expect(hikariConfig())
.expect(hikariDataSource(url))
.expect(serviceKey("hbm"))
.expect(env("prod"))
.expect(bsrb)
.expect(ssrb("none"))
.expect(applySettins(ImmutableMap.of(
AvailableSettings.SESSION_FACTORY_NAME_IS_JNDI, false,
AvailableSettings.SCANNER_DISCOVERY, "class",
AvailableSettings.CURRENT_SESSION_CONTEXT_CLASS, "managed")))
.expect(applyDataSource)
.expect(metadataSources())
.expect(metadataBuilder())
.expect(sessionFactoryBuilder("hbm"))
.expect(beanManager())
.expect(bind(null, SessionFactory.class))
.expect(bind("hbm", SessionFactory.class))
.expect(bind(null, EntityManagerFactory.class))
.expect(bind("hbm", EntityManagerFactory.class))
.expect(sessionProvider())
.expect(bind(null, Session.class, SessionProvider.class))
.expect(bind("hbm", Session.class, SessionProvider.class))
.expect(bind(null, EntityManager.class, SessionProvider.class))
.expect(bind("hbm", EntityManager.class, SessionProvider.class))
.expect(unitOfWork())
.expect(bind(null, UnitOfWork.class, UnitOfWorkProvider.class))
.expect(bind("hbm", UnitOfWork.class, UnitOfWorkProvider.class))
.expect(onStart)
.expect(onStop)
.run(unit -> {
new Hbm()
.configure(unit.get(Env.class), config("hbm"), unit.get(Binder.class));
});
}
@Test
public void genericSetupCallbackShouldWork() throws Exception {
String url = "jdbc:h2:target/hbm";
new MockUnit(Env.class, Config.class, Binder.class, Integrator.class)
.expect(props("org.h2.jdbcx.JdbcDataSource", url, "h2.hbm",
"sa", "", false))
.expect(hikariConfig())
.expect(hikariDataSource(url))
.expect(serviceKey("hbm"))
.expect(env("prod"))
.expect(bsrb)
.expect(ssrb("none"))
.expect(applySettins(ImmutableMap.of(
AvailableSettings.SESSION_FACTORY_NAME_IS_JNDI, false,
AvailableSettings.SCANNER_DISCOVERY, "class",
AvailableSettings.CURRENT_SESSION_CONTEXT_CLASS, "managed")))
.expect(applyDataSource)
.expect(metadataSources())
.expect(metadataBuilder())
.expect(sessionFactoryBuilder("hbm"))
.expect(beanManager())
.expect(bind(null, SessionFactory.class))
.expect(bind("hbm", SessionFactory.class))
.expect(bind(null, EntityManagerFactory.class))
.expect(bind("hbm", EntityManagerFactory.class))
.expect(sessionProvider())
.expect(bind(null, Session.class, SessionProvider.class))
.expect(bind("hbm", Session.class, SessionProvider.class))
.expect(bind(null, EntityManager.class, SessionProvider.class))
.expect(bind("hbm", EntityManager.class, SessionProvider.class))
.expect(unitOfWork())
.expect(bind(null, UnitOfWork.class, UnitOfWorkProvider.class))
.expect(bind("hbm", UnitOfWork.class, UnitOfWorkProvider.class))
.expect(onStart)
.expect(onStop)
.expect(unit -> {
BootstrapServiceRegistryBuilder bsrb = unit.get(BootstrapServiceRegistryBuilder.class);
expect(bsrb.applyIntegrator(unit.get(Integrator.class))).andReturn(bsrb);
})
.run(unit -> {
new Hbm()
.doWith((final BootstrapServiceRegistryBuilder bsrb) -> {
bsrb.applyIntegrator(unit.get(Integrator.class));
})
.configure(unit.get(Env.class), config("hbm"), unit.get(Binder.class));
});
}
@Test(expected = ClassCastException.class)
public void genericSetupCallbackShouldReportClassCastException() throws Exception {
String url = "jdbc:h2:target/hbm";
new MockUnit(Env.class, Config.class, Binder.class, Integrator.class)
.expect(props("org.h2.jdbcx.JdbcDataSource", url, "h2.hbm",
"sa", "", false))
.expect(hikariConfig())
.expect(hikariDataSource(url))
.expect(serviceKey("hbm"))
.expect(env("prod"))
.expect(bsrb)
.expect(ssrb("none"))
.expect(applySettins(ImmutableMap.of(
AvailableSettings.SESSION_FACTORY_NAME_IS_JNDI, false,
AvailableSettings.SCANNER_DISCOVERY, "class",
AvailableSettings.CURRENT_SESSION_CONTEXT_CLASS, "managed")))
.expect(applyDataSource)
.expect(metadataSources())
.expect(metadataBuilder())
.expect(sessionFactoryBuilder("hbm"))
.expect(beanManager())
.expect(bind(null, SessionFactory.class))
.expect(bind("hbm", SessionFactory.class))
.expect(bind(null, EntityManagerFactory.class))
.expect(bind("hbm", EntityManagerFactory.class))
.expect(sessionProvider())
.expect(bind(null, Session.class, SessionProvider.class))
.expect(bind("hbm", Session.class, SessionProvider.class))
.expect(bind(null, EntityManager.class, SessionProvider.class))
.expect(bind("hbm", EntityManager.class, SessionProvider.class))
.expect(unitOfWork())
.expect(bind(null, UnitOfWork.class, UnitOfWorkProvider.class))
.expect(bind("hbm", UnitOfWork.class, UnitOfWorkProvider.class))
.expect(onStart)
.expect(onStop)
.run(unit -> {
new Hbm()
.doWith((final BootstrapServiceRegistryBuilder bsrb) -> {
Object value = "";
System.out.println(((Number) value).intValue());
})
.configure(unit.get(Env.class), config("hbm"), unit.get(Binder.class));
});
}
@Test(expected = NullPointerException.class)
public void genericSetupCallbackShouldReportException() throws Exception {
String url = "jdbc:h2:target/hbm";
new MockUnit(Env.class, Config.class, Binder.class, Integrator.class)
.expect(props("org.h2.jdbcx.JdbcDataSource", url, "h2.hbm",
"sa", "", false))
.expect(hikariConfig())
.expect(hikariDataSource(url))
.expect(serviceKey("hbm"))
.expect(env("prod"))
.expect(bsrb)
.expect(ssrb("none"))
.expect(applySettins(ImmutableMap.of(
AvailableSettings.SESSION_FACTORY_NAME_IS_JNDI, false,
AvailableSettings.SCANNER_DISCOVERY, "class",
AvailableSettings.CURRENT_SESSION_CONTEXT_CLASS, "managed")))
.expect(applyDataSource)
.expect(metadataSources())
.expect(metadataBuilder())
.expect(sessionFactoryBuilder("hbm"))
.expect(beanManager())
.expect(bind(null, SessionFactory.class))
.expect(bind("hbm", SessionFactory.class))
.expect(bind(null, EntityManagerFactory.class))
.expect(bind("hbm", EntityManagerFactory.class))
.expect(sessionProvider())
.expect(bind(null, Session.class, SessionProvider.class))
.expect(bind("hbm", Session.class, SessionProvider.class))
.expect(bind(null, EntityManager.class, SessionProvider.class))
.expect(bind("hbm", EntityManager.class, SessionProvider.class))
.expect(unitOfWork())
.expect(bind(null, UnitOfWork.class, UnitOfWorkProvider.class))
.expect(bind("hbm", UnitOfWork.class, UnitOfWorkProvider.class))
.expect(onStart)
.expect(onStop)
.run(unit -> {
new Hbm()
.doWith((final SessionFactory bsrb) -> {
throw new NullPointerException();
})
.configure(unit.get(Env.class), config("hbm"), unit.get(Binder.class));
});
}
@Test
public void newHbmWithDbProp() throws Exception {
String url = "jdbc:h2:target/hbm";
new MockUnit(Env.class, Config.class, Binder.class)
.expect(props("org.h2.jdbcx.JdbcDataSource", url, "h2.hbm",
"sa", "", false))
.expect(hikariConfig())
.expect(hikariDataSource(url))
.expect(serviceKey("hbm"))
.expect(env("dev"))
.expect(bsrb)
.expect(ssrb("update"))
.expect(applySettins(ImmutableMap.of(
AvailableSettings.SESSION_FACTORY_NAME_IS_JNDI, false,
AvailableSettings.SCANNER_DISCOVERY, "class",
AvailableSettings.CURRENT_SESSION_CONTEXT_CLASS, "managed")))
.expect(applyDataSource)
.expect(metadataSources())
.expect(metadataBuilder())
.expect(sessionFactoryBuilder("hbm"))
.expect(beanManager())
.expect(bind(null, SessionFactory.class))
.expect(bind("hbm", SessionFactory.class))
.expect(bind(null, EntityManagerFactory.class))
.expect(bind("hbm", EntityManagerFactory.class))
.expect(sessionProvider())
.expect(bind(null, Session.class, SessionProvider.class))
.expect(bind("hbm", Session.class, SessionProvider.class))
.expect(bind(null, EntityManager.class, SessionProvider.class))
.expect(bind("hbm", EntityManager.class, SessionProvider.class))
.expect(unitOfWork())
.expect(bind(null, UnitOfWork.class, UnitOfWorkProvider.class))
.expect(bind("hbm", UnitOfWork.class, UnitOfWorkProvider.class))
.expect(onStart)
.expect(onStop)
.run(unit -> {
new Hbm("db")
.configure(unit.get(Env.class), config("hbm"), unit.get(Binder.class));
});
}
private Block sessionProvider() {
return unit -> {
SessionFactory sf = unit.get(SessionFactory.class);
SessionProvider sp = unit.constructor(SessionProvider.class)
.build(sf);
unit.registerMock(SessionProvider.class, sp);
};
}
private Block unitOfWork() {
return unit -> {
SessionFactory sf = unit.get(SessionFactory.class);
UnitOfWorkProvider sp = unit.constructor(UnitOfWorkProvider.class)
.build(sf);
unit.registerMock(UnitOfWorkProvider.class, sp);
};
}
@SuppressWarnings({"rawtypes", "unchecked" })
private Block bind(final String name, final Class type) {
return unit -> {
LinkedBindingBuilder lbb = unit.mock(LinkedBindingBuilder.class);
lbb.toInstance(unit.get(type));
Binder binder = unit.get(Binder.class);
Key key = name == null ? Key.get(type) : Key.get(type, Names.named(name));
expect(binder.bind(key)).andReturn(lbb);
};
}
@SuppressWarnings({"rawtypes", "unchecked" })
private Block bind(final String name, final Class type,
final Class<? extends Provider> provider) {
return unit -> {
LinkedBindingBuilder lbb = unit.mock(LinkedBindingBuilder.class);
expect(lbb.toProvider(unit.get(provider))).andReturn(lbb);
Binder binder = unit.get(Binder.class);
Key key = name == null ? Key.get(type) : Key.get(type, Names.named(name));
expect(binder.bind(key)).andReturn(lbb);
};
}
@SuppressWarnings("unchecked")
private Block beanManager() {
return unit -> {
unit.mockStatic(GuiceBeanManager.class);
BeanManager bm = unit.mock(BeanManager.class);
unit.registerMock(BeanManager.class, bm);
expect(GuiceBeanManager.beanManager(unit.capture(Promise.class))).andReturn(bm);
SessionFactoryBuilder sfb = unit.get(SessionFactoryBuilder.class);
expect(sfb.applyBeanManager(bm)).andReturn(sfb);
};
}
private Block sessionFactoryBuilder(final String name) {
return unit -> {
SessionFactoryBuilder sfb = unit.get(SessionFactoryBuilder.class);
expect(sfb.applyName(name)).andReturn(sfb);
SessionFactoryImplementor sf = unit.mock(SessionFactoryImplementor.class);
expect(sfb.build()).andReturn(sf);
unit.registerMock(SessionFactory.class, sf);
unit.registerMock(SessionFactoryImplementor.class, sf);
unit.registerMock(EntityManagerFactory.class, sf);
};
}
private Block metadataBuilder() {
return unit -> {
MetadataBuilder mb = unit.get(MetadataBuilder.class);
expect(mb.applyImplicitNamingStrategy(ImplicitNamingStrategyJpaCompliantImpl.INSTANCE))
.andReturn(mb);
expect(mb.applyScanEnvironment(unit.get(ScanEnvironment.class))).andReturn(mb);
SessionFactoryBuilder sfb = unit.mock(SessionFactoryBuilder.class);
unit.registerMock(SessionFactoryBuilder.class, sfb);
Metadata md = unit.mock(Metadata.class);
expect(md.getSessionFactoryBuilder()).andReturn(sfb);
expect(mb.build()).andReturn(md);
unit.registerMock(Metadata.class, md);
};
}
@SuppressWarnings("rawtypes")
private Block metadataSources(final Object... resources) {
return unit -> {
StandardServiceRegistry ssr = unit.get(StandardServiceRegistry.class);
MetadataSources sources = unit.constructor(MetadataSources.class)
.build(ssr);
unit.registerMock(MetadataSources.class, sources);
List<String> packages = Arrays.asList(resources)
.stream()
.filter(instanceOf(String.class))
.map(s -> s.toString())
.collect(Collectors.toList());
List<Class> classes = Arrays.asList(resources)
.stream()
.filter(instanceOf(Class.class))
.map(it -> (Class) it)
.collect(Collectors.toList());
MetadataBuilder mb = unit.mock(MetadataBuilder.class);
unit.registerMock(MetadataBuilder.class, mb);
expect(sources.getAnnotatedPackages()).andReturn(packages);
expect(sources.getMetadataBuilder()).andReturn(mb);
packages.forEach(c -> {
expect(sources.addPackage(c)).andReturn(sources);
});
classes.forEach(c -> {
expect(sources.addAnnotatedClass(c)).andReturn(sources);
});
List<URL> urls = packages
.stream()
.map(pkg -> getClass().getResource("/" + pkg.replace('.', '/')))
.collect(Collectors.toList());
ScanEnvImpl scanenv = unit.constructor(ScanEnvImpl.class)
.build(urls);
unit.registerMock(ScanEnvironment.class, scanenv);
};
}
private Block applySettins(final Map<String, Object> settings) {
return unit -> {
StandardServiceRegistryBuilder ssrb = unit.get(StandardServiceRegistryBuilder.class);
expect(ssrb.applySettings(settings)).andReturn(ssrb);
expect(ssrb.applySetting(org.hibernate.jpa.AvailableSettings.DELAY_CDI_ACCESS, true))
.andReturn(ssrb);
};
}
private Block ssrb(final String ddl) {
return unit -> {
StandardServiceRegistryBuilder ssrb = unit.constructor(StandardServiceRegistryBuilder.class)
.build(unit.get(BootstrapServiceRegistry.class));
expect(ssrb.applySetting(AvailableSettings.HBM2DDL_AUTO, ddl)).andReturn(ssrb);
StandardServiceRegistry ssr = unit.mock(StandardServiceRegistry.class);
unit.registerMock(StandardServiceRegistry.class, ssr);
expect(ssrb.build()).andReturn(ssr);
unit.registerMock(StandardServiceRegistryBuilder.class, ssrb);
};
}
private Block env(final String name) {
return unit -> {
Env env = unit.get(Env.class);
expect(env.name()).andReturn(name);
};
}
private Config config(final String db) {
return new Hbm().config()
.withValue("db", ConfigValueFactory.fromAnyRef("fs"))
.withValue("application.ns", ConfigValueFactory.fromAnyRef("my.model"))
.withValue("application.tmpdir", ConfigValueFactory.fromAnyRef("target"))
.withValue("application.name", ConfigValueFactory.fromAnyRef(db))
.withValue("application.charset", ConfigValueFactory.fromAnyRef("UTF-8"))
.withValue("runtime.processors-x2", fromAnyRef("4"))
.resolve();
}
@SuppressWarnings("unchecked")
private Block serviceKey(final String db) {
return unit -> {
Env env = unit.get(Env.class);
ServiceKey skey = new Env.ServiceKey();
expect(env.serviceKey()).andReturn(skey).times(2);
AnnotatedBindingBuilder<DataSource> binding = unit.mock(AnnotatedBindingBuilder.class);
binding.toInstance(unit.get(HikariDataSource.class));
binding.toInstance(unit.get(HikariDataSource.class));
Binder binder = unit.get(Binder.class);
expect(binder.bind(Key.get(DataSource.class))).andReturn(binding);
expect(binder.bind(Key.get(DataSource.class, Names.named(db)))).andReturn(binding);
};
}
private Block hikariConfig() {
return unit -> {
Properties properties = unit.get(Properties.class);
HikariConfig hikari = unit.constructor(HikariConfig.class)
.build(properties);
unit.registerMock(HikariConfig.class, hikari);
};
}
private Block hikariDataSource(final String url) {
return unit -> {
HikariConfig properties = unit.get(HikariConfig.class);
HikariDataSource hikari = unit.constructor(HikariDataSource.class)
.build(properties);
unit.registerMock(HikariDataSource.class, hikari);
};
}
private Block props(final String dataSourceClassName, final String url, final String name,
final String username, final String password, final boolean hasDataSourceClassName) {
return unit -> {
Properties properties = unit.constructor(Properties.class)
.build();
expect(properties
.setProperty("dataSource.dataSourceClassName", dataSourceClassName))
.andReturn(null);
if (username != null) {
expect(properties
.setProperty("dataSource.user", username))
.andReturn(null);
expect(properties
.setProperty("dataSource.password", password))
.andReturn(null);
}
expect(properties
.setProperty("dataSource.url", url))
.andReturn(null);
if (hasDataSourceClassName) {
expect(properties.getProperty("dataSourceClassName")).andReturn(dataSourceClassName);
} else {
expect(properties.getProperty("dataSourceClassName")).andReturn(null);
expect(properties.getProperty("dataSource.dataSourceClassName"))
.andReturn(dataSourceClassName);
expect(properties.setProperty("dataSourceClassName", dataSourceClassName)).andReturn(null);
}
expect(properties.remove("dataSource.dataSourceClassName")).andReturn(dataSourceClassName);
expect(properties.setProperty("poolName", name)).andReturn(null);
expect(properties.setProperty("maximumPoolSize", "4")).andReturn(null);
unit.registerMock(Properties.class, properties);
};
}
}