package org.jooby;
import static org.easymock.EasyMock.eq;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.expectLastCall;
import static org.easymock.EasyMock.isA;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import java.io.File;
import java.nio.charset.Charset;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Optional;
import java.util.Set;
import java.util.TimeZone;
import java.util.function.Function;
import javax.inject.Provider;
import javax.inject.Singleton;
import javax.net.ssl.SSLContext;
import org.jooby.Session.Definition;
import org.jooby.Session.Store;
import org.jooby.internal.AppPrinter;
import org.jooby.internal.BuiltinParser;
import org.jooby.internal.BuiltinRenderer;
import org.jooby.internal.CookieSessionManager;
import org.jooby.internal.DefaulErrRenderer;
import org.jooby.internal.HttpHandlerImpl;
import org.jooby.internal.ParameterNameProvider;
import org.jooby.internal.RequestScope;
import org.jooby.internal.RouteImpl;
import org.jooby.internal.RouteMetadata;
import org.jooby.internal.ServerSessionManager;
import org.jooby.internal.SessionManager;
import org.jooby.internal.TypeConverters;
import org.jooby.internal.parser.BeanParser;
import org.jooby.internal.parser.DateParser;
import org.jooby.internal.parser.LocalDateParser;
import org.jooby.internal.parser.LocaleParser;
import org.jooby.internal.parser.ParserExecutor;
import org.jooby.internal.parser.StaticMethodParser;
import org.jooby.internal.parser.StringConstructorParser;
import org.jooby.internal.ssl.SslContextProvider;
import org.jooby.mvc.GET;
import org.jooby.mvc.POST;
import org.jooby.mvc.Path;
import org.jooby.scope.RequestScoped;
import org.jooby.spi.HttpHandler;
import org.jooby.spi.Server;
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 org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.escape.Escaper;
import com.google.common.html.HtmlEscapers;
import com.google.common.net.UrlEscapers;
import com.google.inject.Binder;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.Key;
import com.google.inject.Module;
import com.google.inject.Stage;
import com.google.inject.TypeLiteral;
import com.google.inject.binder.AnnotatedBindingBuilder;
import com.google.inject.binder.AnnotatedConstantBindingBuilder;
import com.google.inject.binder.ConstantBindingBuilder;
import com.google.inject.binder.LinkedBindingBuilder;
import com.google.inject.binder.ScopedBindingBuilder;
import com.google.inject.multibindings.Multibinder;
import com.google.inject.multibindings.OptionalBinder;
import com.google.inject.name.Named;
import com.google.inject.name.Names;
import com.google.inject.util.Types;
import com.typesafe.config.Config;
import com.typesafe.config.ConfigFactory;
import com.typesafe.config.ConfigValueFactory;
import javaslang.control.Try;
import javaslang.control.Try.CheckedRunnable;
@RunWith(PowerMockRunner.class)
@PrepareForTest({Jooby.class, Guice.class, TypeConverters.class, Multibinder.class,
OptionalBinder.class, Runtime.class, Thread.class, UrlEscapers.class, HtmlEscapers.class,
LoggerFactory.class })
@SuppressWarnings("unchecked")
public class JoobyTest {
public static class InternalOnStart implements Try.CheckedConsumer<Registry> {
@Override
public void accept(final Registry value) throws Throwable {
}
}
@Path("/singleton")
@Singleton
public static class SingletonTestRoute {
@GET
@POST
public Object m1() {
return "";
}
}
@Path("/singleton")
@com.google.inject.Singleton
public static class GuiceSingletonTestRoute {
@GET
@POST
public Object m1() {
return "";
}
}
@Path("/proto")
public static class ProtoTestRoute {
@GET
public Object m1() {
return "";
}
}
@SuppressWarnings("rawtypes")
private MockUnit.Block config = unit -> {
ConstantBindingBuilder strCBB = unit.mock(ConstantBindingBuilder.class);
strCBB.to(isA(String.class));
expectLastCall().anyTimes();
AnnotatedConstantBindingBuilder strACBB = unit.mock(AnnotatedConstantBindingBuilder.class);
expect(strACBB.annotatedWith(isA(Named.class))).andReturn(strCBB).anyTimes();
LinkedBindingBuilder<List<String>> listOfString = unit.mock(LinkedBindingBuilder.class);
listOfString.toInstance(isA(List.class));
expectLastCall().anyTimes();
LinkedBindingBuilder<Config> configBinding = unit.mock(LinkedBindingBuilder.class);
configBinding.toInstance(isA(Config.class));
expectLastCall().anyTimes();
AnnotatedBindingBuilder<Config> configAnnotatedBinding = unit
.mock(AnnotatedBindingBuilder.class);
expect(configAnnotatedBinding.annotatedWith(isA(Named.class))).andReturn(configBinding)
.anyTimes();
// root config
configAnnotatedBinding.toInstance(isA(Config.class));
Binder binder = unit.get(Binder.class);
expect(binder.bindConstant()).andReturn(strACBB).anyTimes();
expect(binder.bind(Config.class)).andReturn(configAnnotatedBinding).anyTimes();
expect(binder.bind(Key.get(Types.listOf(String.class), Names.named("cors.allowedHeaders"))))
.andReturn((LinkedBindingBuilder) listOfString);
expect(binder.bind(Key.get(Types.listOf(String.class), Names.named("cors.allowedMethods"))))
.andReturn((LinkedBindingBuilder) listOfString);
};
private MockUnit.Block env = unit -> {
Binder binder = unit.get(Binder.class);
AnnotatedBindingBuilder<Env> binding = unit.mock(AnnotatedBindingBuilder.class);
binding.toInstance(isA(Env.class));
expect(binder.bind(Env.class)).andReturn(binding);
};
private MockUnit.Block ssl = unit -> {
Binder binder = unit.get(Binder.class);
ScopedBindingBuilder sbbSsl = unit.mock(ScopedBindingBuilder.class);
AnnotatedBindingBuilder<SSLContext> binding = unit.mock(AnnotatedBindingBuilder.class);
expect(binding.toProvider(SslContextProvider.class)).andReturn(sbbSsl);
expect(binder.bind(SSLContext.class)).andReturn(binding);
};
private MockUnit.Block classInfo = unit -> {
Binder binder = unit.get(Binder.class);
AnnotatedBindingBuilder<ParameterNameProvider> binding = unit
.mock(AnnotatedBindingBuilder.class);
binding.toInstance(isA(RouteMetadata.class));
expect(binder.bind(ParameterNameProvider.class)).andReturn(binding);
};
private MockUnit.Block charset = unit -> {
Binder binder = unit.get(Binder.class);
AnnotatedBindingBuilder<Charset> binding = unit.mock(AnnotatedBindingBuilder.class);
binding.toInstance(isA(Charset.class));
expect(binder.bind(Charset.class)).andReturn(binding);
};
private MockUnit.Block locale = unit -> {
Binder binder = unit.get(Binder.class);
AnnotatedBindingBuilder<Locale> binding = unit.mock(AnnotatedBindingBuilder.class);
binding.toInstance(isA(Locale.class));
AnnotatedBindingBuilder<List<Locale>> bindings = unit.mock(AnnotatedBindingBuilder.class);
bindings.toInstance(isA(List.class));
expect(binder.bind(Locale.class)).andReturn(binding);
TypeLiteral<List<Locale>> localeType = (TypeLiteral<List<Locale>>) TypeLiteral
.get(Types.listOf(Locale.class));
expect(binder.bind(localeType)).andReturn(bindings);
};
private MockUnit.Block zoneId = unit -> {
Binder binder = unit.get(Binder.class);
AnnotatedBindingBuilder<ZoneId> binding = unit.mock(AnnotatedBindingBuilder.class);
binding.toInstance(isA(ZoneId.class));
expect(binder.bind(ZoneId.class)).andReturn(binding);
};
private MockUnit.Block timeZone = unit -> {
Binder binder = unit.get(Binder.class);
AnnotatedBindingBuilder<TimeZone> binding = unit.mock(AnnotatedBindingBuilder.class);
binding.toInstance(isA(TimeZone.class));
expect(binder.bind(TimeZone.class)).andReturn(binding);
};
private MockUnit.Block dateTimeFormatter = unit -> {
Binder binder = unit.get(Binder.class);
AnnotatedBindingBuilder<DateTimeFormatter> binding = unit.mock(AnnotatedBindingBuilder.class);
binding.toInstance(isA(DateTimeFormatter.class));
expect(binder.bind(DateTimeFormatter.class)).andReturn(binding);
};
private MockUnit.Block numberFormat = unit -> {
Binder binder = unit.get(Binder.class);
AnnotatedBindingBuilder<NumberFormat> binding = unit.mock(AnnotatedBindingBuilder.class);
binding.toInstance(isA(NumberFormat.class));
expect(binder.bind(NumberFormat.class)).andReturn(binding);
};
private MockUnit.Block decimalFormat = unit -> {
Binder binder = unit.get(Binder.class);
AnnotatedBindingBuilder<DecimalFormat> binding = unit.mock(AnnotatedBindingBuilder.class);
binding.toInstance(isA(DecimalFormat.class));
expect(binder.bind(DecimalFormat.class)).andReturn(binding);
};
private MockUnit.Block renderers = unit -> {
Multibinder<Renderer> multibinder = unit.mock(Multibinder.class);
Binder binder = unit.get(Binder.class);
unit.mockStatic(Multibinder.class);
expect(Multibinder.newSetBinder(binder, Renderer.class)).andReturn(multibinder);
LinkedBindingBuilder<Renderer> formatAsset = unit.mock(LinkedBindingBuilder.class);
formatAsset.toInstance(BuiltinRenderer.asset);
LinkedBindingBuilder<Renderer> formatByteArray = unit.mock(LinkedBindingBuilder.class);
formatByteArray.toInstance(BuiltinRenderer.bytes);
LinkedBindingBuilder<Renderer> formatByteBuffer = unit.mock(LinkedBindingBuilder.class);
formatByteBuffer.toInstance(BuiltinRenderer.byteBuffer);
LinkedBindingBuilder<Renderer> file = unit.mock(LinkedBindingBuilder.class);
file.toInstance(BuiltinRenderer.file);
LinkedBindingBuilder<Renderer> formatStream = unit.mock(LinkedBindingBuilder.class);
formatStream.toInstance(BuiltinRenderer.stream);
LinkedBindingBuilder<Renderer> reader = unit.mock(LinkedBindingBuilder.class);
reader.toInstance(BuiltinRenderer.reader);
LinkedBindingBuilder<Renderer> charBuffer = unit.mock(LinkedBindingBuilder.class);
charBuffer.toInstance(BuiltinRenderer.charBuffer);
LinkedBindingBuilder<Renderer> fchannel = unit.mock(LinkedBindingBuilder.class);
fchannel.toInstance(BuiltinRenderer.fileChannel);
LinkedBindingBuilder<Renderer> err = unit.mock(LinkedBindingBuilder.class);
err.toInstance(isA(DefaulErrRenderer.class));
LinkedBindingBuilder<Renderer> formatAny = unit.mock(LinkedBindingBuilder.class);
formatAny.toInstance(BuiltinRenderer.text);
expect(multibinder.addBinding()).andReturn(formatAsset);
expect(multibinder.addBinding()).andReturn(formatByteArray);
expect(multibinder.addBinding()).andReturn(formatByteBuffer);
expect(multibinder.addBinding()).andReturn(file);
expect(multibinder.addBinding()).andReturn(charBuffer);
expect(multibinder.addBinding()).andReturn(formatStream);
expect(multibinder.addBinding()).andReturn(reader);
expect(multibinder.addBinding()).andReturn(fchannel);
expect(multibinder.addBinding()).andReturn(err);
expect(multibinder.addBinding()).andReturn(formatAny);
};
private MockUnit.Block routes = unit -> {
Multibinder<Route.Definition> multibinder = unit.mock(Multibinder.class);
Binder binder = unit.get(Binder.class);
expect(Multibinder.newSetBinder(binder, Route.Definition.class)).andReturn(multibinder);
};
private MockUnit.Block routeHandler = unit -> {
ScopedBindingBuilder routehandlerscope = unit.mock(ScopedBindingBuilder.class);
routehandlerscope.in(Singleton.class);
AnnotatedBindingBuilder<HttpHandler> routehandlerbinding = unit
.mock(AnnotatedBindingBuilder.class);
expect(routehandlerbinding.to(HttpHandlerImpl.class)).andReturn(routehandlerscope);
expect(unit.get(Binder.class).bind(HttpHandler.class)).andReturn(routehandlerbinding);
};
private MockUnit.Block webSockets = unit -> {
Multibinder<WebSocket.Definition> multibinder = unit.mock(Multibinder.class);
Binder binder = unit.get(Binder.class);
expect(Multibinder.newSetBinder(binder, WebSocket.Definition.class)).andReturn(multibinder);
};
private MockUnit.Block tmpdir = unit -> {
Binder binder = unit.get(Binder.class);
LinkedBindingBuilder<File> instance = unit.mock(LinkedBindingBuilder.class);
instance.toInstance(isA(File.class));
AnnotatedBindingBuilder<File> named = unit.mock(AnnotatedBindingBuilder.class);
expect(named.annotatedWith(Names.named("application.tmpdir"))).andReturn(instance);
expect(binder.bind(java.io.File.class)).andReturn(named);
};
private MockUnit.Block err = unit -> {
Binder binder = unit.get(Binder.class);
LinkedBindingBuilder<Err.Handler> ehlbb = unit.mock(LinkedBindingBuilder.class);
ehlbb.toInstance(isA(Err.DefHandler.class));
Multibinder<Err.Handler> multibinder = unit.mock(Multibinder.class);
expect(Multibinder.newSetBinder(binder, Err.Handler.class)).andReturn(multibinder);
expect(multibinder.addBinding()).andReturn(ehlbb);
};
private MockUnit.Block session = unit -> {
Binder binder = unit.get(Binder.class);
AnnotatedBindingBuilder<SessionManager> smABB = unit.mock(AnnotatedBindingBuilder.class);
expect(smABB.to(ServerSessionManager.class)).andReturn(smABB);
smABB.asEagerSingleton();
ScopedBindingBuilder ssSBB = unit.mock(ScopedBindingBuilder.class);
ssSBB.asEagerSingleton();
AnnotatedBindingBuilder<Store> ssABB = unit.mock(AnnotatedBindingBuilder.class);
expect(ssABB.to(Session.Mem.class)).andReturn(ssSBB);
expect(binder.bind(SessionManager.class)).andReturn(smABB);
expect(binder.bind(Session.Store.class)).andReturn(ssABB);
AnnotatedBindingBuilder<Session.Definition> sdABB = unit.mock(AnnotatedBindingBuilder.class);
expect(sdABB.toProvider(isA(com.google.inject.Provider.class))).andReturn(sdABB);
sdABB.asEagerSingleton();
expect(binder.bind(Session.Definition.class)).andReturn(sdABB);
};
private MockUnit.Block boot = unit -> {
Module module = unit.captured(Module.class).iterator().next();
module.configure(unit.get(Binder.class));
unit.captured(Runnable.class).get(0).run();
};
private MockUnit.Block requestScope = unit -> {
Binder binder = unit.get(Binder.class);
AnnotatedBindingBuilder<RequestScope> reqscopebinding = unit
.mock(AnnotatedBindingBuilder.class);
reqscopebinding.toInstance(isA(RequestScope.class));
expect(binder.bind(RequestScope.class)).andReturn(reqscopebinding);
binder.bindScope(eq(RequestScoped.class), isA(RequestScope.class));
ScopedBindingBuilder reqscope = unit.mock(ScopedBindingBuilder.class);
reqscope.in(RequestScoped.class);
reqscope.in(RequestScoped.class);
AnnotatedBindingBuilder<Request> reqbinding = unit.mock(AnnotatedBindingBuilder.class);
expect(reqbinding.toProvider(isA(Provider.class))).andReturn(reqscope);
expect(binder.bind(Request.class)).andReturn(reqbinding);
ScopedBindingBuilder rspscope = unit.mock(ScopedBindingBuilder.class);
rspscope.in(RequestScoped.class);
AnnotatedBindingBuilder<Response> rspbinding = unit.mock(AnnotatedBindingBuilder.class);
expect(rspbinding.toProvider(isA(Provider.class))).andReturn(rspscope);
expect(binder.bind(Response.class)).andReturn(rspbinding);
ScopedBindingBuilder sessionscope = unit.mock(ScopedBindingBuilder.class);
sessionscope.in(RequestScoped.class);
AnnotatedBindingBuilder<Session> sessionbinding = unit.mock(AnnotatedBindingBuilder.class);
expect(sessionbinding.toProvider(isA(Provider.class)))
.andReturn(sessionscope);
expect(binder.bind(Session.class)).andReturn(sessionbinding);
AnnotatedBindingBuilder<Sse> sseb = unit.mock(AnnotatedBindingBuilder.class);
expect(sseb.toProvider(isA(Provider.class)))
.andReturn(reqscope);
expect(binder.bind(Sse.class)).andReturn(sseb);
};
private MockUnit.Block params = unit -> {
Binder binder = unit.get(Binder.class);
AnnotatedBindingBuilder<ParserExecutor> parambinding = unit
.mock(AnnotatedBindingBuilder.class);
parambinding.in(Singleton.class);
expect(binder.bind(ParserExecutor.class)).andReturn(parambinding);
Multibinder<Parser> multibinder = unit.mock(Multibinder.class, true);
for (Parser parser : BuiltinParser.values()) {
LinkedBindingBuilder<Parser> converterBinding = unit.mock(LinkedBindingBuilder.class);
converterBinding.toInstance(parser);
expect(multibinder.addBinding()).andReturn(converterBinding);
}
@SuppressWarnings("rawtypes")
Class[] parserClasses = {
DateParser.class,
LocalDateParser.class,
LocaleParser.class,
StaticMethodParser.class,
StaticMethodParser.class,
StaticMethodParser.class,
StringConstructorParser.class,
BeanParser.class
};
for (Class<? extends Parser> converter : parserClasses) {
LinkedBindingBuilder<Parser> converterBinding = unit.mock(LinkedBindingBuilder.class);
converterBinding.toInstance(isA(converter));
expect(multibinder.addBinding()).andReturn(converterBinding);
}
expect(Multibinder.newSetBinder(binder, Parser.class)).andReturn(multibinder);
};
private MockUnit.Block shutdown = unit -> {
unit.mockStatic(Runtime.class);
Thread thread = unit.mockConstructor(Thread.class, new Class<?>[]{Runnable.class },
unit.capture(Runnable.class));
Runtime runtime = unit.mock(Runtime.class);
expect(Runtime.getRuntime()).andReturn(runtime).times(2);
runtime.addShutdownHook(thread);
expect(runtime.availableProcessors()).andReturn(1);
};
private MockUnit.Block guice = unit -> {
Server server = unit.mock(Server.class);
server.start();
server.join();
server.stop();
ScopedBindingBuilder serverScope = unit.mock(ScopedBindingBuilder.class);
serverScope.in(Singleton.class);
expectLastCall().times(0, 1);
AnnotatedBindingBuilder<Server> serverBinding = unit.mock(AnnotatedBindingBuilder.class);
expect(serverBinding.to(isA(Class.class))).andReturn(serverScope).times(0, 1);
Binder binder = unit.get(Binder.class);
expect(binder.bind(Server.class)).andReturn(serverBinding).times(0, 1);
// ConfigOrigin configOrigin = unit.mock(ConfigOrigin.class);
// expect(configOrigin.description()).andReturn("test.conf, mock.conf").times(0, 1);
Config config = unit.mock(Config.class);
expect(config.getString("application.env")).andReturn("dev");
expect(config.hasPath("server.join")).andReturn(true);
expect(config.getBoolean("server.join")).andReturn(true);
unit.registerMock(Config.class, config);
// expect(config.origin()).andReturn(configOrigin).times(0, 1);
Injector injector = unit.mock(Injector.class);
expect(injector.getInstance(Server.class)).andReturn(server).times(1, 2);
expect(injector.getInstance(Config.class)).andReturn(config);
expect(injector.getInstance(Route.KEY)).andReturn(Collections.emptySet());
expect(injector.getInstance(WebSocket.KEY)).andReturn(Collections.emptySet());
injector.injectMembers(isA(Jooby.class));
unit.registerMock(Injector.class, injector);
AppPrinter printer = unit.constructor(AppPrinter.class)
.args(Set.class, Set.class, Config.class)
.build(isA(Set.class), isA(Set.class), isA(Config.class));
printer.printConf(isA(Logger.class), eq(config));
unit.mockStatic(Guice.class);
expect(Guice.createInjector(eq(Stage.DEVELOPMENT), unit.capture(Module.class))).andReturn(
injector);
unit.mockStatic(OptionalBinder.class);
TypeConverters tc = unit.mockConstructor(TypeConverters.class);
tc.configure(binder);
};
@Test
public void applicationSecret() throws Exception {
new MockUnit(Binder.class)
.expect(
unit -> {
Server server = unit.mock(Server.class);
server.start();
server.join();
server.stop();
ScopedBindingBuilder serverScope = unit.mock(ScopedBindingBuilder.class);
serverScope.in(Singleton.class);
expectLastCall().times(0, 1);
AnnotatedBindingBuilder<Server> serverBinding = unit
.mock(AnnotatedBindingBuilder.class);
expect(serverBinding.to(isA(Class.class))).andReturn(serverScope).times(0, 1);
Binder binder = unit.get(Binder.class);
expect(binder.bind(Server.class)).andReturn(serverBinding).times(0, 1);
// ConfigOrigin configOrigin = unit.mock(ConfigOrigin.class);
// expect(configOrigin.description()).andReturn("test.conf, mock.conf").times(0, 1);
Config config = unit.mock(Config.class);
expect(config.getString("application.env")).andReturn("dev");
expect(config.hasPath("server.join")).andReturn(true);
expect(config.getBoolean("server.join")).andReturn(true);
unit.registerMock(Config.class, config);
// expect(config.origin()).andReturn(configOrigin).times(0, 1);
AppPrinter printer = unit.constructor(AppPrinter.class)
.args(Set.class, Set.class, Config.class)
.build(isA(Set.class), isA(Set.class), isA(Config.class));
printer.printConf(isA(Logger.class), eq(config));
Injector injector = unit.mock(Injector.class);
expect(injector.getInstance(Server.class)).andReturn(server).times(1, 2);
expect(injector.getInstance(Config.class)).andReturn(config);
expect(injector.getInstance(Route.KEY)).andReturn(Collections.emptySet());
expect(injector.getInstance(WebSocket.KEY)).andReturn(Collections.emptySet());
injector.injectMembers(isA(Jooby.class));
unit.mockStatic(Guice.class);
expect(Guice.createInjector(eq(Stage.PRODUCTION), unit.capture(Module.class)))
.andReturn(
injector);
unit.mockStatic(OptionalBinder.class);
TypeConverters tc = unit.mockConstructor(TypeConverters.class);
tc.configure(binder);
})
.expect(shutdown)
.expect(config)
.expect(internalOnStart(false))
.expect(ssl)
.expect(env)
.expect(classInfo)
.expect(charset)
.expect(locale)
.expect(zoneId)
.expect(timeZone)
.expect(dateTimeFormatter)
.expect(numberFormat)
.expect(decimalFormat)
.expect(renderers)
.expect(session)
.expect(routes)
.expect(routeHandler)
.expect(params)
.expect(requestScope)
.expect(webSockets)
.expect(tmpdir)
.expect(err).expect(executor("deferred"))
.run(unit -> {
Jooby jooby = new Jooby();
jooby.use(ConfigFactory.empty()
.withValue("application.env", ConfigValueFactory.fromAnyRef("prod"))
.withValue("application.secret", ConfigValueFactory.fromAnyRef("234")));
jooby.start();
}, boot);
}
@Test
public void defaults() throws Exception {
new MockUnit(Binder.class)
.expect(guice)
.expect(internalOnStart(false))
.expect(shutdown)
.expect(config)
.expect(env)
.expect(classInfo)
.expect(ssl)
.expect(charset)
.expect(locale)
.expect(zoneId)
.expect(timeZone)
.expect(dateTimeFormatter)
.expect(numberFormat)
.expect(decimalFormat)
.expect(renderers)
.expect(session)
.expect(routes)
.expect(routeHandler)
.expect(params)
.expect(requestScope)
.expect(webSockets)
.expect(tmpdir)
.expect(err).expect(executor("deferred"))
.run(unit -> {
Jooby jooby = new Jooby();
assertEquals(false, jooby.isStarted());
jooby.start();
assertEquals(true, jooby.isStarted());
}, boot);
}
@Test
public void withInternalOnStart() throws Exception {
new MockUnit(Binder.class)
.expect(guice)
.expect(internalOnStart(true))
.expect(shutdown)
.expect(config)
.expect(env)
.expect(classInfo)
.expect(ssl)
.expect(charset)
.expect(locale)
.expect(zoneId)
.expect(timeZone)
.expect(dateTimeFormatter)
.expect(numberFormat)
.expect(decimalFormat)
.expect(renderers)
.expect(session)
.expect(routes)
.expect(routeHandler)
.expect(params)
.expect(requestScope)
.expect(webSockets)
.expect(tmpdir)
.expect(err).expect(executor("deferred"))
.run(unit -> {
Jooby jooby = new Jooby();
assertEquals(false, jooby.isStarted());
jooby.start();
assertEquals(true, jooby.isStarted());
}, boot);
}
private Block internalOnStart(final boolean b) {
return unit -> {
Config conf = unit.get(Config.class);
expect(conf.hasPath("jooby.internal.onStart")).andReturn(b);
if (b) {
expect(conf.getString("jooby.internal.onStart"))
.andReturn(InternalOnStart.class.getName());
}
};
}
@Test
public void cookieSession() throws Exception {
new MockUnit(Binder.class)
.expect(guice)
.expect(shutdown)
.expect(config)
.expect(env)
.expect(classInfo)
.expect(ssl)
.expect(charset)
.expect(locale)
.expect(zoneId)
.expect(timeZone)
.expect(dateTimeFormatter)
.expect(numberFormat)
.expect(decimalFormat)
.expect(renderers)
.expect(unit -> {
Binder binder = unit.get(Binder.class);
AnnotatedBindingBuilder<SessionManager> smABB = unit.mock(AnnotatedBindingBuilder.class);
expect(smABB.to(CookieSessionManager.class)).andReturn(smABB);
smABB.asEagerSingleton();
expect(binder.bind(SessionManager.class)).andReturn(smABB);
AnnotatedBindingBuilder<Session.Definition> sdABB = unit
.mock(AnnotatedBindingBuilder.class);
expect(sdABB.toProvider(isA(com.google.inject.Provider.class))).andReturn(sdABB);
sdABB.asEagerSingleton();
expect(binder.bind(Session.Definition.class)).andReturn(sdABB);
})
.expect(routes)
.expect(routeHandler)
.expect(params)
.expect(requestScope)
.expect(webSockets)
.expect(tmpdir)
.expect(internalOnStart(false))
.expect(err).expect(executor("deferred"))
.run(unit -> {
Jooby jooby = new Jooby();
jooby.use(ConfigFactory.empty()
.withValue("application.secret", ConfigValueFactory.fromAnyRef("234")));
jooby.cookieSession();
jooby.start();
}, boot);
}
@Test
public void cookieSessionShouldFailWhenApplicationSecretIsnotPresent() throws Throwable {
Jooby jooby = new Jooby();
jooby.cookieSession();
jooby.start();
}
@Test
public void onStartStopCallback() throws Exception {
new MockUnit(Binder.class, CheckedRunnable.class)
.expect(guice)
.expect(shutdown)
.expect(config)
.expect(env)
.expect(classInfo)
.expect(ssl)
.expect(charset)
.expect(locale)
.expect(zoneId)
.expect(timeZone)
.expect(dateTimeFormatter)
.expect(numberFormat)
.expect(decimalFormat)
.expect(renderers)
.expect(session)
.expect(routes)
.expect(routeHandler)
.expect(params)
.expect(requestScope)
.expect(webSockets)
.expect(tmpdir)
.expect(err)
.expect(internalOnStart(false))
.expect(executor("deferred"))
.expect(unit -> {
unit.get(CheckedRunnable.class).run();
unit.get(CheckedRunnable.class).run();
})
.run(unit -> {
Jooby app = new Jooby()
.onStart(unit.get(CheckedRunnable.class))
.onStop(unit.get(CheckedRunnable.class));
app.start();
app.stop();
}, boot);
}
@Test(expected = IllegalStateException.class)
public void appDidnStart() throws Exception {
new Jooby().require(Object.class);
}
@Test
public void onStopCallbackLogError() throws Exception {
new MockUnit(Binder.class, CheckedRunnable.class)
.expect(guice)
.expect(shutdown)
.expect(config)
.expect(env)
.expect(classInfo)
.expect(ssl)
.expect(charset)
.expect(locale)
.expect(zoneId)
.expect(timeZone)
.expect(dateTimeFormatter)
.expect(numberFormat)
.expect(decimalFormat)
.expect(renderers)
.expect(session)
.expect(routes)
.expect(routeHandler)
.expect(params)
.expect(requestScope)
.expect(webSockets)
.expect(tmpdir)
.expect(err)
.expect(internalOnStart(false))
.expect(executor("deferred"))
.expect(unit -> {
unit.get(CheckedRunnable.class).run();
unit.get(CheckedRunnable.class).run();
expectLastCall().andThrow(new IllegalStateException("intentional err"));
})
.run(unit -> {
Jooby app = new Jooby()
.onStart(unit.get(CheckedRunnable.class))
.onStop(unit.get(CheckedRunnable.class));
app.start();
app.stop();
}, boot);
}
@Test
public void defaultsWithCallback() throws Exception {
Jooby jooby = new Jooby();
assertNotNull(Jooby.exportRoutes(jooby));
}
@Test
public void customEnv() throws Exception {
new MockUnit(Binder.class, Env.Builder.class)
.expect(guice)
.expect(shutdown)
.expect(config)
.expect(unit -> {
Env env = unit.mock(Env.class);
expect(env.name()).andReturn("dev").times(2);
expect(env.startTasks()).andReturn(Collections.emptyList());
expect(env.startedTasks()).andReturn(Collections.emptyList());
expect(env.stopTasks()).andReturn(Collections.emptyList());
Env.Builder builder = unit.get(Env.Builder.class);
expect(builder.build(isA(Config.class), isA(Jooby.class), isA(Locale.class)))
.andReturn(env);
unit.mockStatic(UrlEscapers.class);
unit.mockStatic(HtmlEscapers.class);
Escaper escaper = unit.mock(Escaper.class);
expect(UrlEscapers.urlFragmentEscaper()).andReturn(escaper);
expect(UrlEscapers.urlFormParameterEscaper()).andReturn(escaper);
expect(UrlEscapers.urlPathSegmentEscaper()).andReturn(escaper);
expect(HtmlEscapers.htmlEscaper()).andReturn(escaper);
expect(env.xss(eq("urlFragment"), unit.capture(Function.class))).andReturn(env);
expect(env.xss(eq("formParam"), unit.capture(Function.class))).andReturn(env);
expect(env.xss(eq("pathSegment"), unit.capture(Function.class))).andReturn(env);
expect(env.xss(eq("html"), unit.capture(Function.class))).andReturn(env);
Binder binder = unit.get(Binder.class);
AnnotatedBindingBuilder<Env> binding = unit.mock(AnnotatedBindingBuilder.class);
binding.toInstance(env);
expect(binder.bind(Env.class)).andReturn(binding);
})
.expect(classInfo)
.expect(ssl)
.expect(charset)
.expect(locale)
.expect(zoneId)
.expect(timeZone)
.expect(dateTimeFormatter)
.expect(numberFormat)
.expect(decimalFormat)
.expect(renderers)
.expect(session)
.expect(routes)
.expect(routeHandler)
.expect(params)
.expect(requestScope)
.expect(webSockets)
.expect(tmpdir)
.expect(err)
.expect(internalOnStart(false))
.expect(executor("deferred"))
.run(unit -> {
Jooby jooby = new Jooby();
jooby.env(unit.get(Env.Builder.class));
jooby.start();
}, boot);
}
@Test
public void exportRoutes() {
Jooby app = new Jooby();
app.get("/export", () -> "OK");
List<Route.Definition> routes = Jooby.exportRoutes(app);
assertEquals(1, routes.size());
assertEquals("/export", routes.get(0).pattern());
assertEquals("GET", routes.get(0).method());
}
@Test
public void exportConf() {
Jooby app = new Jooby();
app.use(ConfigFactory.empty().withValue("JoobyTest", ConfigValueFactory.fromAnyRef("foo")));
Config conf = Jooby.exportConf(app);
assertEquals("foo", conf.getString("JoobyTest"));
}
@Test
public void exportRoutesFailure() {
Jooby app = new Jooby();
// generate an error on bootstrap
app.use(ConfigFactory.empty().withValue("application.lang", ConfigValueFactory.fromAnyRef("")));
app.get("/export", () -> "OK");
List<Route.Definition> routes = Jooby.exportRoutes(app);
assertEquals(0, routes.size());
}
@Test
public void customLang() throws Exception {
new MockUnit(Binder.class)
.expect(guice)
.expect(shutdown)
.expect(config)
.expect(env)
.expect(classInfo)
.expect(ssl)
.expect(charset)
.expect(locale)
.expect(zoneId)
.expect(timeZone)
.expect(dateTimeFormatter)
.expect(numberFormat)
.expect(decimalFormat)
.expect(renderers)
.expect(session)
.expect(routes)
.expect(routeHandler)
.expect(params)
.expect(requestScope)
.expect(webSockets)
.expect(tmpdir)
.expect(internalOnStart(false))
.expect(err)
.expect(executor("deferred"))
.run(
unit -> {
Jooby jooby = new Jooby();
jooby.use(ConfigFactory.empty().withValue("application.lang",
ConfigValueFactory.fromAnyRef("es")));
jooby.start();
}, boot);
}
@Test
public void stopOnServerFailure() throws Exception {
new MockUnit(Binder.class)
.expect(
unit -> {
Server server = unit.mock(Server.class);
server.start();
server.join();
server.stop();
expectLastCall().andThrow(new Exception());
ScopedBindingBuilder serverScope = unit.mock(ScopedBindingBuilder.class);
serverScope.in(Singleton.class);
expectLastCall().times(0, 1);
AnnotatedBindingBuilder<Server> serverBinding = unit
.mock(AnnotatedBindingBuilder.class);
expect(serverBinding.to(isA(Class.class))).andReturn(serverScope).times(0, 1);
Binder binder = unit.get(Binder.class);
expect(binder.bind(Server.class)).andReturn(serverBinding).times(0, 1);
// ConfigOrigin configOrigin = unit.mock(ConfigOrigin.class);
// expect(configOrigin.description()).andReturn("test.conf, mock.conf").times(0, 1);
Config config = unit.mock(Config.class);
expect(config.getString("application.env")).andReturn("dev");
expect(config.hasPath("server.join")).andReturn(true);
expect(config.getBoolean("server.join")).andReturn(true);
unit.registerMock(Config.class, config);
AppPrinter printer = unit.constructor(AppPrinter.class)
.args(Set.class, Set.class, Config.class)
.build(isA(Set.class), isA(Set.class), isA(Config.class));
printer.printConf(isA(Logger.class), eq(config));
Injector injector = unit.mock(Injector.class);
expect(injector.getInstance(Server.class)).andReturn(server).times(1, 2);
expect(injector.getInstance(Config.class)).andReturn(config);
expect(injector.getInstance(Route.KEY)).andReturn(Collections.emptySet());
expect(injector.getInstance(WebSocket.KEY)).andReturn(Collections.emptySet());
injector.injectMembers(isA(Jooby.class));
unit.mockStatic(Guice.class);
expect(Guice.createInjector(eq(Stage.DEVELOPMENT), unit.capture(Module.class)))
.andReturn(
injector);
unit.mockStatic(OptionalBinder.class);
TypeConverters tc = unit.mockConstructor(TypeConverters.class);
tc.configure(binder);
})
.expect(shutdown)
.expect(config)
.expect(env)
.expect(classInfo)
.expect(ssl)
.expect(charset)
.expect(locale)
.expect(zoneId)
.expect(timeZone)
.expect(dateTimeFormatter)
.expect(numberFormat)
.expect(decimalFormat)
.expect(renderers)
.expect(session)
.expect(routes)
.expect(routeHandler)
.expect(params)
.expect(requestScope)
.expect(webSockets)
.expect(internalOnStart(false))
.expect(tmpdir)
.expect(err).expect(executor("deferred"))
.run(unit -> {
Jooby jooby = new Jooby();
jooby.start();
}, boot);
}
@Test
public void useFilter() throws Exception {
List<Route.Definition> expected = new LinkedList<>();
new MockUnit(Binder.class, Route.Filter.class)
.expect(guice)
.expect(shutdown)
.expect(config)
.expect(env)
.expect(classInfo)
.expect(ssl)
.expect(charset)
.expect(locale)
.expect(zoneId)
.expect(timeZone)
.expect(dateTimeFormatter)
.expect(numberFormat)
.expect(decimalFormat)
.expect(renderers)
.expect(session)
.expect(unit -> {
Multibinder<Route.Definition> multibinder = unit.mock(Multibinder.class);
Binder binder = unit.get(Binder.class);
expect(Multibinder.newSetBinder(binder, Route.Definition.class)).andReturn(multibinder);
LinkedBindingBuilder<Route.Definition> binding = unit.mock(LinkedBindingBuilder.class);
expect(multibinder.addBinding()).andReturn(binding);
expect(multibinder.addBinding()).andReturn(binding);
binding.toInstance(unit.capture(Route.Definition.class));
binding.toInstance(unit.capture(Route.Definition.class));
})
.expect(routeHandler)
.expect(params)
.expect(requestScope)
.expect(webSockets)
.expect(tmpdir)
.expect(internalOnStart(false))
.expect(err)
.expect(executor("deferred"))
.run(unit -> {
Jooby jooby = new Jooby();
Route.Definition first = jooby.use("/filter", unit.get(Route.Filter.class));
assertNotNull(first);
assertEquals("/filter", first.pattern());
assertEquals("*", first.method());
assertEquals("/anonymous", first.name());
assertEquals(MediaType.ALL, first.consumes());
assertEquals(MediaType.ALL, first.produces());
expected.add(first);
Route.Definition second = jooby.use("GET", "*", unit.get(Route.Filter.class));
assertNotNull(second);
assertEquals("/**", second.pattern());
assertEquals("GET", second.method());
assertEquals("/anonymous", second.name());
assertEquals(MediaType.ALL, second.consumes());
assertEquals(MediaType.ALL, second.produces());
expected.add(second);
jooby.start();
}, boot,
unit -> {
List<Route.Definition> found = unit.captured(Route.Definition.class);
assertEquals(expected, found);
});
}
@Test
public void useHandler() throws Exception {
List<Route.Definition> expected = new LinkedList<>();
new MockUnit(Binder.class, Route.Handler.class)
.expect(guice)
.expect(shutdown)
.expect(config)
.expect(env)
.expect(classInfo)
.expect(ssl)
.expect(charset)
.expect(locale)
.expect(zoneId)
.expect(timeZone)
.expect(dateTimeFormatter)
.expect(numberFormat)
.expect(decimalFormat)
.expect(renderers)
.expect(session)
.expect(unit -> {
Multibinder<Route.Definition> multibinder = unit.mock(Multibinder.class);
Binder binder = unit.get(Binder.class);
expect(Multibinder.newSetBinder(binder, Route.Definition.class)).andReturn(multibinder);
LinkedBindingBuilder<Route.Definition> binding = unit.mock(LinkedBindingBuilder.class);
expect(multibinder.addBinding()).andReturn(binding);
expect(multibinder.addBinding()).andReturn(binding);
binding.toInstance(unit.capture(Route.Definition.class));
binding.toInstance(unit.capture(Route.Definition.class));
})
.expect(routeHandler)
.expect(params)
.expect(requestScope)
.expect(webSockets)
.expect(tmpdir)
.expect(err)
.expect(internalOnStart(false))
.expect(executor("deferred"))
.run(unit -> {
Jooby jooby = new Jooby();
Route.Definition first = jooby.use("/first", unit.get(Route.Handler.class));
assertNotNull(first);
assertEquals("/first", first.pattern());
assertEquals("*", first.method());
assertEquals("/anonymous", first.name());
assertEquals(MediaType.ALL, first.consumes());
assertEquals(MediaType.ALL, first.produces());
expected.add(first);
Route.Definition second = jooby.use("GET", "*", unit.get(Route.Handler.class));
assertNotNull(second);
assertEquals("/**", second.pattern());
assertEquals("GET", second.method());
assertEquals("/anonymous", second.name());
assertEquals(MediaType.ALL, second.consumes());
assertEquals(MediaType.ALL, second.produces());
expected.add(second);
jooby.start();
}, boot,
unit -> {
List<Route.Definition> found = unit.captured(Route.Definition.class);
assertEquals(expected, found);
});
}
@Test
public void postHandlers() throws Exception {
List<Route.Definition> expected = new LinkedList<>();
new MockUnit(Binder.class, Route.Handler.class, Route.OneArgHandler.class,
Route.ZeroArgHandler.class, Route.Filter.class)
.expect(guice)
.expect(shutdown)
.expect(config)
.expect(env)
.expect(classInfo)
.expect(ssl)
.expect(charset)
.expect(locale)
.expect(zoneId)
.expect(timeZone)
.expect(dateTimeFormatter)
.expect(numberFormat)
.expect(decimalFormat)
.expect(renderers)
.expect(session)
.expect(unit -> {
Multibinder<Route.Definition> multibinder = unit.mock(Multibinder.class);
Binder binder = unit.get(Binder.class);
expect(Multibinder.newSetBinder(binder, Route.Definition.class))
.andReturn(multibinder);
LinkedBindingBuilder<Route.Definition> binding = unit
.mock(LinkedBindingBuilder.class);
expect(multibinder.addBinding()).andReturn(binding).times(4);
binding.toInstance(unit.capture(Route.Definition.class));
binding.toInstance(unit.capture(Route.Definition.class));
binding.toInstance(unit.capture(Route.Definition.class));
binding.toInstance(unit.capture(Route.Definition.class));
})
.expect(routeHandler)
.expect(params)
.expect(requestScope)
.expect(webSockets)
.expect(tmpdir)
.expect(internalOnStart(false))
.expect(err).expect(executor("deferred"))
.run(unit -> {
Jooby jooby = new Jooby();
Route.Definition first = jooby.post("/first", unit.get(Route.Handler.class));
assertNotNull(first);
assertEquals("/first", first.pattern());
assertEquals("POST", first.method());
assertEquals("/anonymous", first.name());
assertEquals(MediaType.ALL, first.consumes());
assertEquals(MediaType.ALL, first.produces());
expected.add(first);
Route.Definition second = jooby.post("/second", unit.get(Route.OneArgHandler.class));
assertNotNull(second);
assertEquals("/second", second.pattern());
assertEquals("POST", second.method());
assertEquals("/anonymous", second.name());
assertEquals(MediaType.ALL, second.consumes());
assertEquals(MediaType.ALL, second.produces());
expected.add(second);
Route.Definition third = jooby.post("/third", unit.get(Route.ZeroArgHandler.class));
assertNotNull(third);
assertEquals("/third", third.pattern());
assertEquals("POST", third.method());
assertEquals("/anonymous", third.name());
assertEquals(MediaType.ALL, third.consumes());
assertEquals(MediaType.ALL, third.produces());
expected.add(third);
Route.Definition fourth = jooby.post("/fourth", unit.get(Route.Filter.class));
assertNotNull(fourth);
assertEquals("/fourth", fourth.pattern());
assertEquals("POST", fourth.method());
assertEquals("/anonymous", fourth.name());
assertEquals(MediaType.ALL, fourth.consumes());
assertEquals(MediaType.ALL, fourth.produces());
expected.add(fourth);
jooby.start();
}, boot,
unit -> {
List<Route.Definition> found = unit.captured(Route.Definition.class);
assertEquals(expected, found);
});
}
@Test
public void headHandlers() throws Exception {
List<Route.Definition> expected = new LinkedList<>();
new MockUnit(Binder.class, Route.Handler.class, Route.OneArgHandler.class,
Route.ZeroArgHandler.class, Route.Filter.class)
.expect(guice)
.expect(shutdown)
.expect(config)
.expect(env)
.expect(classInfo)
.expect(ssl)
.expect(charset)
.expect(locale)
.expect(zoneId)
.expect(timeZone)
.expect(dateTimeFormatter)
.expect(numberFormat)
.expect(decimalFormat)
.expect(renderers)
.expect(session)
.expect(unit -> {
Multibinder<Route.Definition> multibinder = unit.mock(Multibinder.class);
Binder binder = unit.get(Binder.class);
expect(Multibinder.newSetBinder(binder, Route.Definition.class))
.andReturn(multibinder);
LinkedBindingBuilder<Route.Definition> binding = unit
.mock(LinkedBindingBuilder.class);
expect(multibinder.addBinding()).andReturn(binding).times(4);
binding.toInstance(unit.capture(Route.Definition.class));
binding.toInstance(unit.capture(Route.Definition.class));
binding.toInstance(unit.capture(Route.Definition.class));
binding.toInstance(unit.capture(Route.Definition.class));
})
.expect(routeHandler)
.expect(params)
.expect(requestScope)
.expect(webSockets)
.expect(tmpdir)
.expect(internalOnStart(false))
.expect(err).expect(executor("deferred"))
.run(unit -> {
Jooby jooby = new Jooby();
Route.Definition first = jooby.head("/first", unit.get(Route.Handler.class));
assertNotNull(first);
assertEquals("/first", first.pattern());
assertEquals("HEAD", first.method());
assertEquals("/anonymous", first.name());
assertEquals(MediaType.ALL, first.consumes());
assertEquals(MediaType.ALL, first.produces());
expected.add(first);
Route.Definition second = jooby.head("/second", unit.get(Route.OneArgHandler.class));
assertNotNull(second);
assertEquals("/second", second.pattern());
assertEquals("HEAD", second.method());
assertEquals("/anonymous", second.name());
assertEquals(MediaType.ALL, second.consumes());
assertEquals(MediaType.ALL, second.produces());
expected.add(second);
Route.Definition third = jooby.head("/third", unit.get(Route.ZeroArgHandler.class));
assertNotNull(third);
assertEquals("/third", third.pattern());
assertEquals("HEAD", third.method());
assertEquals("/anonymous", third.name());
assertEquals(MediaType.ALL, third.consumes());
assertEquals(MediaType.ALL, third.produces());
expected.add(third);
Route.Definition fourth = jooby.head("/fourth", unit.get(Route.Filter.class));
assertNotNull(fourth);
assertEquals("/fourth", fourth.pattern());
assertEquals("HEAD", fourth.method());
assertEquals("/anonymous", fourth.name());
assertEquals(MediaType.ALL, fourth.consumes());
assertEquals(MediaType.ALL, fourth.produces());
expected.add(fourth);
jooby.start();
}, boot,
unit -> {
List<Route.Definition> found = unit.captured(Route.Definition.class);
assertEquals(expected, found);
});
}
@Test
public void optionsHandlers() throws Exception {
List<Route.Definition> expected = new LinkedList<>();
new MockUnit(Binder.class, Route.Handler.class, Route.OneArgHandler.class,
Route.ZeroArgHandler.class, Route.Filter.class)
.expect(guice)
.expect(shutdown)
.expect(config)
.expect(env)
.expect(classInfo)
.expect(ssl)
.expect(charset)
.expect(locale)
.expect(zoneId)
.expect(timeZone)
.expect(dateTimeFormatter)
.expect(numberFormat)
.expect(decimalFormat)
.expect(renderers)
.expect(session)
.expect(unit -> {
Multibinder<Route.Definition> multibinder = unit.mock(Multibinder.class);
Binder binder = unit.get(Binder.class);
expect(Multibinder.newSetBinder(binder, Route.Definition.class))
.andReturn(multibinder);
LinkedBindingBuilder<Route.Definition> binding = unit
.mock(LinkedBindingBuilder.class);
expect(multibinder.addBinding()).andReturn(binding).times(4);
binding.toInstance(unit.capture(Route.Definition.class));
binding.toInstance(unit.capture(Route.Definition.class));
binding.toInstance(unit.capture(Route.Definition.class));
binding.toInstance(unit.capture(Route.Definition.class));
})
.expect(routeHandler)
.expect(params)
.expect(requestScope)
.expect(webSockets)
.expect(tmpdir)
.expect(internalOnStart(false))
.expect(err)
.expect(executor("deferred"))
.run(unit -> {
Jooby jooby = new Jooby();
Route.Definition first = jooby.options("/first", unit.get(Route.Handler.class));
assertNotNull(first);
assertEquals("/first", first.pattern());
assertEquals("OPTIONS", first.method());
assertEquals("/anonymous", first.name());
assertEquals(MediaType.ALL, first.consumes());
assertEquals(MediaType.ALL, first.produces());
expected.add(first);
Route.Definition second = jooby.options("/second",
unit.get(Route.OneArgHandler.class));
assertNotNull(second);
assertEquals("/second", second.pattern());
assertEquals("OPTIONS", second.method());
assertEquals("/anonymous", second.name());
assertEquals(MediaType.ALL, second.consumes());
assertEquals(MediaType.ALL, second.produces());
expected.add(second);
Route.Definition third = jooby.options("/third",
unit.get(Route.ZeroArgHandler.class));
assertNotNull(third);
assertEquals("/third", third.pattern());
assertEquals("OPTIONS", third.method());
assertEquals("/anonymous", third.name());
assertEquals(MediaType.ALL, third.consumes());
assertEquals(MediaType.ALL, third.produces());
expected.add(third);
Route.Definition fourth = jooby.options("/fourth", unit.get(Route.Filter.class));
assertNotNull(fourth);
assertEquals("/fourth", fourth.pattern());
assertEquals("OPTIONS", fourth.method());
assertEquals("/anonymous", fourth.name());
assertEquals(MediaType.ALL, fourth.consumes());
assertEquals(MediaType.ALL, fourth.produces());
expected.add(fourth);
jooby.start();
}, boot,
unit -> {
List<Route.Definition> found = unit.captured(Route.Definition.class);
assertEquals(expected, found);
});
}
@Test
public void putHandlers() throws Exception {
List<Route.Definition> expected = new LinkedList<>();
new MockUnit(Binder.class, Route.Handler.class, Route.OneArgHandler.class,
Route.ZeroArgHandler.class, Route.Filter.class)
.expect(guice)
.expect(shutdown)
.expect(config)
.expect(env)
.expect(classInfo)
.expect(ssl)
.expect(charset)
.expect(locale)
.expect(zoneId)
.expect(timeZone)
.expect(dateTimeFormatter)
.expect(numberFormat)
.expect(decimalFormat)
.expect(renderers)
.expect(session)
.expect(unit -> {
Multibinder<Route.Definition> multibinder = unit.mock(Multibinder.class);
Binder binder = unit.get(Binder.class);
expect(Multibinder.newSetBinder(binder, Route.Definition.class))
.andReturn(multibinder);
LinkedBindingBuilder<Route.Definition> binding = unit
.mock(LinkedBindingBuilder.class);
expect(multibinder.addBinding()).andReturn(binding).times(4);
binding.toInstance(unit.capture(Route.Definition.class));
binding.toInstance(unit.capture(Route.Definition.class));
binding.toInstance(unit.capture(Route.Definition.class));
binding.toInstance(unit.capture(Route.Definition.class));
})
.expect(routeHandler)
.expect(params)
.expect(requestScope)
.expect(webSockets)
.expect(tmpdir)
.expect(internalOnStart(false))
.expect(err).expect(executor("deferred"))
.run(unit -> {
Jooby jooby = new Jooby();
Route.Definition first = jooby.put("/first", unit.get(Route.Handler.class));
assertNotNull(first);
assertEquals("/first", first.pattern());
assertEquals("PUT", first.method());
assertEquals("/anonymous", first.name());
assertEquals(MediaType.ALL, first.consumes());
assertEquals(MediaType.ALL, first.produces());
expected.add(first);
Route.Definition second = jooby.put("/second", unit.get(Route.OneArgHandler.class));
assertNotNull(second);
assertEquals("/second", second.pattern());
assertEquals("PUT", second.method());
assertEquals("/anonymous", second.name());
assertEquals(MediaType.ALL, second.consumes());
assertEquals(MediaType.ALL, second.produces());
expected.add(second);
Route.Definition third = jooby.put("/third", unit.get(Route.ZeroArgHandler.class));
assertNotNull(third);
assertEquals("/third", third.pattern());
assertEquals("PUT", third.method());
assertEquals("/anonymous", third.name());
assertEquals(MediaType.ALL, third.consumes());
assertEquals(MediaType.ALL, third.produces());
expected.add(third);
Route.Definition fourth = jooby.put("/fourth", unit.get(Route.Filter.class));
assertNotNull(fourth);
assertEquals("/fourth", fourth.pattern());
assertEquals("PUT", fourth.method());
assertEquals("/anonymous", fourth.name());
assertEquals(MediaType.ALL, fourth.consumes());
assertEquals(MediaType.ALL, fourth.produces());
expected.add(fourth);
jooby.start();
}, boot,
unit -> {
List<Route.Definition> found = unit.captured(Route.Definition.class);
assertEquals(expected, found);
});
}
@Test
public void patchHandlers() throws Exception {
List<Route.Definition> expected = new LinkedList<>();
new MockUnit(Binder.class, Route.Handler.class, Route.OneArgHandler.class,
Route.ZeroArgHandler.class, Route.Filter.class)
.expect(guice)
.expect(shutdown)
.expect(config)
.expect(env)
.expect(classInfo)
.expect(ssl)
.expect(charset)
.expect(locale)
.expect(zoneId)
.expect(timeZone)
.expect(dateTimeFormatter)
.expect(numberFormat)
.expect(decimalFormat)
.expect(renderers)
.expect(session)
.expect(unit -> {
Multibinder<Route.Definition> multibinder = unit.mock(Multibinder.class);
Binder binder = unit.get(Binder.class);
expect(Multibinder.newSetBinder(binder, Route.Definition.class))
.andReturn(multibinder);
LinkedBindingBuilder<Route.Definition> binding = unit
.mock(LinkedBindingBuilder.class);
expect(multibinder.addBinding()).andReturn(binding).times(4);
binding.toInstance(unit.capture(Route.Definition.class));
binding.toInstance(unit.capture(Route.Definition.class));
binding.toInstance(unit.capture(Route.Definition.class));
binding.toInstance(unit.capture(Route.Definition.class));
})
.expect(routeHandler)
.expect(params)
.expect(requestScope)
.expect(webSockets)
.expect(tmpdir)
.expect(internalOnStart(false))
.expect(err).expect(executor("deferred"))
.run(unit -> {
Jooby jooby = new Jooby();
Route.Definition first = jooby.patch("/first", unit.get(Route.Handler.class));
assertNotNull(first);
assertEquals("/first", first.pattern());
assertEquals("PATCH", first.method());
assertEquals("/anonymous", first.name());
assertEquals(MediaType.ALL, first.consumes());
assertEquals(MediaType.ALL, first.produces());
expected.add(first);
Route.Definition second = jooby.patch("/second", unit.get(Route.OneArgHandler.class));
assertNotNull(second);
assertEquals("/second", second.pattern());
assertEquals("PATCH", second.method());
assertEquals("/anonymous", second.name());
assertEquals(MediaType.ALL, second.consumes());
assertEquals(MediaType.ALL, second.produces());
expected.add(second);
Route.Definition third = jooby.patch("/third", unit.get(Route.ZeroArgHandler.class));
assertNotNull(third);
assertEquals("/third", third.pattern());
assertEquals("PATCH", third.method());
assertEquals("/anonymous", third.name());
assertEquals(MediaType.ALL, third.consumes());
assertEquals(MediaType.ALL, third.produces());
expected.add(third);
Route.Definition fourth = jooby.patch("/fourth", unit.get(Route.Filter.class));
assertNotNull(fourth);
assertEquals("/fourth", fourth.pattern());
assertEquals("PATCH", fourth.method());
assertEquals("/anonymous", fourth.name());
assertEquals(MediaType.ALL, fourth.consumes());
assertEquals(MediaType.ALL, fourth.produces());
expected.add(fourth);
jooby.start();
}, boot,
unit -> {
List<Route.Definition> found = unit.captured(Route.Definition.class);
assertEquals(expected, found);
});
}
@Test
public void deleteHandlers() throws Exception {
List<Route.Definition> expected = new LinkedList<>();
new MockUnit(Binder.class, Route.Handler.class, Route.OneArgHandler.class,
Route.ZeroArgHandler.class, Route.Filter.class)
.expect(guice)
.expect(shutdown)
.expect(config)
.expect(env)
.expect(classInfo)
.expect(ssl)
.expect(charset)
.expect(locale)
.expect(zoneId)
.expect(timeZone)
.expect(dateTimeFormatter)
.expect(numberFormat)
.expect(decimalFormat)
.expect(renderers)
.expect(session)
.expect(unit -> {
Multibinder<Route.Definition> multibinder = unit.mock(Multibinder.class);
Binder binder = unit.get(Binder.class);
expect(Multibinder.newSetBinder(binder, Route.Definition.class))
.andReturn(multibinder);
LinkedBindingBuilder<Route.Definition> binding = unit
.mock(LinkedBindingBuilder.class);
expect(multibinder.addBinding()).andReturn(binding).times(4);
binding.toInstance(unit.capture(Route.Definition.class));
binding.toInstance(unit.capture(Route.Definition.class));
binding.toInstance(unit.capture(Route.Definition.class));
binding.toInstance(unit.capture(Route.Definition.class));
})
.expect(routeHandler)
.expect(params)
.expect(requestScope)
.expect(webSockets)
.expect(tmpdir)
.expect(internalOnStart(false))
.expect(err).expect(executor("deferred"))
.run(unit -> {
Jooby jooby = new Jooby();
Route.Definition first = jooby.delete("/first", unit.get(Route.Handler.class));
assertNotNull(first);
assertEquals("/first", first.pattern());
assertEquals("DELETE", first.method());
assertEquals("/anonymous", first.name());
assertEquals(MediaType.ALL, first.consumes());
assertEquals(MediaType.ALL, first.produces());
expected.add(first);
Route.Definition second = jooby.delete("/second",
unit.get(Route.OneArgHandler.class));
assertNotNull(second);
assertEquals("/second", second.pattern());
assertEquals("DELETE", second.method());
assertEquals("/anonymous", second.name());
assertEquals(MediaType.ALL, second.consumes());
assertEquals(MediaType.ALL, second.produces());
expected.add(second);
Route.Definition third = jooby.delete("/third", unit.get(Route.ZeroArgHandler.class));
assertNotNull(third);
assertEquals("/third", third.pattern());
assertEquals("DELETE", third.method());
assertEquals("/anonymous", third.name());
assertEquals(MediaType.ALL, third.consumes());
assertEquals(MediaType.ALL, third.produces());
expected.add(third);
Route.Definition fourth = jooby.delete("/fourth", unit.get(Route.Filter.class));
assertNotNull(fourth);
assertEquals("/fourth", fourth.pattern());
assertEquals("DELETE", fourth.method());
assertEquals("/anonymous", fourth.name());
assertEquals(MediaType.ALL, fourth.consumes());
assertEquals(MediaType.ALL, fourth.produces());
expected.add(fourth);
jooby.start();
}, boot,
unit -> {
List<Route.Definition> found = unit.captured(Route.Definition.class);
assertEquals(expected, found);
});
}
@Test
public void connectHandlers() throws Exception {
List<Route.Definition> expected = new LinkedList<>();
new MockUnit(Binder.class, Route.Handler.class, Route.OneArgHandler.class,
Route.ZeroArgHandler.class, Route.Filter.class)
.expect(guice)
.expect(shutdown)
.expect(config)
.expect(env)
.expect(classInfo)
.expect(ssl)
.expect(charset)
.expect(locale)
.expect(zoneId)
.expect(timeZone)
.expect(dateTimeFormatter)
.expect(numberFormat)
.expect(decimalFormat)
.expect(renderers)
.expect(session)
.expect(unit -> {
Multibinder<Route.Definition> multibinder = unit.mock(Multibinder.class);
Binder binder = unit.get(Binder.class);
expect(Multibinder.newSetBinder(binder, Route.Definition.class))
.andReturn(multibinder);
LinkedBindingBuilder<Route.Definition> binding = unit
.mock(LinkedBindingBuilder.class);
expect(multibinder.addBinding()).andReturn(binding).times(4);
binding.toInstance(unit.capture(Route.Definition.class));
binding.toInstance(unit.capture(Route.Definition.class));
binding.toInstance(unit.capture(Route.Definition.class));
binding.toInstance(unit.capture(Route.Definition.class));
})
.expect(routeHandler)
.expect(params)
.expect(requestScope)
.expect(webSockets)
.expect(tmpdir)
.expect(internalOnStart(false))
.expect(err).expect(executor("deferred"))
.run(unit -> {
Jooby jooby = new Jooby();
Route.Definition first = jooby.connect("/first", unit.get(Route.Handler.class));
assertNotNull(first);
assertEquals("/first", first.pattern());
assertEquals("CONNECT", first.method());
assertEquals("/anonymous", first.name());
assertEquals(MediaType.ALL, first.consumes());
assertEquals(MediaType.ALL, first.produces());
expected.add(first);
Route.Definition second = jooby.connect("/second",
unit.get(Route.OneArgHandler.class));
assertNotNull(second);
assertEquals("/second", second.pattern());
assertEquals("CONNECT", second.method());
assertEquals("/anonymous", second.name());
assertEquals(MediaType.ALL, second.consumes());
assertEquals(MediaType.ALL, second.produces());
expected.add(second);
Route.Definition third = jooby.connect("/third",
unit.get(Route.ZeroArgHandler.class));
assertNotNull(third);
assertEquals("/third", third.pattern());
assertEquals("CONNECT", third.method());
assertEquals("/anonymous", third.name());
assertEquals(MediaType.ALL, third.consumes());
assertEquals(MediaType.ALL, third.produces());
expected.add(third);
Route.Definition fourth = jooby.connect("/fourth", unit.get(Route.Filter.class));
assertNotNull(fourth);
assertEquals("/fourth", fourth.pattern());
assertEquals("CONNECT", fourth.method());
assertEquals("/anonymous", fourth.name());
assertEquals(MediaType.ALL, fourth.consumes());
assertEquals(MediaType.ALL, fourth.produces());
expected.add(fourth);
jooby.start();
}, boot,
unit -> {
List<Route.Definition> found = unit.captured(Route.Definition.class);
assertEquals(expected, found);
});
}
@Test
public void traceHandlers() throws Exception {
List<Route.Definition> expected = new LinkedList<>();
new MockUnit(Binder.class, Route.Handler.class, Route.OneArgHandler.class,
Route.ZeroArgHandler.class, Route.Filter.class)
.expect(guice)
.expect(shutdown)
.expect(config)
.expect(env)
.expect(classInfo)
.expect(ssl)
.expect(charset)
.expect(locale)
.expect(zoneId)
.expect(timeZone)
.expect(dateTimeFormatter)
.expect(numberFormat)
.expect(decimalFormat)
.expect(renderers)
.expect(session)
.expect(unit -> {
Multibinder<Route.Definition> multibinder = unit.mock(Multibinder.class);
Binder binder = unit.get(Binder.class);
expect(Multibinder.newSetBinder(binder, Route.Definition.class))
.andReturn(multibinder);
LinkedBindingBuilder<Route.Definition> binding = unit
.mock(LinkedBindingBuilder.class);
expect(multibinder.addBinding()).andReturn(binding).times(4);
binding.toInstance(unit.capture(Route.Definition.class));
binding.toInstance(unit.capture(Route.Definition.class));
binding.toInstance(unit.capture(Route.Definition.class));
binding.toInstance(unit.capture(Route.Definition.class));
})
.expect(routeHandler)
.expect(params)
.expect(requestScope)
.expect(webSockets)
.expect(tmpdir)
.expect(internalOnStart(false))
.expect(err).expect(executor("deferred"))
.run(unit -> {
Jooby jooby = new Jooby();
Route.Definition first = jooby.trace("/first", unit.get(Route.Handler.class));
assertNotNull(first);
assertEquals("/first", first.pattern());
assertEquals("TRACE", first.method());
assertEquals("/anonymous", first.name());
assertEquals(MediaType.ALL, first.consumes());
assertEquals(MediaType.ALL, first.produces());
expected.add(first);
Route.Definition second = jooby.trace("/second", unit.get(Route.OneArgHandler.class));
assertNotNull(second);
assertEquals("/second", second.pattern());
assertEquals("TRACE", second.method());
assertEquals("/anonymous", second.name());
assertEquals(MediaType.ALL, second.consumes());
assertEquals(MediaType.ALL, second.produces());
expected.add(second);
Route.Definition third = jooby.trace("/third", unit.get(Route.ZeroArgHandler.class));
assertNotNull(third);
assertEquals("/third", third.pattern());
assertEquals("TRACE", third.method());
assertEquals("/anonymous", third.name());
assertEquals(MediaType.ALL, third.consumes());
assertEquals(MediaType.ALL, third.produces());
expected.add(third);
Route.Definition fourth = jooby.trace("/fourth", unit.get(Route.Filter.class));
assertNotNull(fourth);
assertEquals("/fourth", fourth.pattern());
assertEquals("TRACE", fourth.method());
assertEquals("/anonymous", fourth.name());
assertEquals(MediaType.ALL, fourth.consumes());
assertEquals(MediaType.ALL, fourth.produces());
expected.add(fourth);
jooby.start();
}, boot,
unit -> {
List<Route.Definition> found = unit.captured(Route.Definition.class);
assertEquals(expected, found);
});
}
@Test
public void assets() throws Exception {
List<Route.Definition> expected = new LinkedList<>();
String path = "/org/jooby/JoobyTest.js";
new MockUnit(Binder.class, Request.class, Response.class, Route.Chain.class)
.expect(guice)
.expect(shutdown)
.expect(config)
.expect(env)
.expect(classInfo)
.expect(ssl)
.expect(charset)
.expect(locale)
.expect(zoneId)
.expect(timeZone)
.expect(dateTimeFormatter)
.expect(numberFormat)
.expect(decimalFormat)
.expect(unit -> {
Multibinder<Renderer> multibinder = unit.mock(Multibinder.class);
Binder binder = unit.get(Binder.class);
unit.mockStatic(Multibinder.class);
expect(Multibinder.newSetBinder(binder, Renderer.class)).andReturn(multibinder);
LinkedBindingBuilder<Renderer> customFormatter = unit
.mock(LinkedBindingBuilder.class);
customFormatter.toInstance(BuiltinRenderer.asset);
LinkedBindingBuilder<Renderer> formatByteArray = unit.mock(LinkedBindingBuilder.class);
formatByteArray.toInstance(BuiltinRenderer.bytes);
LinkedBindingBuilder<Renderer> formatByteBuffer = unit.mock(LinkedBindingBuilder.class);
formatByteBuffer.toInstance(BuiltinRenderer.byteBuffer);
LinkedBindingBuilder<Renderer> file = unit.mock(LinkedBindingBuilder.class);
file.toInstance(BuiltinRenderer.file);
LinkedBindingBuilder<Renderer> formatStream = unit.mock(LinkedBindingBuilder.class);
formatStream.toInstance(BuiltinRenderer.stream);
LinkedBindingBuilder<Renderer> reader = unit.mock(LinkedBindingBuilder.class);
reader.toInstance(BuiltinRenderer.reader);
LinkedBindingBuilder<Renderer> charBuffer = unit.mock(LinkedBindingBuilder.class);
charBuffer.toInstance(BuiltinRenderer.charBuffer);
LinkedBindingBuilder<Renderer> fchannel = unit.mock(LinkedBindingBuilder.class);
fchannel.toInstance(BuiltinRenderer.fileChannel);
LinkedBindingBuilder<Renderer> err = unit.mock(LinkedBindingBuilder.class);
err.toInstance(isA(DefaulErrRenderer.class));
LinkedBindingBuilder<Renderer> formatAny = unit.mock(LinkedBindingBuilder.class);
formatAny.toInstance(BuiltinRenderer.text);
expect(multibinder.addBinding()).andReturn(customFormatter);
expect(multibinder.addBinding()).andReturn(formatByteArray);
expect(multibinder.addBinding()).andReturn(formatByteBuffer);
expect(multibinder.addBinding()).andReturn(file);
expect(multibinder.addBinding()).andReturn(charBuffer);
expect(multibinder.addBinding()).andReturn(formatStream);
expect(multibinder.addBinding()).andReturn(reader);
expect(multibinder.addBinding()).andReturn(fchannel);
expect(multibinder.addBinding()).andReturn(err);
expect(multibinder.addBinding()).andReturn(formatAny);
})
.expect(session)
.expect(unit -> {
Multibinder<Route.Definition> multibinder = unit.mock(Multibinder.class);
Binder binder = unit.get(Binder.class);
expect(Multibinder.newSetBinder(binder, Route.Definition.class)).andReturn(multibinder);
LinkedBindingBuilder<Route.Definition> binding = unit.mock(LinkedBindingBuilder.class);
expect(multibinder.addBinding()).andReturn(binding).times(2);
binding.toInstance(unit.capture(Route.Definition.class));
binding.toInstance(unit.capture(Route.Definition.class));
})
.expect(routeHandler)
.expect(params)
.expect(requestScope)
.expect(webSockets)
.expect(tmpdir)
.expect(err)
.expect(executor("deferred"))
.expect(unit -> {
Mutant ifModifiedSince = unit.mock(Mutant.class);
expect(ifModifiedSince.toOptional(Long.class)).andReturn(Optional.empty());
Mutant ifnm = unit.mock(Mutant.class);
expect(ifnm.toOptional()).andReturn(Optional.empty());
Request req = unit.get(Request.class);
expect(req.path()).andReturn(path);
expect(req.header("If-Modified-Since")).andReturn(ifModifiedSince);
expect(req.header("If-None-Match")).andReturn(ifnm);
Response rsp = unit.get(Response.class);
expect(rsp.header(eq("Last-Modified"), unit.capture(java.util.Date.class)))
.andReturn(rsp);
expect(rsp.header(eq("ETag"), isA(String.class))).andReturn(rsp);
rsp.send(isA(Asset.class));
Route.Chain chain = unit.get(Route.Chain.class);
chain.next(req, rsp);
})
.expect(internalOnStart(false))
.expect(unit -> {
Config conf = unit.get(Config.class);
expect(conf.getString("assets.cdn")).andReturn("").times(2);
expect(conf.getBoolean("assets.lastModified")).andReturn(true).times(2);
expect(conf.getBoolean("assets.etag")).andReturn(true).times(2);
expect(conf.getString("assets.cache.maxAge")).andReturn("-1").times(2);
Injector injector = unit.get(Injector.class);
expect(injector.getInstance(Key.get(Config.class))).andReturn(conf).times(2);
})
.run(unit -> {
Jooby jooby = new Jooby();
Route.Definition assets = jooby.assets("/org/jooby/**");
expected.add(assets);
Route.Definition dir = jooby.assets("/dir/**");
expected.add(dir);
jooby.start();
Optional<Route> route = assets.matches("GET", "/org/jooby/JoobyTest.js",
MediaType.all, MediaType.ALL);
assertNotNull(route);
assertTrue(route.isPresent());
((RouteImpl) route.get()).handle(unit.get(Request.class), unit.get(Response.class),
unit.get(Route.Chain.class));
}, boot, unit -> {
List<Route.Definition> found = unit.captured(Route.Definition.class);
assertEquals(expected, found);
});
}
@Test
public void mvcRoute() throws Exception {
new MockUnit(Binder.class)
.expect(guice)
.expect(shutdown)
.expect(config)
.expect(env)
.expect(classInfo)
.expect(ssl)
.expect(charset)
.expect(locale)
.expect(zoneId)
.expect(timeZone)
.expect(dateTimeFormatter)
.expect(numberFormat)
.expect(decimalFormat)
.expect(renderers)
.expect(session)
.expect(unit -> {
Multibinder<Route.Definition> multibinder = unit.mock(Multibinder.class);
Binder binder = unit.get(Binder.class);
expect(Multibinder.newSetBinder(binder, Route.Definition.class)).andReturn(
multibinder);
LinkedBindingBuilder<Route.Definition> binding = unit
.mock(LinkedBindingBuilder.class);
expect(multibinder.addBinding()).andReturn(binding).times(5);
binding.toInstance(unit.capture(Route.Definition.class));
binding.toInstance(unit.capture(Route.Definition.class));
binding.toInstance(unit.capture(Route.Definition.class));
binding.toInstance(unit.capture(Route.Definition.class));
binding.toInstance(unit.capture(Route.Definition.class));
expect(binder.bind(SingletonTestRoute.class)).andReturn(null);
expect(binder.bind(GuiceSingletonTestRoute.class)).andReturn(null);
expect(binder.bind(ProtoTestRoute.class)).andReturn(null);
})
.expect(routeHandler)
.expect(params)
.expect(requestScope)
.expect(webSockets)
.expect(tmpdir)
.expect(internalOnStart(false))
.expect(err).expect(executor("deferred"))
.run(unit -> {
Jooby jooby = new Jooby();
jooby.use(SingletonTestRoute.class);
jooby.use(GuiceSingletonTestRoute.class);
jooby.use(ProtoTestRoute.class);
jooby.start();
},
boot,
unit -> {
// assert routes
List<Route.Definition> defs = unit.captured(Route.Definition.class);
assertEquals(5, defs.size());
assertEquals("GET", defs.get(0).method());
assertEquals("/singleton", defs.get(0).pattern());
assertEquals("/SingletonTestRoute.m1", defs.get(0).name());
assertEquals("POST", defs.get(1).method());
assertEquals("/singleton", defs.get(1).pattern());
assertEquals("/SingletonTestRoute.m1", defs.get(1).name());
assertEquals("GET", defs.get(2).method());
assertEquals("/singleton", defs.get(2).pattern());
assertEquals("/GuiceSingletonTestRoute.m1", defs.get(2).name());
assertEquals("POST", defs.get(3).method());
assertEquals("/singleton", defs.get(3).pattern());
assertEquals("/GuiceSingletonTestRoute.m1", defs.get(3).name());
assertEquals("GET", defs.get(4).method());
assertEquals("/proto", defs.get(4).pattern());
assertEquals("/ProtoTestRoute.m1", defs.get(4).name());
});
}
@Test
public void globHead() throws Exception {
new MockUnit(Request.class, Response.class)
.run(unit -> {
Jooby jooby = new Jooby();
Route.Definition head = jooby.head();
assertNotNull(head);
assertEquals("/**", head.pattern());
assertEquals("HEAD", head.method());
});
}
@Test
public void globOptions() throws Exception {
new MockUnit(Request.class, Response.class)
.run(unit -> {
Jooby jooby = new Jooby();
Route.Definition options = jooby.options();
assertNotNull(options);
assertEquals("/**", options.pattern());
assertEquals("OPTIONS", options.method());
});
}
@Test
public void globTrace() throws Exception {
new MockUnit(Request.class, Response.class)
.run(unit -> {
Jooby jooby = new Jooby();
Route.Definition trace = jooby.trace();
assertNotNull(trace);
assertEquals("/**", trace.pattern());
assertEquals("TRACE", trace.method());
});
}
@Test
public void ws() throws Exception {
List<WebSocket.Definition> defs = new LinkedList<>();
new MockUnit(Binder.class)
.expect(guice)
.expect(shutdown)
.expect(config)
.expect(env)
.expect(classInfo)
.expect(ssl)
.expect(charset)
.expect(locale)
.expect(zoneId)
.expect(timeZone)
.expect(dateTimeFormatter)
.expect(numberFormat)
.expect(decimalFormat)
.expect(renderers)
.expect(session)
.expect(routes)
.expect(routeHandler)
.expect(params)
.expect(requestScope)
.expect(unit -> {
Multibinder<WebSocket.Definition> multibinder = unit.mock(Multibinder.class);
LinkedBindingBuilder<WebSocket.Definition> binding = unit
.mock(LinkedBindingBuilder.class);
binding.toInstance(unit.capture(WebSocket.Definition.class));
expect(multibinder.addBinding()).andReturn(binding);
Binder binder = unit.get(Binder.class);
expect(Multibinder.newSetBinder(binder, WebSocket.Definition.class)).andReturn(
multibinder);
})
.expect(tmpdir)
.expect(err)
.expect(internalOnStart(false))
.expect(executor("deferred"))
.run(unit -> {
Jooby jooby = new Jooby();
WebSocket.Definition ws = jooby.ws("/", (socket) -> {
});
assertEquals("/", ws.pattern());
assertEquals(MediaType.plain, ws.consumes());
assertEquals(MediaType.plain, ws.produces());
defs.add(ws);
jooby.start();
}, boot, unit -> {
assertEquals(defs, unit.captured(WebSocket.Definition.class));
});
}
@Test
public void useStore() throws Exception {
new MockUnit(Store.class, Binder.class)
.expect(guice)
.expect(shutdown)
.expect(config)
.expect(env)
.expect(classInfo)
.expect(ssl)
.expect(charset)
.expect(locale)
.expect(zoneId)
.expect(timeZone)
.expect(dateTimeFormatter)
.expect(numberFormat)
.expect(decimalFormat)
.expect(renderers)
.expect(
unit -> {
Binder binder = unit.get(Binder.class);
AnnotatedBindingBuilder<SessionManager> smABB = unit
.mock(AnnotatedBindingBuilder.class);
expect(smABB.to(ServerSessionManager.class)).andReturn(smABB);
smABB.asEagerSingleton();
ScopedBindingBuilder ssSBB = unit.mock(ScopedBindingBuilder.class);
ssSBB.asEagerSingleton();
AnnotatedBindingBuilder<Store> ssABB = unit.mock(AnnotatedBindingBuilder.class);
expect(ssABB.to(unit.get(Session.Store.class).getClass())).andReturn(ssSBB);
expect(binder.bind(SessionManager.class)).andReturn(smABB);
expect(binder.bind(Session.Store.class)).andReturn(ssABB);
AnnotatedBindingBuilder<Session.Definition> sdABB = unit
.mock(AnnotatedBindingBuilder.class);
expect(sdABB.toProvider(unit.capture(com.google.inject.Provider.class)))
.andReturn(sdABB);
sdABB.asEagerSingleton();
expect(binder.bind(Session.Definition.class)).andReturn(sdABB);
})
.expect(routes)
.expect(routeHandler)
.expect(params)
.expect(requestScope)
.expect(webSockets)
.expect(tmpdir)
.expect(internalOnStart(false))
.expect(err).expect(executor("deferred"))
.run(unit -> {
Jooby jooby = new Jooby();
jooby.session(unit.get(Store.class).getClass());
jooby.start();
}, boot, unit -> {
Definition def = (Definition) unit.captured(com.google.inject.Provider.class)
.iterator().next().get();
assertEquals(unit.get(Store.class).getClass(), def.store());
});
}
@Test
public void renderer() throws Exception {
new MockUnit(Renderer.class, Binder.class)
.expect(guice)
.expect(shutdown)
.expect(config)
.expect(env)
.expect(classInfo)
.expect(ssl)
.expect(charset)
.expect(locale)
.expect(zoneId)
.expect(timeZone)
.expect(dateTimeFormatter)
.expect(numberFormat)
.expect(decimalFormat)
.expect(session)
.expect(unit -> {
Multibinder<Renderer> multibinder = unit.mock(Multibinder.class);
Binder binder = unit.get(Binder.class);
unit.mockStatic(Multibinder.class);
expect(Multibinder.newSetBinder(binder, Renderer.class)).andReturn(multibinder);
LinkedBindingBuilder<Renderer> customFormatter = unit
.mock(LinkedBindingBuilder.class);
customFormatter.toInstance(unit.get(Renderer.class));
LinkedBindingBuilder<Renderer> formatAsset = unit.mock(LinkedBindingBuilder.class);
formatAsset.toInstance(BuiltinRenderer.asset);
LinkedBindingBuilder<Renderer> formatByteArray = unit.mock(LinkedBindingBuilder.class);
formatByteArray.toInstance(BuiltinRenderer.bytes);
LinkedBindingBuilder<Renderer> formatByteBuffer = unit.mock(LinkedBindingBuilder.class);
formatByteBuffer.toInstance(BuiltinRenderer.byteBuffer);
LinkedBindingBuilder<Renderer> file = unit.mock(LinkedBindingBuilder.class);
file.toInstance(BuiltinRenderer.file);
LinkedBindingBuilder<Renderer> formatStream = unit.mock(LinkedBindingBuilder.class);
formatStream.toInstance(BuiltinRenderer.stream);
LinkedBindingBuilder<Renderer> reader = unit.mock(LinkedBindingBuilder.class);
reader.toInstance(BuiltinRenderer.reader);
LinkedBindingBuilder<Renderer> charBuffer = unit.mock(LinkedBindingBuilder.class);
charBuffer.toInstance(BuiltinRenderer.charBuffer);
LinkedBindingBuilder<Renderer> fchannel = unit.mock(LinkedBindingBuilder.class);
fchannel.toInstance(BuiltinRenderer.fileChannel);
LinkedBindingBuilder<Renderer> err = unit.mock(LinkedBindingBuilder.class);
err.toInstance(isA(DefaulErrRenderer.class));
LinkedBindingBuilder<Renderer> formatAny = unit.mock(LinkedBindingBuilder.class);
formatAny.toInstance(BuiltinRenderer.text);
expect(multibinder.addBinding()).andReturn(formatAsset);
expect(multibinder.addBinding()).andReturn(formatByteArray);
expect(multibinder.addBinding()).andReturn(formatByteBuffer);
expect(multibinder.addBinding()).andReturn(file);
expect(multibinder.addBinding()).andReturn(charBuffer);
expect(multibinder.addBinding()).andReturn(formatStream);
expect(multibinder.addBinding()).andReturn(reader);
expect(multibinder.addBinding()).andReturn(fchannel);
expect(multibinder.addBinding()).andReturn(customFormatter);
expect(multibinder.addBinding()).andReturn(err);
expect(multibinder.addBinding()).andReturn(formatAny);
})
.expect(routes)
.expect(routeHandler)
.expect(params)
.expect(requestScope)
.expect(webSockets)
.expect(tmpdir)
.expect(internalOnStart(false))
.expect(err).expect(executor("deferred"))
.run(unit -> {
Jooby jooby = new Jooby();
jooby.renderer(unit.get(Renderer.class));
jooby.start();
}, boot);
}
@Test
@SuppressWarnings("rawtypes")
public void useParser() throws Exception {
new MockUnit(Parser.class, Binder.class)
.expect(guice)
.expect(shutdown)
.expect(config)
.expect(env)
.expect(classInfo)
.expect(ssl)
.expect(charset)
.expect(locale)
.expect(zoneId)
.expect(timeZone)
.expect(dateTimeFormatter)
.expect(numberFormat)
.expect(decimalFormat)
.expect(renderers)
.expect(unit -> {
Binder binder = unit.get(Binder.class);
AnnotatedBindingBuilder<ParserExecutor> parambinding = unit
.mock(AnnotatedBindingBuilder.class);
parambinding.in(Singleton.class);
expect(binder.bind(ParserExecutor.class)).andReturn(parambinding);
Multibinder<Parser> multibinder = unit.mock(Multibinder.class, true);
LinkedBindingBuilder<Parser> customParser = unit.mock(LinkedBindingBuilder.class);
customParser.toInstance(unit.get(Parser.class));
for (Parser parser : BuiltinParser.values()) {
LinkedBindingBuilder<Parser> converterBinding = unit.mock(LinkedBindingBuilder.class);
converterBinding.toInstance(parser);
expect(multibinder.addBinding()).andReturn(converterBinding);
}
expect(multibinder.addBinding()).andReturn(customParser);
Class[] parserClasses = {
DateParser.class,
LocalDateParser.class,
LocaleParser.class,
StaticMethodParser.class,
StaticMethodParser.class,
StaticMethodParser.class,
StringConstructorParser.class,
BeanParser.class
};
for (Class<? extends Parser> converter : parserClasses) {
LinkedBindingBuilder<Parser> converterBinding = unit.mock(LinkedBindingBuilder.class);
converterBinding.toInstance(isA(converter));
expect(multibinder.addBinding()).andReturn(converterBinding);
}
expect(Multibinder.newSetBinder(binder, Parser.class)).andReturn(multibinder);
})
.expect(session)
.expect(routes)
.expect(routeHandler)
.expect(requestScope)
.expect(webSockets)
.expect(tmpdir)
.expect(internalOnStart(false))
.expect(err).expect(executor("deferred"))
.run(unit -> {
Jooby jooby = new Jooby();
jooby.parser(unit.get(Parser.class));
jooby.start();
}, boot);
}
@Test
public void useModule() throws Exception {
new MockUnit(Binder.class, Jooby.Module.class)
.expect(guice)
.expect(shutdown)
.expect(config)
.expect(env)
.expect(classInfo)
.expect(ssl)
.expect(charset)
.expect(locale)
.expect(zoneId)
.expect(timeZone)
.expect(dateTimeFormatter)
.expect(numberFormat)
.expect(decimalFormat)
.expect(renderers)
.expect(session)
.expect(routes)
.expect(routeHandler)
.expect(params)
.expect(requestScope)
.expect(webSockets)
.expect(tmpdir)
.expect(internalOnStart(false))
.expect(err).expect(executor("deferred"))
.expect(unit -> {
Binder binder = unit.get(Binder.class);
Jooby.Module module = unit.get(Jooby.Module.class);
Config config = ConfigFactory.empty();
expect(module.config()).andReturn(config).times(2);
module.configure(isA(Env.class), isA(Config.class), eq(binder));
})
.run(unit -> {
Jooby jooby = new Jooby();
jooby.use(unit.get(Jooby.Module.class));
jooby.start();
}, boot);
}
@Test
public void useModuleWithError() throws Exception {
Jooby jooby = new Jooby();
jooby.use((env, conf, binder) -> {
throw new NullPointerException("intentional err");
});
jooby.start();
}
@Test
public void useConfig() throws Exception {
new MockUnit(Binder.class)
.expect(guice)
.expect(shutdown)
.expect(config)
.expect(env)
.expect(classInfo)
.expect(ssl)
.expect(charset)
.expect(locale)
.expect(zoneId)
.expect(timeZone)
.expect(dateTimeFormatter)
.expect(numberFormat)
.expect(decimalFormat)
.expect(renderers)
.expect(session)
.expect(routes)
.expect(routeHandler)
.expect(params)
.expect(requestScope)
.expect(webSockets)
.expect(tmpdir)
.expect(internalOnStart(false))
.expect(err)
.expect(executor("deferred"))
.expect(unit -> {
AnnotatedBindingBuilder<List<Integer>> listAnnotatedBinding = unit
.mock(AnnotatedBindingBuilder.class);
listAnnotatedBinding.toInstance(Arrays.asList(1, 2, 3));
Binder binder = unit.get(Binder.class);
Key<List<Integer>> key = (Key<List<Integer>>) Key.get(Types.listOf(Integer.class),
Names.named("list"));
expect(binder.bind(key)).andReturn(listAnnotatedBinding);
})
.run(unit -> {
Jooby jooby = new Jooby();
jooby.use(ConfigFactory.parseResources(getClass(), "JoobyTest.conf"));
jooby.start();
}, boot);
}
@Test
public void customConf() throws Exception {
new MockUnit(Binder.class)
.expect(guice)
.expect(shutdown)
.expect(config)
.expect(env)
.expect(classInfo)
.expect(ssl)
.expect(charset)
.expect(locale)
.expect(zoneId)
.expect(timeZone)
.expect(dateTimeFormatter)
.expect(numberFormat)
.expect(decimalFormat)
.expect(renderers)
.expect(session)
.expect(routes)
.expect(routeHandler)
.expect(params)
.expect(requestScope)
.expect(webSockets)
.expect(tmpdir)
.expect(internalOnStart(false))
.expect(err)
.expect(executor("deferred"))
.run(unit -> {
Jooby jooby = new Jooby();
jooby.conf("JoobyTest.conf");
jooby.start();
}, boot);
}
@Test
public void customConfFile() throws Exception {
new MockUnit(Binder.class)
.expect(guice)
.expect(shutdown)
.expect(config)
.expect(env)
.expect(classInfo)
.expect(ssl)
.expect(charset)
.expect(locale)
.expect(zoneId)
.expect(timeZone)
.expect(dateTimeFormatter)
.expect(numberFormat)
.expect(decimalFormat)
.expect(renderers)
.expect(session)
.expect(routes)
.expect(routeHandler)
.expect(params)
.expect(requestScope)
.expect(webSockets)
.expect(tmpdir)
.expect(internalOnStart(false))
.expect(err)
.expect(executor("deferred"))
.run(unit -> {
Jooby jooby = new Jooby();
jooby.conf(new File("JoobyTest.conf"));
jooby.start();
}, boot);
}
@Test
public void useMissingConfig() throws Exception {
new MockUnit(Binder.class)
.expect(guice)
.expect(shutdown)
.expect(config)
.expect(env)
.expect(ssl)
.expect(classInfo)
.expect(charset)
.expect(locale)
.expect(zoneId)
.expect(timeZone)
.expect(dateTimeFormatter)
.expect(numberFormat)
.expect(decimalFormat)
.expect(renderers)
.expect(session)
.expect(routes)
.expect(routeHandler)
.expect(params)
.expect(requestScope)
.expect(webSockets)
.expect(tmpdir)
.expect(internalOnStart(false))
.expect(err).expect(executor("deferred"))
.run(unit -> {
Jooby jooby = new Jooby();
jooby.use(ConfigFactory.parseResources("missing.conf"));
jooby.start();
}, boot);
}
@Test
public void useErr() throws Exception {
new MockUnit(Binder.class, Err.Handler.class)
.expect(guice)
.expect(shutdown)
.expect(config)
.expect(env)
.expect(ssl)
.expect(classInfo)
.expect(charset)
.expect(locale)
.expect(zoneId)
.expect(timeZone)
.expect(dateTimeFormatter)
.expect(numberFormat)
.expect(decimalFormat)
.expect(renderers)
.expect(session)
.expect(routes)
.expect(routeHandler)
.expect(params)
.expect(requestScope)
.expect(webSockets)
.expect(tmpdir)
.expect(internalOnStart(false))
.expect(unit -> {
Binder binder = unit.get(Binder.class);
LinkedBindingBuilder<Err.Handler> ehlbb = unit.mock(LinkedBindingBuilder.class);
ehlbb.toInstance(unit.get(Err.Handler.class));
LinkedBindingBuilder<Err.Handler> dehlbb = unit.mock(LinkedBindingBuilder.class);
dehlbb.toInstance(isA(Err.DefHandler.class));
Multibinder<Err.Handler> multibinder = unit.mock(Multibinder.class);
expect(Multibinder.newSetBinder(binder, Err.Handler.class)).andReturn(multibinder);
expect(multibinder.addBinding()).andReturn(ehlbb);
expect(multibinder.addBinding()).andReturn(dehlbb);
})
.expect(executor("deferred"))
.run(unit -> {
Jooby jooby = new Jooby();
jooby.err(unit.get(Err.Handler.class));
jooby.start();
}, boot);
}
private Block executor(final String name) {
return unit -> {
// Binder binder = unit.get(Binder.class);
//
// unit.mockStatic(OptionalBinder.class);
//
// LinkedBindingBuilder lbb = unit.mock(LinkedBindingBuilder.class);
// lbb.toInstance(unit.capture(ExecutorService.class));
//
// LinkedBindingBuilder lbbn = unit.mock(LinkedBindingBuilder.class);
// lbbn.toInstance(name);
//
// expect(binder.bind(Key.get(String.class, Names.named("deferred")))).andReturn(lbbn);
// expect(binder.bind(Key.get(Executor.class, Names.named(name)))).andReturn(lbb);
};
}
}