Skip to content

Commit 15ca647

Browse files
committed
Improve the exceptions that are thrown by Kotlin-Guiced
1 parent b9cb186 commit 15ca647

File tree

4 files changed

+59
-3
lines changed

4 files changed

+59
-3
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,18 @@
11
package org.jlleitschuh.guice
22

3+
import com.google.inject.Binder
34
import com.google.inject.Module
45
import com.google.inject.PrivateModule
6+
import com.google.inject.binder.AnnotatedBindingBuilder
7+
import org.jlleitschuh.guice.binder.LinkedBindingBuilderScope
8+
import org.jlleitschuh.guice.binder.ScopedBindingBuilderScope
59

610
/**
711
* Creates a [Module] with the [BinderScope] being configured when [Module.configure]
812
* is called by Guice.
913
*/
1014
fun module(configure: BinderScope.() -> Unit) =
11-
Module { binder -> BinderScope(binder).configure() }
15+
Module { binder -> BinderScope(binder.excludesLibrarySources()).configure() }
1216

1317
/**
1418
* Creates a [PrivateModule] with the [PrivateBinderScope] being configured when [PrivateModule.configure]
@@ -18,6 +22,14 @@ fun privateModule(configure: PrivateBinderScope.() -> Unit) =
1822
// The PrivateModule data type has some reflection checks to get the right type passed in. Easier to just use it.
1923
object : PrivateModule() {
2024
override fun configure() =
21-
configure.invoke(PrivateBinderScope(binder()))
25+
configure.invoke(PrivateBinderScope(binder().excludesLibrarySources()))
26+
}
2227

23-
}
28+
private inline fun <reified T : Binder> T.excludesLibrarySources(): T =
29+
skipSources(
30+
BinderScope::class.java,
31+
PrivateBinderScope::class.java,
32+
AnnotatedBindingBuilder::class.java,
33+
LinkedBindingBuilderScope::class.java,
34+
ScopedBindingBuilderScope::class.java
35+
) as T

core/src/test/kotlin/org/jlleitschuh/guice/ModuleTest.kt

+23
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
11
package org.jlleitschuh.guice
22

33
import com.google.inject.AbstractModule
4+
import com.google.inject.CreationException
45
import com.google.inject.Guice
6+
import com.natpryce.hamkrest.and
7+
import com.natpryce.hamkrest.assertion.assertThat
8+
import com.natpryce.hamkrest.containsSubstring
59
import org.junit.jupiter.api.Assertions.assertNotSame
610
import org.junit.jupiter.api.Assertions.assertSame
711
import org.junit.jupiter.api.Assertions.assertTrue
812
import org.junit.jupiter.api.Test
13+
import org.junit.jupiter.api.assertThrows
914

1015
class ModuleTest {
1116

@@ -72,4 +77,22 @@ class ModuleTest {
7277
val second = injector.getInstance(key<Interface>())
7378
assertNotSame(first, second)
7479
}
80+
81+
@Test
82+
fun `module binding exceptions provide meaningful exceptions`() {
83+
val module = module {
84+
bind<Interface>().toProvider<InterfaceProvider>()
85+
bind<Interface>().toProvider<InterfaceProvider2>()
86+
}
87+
val exception = assertThrows<CreationException> {
88+
Guice.createInjector(module)
89+
}
90+
91+
val expectedString1 =
92+
"1) A binding to org.jlleitschuh.guice.Interface was already configured at org.jlleitschuh.guice.ModuleTest${'$'}module binding exceptions provide meaningful exceptions${'$'}module${'$'}1.invoke(ModuleTest.kt:"
93+
val expectedString2 =
94+
"at org.jlleitschuh.guice.ModuleTest${'$'}module binding exceptions provide meaningful exceptions${'$'}module${'$'}1.invoke(ModuleTest.kt:"
95+
96+
assertThat(exception.message!!, containsSubstring(expectedString1) and containsSubstring(expectedString2))
97+
}
7598
}

core/src/test/kotlin/org/jlleitschuh/guice/TestUtility.kt

+4
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,7 @@ class Implementation : Interface
99
class InterfaceProvider : Provider<Interface> {
1010
override fun get() = Implementation()
1111
}
12+
13+
class InterfaceProvider2 : Provider<Interface> {
14+
override fun get() = Implementation()
15+
}

kotlin-guiced.gradle.kts

+17
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import org.gradle.api.tasks.bundling.Jar
33
import org.gradle.api.tasks.testing.logging.TestExceptionFormat
44
import org.gradle.api.tasks.testing.logging.TestLogEvent
55
import org.gradle.api.tasks.wrapper.Wrapper
6+
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
67

78
buildscript {
89
repositories {
@@ -69,10 +70,26 @@ subprojects {
6970

7071
"testCompile"(junitJupiter("junit-jupiter-api"))
7172
"testCompile"(junitJupiter("junit-jupiter-params"))
73+
"testCompile"(group = "com.natpryce", name = "hamkrest", version = "1.5.0.0")
7274
"testRuntime"(junitJupiter("junit-jupiter-engine"))
7375
"testRuntime"(create(group = "org.junit.platform", name = "junit-platform-launcher", version = "1.3.1"))
7476
}
7577

78+
tasks.withType<KotlinCompile>().configureEach {
79+
// Kotlin incremental compilation is enabled by default
80+
kotlinOptions {
81+
jvmTarget = "1.8"
82+
83+
freeCompilerArgs += "-Xprogressive"
84+
85+
/*
86+
* Enables strict null checking when calling java methods using jsr305 annotations.
87+
* https://kotlinlang.org/docs/reference/java-interop.html#jsr-305-support
88+
*/
89+
freeCompilerArgs += "-Xjsr305=strict"
90+
}
91+
}
92+
7693
tasks.withType<Test>().configureEach {
7794
extensions.configure(typeOf<JacocoTaskExtension>()) {
7895
/*

0 commit comments

Comments
 (0)