mirror of
https://github.com/jlengrand/detekt.git
synced 2026-03-10 08:11:23 +00:00
Migrate detekt-rules-exceptions tests to JUnit (#4572)
* Migrate detekt-rules-exceptions tests to JUnit * Improve nested test descriptions
This commit is contained in:
@@ -5,6 +5,5 @@ plugins {
|
||||
dependencies {
|
||||
compileOnly(projects.detektApi)
|
||||
testImplementation(projects.detektTest)
|
||||
testImplementation(libs.bundles.testImplementation)
|
||||
testRuntimeOnly(libs.spek.runner)
|
||||
testImplementation(libs.assertj)
|
||||
}
|
||||
|
||||
@@ -167,7 +167,8 @@ class SwallowedException(config: Config = Config.empty) : Rule(config) {
|
||||
}
|
||||
|
||||
companion object {
|
||||
internal val EXCEPTIONS_IGNORED_BY_DEFAULT = listOf(
|
||||
@JvmStatic
|
||||
val EXCEPTIONS_IGNORED_BY_DEFAULT = listOf(
|
||||
"InterruptedException",
|
||||
"MalformedURLException",
|
||||
"NumberFormatException",
|
||||
|
||||
@@ -5,25 +5,29 @@ import io.gitlab.arturbosch.detekt.test.TestConfig
|
||||
import io.gitlab.arturbosch.detekt.test.compileAndLint
|
||||
import io.gitlab.arturbosch.detekt.test.lint
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.spekframework.spek2.Spek
|
||||
import org.spekframework.spek2.style.specification.describe
|
||||
import org.junit.jupiter.api.Nested
|
||||
import org.junit.jupiter.api.Test
|
||||
|
||||
class ExceptionRaisedInUnexpectedLocationSpec : Spek({
|
||||
val subject by memoized { ExceptionRaisedInUnexpectedLocation() }
|
||||
class ExceptionRaisedInUnexpectedLocationSpec {
|
||||
val subject = ExceptionRaisedInUnexpectedLocation()
|
||||
|
||||
describe("ExceptionRaisedInUnexpectedLocation rule") {
|
||||
@Nested
|
||||
inner class `ExceptionRaisedInUnexpectedLocation rule` {
|
||||
|
||||
it("reports methods raising an unexpected exception") {
|
||||
@Test
|
||||
fun `reports methods raising an unexpected exception`() {
|
||||
val path = resourceAsPath("ExceptionRaisedInMethodsPositive.kt")
|
||||
assertThat(subject.lint(path)).hasSize(5)
|
||||
}
|
||||
|
||||
it("does not report methods raising no exception") {
|
||||
@Test
|
||||
fun `does not report methods raising no exception`() {
|
||||
val path = resourceAsPath("ExceptionRaisedInMethodsNegative.kt")
|
||||
assertThat(subject.lint(path)).isEmpty()
|
||||
}
|
||||
|
||||
it("reports the configured method") {
|
||||
@Test
|
||||
fun `reports the configured method`() {
|
||||
val config = TestConfig(mapOf("methodNames" to listOf("toDo", "todo2")))
|
||||
val findings = ExceptionRaisedInUnexpectedLocation(config).compileAndLint(
|
||||
"""
|
||||
@@ -34,7 +38,8 @@ class ExceptionRaisedInUnexpectedLocationSpec : Spek({
|
||||
assertThat(findings).hasSize(1)
|
||||
}
|
||||
|
||||
it("reports the configured method with String") {
|
||||
@Test
|
||||
fun `reports the configured method with String`() {
|
||||
val config = TestConfig(mapOf("methodNames" to "toDo,todo2"))
|
||||
val findings = ExceptionRaisedInUnexpectedLocation(config).compileAndLint(
|
||||
"""
|
||||
@@ -45,4 +50,4 @@ class ExceptionRaisedInUnexpectedLocationSpec : Spek({
|
||||
assertThat(findings).hasSize(1)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,22 +1,21 @@
|
||||
package io.gitlab.arturbosch.detekt.rules.exceptions
|
||||
|
||||
import io.gitlab.arturbosch.detekt.rules.setupKotlinEnvironment
|
||||
import io.gitlab.arturbosch.detekt.rules.KotlinCoreEnvironmentTest
|
||||
import io.gitlab.arturbosch.detekt.test.compileAndLintWithContext
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
||||
import org.spekframework.spek2.Spek
|
||||
import org.spekframework.spek2.style.specification.describe
|
||||
import org.junit.jupiter.api.Nested
|
||||
import org.junit.jupiter.api.Test
|
||||
|
||||
class InstanceOfCheckForExceptionSpec : Spek({
|
||||
setupKotlinEnvironment()
|
||||
@KotlinCoreEnvironmentTest
|
||||
class InstanceOfCheckForExceptionSpec(val env: KotlinCoreEnvironment) {
|
||||
val subject = InstanceOfCheckForException()
|
||||
|
||||
val env: KotlinCoreEnvironment by memoized()
|
||||
val subject by memoized { InstanceOfCheckForException() }
|
||||
|
||||
describe("InstanceOfCheckForException rule") {
|
||||
|
||||
it("has is and as checks") {
|
||||
@Nested
|
||||
inner class `InstanceOfCheckForException rule` {
|
||||
|
||||
@Test
|
||||
fun `has is and as checks`() {
|
||||
val code = """
|
||||
fun x() {
|
||||
try {
|
||||
@@ -30,7 +29,8 @@ class InstanceOfCheckForExceptionSpec : Spek({
|
||||
assertThat(subject.compileAndLintWithContext(env, code)).hasSize(2)
|
||||
}
|
||||
|
||||
it("has nested is and as checks") {
|
||||
@Test
|
||||
fun `has nested is and as checks`() {
|
||||
val code = """
|
||||
fun x() {
|
||||
try {
|
||||
@@ -44,7 +44,8 @@ class InstanceOfCheckForExceptionSpec : Spek({
|
||||
assertThat(subject.compileAndLintWithContext(env, code)).hasSize(2)
|
||||
}
|
||||
|
||||
it("has no instance of check") {
|
||||
@Test
|
||||
fun `has no instance of check`() {
|
||||
val code = """
|
||||
fun x() {
|
||||
try {
|
||||
@@ -60,7 +61,8 @@ class InstanceOfCheckForExceptionSpec : Spek({
|
||||
assertThat(subject.compileAndLintWithContext(env, code)).isEmpty()
|
||||
}
|
||||
|
||||
it("has no checks for the subtype of an exception") {
|
||||
@Test
|
||||
fun `has no checks for the subtype of an exception`() {
|
||||
val code = """
|
||||
interface I
|
||||
|
||||
@@ -75,4 +77,4 @@ class InstanceOfCheckForExceptionSpec : Spek({
|
||||
assertThat(subject.compileAndLintWithContext(env, code)).isEmpty()
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -2,15 +2,17 @@ package io.gitlab.arturbosch.detekt.rules.exceptions
|
||||
|
||||
import io.gitlab.arturbosch.detekt.test.compileAndLint
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.spekframework.spek2.Spek
|
||||
import org.spekframework.spek2.style.specification.describe
|
||||
import org.junit.jupiter.api.Nested
|
||||
import org.junit.jupiter.api.Test
|
||||
|
||||
class NotImplementedDeclarationSpec : Spek({
|
||||
val subject by memoized { NotImplementedDeclaration() }
|
||||
class NotImplementedDeclarationSpec {
|
||||
val subject = NotImplementedDeclaration()
|
||||
|
||||
describe("NotImplementedDeclaration rule") {
|
||||
@Nested
|
||||
inner class `NotImplementedDeclaration rule` {
|
||||
|
||||
it("reports NotImplementedErrors") {
|
||||
@Test
|
||||
fun `reports NotImplementedErrors`() {
|
||||
val code = """
|
||||
fun f() {
|
||||
if (1 == 1) throw NotImplementedError()
|
||||
@@ -19,7 +21,8 @@ class NotImplementedDeclarationSpec : Spek({
|
||||
assertThat(subject.compileAndLint(code)).hasSize(2)
|
||||
}
|
||||
|
||||
it("reports TODO method calls") {
|
||||
@Test
|
||||
fun `reports TODO method calls`() {
|
||||
val code = """
|
||||
fun f() {
|
||||
TODO("not implemented")
|
||||
@@ -28,7 +31,8 @@ class NotImplementedDeclarationSpec : Spek({
|
||||
assertThat(subject.compileAndLint(code)).hasSize(2)
|
||||
}
|
||||
|
||||
it("does not report TODO comments") {
|
||||
@Test
|
||||
fun `does not report TODO comments`() {
|
||||
val code = """
|
||||
fun f() {
|
||||
// TODO
|
||||
@@ -36,4 +40,4 @@ class NotImplementedDeclarationSpec : Spek({
|
||||
assertThat(subject.compileAndLint(code)).isEmpty()
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,21 +1,22 @@
|
||||
package io.gitlab.arturbosch.detekt.rules.exceptions
|
||||
|
||||
import io.gitlab.arturbosch.detekt.rules.setupKotlinEnvironment
|
||||
import io.gitlab.arturbosch.detekt.rules.KotlinCoreEnvironmentTest
|
||||
import io.gitlab.arturbosch.detekt.test.compileAndLintWithContext
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
||||
import org.spekframework.spek2.Spek
|
||||
import org.spekframework.spek2.style.specification.describe
|
||||
import org.junit.jupiter.api.Nested
|
||||
import org.junit.jupiter.api.Test
|
||||
|
||||
class ObjectExtendsThrowableSpec : Spek({
|
||||
setupKotlinEnvironment()
|
||||
@KotlinCoreEnvironmentTest
|
||||
class ObjectExtendsThrowableSpec(val env: KotlinCoreEnvironment) {
|
||||
|
||||
val subject by memoized { ObjectExtendsThrowable() }
|
||||
val env: KotlinCoreEnvironment by memoized()
|
||||
val subject = ObjectExtendsThrowable()
|
||||
|
||||
describe("ObjectExtendsThrowable rule") {
|
||||
@Nested
|
||||
inner class `ObjectExtendsThrowable rule` {
|
||||
|
||||
it("reports top-level objects that extend Throwable") {
|
||||
@Test
|
||||
fun `reports top-level objects that extend Throwable`() {
|
||||
val code = """
|
||||
object BanException : Throwable()
|
||||
object AuthException : RuntimeException()
|
||||
@@ -25,7 +26,8 @@ class ObjectExtendsThrowableSpec : Spek({
|
||||
assertThat(subject.compileAndLintWithContext(env, code)).hasSize(4)
|
||||
}
|
||||
|
||||
it("reports object subtype of sealed class that extends Throwable") {
|
||||
@Test
|
||||
fun `reports object subtype of sealed class that extends Throwable`() {
|
||||
val code = """
|
||||
sealed class DomainException : RuntimeException() {
|
||||
data class Exception1(val prop1: String, val prop2: Boolean) : DomainException()
|
||||
@@ -36,7 +38,8 @@ class ObjectExtendsThrowableSpec : Spek({
|
||||
assertThat(subject.compileAndLintWithContext(env, code)).hasSize(1)
|
||||
}
|
||||
|
||||
it("reports object that extends custom exception") {
|
||||
@Test
|
||||
fun `reports object that extends custom exception`() {
|
||||
val code = """
|
||||
object ObjectCustomException : CustomException("singleton custom exception")
|
||||
|
||||
@@ -45,7 +48,8 @@ class ObjectExtendsThrowableSpec : Spek({
|
||||
assertThat(subject.compileAndLintWithContext(env, code)).hasSize(1)
|
||||
}
|
||||
|
||||
it("reports companion objects that extend Throwable") {
|
||||
@Test
|
||||
fun `reports companion objects that extend Throwable`() {
|
||||
val code = """
|
||||
class Test1 {
|
||||
companion object : Throwable() {
|
||||
@@ -74,7 +78,8 @@ class ObjectExtendsThrowableSpec : Spek({
|
||||
assertThat(subject.compileAndLintWithContext(env, code)).hasSize(4)
|
||||
}
|
||||
|
||||
it("does not report objects that do not extend Throwable") {
|
||||
@Test
|
||||
fun `does not report objects that do not extend Throwable`() {
|
||||
val code = """
|
||||
object BanException
|
||||
object AuthException : CustomException(message = "Authentication failed!")
|
||||
@@ -90,7 +95,8 @@ class ObjectExtendsThrowableSpec : Spek({
|
||||
assertThat(subject.compileAndLintWithContext(env, code)).isEmpty()
|
||||
}
|
||||
|
||||
it("does not report companion objects that do not extend Throwable") {
|
||||
@Test
|
||||
fun `does not report companion objects that do not extend Throwable`() {
|
||||
val code = """
|
||||
class Test1 {
|
||||
companion object {
|
||||
@@ -107,7 +113,8 @@ class ObjectExtendsThrowableSpec : Spek({
|
||||
assertThat(subject.compileAndLintWithContext(env, code)).isEmpty()
|
||||
}
|
||||
|
||||
it("does not report non-objects that do extend Throwable") {
|
||||
@Test
|
||||
fun `does not report non-objects that do extend Throwable`() {
|
||||
val code = """
|
||||
class BanException : Throwable()
|
||||
data class AuthException(val code: Int) : RuntimeException()
|
||||
@@ -126,7 +133,8 @@ class ObjectExtendsThrowableSpec : Spek({
|
||||
assertThat(subject.compileAndLintWithContext(env, code)).isEmpty()
|
||||
}
|
||||
|
||||
it("does not report an anonymous object that extends Throwable") {
|
||||
@Test
|
||||
fun `does not report an anonymous object that extends Throwable`() {
|
||||
val code = """
|
||||
val exception = object : AbstractCustomException() {}
|
||||
|
||||
@@ -135,4 +143,4 @@ class ObjectExtendsThrowableSpec : Spek({
|
||||
assertThat(subject.compileAndLintWithContext(env, code)).isEmpty()
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -2,17 +2,20 @@ package io.gitlab.arturbosch.detekt.rules.exceptions
|
||||
|
||||
import io.gitlab.arturbosch.detekt.test.compileAndLint
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.spekframework.spek2.Spek
|
||||
import org.spekframework.spek2.style.specification.describe
|
||||
import org.junit.jupiter.api.Nested
|
||||
import org.junit.jupiter.api.Test
|
||||
|
||||
class PrintStackTraceSpec : Spek({
|
||||
val subject by memoized { PrintStackTrace() }
|
||||
class PrintStackTraceSpec {
|
||||
val subject = PrintStackTrace()
|
||||
|
||||
describe("PrintStackTrace") {
|
||||
@Nested
|
||||
inner class `print stack trace rule` {
|
||||
|
||||
context("catch clauses with printStacktrace methods") {
|
||||
@Nested
|
||||
inner class `catch clauses with printStacktrace methods` {
|
||||
|
||||
it("prints a stacktrace") {
|
||||
@Test
|
||||
fun `prints a stacktrace`() {
|
||||
val code = """
|
||||
fun x() {
|
||||
try {
|
||||
@@ -23,7 +26,8 @@ class PrintStackTraceSpec : Spek({
|
||||
assertThat(subject.compileAndLint(code)).hasSize(1)
|
||||
}
|
||||
|
||||
it("does not print a stacktrace") {
|
||||
@Test
|
||||
fun `does not print a stacktrace`() {
|
||||
val code = """
|
||||
fun x() {
|
||||
try {
|
||||
@@ -39,9 +43,11 @@ class PrintStackTraceSpec : Spek({
|
||||
}
|
||||
}
|
||||
|
||||
context("a stacktrace printed by a thread") {
|
||||
@Nested
|
||||
inner class `a stacktrace printed by a thread` {
|
||||
|
||||
it("prints one") {
|
||||
@Test
|
||||
fun `prints one`() {
|
||||
val code = """
|
||||
fun x() {
|
||||
Thread.dumpStack()
|
||||
@@ -53,4 +59,4 @@ class PrintStackTraceSpec : Spek({
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -2,15 +2,17 @@ package io.gitlab.arturbosch.detekt.rules.exceptions
|
||||
|
||||
import io.gitlab.arturbosch.detekt.test.compileAndLint
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.spekframework.spek2.Spek
|
||||
import org.spekframework.spek2.style.specification.describe
|
||||
import org.junit.jupiter.api.Nested
|
||||
import org.junit.jupiter.api.Test
|
||||
|
||||
class RethrowCaughtExceptionSpec : Spek({
|
||||
val subject by memoized { RethrowCaughtException() }
|
||||
class RethrowCaughtExceptionSpec {
|
||||
val subject = RethrowCaughtException()
|
||||
|
||||
describe("RethrowCaughtException rule") {
|
||||
@Nested
|
||||
inner class `RethrowCaughtException rule` {
|
||||
|
||||
it("reports when the same exception is rethrown") {
|
||||
@Test
|
||||
fun `reports when the same exception is rethrown`() {
|
||||
val code = """
|
||||
fun f() {
|
||||
try {
|
||||
@@ -22,7 +24,8 @@ class RethrowCaughtExceptionSpec : Spek({
|
||||
assertThat(subject.compileAndLint(code)).hasSize(1)
|
||||
}
|
||||
|
||||
it("does not report when the other exception is rethrown with same name") {
|
||||
@Test
|
||||
fun `does not report when the other exception is rethrown with same name`() {
|
||||
val code = """
|
||||
class A {
|
||||
private lateinit var e: Exception
|
||||
@@ -37,7 +40,8 @@ class RethrowCaughtExceptionSpec : Spek({
|
||||
assertThat(subject.compileAndLint(code)).isEmpty()
|
||||
}
|
||||
|
||||
it("reports when the same exception succeeded by dead code is rethrown") {
|
||||
@Test
|
||||
fun `reports when the same exception succeeded by dead code is rethrown`() {
|
||||
val code = """
|
||||
fun f() {
|
||||
try {
|
||||
@@ -50,7 +54,8 @@ class RethrowCaughtExceptionSpec : Spek({
|
||||
assertThat(subject.compileAndLint(code)).hasSize(1)
|
||||
}
|
||||
|
||||
it("reports when the same nested exception is rethrown") {
|
||||
@Test
|
||||
fun `reports when the same nested exception is rethrown`() {
|
||||
val code = """
|
||||
fun f() {
|
||||
try {
|
||||
@@ -65,7 +70,8 @@ class RethrowCaughtExceptionSpec : Spek({
|
||||
assertThat(subject.compileAndLint(code)).hasSize(1)
|
||||
}
|
||||
|
||||
it("does not report a wrapped exception") {
|
||||
@Test
|
||||
fun `does not report a wrapped exception`() {
|
||||
val code = """
|
||||
fun f() {
|
||||
try {
|
||||
@@ -77,7 +83,8 @@ class RethrowCaughtExceptionSpec : Spek({
|
||||
assertThat(subject.compileAndLint(code)).isEmpty()
|
||||
}
|
||||
|
||||
it("does not report wrapped exceptions") {
|
||||
@Test
|
||||
fun `does not report wrapped exceptions`() {
|
||||
val code = """
|
||||
fun f() {
|
||||
try {
|
||||
@@ -91,7 +98,8 @@ class RethrowCaughtExceptionSpec : Spek({
|
||||
assertThat(subject.compileAndLint(code)).isEmpty()
|
||||
}
|
||||
|
||||
it("does not report logged exceptions") {
|
||||
@Test
|
||||
fun `does not report logged exceptions`() {
|
||||
val code = """
|
||||
fun f() {
|
||||
try {
|
||||
@@ -106,7 +114,8 @@ class RethrowCaughtExceptionSpec : Spek({
|
||||
assertThat(subject.compileAndLint(code)).isEmpty()
|
||||
}
|
||||
|
||||
it("does not report when taking specific actions before throwing the exception") {
|
||||
@Test
|
||||
fun `does not report when taking specific actions before throwing the exception`() {
|
||||
val code = """
|
||||
fun f() {
|
||||
try {
|
||||
@@ -124,7 +133,8 @@ class RethrowCaughtExceptionSpec : Spek({
|
||||
assertThat(subject.compileAndLint(code)).isEmpty()
|
||||
}
|
||||
|
||||
it("does not report when exception rethrown only in first catch") {
|
||||
@Test
|
||||
fun `does not report when exception rethrown only in first catch`() {
|
||||
val code = """
|
||||
fun f() {
|
||||
try {
|
||||
@@ -138,7 +148,8 @@ class RethrowCaughtExceptionSpec : Spek({
|
||||
assertThat(subject.compileAndLint(code)).isEmpty()
|
||||
}
|
||||
|
||||
it("does not report when some work is done in last catch") {
|
||||
@Test
|
||||
fun `does not report when some work is done in last catch`() {
|
||||
val code = """
|
||||
fun f() {
|
||||
try {
|
||||
@@ -153,7 +164,8 @@ class RethrowCaughtExceptionSpec : Spek({
|
||||
assertThat(subject.compileAndLint(code)).isEmpty()
|
||||
}
|
||||
|
||||
it("does not report when there is no catch clauses") {
|
||||
@Test
|
||||
fun `does not report when there is no catch clauses`() {
|
||||
val code = """
|
||||
fun f() {
|
||||
try {
|
||||
@@ -164,7 +176,8 @@ class RethrowCaughtExceptionSpec : Spek({
|
||||
assertThat(subject.compileAndLint(code)).isEmpty()
|
||||
}
|
||||
|
||||
it("reports when exception rethrown in last catch") {
|
||||
@Test
|
||||
fun `reports when exception rethrown in last catch`() {
|
||||
val code = """
|
||||
fun f() {
|
||||
try {
|
||||
@@ -178,7 +191,8 @@ class RethrowCaughtExceptionSpec : Spek({
|
||||
assertThat(subject.compileAndLint(code)).hasSize(1)
|
||||
}
|
||||
|
||||
it("reports 2 violations for each catch") {
|
||||
@Test
|
||||
fun `reports 2 violations for each catch`() {
|
||||
val code = """
|
||||
fun f() {
|
||||
try {
|
||||
@@ -197,4 +211,4 @@ class RethrowCaughtExceptionSpec : Spek({
|
||||
assertThat(result[1].startPosition.line == 7).isTrue
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,22 +1,23 @@
|
||||
package io.gitlab.arturbosch.detekt.rules.exceptions
|
||||
|
||||
import io.gitlab.arturbosch.detekt.rules.setupKotlinEnvironment
|
||||
import io.gitlab.arturbosch.detekt.rules.KotlinCoreEnvironmentTest
|
||||
import io.gitlab.arturbosch.detekt.test.TestConfig
|
||||
import io.gitlab.arturbosch.detekt.test.assertThat
|
||||
import io.gitlab.arturbosch.detekt.test.compileAndLintWithContext
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
||||
import org.spekframework.spek2.Spek
|
||||
import org.spekframework.spek2.style.specification.describe
|
||||
import org.junit.jupiter.api.Nested
|
||||
import org.junit.jupiter.api.Test
|
||||
|
||||
class ReturnFromFinallySpec : Spek({
|
||||
setupKotlinEnvironment()
|
||||
@KotlinCoreEnvironmentTest
|
||||
class ReturnFromFinallySpec(val env: KotlinCoreEnvironment) {
|
||||
|
||||
val subject by memoized { ReturnFromFinally() }
|
||||
val env: KotlinCoreEnvironment by memoized()
|
||||
val subject = ReturnFromFinally()
|
||||
|
||||
describe("ReturnFromFinally rule") {
|
||||
@Nested
|
||||
inner class `ReturnFromFinally rule` {
|
||||
|
||||
context("a finally block with a return statement") {
|
||||
@Nested
|
||||
inner class `a finally block with a return statement` {
|
||||
val code = """
|
||||
fun x() {
|
||||
try {
|
||||
@@ -26,13 +27,15 @@ class ReturnFromFinallySpec : Spek({
|
||||
}
|
||||
"""
|
||||
|
||||
it("should report") {
|
||||
@Test
|
||||
fun `should report`() {
|
||||
val findings = subject.compileAndLintWithContext(env, code)
|
||||
assertThat(findings).hasSize(1)
|
||||
}
|
||||
}
|
||||
|
||||
context("a finally block with no return statement") {
|
||||
@Nested
|
||||
inner class `a finally block with no return statement` {
|
||||
val code = """
|
||||
fun x() {
|
||||
try {
|
||||
@@ -41,13 +44,15 @@ class ReturnFromFinallySpec : Spek({
|
||||
}
|
||||
"""
|
||||
|
||||
it("should not report") {
|
||||
@Test
|
||||
fun `should not report`() {
|
||||
val findings = subject.compileAndLintWithContext(env, code)
|
||||
assertThat(findings).isEmpty()
|
||||
}
|
||||
}
|
||||
|
||||
context("a finally block with a nested return statement") {
|
||||
@Nested
|
||||
inner class `a finally block with a nested return statement` {
|
||||
val code = """
|
||||
fun x() {
|
||||
try {
|
||||
@@ -59,13 +64,15 @@ class ReturnFromFinallySpec : Spek({
|
||||
}
|
||||
"""
|
||||
|
||||
it("should report") {
|
||||
@Test
|
||||
fun `should report`() {
|
||||
val findings = subject.compileAndLintWithContext(env, code)
|
||||
assertThat(findings).hasSize(1)
|
||||
}
|
||||
}
|
||||
|
||||
context("a finally block with a return in an inner function") {
|
||||
@Nested
|
||||
inner class `a finally block with a return in an inner function` {
|
||||
val code = """
|
||||
fun x() {
|
||||
try {
|
||||
@@ -78,13 +85,15 @@ class ReturnFromFinallySpec : Spek({
|
||||
}
|
||||
"""
|
||||
|
||||
it("should not report") {
|
||||
@Test
|
||||
fun `should not report`() {
|
||||
val findings = subject.compileAndLintWithContext(env, code)
|
||||
assertThat(findings).isEmpty()
|
||||
}
|
||||
}
|
||||
|
||||
context("a finally block with a return as labelled expression") {
|
||||
@Nested
|
||||
inner class `a finally block with a return as labelled expression` {
|
||||
val code = """
|
||||
fun x() {
|
||||
label@{
|
||||
@@ -95,20 +104,25 @@ class ReturnFromFinallySpec : Spek({
|
||||
}
|
||||
}
|
||||
"""
|
||||
it("should report when ignoreLabeled is false") {
|
||||
|
||||
@Test
|
||||
fun `should report when ignoreLabeled is false`() {
|
||||
val findings = subject.compileAndLintWithContext(env, code)
|
||||
assertThat(findings).hasSize(1)
|
||||
}
|
||||
|
||||
it("should not report when ignoreLabeled is true") {
|
||||
@Test
|
||||
fun `should not report when ignoreLabeled is true`() {
|
||||
val config = TestConfig(mapOf("ignoreLabeled" to "true"))
|
||||
val findings = ReturnFromFinally(config).compileAndLintWithContext(env, code)
|
||||
assertThat(findings).isEmpty()
|
||||
}
|
||||
}
|
||||
|
||||
context("a finally block as expression for property") {
|
||||
it("should report") {
|
||||
@Nested
|
||||
inner class `a finally block as expression for property` {
|
||||
@Test
|
||||
fun `should report`() {
|
||||
val code = """
|
||||
val expression = try {
|
||||
"try"
|
||||
@@ -125,8 +139,10 @@ class ReturnFromFinallySpec : Spek({
|
||||
}
|
||||
}
|
||||
|
||||
context("a finally block as expression for method") {
|
||||
it("should report") {
|
||||
@Nested
|
||||
inner class `a finally block as expression for method` {
|
||||
@Test
|
||||
fun `should report`() {
|
||||
val code = """
|
||||
fun expression() = try {
|
||||
"try"
|
||||
@@ -143,8 +159,10 @@ class ReturnFromFinallySpec : Spek({
|
||||
}
|
||||
}
|
||||
|
||||
context("when a finally block called method that return value") {
|
||||
it("should report") {
|
||||
@Nested
|
||||
inner class `when a finally block called method that return value` {
|
||||
@Test
|
||||
fun `should report`() {
|
||||
val code = """
|
||||
fun expression() = try {
|
||||
"try"
|
||||
@@ -163,8 +181,10 @@ class ReturnFromFinallySpec : Spek({
|
||||
}
|
||||
}
|
||||
|
||||
context("when finally block absents in expression for property") {
|
||||
it("shouldn't report") {
|
||||
@Nested
|
||||
inner class `when finally block absents in expression for property` {
|
||||
@Test
|
||||
fun `shouldn't report`() {
|
||||
val code = """
|
||||
val expression = try {
|
||||
"try"
|
||||
@@ -179,9 +199,11 @@ class ReturnFromFinallySpec : Spek({
|
||||
}
|
||||
}
|
||||
|
||||
context("when finally block absents in expression for method") {
|
||||
@Nested
|
||||
inner class `when finally block absents in expression for method` {
|
||||
|
||||
it("shouldn't report") {
|
||||
@Test
|
||||
fun `shouldn't report`() {
|
||||
val code = """
|
||||
fun expression() = try {
|
||||
"try"
|
||||
@@ -196,8 +218,10 @@ class ReturnFromFinallySpec : Spek({
|
||||
}
|
||||
}
|
||||
|
||||
context("when try catch finally block is independent") {
|
||||
it("shouldn't report") {
|
||||
@Nested
|
||||
inner class `when try catch finally block is independent` {
|
||||
@Test
|
||||
fun `shouldn't report`() {
|
||||
val code = """
|
||||
fun expression() {
|
||||
try {
|
||||
@@ -216,8 +240,10 @@ class ReturnFromFinallySpec : Spek({
|
||||
}
|
||||
}
|
||||
|
||||
context("when finally block doesn't contain return value") {
|
||||
it("shouldn't report") {
|
||||
@Nested
|
||||
inner class `when finally block doesn't contain return value` {
|
||||
@Test
|
||||
fun `shouldn't report`() {
|
||||
val code = """
|
||||
val expression = try {
|
||||
"try"
|
||||
@@ -234,8 +260,10 @@ class ReturnFromFinallySpec : Spek({
|
||||
}
|
||||
}
|
||||
|
||||
context("when return value in finally block is property") {
|
||||
it("should report") {
|
||||
@Nested
|
||||
inner class `when return value in finally block is property` {
|
||||
@Test
|
||||
fun `should report`() {
|
||||
val code = """
|
||||
val property: String = "property"
|
||||
val expression = try {
|
||||
@@ -254,4 +282,4 @@ class ReturnFromFinallySpec : Spek({
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -3,15 +3,19 @@ package io.gitlab.arturbosch.detekt.rules.exceptions
|
||||
import io.gitlab.arturbosch.detekt.test.TestConfig
|
||||
import io.gitlab.arturbosch.detekt.test.compileAndLint
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.spekframework.spek2.Spek
|
||||
import org.spekframework.spek2.style.specification.describe
|
||||
import org.junit.jupiter.api.Nested
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.params.ParameterizedTest
|
||||
import org.junit.jupiter.params.provider.MethodSource
|
||||
|
||||
class SwallowedExceptionSpec : Spek({
|
||||
val subject by memoized { SwallowedException() }
|
||||
class SwallowedExceptionSpec {
|
||||
val subject = SwallowedException()
|
||||
|
||||
describe("SwallowedException rule") {
|
||||
@Nested
|
||||
inner class `SwallowedException rule` {
|
||||
|
||||
it("reports a swallowed exception") {
|
||||
@Test
|
||||
fun `reports a swallowed exception`() {
|
||||
val code = """
|
||||
fun f() {
|
||||
try {
|
||||
@@ -23,7 +27,8 @@ class SwallowedExceptionSpec : Spek({
|
||||
assertThat(subject.compileAndLint(code)).hasSize(1)
|
||||
}
|
||||
|
||||
it("reports swallowed exceptions only using exception strings") {
|
||||
@Test
|
||||
fun `reports swallowed exceptions only using exception strings`() {
|
||||
val code = """
|
||||
fun f() {
|
||||
try {
|
||||
@@ -37,7 +42,8 @@ class SwallowedExceptionSpec : Spek({
|
||||
assertThat(subject.compileAndLint(code)).hasSize(2)
|
||||
}
|
||||
|
||||
it("reports swallowed exceptions only using exception strings via variables") {
|
||||
@Test
|
||||
fun `reports swallowed exceptions only using exception strings via variables`() {
|
||||
val code = """
|
||||
fun f() {
|
||||
try {
|
||||
@@ -53,7 +59,8 @@ class SwallowedExceptionSpec : Spek({
|
||||
assertThat(subject.compileAndLint(code)).hasSize(2)
|
||||
}
|
||||
|
||||
it("reports swallowed exceptions only using exception strings via variables in 'if' block") {
|
||||
@Test
|
||||
fun `reports swallowed exceptions only using exception strings via variables in 'if' block`() {
|
||||
val code = """
|
||||
fun f() {
|
||||
try {
|
||||
@@ -73,7 +80,8 @@ class SwallowedExceptionSpec : Spek({
|
||||
assertThat(subject.compileAndLint(code)).hasSize(2)
|
||||
}
|
||||
|
||||
it("reports swallowed exceptions when it has multiple throw expressions") {
|
||||
@Test
|
||||
fun `reports swallowed exceptions when it has multiple throw expressions`() {
|
||||
val code = """
|
||||
fun f(condition: Boolean) {
|
||||
try {
|
||||
@@ -89,7 +97,8 @@ class SwallowedExceptionSpec : Spek({
|
||||
assertThat(subject.compileAndLint(code)).hasSize(1)
|
||||
}
|
||||
|
||||
it("reports swallowed exceptions when it has multiple throw expressions 2") {
|
||||
@Test
|
||||
fun `reports swallowed exceptions when it has multiple throw expressions 2`() {
|
||||
val code = """
|
||||
fun f(condition: Boolean) {
|
||||
try {
|
||||
@@ -105,7 +114,8 @@ class SwallowedExceptionSpec : Spek({
|
||||
assertThat(subject.compileAndLint(code)).hasSize(1)
|
||||
}
|
||||
|
||||
it("reports nested swallowed exceptions") {
|
||||
@Test
|
||||
fun `reports nested swallowed exceptions`() {
|
||||
val code = """
|
||||
fun f(condition: Boolean) {
|
||||
try {
|
||||
@@ -122,7 +132,8 @@ class SwallowedExceptionSpec : Spek({
|
||||
assertThat(subject.compileAndLint(code)).hasSize(1)
|
||||
}
|
||||
|
||||
it("reports a swallowed exception that is not logged") {
|
||||
@Test
|
||||
fun `reports a swallowed exception that is not logged`() {
|
||||
val code = """
|
||||
fun f() {
|
||||
try {
|
||||
@@ -134,15 +145,20 @@ class SwallowedExceptionSpec : Spek({
|
||||
assertThat(subject.compileAndLint(code)).hasSize(1)
|
||||
}
|
||||
|
||||
listOf(listOf("IllegalArgumentException"), "IllegalArgumentException").forEach { ignoredExceptionValue ->
|
||||
context("ignores given exception types config") {
|
||||
@Nested
|
||||
inner class `when given listOf(IllegalArgumentException)` {
|
||||
val ignoredExceptionValue = listOf("IllegalArgumentException")
|
||||
|
||||
val config by memoized {
|
||||
@Nested
|
||||
inner class `ignores given exception types config` {
|
||||
|
||||
val config =
|
||||
TestConfig("ignoredExceptionTypes" to ignoredExceptionValue)
|
||||
}
|
||||
val rule by memoized { SwallowedException(config) }
|
||||
|
||||
it("ignores given exception type in configuration") {
|
||||
val rule = SwallowedException(config)
|
||||
|
||||
@Test
|
||||
fun `ignores given exception type in configuration`() {
|
||||
val code = """
|
||||
fun f() {
|
||||
try {
|
||||
@@ -153,7 +169,8 @@ class SwallowedExceptionSpec : Spek({
|
||||
assertThat(rule.compileAndLint(code)).isEmpty()
|
||||
}
|
||||
|
||||
it("reports exception type that is missing in the configuration") {
|
||||
@Test
|
||||
fun `reports exception type that is missing in the configuration`() {
|
||||
val code = """
|
||||
fun f() {
|
||||
try {
|
||||
@@ -166,12 +183,52 @@ class SwallowedExceptionSpec : Spek({
|
||||
}
|
||||
}
|
||||
|
||||
context("ignores given exception name config") {
|
||||
@Nested
|
||||
inner class `when given IllegalArgumentException` {
|
||||
val ignoredExceptionValue = "IllegalArgumentException"
|
||||
|
||||
val config by memoized { TestConfig(mapOf("allowedExceptionNameRegex" to "myIgnore")) }
|
||||
val rule by memoized { SwallowedException(config) }
|
||||
@Nested
|
||||
inner class `ignores given exception types config` {
|
||||
|
||||
it("ignores given exception name") {
|
||||
val config =
|
||||
TestConfig("ignoredExceptionTypes" to ignoredExceptionValue)
|
||||
|
||||
val rule = SwallowedException(config)
|
||||
|
||||
@Test
|
||||
fun `ignores given exception type in configuration`() {
|
||||
val code = """
|
||||
fun f() {
|
||||
try {
|
||||
} catch (e: IllegalArgumentException) {
|
||||
}
|
||||
}
|
||||
"""
|
||||
assertThat(rule.compileAndLint(code)).isEmpty()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `reports exception type that is missing in the configuration`() {
|
||||
val code = """
|
||||
fun f() {
|
||||
try {
|
||||
} catch (e: Exception) {
|
||||
}
|
||||
}
|
||||
"""
|
||||
assertThat(rule.compileAndLint(code)).hasSize(1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
inner class `ignores given exception name config` {
|
||||
|
||||
val config = TestConfig(mapOf("allowedExceptionNameRegex" to "myIgnore"))
|
||||
val rule = SwallowedException(config)
|
||||
|
||||
@Test
|
||||
fun `ignores given exception name`() {
|
||||
val code = """
|
||||
fun f() {
|
||||
try {
|
||||
@@ -182,7 +239,8 @@ class SwallowedExceptionSpec : Spek({
|
||||
assertThat(rule.compileAndLint(code)).isEmpty()
|
||||
}
|
||||
|
||||
it("reports exception name") {
|
||||
@Test
|
||||
fun `reports exception name`() {
|
||||
val code = """
|
||||
fun f() {
|
||||
try {
|
||||
@@ -194,7 +252,8 @@ class SwallowedExceptionSpec : Spek({
|
||||
}
|
||||
}
|
||||
|
||||
it("does not report wrapped exceptions") {
|
||||
@Test
|
||||
fun `does not report wrapped exceptions`() {
|
||||
val code = """
|
||||
fun f() {
|
||||
try {
|
||||
@@ -208,7 +267,8 @@ class SwallowedExceptionSpec : Spek({
|
||||
assertThat(subject.compileAndLint(code)).isEmpty()
|
||||
}
|
||||
|
||||
it("does not report used exception variables") {
|
||||
@Test
|
||||
fun `does not report used exception variables`() {
|
||||
val code = """
|
||||
fun f() {
|
||||
try {
|
||||
@@ -222,9 +282,10 @@ class SwallowedExceptionSpec : Spek({
|
||||
assertThat(subject.compileAndLint(code)).isEmpty()
|
||||
}
|
||||
|
||||
SwallowedException.EXCEPTIONS_IGNORED_BY_DEFAULT.forEach { exceptionName ->
|
||||
it("ignores $exceptionName in the catch clause by default") {
|
||||
val code = """
|
||||
@ParameterizedTest(name = "ignores {0} in the catch clause by default")
|
||||
@MethodSource("io.gitlab.arturbosch.detekt.rules.exceptions.SwallowedException#getEXCEPTIONS_IGNORED_BY_DEFAULT")
|
||||
fun `ignores $exceptionName in the catch clause by default`(exceptionName: String) {
|
||||
val code = """
|
||||
import java.net.MalformedURLException
|
||||
import java.text.ParseException
|
||||
|
||||
@@ -235,17 +296,19 @@ class SwallowedExceptionSpec : Spek({
|
||||
}
|
||||
}
|
||||
"""
|
||||
assertThat(subject.compileAndLint(code)).isEmpty()
|
||||
assertThat(subject.compileAndLint(code)).isEmpty()
|
||||
}
|
||||
|
||||
@ParameterizedTest(name = "ignores {0} in the catch body by default")
|
||||
@MethodSource("io.gitlab.arturbosch.detekt.rules.exceptions.SwallowedException#getEXCEPTIONS_IGNORED_BY_DEFAULT")
|
||||
fun `ignores $exceptionName in the catch body by default`(exceptionName: String) {
|
||||
val exceptionInstantiation = if (exceptionName == "ParseException") {
|
||||
"$exceptionName(\"\", 0)"
|
||||
} else {
|
||||
"$exceptionName(\"\")"
|
||||
}
|
||||
|
||||
it("ignores $exceptionName in the catch body by default") {
|
||||
val exceptionInstantiation = if (exceptionName == "ParseException") {
|
||||
"$exceptionName(\"\", 0)"
|
||||
} else {
|
||||
"$exceptionName(\"\")"
|
||||
}
|
||||
|
||||
val code = """
|
||||
val code = """
|
||||
import java.net.MalformedURLException
|
||||
import java.text.ParseException
|
||||
|
||||
@@ -256,8 +319,7 @@ class SwallowedExceptionSpec : Spek({
|
||||
}
|
||||
}
|
||||
"""
|
||||
assertThat(subject.compileAndLint(code)).isEmpty()
|
||||
}
|
||||
assertThat(subject.compileAndLint(code)).isEmpty()
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -2,15 +2,17 @@ package io.gitlab.arturbosch.detekt.rules.exceptions
|
||||
|
||||
import io.gitlab.arturbosch.detekt.test.compileAndLint
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.spekframework.spek2.Spek
|
||||
import org.spekframework.spek2.style.specification.describe
|
||||
import org.junit.jupiter.api.Nested
|
||||
import org.junit.jupiter.api.Test
|
||||
|
||||
class ThrowingExceptionFromFinallySpec : Spek({
|
||||
val subject by memoized { ThrowingExceptionFromFinally() }
|
||||
class ThrowingExceptionFromFinallySpec {
|
||||
val subject = ThrowingExceptionFromFinally()
|
||||
|
||||
describe("ThrowingExceptionFromFinally rule") {
|
||||
@Nested
|
||||
inner class `ThrowingExceptionFromFinally rule` {
|
||||
|
||||
it("should report a throw expression") {
|
||||
@Test
|
||||
fun `should report a throw expression`() {
|
||||
val code = """
|
||||
fun x() {
|
||||
try {
|
||||
@@ -23,7 +25,8 @@ class ThrowingExceptionFromFinallySpec : Spek({
|
||||
assertThat(subject.compileAndLint(code)).hasSize(1)
|
||||
}
|
||||
|
||||
it("should report a nested throw expression") {
|
||||
@Test
|
||||
fun `should report a nested throw expression`() {
|
||||
val code = """
|
||||
fun x() {
|
||||
try {
|
||||
@@ -34,7 +37,8 @@ class ThrowingExceptionFromFinallySpec : Spek({
|
||||
assertThat(subject.compileAndLint(code)).hasSize(1)
|
||||
}
|
||||
|
||||
it("should not report a finally expression without a throw expression") {
|
||||
@Test
|
||||
fun `should not report a finally expression without a throw expression`() {
|
||||
val code = """
|
||||
fun x() {
|
||||
try {
|
||||
@@ -45,4 +49,4 @@ class ThrowingExceptionFromFinallySpec : Spek({
|
||||
assertThat(subject.compileAndLint(code)).isEmpty()
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -3,15 +3,17 @@ package io.gitlab.arturbosch.detekt.rules.exceptions
|
||||
import io.gitlab.arturbosch.detekt.test.compileAndLint
|
||||
import io.gitlab.arturbosch.detekt.test.lint
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.spekframework.spek2.Spek
|
||||
import org.spekframework.spek2.style.specification.describe
|
||||
import org.junit.jupiter.api.Nested
|
||||
import org.junit.jupiter.api.Test
|
||||
|
||||
class ThrowingExceptionInMainSpec : Spek({
|
||||
val subject by memoized { ThrowingExceptionInMain() }
|
||||
class ThrowingExceptionInMainSpec {
|
||||
val subject = ThrowingExceptionInMain()
|
||||
|
||||
describe("ThrowingExceptionInMain rule") {
|
||||
@Nested
|
||||
inner class `ThrowingExceptionInMain rule` {
|
||||
|
||||
it("reports a runnable main function which throws an exception") {
|
||||
@Test
|
||||
fun `reports a runnable main function which throws an exception`() {
|
||||
val code = """
|
||||
fun main(args: Array<String>) { throw IllegalArgumentException() }
|
||||
fun main(vararg args: String) { throw IllegalArgumentException() }
|
||||
@@ -20,7 +22,8 @@ class ThrowingExceptionInMainSpec : Spek({
|
||||
assertThat(subject.compileAndLint(code)).hasSize(3)
|
||||
}
|
||||
|
||||
it("reports runnable main functions with @JvmStatic annotation which throw an exception") {
|
||||
@Test
|
||||
fun `reports runnable main functions with @JvmStatic annotation which throw an exception`() {
|
||||
val code = """
|
||||
class A {
|
||||
companion object {
|
||||
@@ -44,7 +47,8 @@ class ThrowingExceptionInMainSpec : Spek({
|
||||
assertThat(subject.compileAndLint(code)).hasSize(3)
|
||||
}
|
||||
|
||||
it("does not report top level main functions with a wrong signature") {
|
||||
@Test
|
||||
fun `does not report top level main functions with a wrong signature`() {
|
||||
val code = """
|
||||
private fun main(args: Array<String>) { throw IllegalArgumentException() }
|
||||
private fun main() { throw IllegalArgumentException() }
|
||||
@@ -54,7 +58,8 @@ class ThrowingExceptionInMainSpec : Spek({
|
||||
assertThat(subject.lint(code)).isEmpty()
|
||||
}
|
||||
|
||||
it("does not report top level main functions which throw no exception") {
|
||||
@Test
|
||||
fun `does not report top level main functions which throw no exception`() {
|
||||
val code = """
|
||||
fun main(args: Array<String>) { }
|
||||
fun main() { }
|
||||
@@ -63,7 +68,8 @@ class ThrowingExceptionInMainSpec : Spek({
|
||||
assertThat(subject.compileAndLint(code)).isEmpty()
|
||||
}
|
||||
|
||||
it("does not report top level main functions with expression body which throw no exception") {
|
||||
@Test
|
||||
fun `does not report top level main functions with expression body which throw no exception`() {
|
||||
val code = """
|
||||
fun main(args: Array<String>) = ""
|
||||
fun main() = Unit
|
||||
@@ -71,7 +77,8 @@ class ThrowingExceptionInMainSpec : Spek({
|
||||
assertThat(subject.compileAndLint(code)).isEmpty()
|
||||
}
|
||||
|
||||
it("does not report main functions with no @JvmStatic annotation inside a class") {
|
||||
@Test
|
||||
fun `does not report main functions with no @JvmStatic annotation inside a class`() {
|
||||
val code = """
|
||||
class A {
|
||||
fun main(args: Array<String>) { throw IllegalArgumentException() }
|
||||
@@ -84,4 +91,4 @@ class ThrowingExceptionInMainSpec : Spek({
|
||||
assertThat(subject.compileAndLint(code)).isEmpty()
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -3,19 +3,20 @@ package io.gitlab.arturbosch.detekt.rules.exceptions
|
||||
import io.gitlab.arturbosch.detekt.test.TestConfig
|
||||
import io.gitlab.arturbosch.detekt.test.compileAndLint
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.spekframework.spek2.Spek
|
||||
import org.spekframework.spek2.style.specification.describe
|
||||
import org.junit.jupiter.api.Nested
|
||||
import org.junit.jupiter.api.Test
|
||||
|
||||
class ThrowingExceptionsWithoutMessageOrCauseSpec : Spek({
|
||||
val subject by memoized {
|
||||
class ThrowingExceptionsWithoutMessageOrCauseSpec {
|
||||
val subject =
|
||||
ThrowingExceptionsWithoutMessageOrCause(
|
||||
TestConfig("exceptions" to listOf("IllegalArgumentException"))
|
||||
)
|
||||
}
|
||||
|
||||
describe("ThrowingExceptionsWithoutMessageOrCause rule") {
|
||||
@Nested
|
||||
inner class `ThrowingExceptionsWithoutMessageOrCause rule` {
|
||||
|
||||
context("several exception calls") {
|
||||
@Nested
|
||||
inner class `several exception calls` {
|
||||
|
||||
val code = """
|
||||
fun x() {
|
||||
@@ -24,20 +25,24 @@ class ThrowingExceptionsWithoutMessageOrCauseSpec : Spek({
|
||||
throw IllegalArgumentException()
|
||||
}"""
|
||||
|
||||
it("reports calls to the default constructor") {
|
||||
@Test
|
||||
fun `reports calls to the default constructor`() {
|
||||
assertThat(subject.compileAndLint(code)).hasSize(2)
|
||||
}
|
||||
|
||||
it("does not report calls to the default constructor with empty configuration") {
|
||||
@Test
|
||||
fun `does not report calls to the default constructor with empty configuration`() {
|
||||
val config = TestConfig("exceptions" to emptyList<String>())
|
||||
val findings = ThrowingExceptionsWithoutMessageOrCause(config).compileAndLint(code)
|
||||
assertThat(findings).isEmpty()
|
||||
}
|
||||
}
|
||||
|
||||
context("a test code which asserts an exception") {
|
||||
@Nested
|
||||
inner class `a test code which asserts an exception` {
|
||||
|
||||
it("does not report a call to this exception") {
|
||||
@Test
|
||||
fun `does not report a call to this exception`() {
|
||||
val code = """
|
||||
fun test() {
|
||||
org.assertj.core.api.Assertions.assertThatIllegalArgumentException().isThrownBy { println() }
|
||||
@@ -47,4 +52,4 @@ class ThrowingExceptionsWithoutMessageOrCauseSpec : Spek({
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -2,15 +2,18 @@ package io.gitlab.arturbosch.detekt.rules.exceptions
|
||||
|
||||
import io.gitlab.arturbosch.detekt.test.compileAndLint
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.spekframework.spek2.Spek
|
||||
import org.spekframework.spek2.style.specification.describe
|
||||
import org.junit.jupiter.api.DisplayName
|
||||
import org.junit.jupiter.api.Nested
|
||||
import org.junit.jupiter.api.Test
|
||||
|
||||
class ThrowingNewInstanceOfSameExceptionSpec : Spek({
|
||||
val subject by memoized { ThrowingNewInstanceOfSameException() }
|
||||
class ThrowingNewInstanceOfSameExceptionSpec {
|
||||
val subject = ThrowingNewInstanceOfSameException()
|
||||
|
||||
describe("ThrowingNewInstanceOfSameException rule") {
|
||||
@Nested
|
||||
inner class `ThrowingNewInstanceOfSameException rule` {
|
||||
|
||||
context("a catch block which rethrows a new instance of the caught exception") {
|
||||
@Nested
|
||||
inner class `a catch block which rethrows a new instance of the caught exception` {
|
||||
val code = """
|
||||
fun x() {
|
||||
try {
|
||||
@@ -20,13 +23,15 @@ class ThrowingNewInstanceOfSameExceptionSpec : Spek({
|
||||
}
|
||||
"""
|
||||
|
||||
it("should report") {
|
||||
@Test
|
||||
fun `should report`() {
|
||||
val findings = subject.compileAndLint(code)
|
||||
assertThat(findings).hasSize(1)
|
||||
}
|
||||
}
|
||||
|
||||
context("a catch block which rethrows a new instance of another exception") {
|
||||
@Nested
|
||||
inner class `a catch block which rethrows a new instance of another exception` {
|
||||
val code = """
|
||||
fun x() {
|
||||
try {
|
||||
@@ -36,13 +41,16 @@ class ThrowingNewInstanceOfSameExceptionSpec : Spek({
|
||||
}
|
||||
"""
|
||||
|
||||
it("should not report") {
|
||||
@Test
|
||||
fun `should not report`() {
|
||||
val findings = subject.compileAndLint(code)
|
||||
assertThat(findings).isEmpty()
|
||||
}
|
||||
}
|
||||
|
||||
context("a catch block which throws a new instance of the same exception type without wrapping the caught exception") {
|
||||
@Nested
|
||||
@DisplayName("a catch block which throws a new instance of the same exception type without wrapping the caught exception")
|
||||
inner class CatchBlockThrowingSameExceptionWithoutWrapping {
|
||||
val code = """
|
||||
fun x() {
|
||||
try {
|
||||
@@ -52,10 +60,11 @@ class ThrowingNewInstanceOfSameExceptionSpec : Spek({
|
||||
}
|
||||
"""
|
||||
|
||||
it("should not report") {
|
||||
@Test
|
||||
fun `should not report`() {
|
||||
val findings = subject.compileAndLint(code)
|
||||
assertThat(findings).isEmpty()
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -5,18 +5,20 @@ import io.gitlab.arturbosch.detekt.test.TestConfig
|
||||
import io.gitlab.arturbosch.detekt.test.compileAndLint
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.assertj.core.api.Assertions.assertThatExceptionOfType
|
||||
import org.spekframework.spek2.Spek
|
||||
import org.spekframework.spek2.style.specification.describe
|
||||
import org.junit.jupiter.api.Nested
|
||||
import org.junit.jupiter.api.Test
|
||||
import java.util.regex.PatternSyntaxException
|
||||
|
||||
private const val CAUGHT_EXCEPTIONS_PROPERTY = "exceptionNames"
|
||||
private const val ALLOWED_EXCEPTION_NAME_REGEX = "allowedExceptionNameRegex"
|
||||
|
||||
class TooGenericExceptionCaughtSpec : Spek({
|
||||
class TooGenericExceptionCaughtSpec {
|
||||
|
||||
describe("a file with many caught exceptions") {
|
||||
@Nested
|
||||
inner class `a file with many caught exceptions` {
|
||||
|
||||
it("should find one of each kind of defaults") {
|
||||
@Test
|
||||
fun `should find one of each kind of defaults`() {
|
||||
val rule = TooGenericExceptionCaught(Config.empty)
|
||||
|
||||
val findings = rule.compileAndLint(tooGenericExceptionCode)
|
||||
@@ -25,7 +27,8 @@ class TooGenericExceptionCaughtSpec : Spek({
|
||||
}
|
||||
}
|
||||
|
||||
describe("a file with a caught exception which is ignored") {
|
||||
@Nested
|
||||
inner class `a file with a caught exception which is ignored` {
|
||||
|
||||
val code = """
|
||||
class MyTooGenericException : RuntimeException()
|
||||
@@ -39,7 +42,8 @@ class TooGenericExceptionCaughtSpec : Spek({
|
||||
}
|
||||
"""
|
||||
|
||||
it("should not report an ignored catch blocks because of its exception name") {
|
||||
@Test
|
||||
fun `should not report an ignored catch blocks because of its exception name`() {
|
||||
val config = TestConfig(mapOf(ALLOWED_EXCEPTION_NAME_REGEX to "myIgnore"))
|
||||
val rule = TooGenericExceptionCaught(config)
|
||||
|
||||
@@ -48,7 +52,8 @@ class TooGenericExceptionCaughtSpec : Spek({
|
||||
assertThat(findings).isEmpty()
|
||||
}
|
||||
|
||||
it("should not report an ignored catch blocks because of its exception type") {
|
||||
@Test
|
||||
fun `should not report an ignored catch blocks because of its exception type`() {
|
||||
val config = TestConfig(mapOf(CAUGHT_EXCEPTIONS_PROPERTY to "[MyException]"))
|
||||
val rule = TooGenericExceptionCaught(config)
|
||||
|
||||
@@ -57,7 +62,8 @@ class TooGenericExceptionCaughtSpec : Spek({
|
||||
assertThat(findings).isEmpty()
|
||||
}
|
||||
|
||||
it("should not fail when disabled with invalid regex on allowed exception names") {
|
||||
@Test
|
||||
fun `should not fail when disabled with invalid regex on allowed exception names`() {
|
||||
val configRules = mapOf(
|
||||
"active" to "false",
|
||||
ALLOWED_EXCEPTION_NAME_REGEX to "*MyException"
|
||||
@@ -69,7 +75,8 @@ class TooGenericExceptionCaughtSpec : Spek({
|
||||
assertThat(findings).isEmpty()
|
||||
}
|
||||
|
||||
it("should fail with invalid regex on allowed exception names") {
|
||||
@Test
|
||||
fun `should fail with invalid regex on allowed exception names`() {
|
||||
val config = TestConfig(mapOf(ALLOWED_EXCEPTION_NAME_REGEX to "*Foo"))
|
||||
val rule = TooGenericExceptionCaught(config)
|
||||
assertThatExceptionOfType(PatternSyntaxException::class.java).isThrownBy {
|
||||
@@ -77,4 +84,4 @@ class TooGenericExceptionCaughtSpec : Spek({
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -3,14 +3,16 @@ package io.gitlab.arturbosch.detekt.rules.exceptions
|
||||
import io.github.detekt.test.utils.compileContentForTest
|
||||
import io.gitlab.arturbosch.detekt.test.yamlConfig
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.spekframework.spek2.Spek
|
||||
import org.spekframework.spek2.style.specification.describe
|
||||
import org.junit.jupiter.api.Nested
|
||||
import org.junit.jupiter.api.Test
|
||||
|
||||
class TooGenericExceptionSpec : Spek({
|
||||
class TooGenericExceptionSpec {
|
||||
|
||||
describe("TooGenericException rule") {
|
||||
@Nested
|
||||
inner class `TooGenericException rule` {
|
||||
|
||||
it("should not report any as all catch exception rules are deactivated") {
|
||||
@Test
|
||||
fun `should not report any as all catch exception rules are deactivated`() {
|
||||
val config = yamlConfig("deactivated-exceptions.yml")
|
||||
val ruleSet = ExceptionsProvider().instance(config)
|
||||
val file = compileContentForTest(tooGenericExceptionCode)
|
||||
@@ -21,7 +23,7 @@ class TooGenericExceptionSpec : Spek({
|
||||
assertThat(findings).isEmpty()
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const val tooGenericExceptionCode = """
|
||||
fun main() {
|
||||
|
||||
@@ -3,34 +3,31 @@ package io.gitlab.arturbosch.detekt.rules.exceptions
|
||||
import io.gitlab.arturbosch.detekt.test.TestConfig
|
||||
import io.gitlab.arturbosch.detekt.test.compileAndLint
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.spekframework.spek2.Spek
|
||||
import org.spekframework.spek2.style.specification.describe
|
||||
import org.junit.jupiter.api.Nested
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.params.ParameterizedTest
|
||||
import org.junit.jupiter.params.provider.ValueSource
|
||||
|
||||
private const val EXCEPTION_NAMES = "exceptionNames"
|
||||
|
||||
private val tooGenericExceptions = listOf(
|
||||
"Error",
|
||||
"Exception",
|
||||
"Throwable",
|
||||
"RuntimeException"
|
||||
)
|
||||
class TooGenericExceptionThrownSpec {
|
||||
|
||||
class TooGenericExceptionThrownSpec : Spek({
|
||||
@Nested
|
||||
inner class `a file with many thrown exceptions` {
|
||||
|
||||
describe("a file with many thrown exceptions") {
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = ["Error", "Exception", "Throwable", "RuntimeException"])
|
||||
fun `should report $exceptionName`(exceptionName: String) {
|
||||
val config = TestConfig(mapOf(EXCEPTION_NAMES to "[$exceptionName]"))
|
||||
val rule = TooGenericExceptionThrown(config)
|
||||
|
||||
tooGenericExceptions.forEach { exceptionName ->
|
||||
it("should report $exceptionName") {
|
||||
val config = TestConfig(mapOf(EXCEPTION_NAMES to "[$exceptionName]"))
|
||||
val rule = TooGenericExceptionThrown(config)
|
||||
val findings = rule.compileAndLint(tooGenericExceptionCode)
|
||||
|
||||
val findings = rule.compileAndLint(tooGenericExceptionCode)
|
||||
|
||||
assertThat(findings).hasSize(1)
|
||||
}
|
||||
assertThat(findings).hasSize(1)
|
||||
}
|
||||
|
||||
it("should not report thrown exceptions") {
|
||||
@Test
|
||||
fun `should not report thrown exceptions`() {
|
||||
val config = TestConfig(mapOf(EXCEPTION_NAMES to "['MyException', Bar]"))
|
||||
val rule = TooGenericExceptionThrown(config)
|
||||
|
||||
@@ -39,7 +36,8 @@ class TooGenericExceptionThrownSpec : Spek({
|
||||
assertThat(findings).isEmpty()
|
||||
}
|
||||
|
||||
it("should not report caught exceptions") {
|
||||
@Test
|
||||
fun `should not report caught exceptions`() {
|
||||
val config = TestConfig(mapOf(EXCEPTION_NAMES to "['Exception']"))
|
||||
val rule = TooGenericExceptionThrown(config)
|
||||
|
||||
@@ -57,7 +55,8 @@ class TooGenericExceptionThrownSpec : Spek({
|
||||
assertThat(findings).isEmpty()
|
||||
}
|
||||
|
||||
it("should not report initialize exceptions") {
|
||||
@Test
|
||||
fun `should not report initialize exceptions`() {
|
||||
val config = TestConfig(mapOf(EXCEPTION_NAMES to "['Exception']"))
|
||||
val rule = TooGenericExceptionThrown(config)
|
||||
|
||||
@@ -67,4 +66,4 @@ class TooGenericExceptionThrownSpec : Spek({
|
||||
assertThat(findings).isEmpty()
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user