🎨 Add container for new posts/replies
[Sone.git] / src / test / kotlin / net / pterodactylus / sone / test / Guice.kt
1 package net.pterodactylus.sone.test
2
3 import com.google.inject.Injector
4 import com.google.inject.Key
5 import com.google.inject.Module
6 import com.google.inject.TypeLiteral
7 import com.google.inject.name.Names
8 import org.hamcrest.MatcherAssert.assertThat
9 import org.hamcrest.Matchers.sameInstance
10 import org.mockito.Mockito
11 import javax.inject.Provider
12 import kotlin.reflect.KClass
13
14 fun <T : Any> KClass<T>.isProvidedBy(instance: T) = Module { it.bind(this.java).toProvider(Provider<T> { instance }) }
15 fun <T : Any> KClass<T>.withNameIsProvidedBy(instance: T, name: String) = Module { it.bind(this.java).annotatedWith(Names.named(name)).toProvider(Provider<T> { instance }) }
16 fun <T : Any> KClass<T>.isProvidedBy(provider: com.google.inject.Provider<T>) = Module { it.bind(this.java).toProvider(provider) }
17 fun <T : Any> KClass<T>.isProvidedBy(provider: KClass<out Provider<T>>) = Module { it.bind(this.java).toProvider(provider.java) }
18 fun <T : Any> Key<T>.isProvidedBy(instance: T) = Module { it.bind(this).toProvider(Provider<T> { instance }) }
19 inline fun <reified T : Any> KClass<T>.isProvidedByMock() = Module { it.bind(this.java).toProvider(Provider<T> { mock() }) }
20 inline fun <reified T : Any> KClass<T>.isProvidedByDeepMock() = Module { it.bind(this.java).toProvider(Provider<T> { deepMock() }) }
21
22 inline fun <reified T> key(): Key<T> = Key.get(object : TypeLiteral<T>() {})
23 inline fun <reified T> key(annotation: Annotation): Key<T> = Key.get(object : TypeLiteral<T>() {}, annotation)
24
25 inline fun <reified T : Any> Injector.getInstance(annotation: Annotation? = null): T = annotation
26                 ?.let { getInstance(Key.get(object : TypeLiteral<T>() {}, it)) }
27                 ?: getInstance(Key.get(object : TypeLiteral<T>() {}))
28
29
30 inline fun <reified T : Any> Injector.verifySingletonInstance(annotation: Annotation? = null) {
31         val firstInstance = getInstance<T>(annotation)
32         val secondInstance = getInstance<T>(annotation)
33         assertThat(firstInstance, sameInstance(secondInstance))
34 }
35
36 fun <T : Any> supply(javaClass: Class<T>): Source<T> = object : Source<T> {
37         override fun fromInstance(instance: T) = Module { it.bind(javaClass).toInstance(instance) }
38         override fun byInstance(instance: T) = Module { it.bind(javaClass).toProvider(Provider<T> { instance }) }
39         override fun byProvider(provider: com.google.inject.Provider<T>) = Module { it.bind(javaClass).toProvider(provider) }
40         override fun byProvider(provider: Class<Provider<T>>) = Module { it.bind(javaClass).toProvider(provider) }
41         override fun byMock() = Module { it.bind(javaClass).toInstance(Mockito.mock(javaClass)) }
42 }
43
44 interface Source<T : Any> {
45         fun fromInstance(instance: T): Module
46         fun byInstance(instance: T): Module
47         fun byProvider(provider: com.google.inject.Provider<T>): Module
48         fun byProvider(provider: Class<Provider<T>>): Module
49         fun byMock(): Module
50 }