Skip to content

Commit

Permalink
Migrate detekt-rules-performance tests to JUnit (#4569)
Browse files Browse the repository at this point in the history
  • Loading branch information
3flex committed Feb 7, 2022
1 parent 780849f commit 7126e4b
Show file tree
Hide file tree
Showing 5 changed files with 191 additions and 102 deletions.
3 changes: 1 addition & 2 deletions detekt-rules-performance/build.gradle.kts
Expand Up @@ -5,6 +5,5 @@ plugins {
dependencies {
compileOnly(projects.detektApi)
testImplementation(projects.detektTest)
testImplementation(libs.bundles.testImplementation)
testRuntimeOnly(libs.spek.runner)
testImplementation(libs.assertj)
}
@@ -1,210 +1,266 @@
package io.gitlab.arturbosch.detekt.rules.performance

import io.gitlab.arturbosch.detekt.rules.setupKotlinEnvironment
import io.gitlab.arturbosch.detekt.rules.KotlinCoreEnvironmentTest
import io.gitlab.arturbosch.detekt.test.compileAndLint
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.DisplayName
import org.junit.jupiter.api.Nested
import org.junit.jupiter.api.Test

class ArrayPrimitiveSpec : Spek({
setupKotlinEnvironment()
@KotlinCoreEnvironmentTest
class ArrayPrimitiveSpec(val env: KotlinCoreEnvironment) {

val env: KotlinCoreEnvironment by memoized()
val subject by memoized { ArrayPrimitive() }
val subject = ArrayPrimitive()

describe("one function parameter") {
it("is an array of primitive type") {
@Nested
inner class `one function parameter` {
@Test
fun `is an array of primitive type`() {
val code = "fun function(array: Array<Int>) {}"
assertThat(subject.compileAndLint(code)).hasSize(1)
}

it("is not an array") {
@Test
fun `is not an array`() {
val code = "fun function(i: Int) {}"
assertThat(subject.compileAndLint(code)).isEmpty()
}

it("is a specialized array") {
@Test
fun `is a specialized array`() {
val code = "fun function(array: ByteArray) {}"
assertThat(subject.compileAndLint(code)).isEmpty()
}

it("is a star-projected array") {
@Test
fun `is a star-projected array`() {
val code = "fun function(array: Array<*>) {}"
assertThat(subject.compileAndLint(code)).isEmpty()
}

it("is not present") {
@Test
fun `is not present`() {
val code = "fun function() {}"
assertThat(subject.compileAndLint(code)).isEmpty()
}

it("is an array of a non-primitive type") {
@Test
fun `is an array of a non-primitive type`() {
val code = "fun function(array: Array<String>) {}"
assertThat(subject.compileAndLint(code)).isEmpty()
}

it("is an array of an array of a primitive type") {
@Test
fun `is an array of an array of a primitive type`() {
val code = "fun function(array: Array<Array<Int>>) {}"
assertThat(subject.compileAndLint(code)).hasSize(1)
}

it("is a dictionary with an array of a primitive type as key") {
@Test
fun `is a dictionary with an array of a primitive type as key`() {
val code = "fun function(dict: java.util.Dictionary<Int, Array<Int>>) {}"
assertThat(subject.compileAndLint(code)).hasSize(1)
}
}

describe("multiple function parameters") {
it("one is Array<Primitive> and the other is not") {
@Nested
inner class `multiple function parameters` {
@Test
@DisplayName("one is Array<Primitive> and the other is not")
fun oneArrayPrimitive() {
val code = "fun function(array: Array<Int>, array2: IntArray) {}"
assertThat(subject.compileAndLint(code)).hasSize(1)
}

it("both are arrays of primitive types") {
@Test
fun `both are arrays of primitive types`() {
val code = "fun function(array: Array<Int>, array2: Array<Double>) {}"
assertThat(subject.compileAndLint(code)).hasSize(2)
}
}

describe("return type") {
it("is Array<Primitive>") {
@Nested
inner class `return type` {
@Test
@DisplayName("is Array<Primitive>")
fun isArrayPrimitive() {
val code = "fun returningFunction(): Array<Float> { return emptyArray() }"
assertThat(subject.compileAndLint(code)).hasSize(1)
}

it("is not an array") {
@Test
fun `is not an array`() {
val code = "fun returningFunction(): Int { return 1 }"
assertThat(subject.compileAndLint(code)).isEmpty()
}

it("is a specialized array") {
@Test
fun `is a specialized array`() {
val code = "fun returningFunction(): CharArray { return CharArray(0) }"
assertThat(subject.compileAndLint(code)).isEmpty()
}

it("is a star-projected array") {
@Test
fun `is a star-projected array`() {
val code = "fun returningFunction(): Array<*> { return emptyArray<Any>() }"
assertThat(subject.compileAndLint(code)).isEmpty()
}

it("is not explicitly set") {
@Test
fun `is not explicitly set`() {
val code = "fun returningFunction() {}"
assertThat(subject.compileAndLint(code)).isEmpty()
}
}

describe("variable type") {
it("is Array<Primitive>") {
@Nested
inner class `variable type` {
@Test
@DisplayName("is Array<Primitive>")
fun isArrayPrimitive() {
val code = "val foo: Array<Int>? = null"
assertThat(subject.compileAndLintWithContext(env, code)).hasSize(1)
}
}

describe("receiver type") {
it("is Array<Primitive>") {
@Nested
inner class `receiver type` {
@Test
@DisplayName("is Array<Primitive>")
fun isArrayPrimitive() {
val code = "fun Array<Boolean>.foo() { println(this) }"
assertThat(subject.compileAndLintWithContext(env, code)).hasSize(1)
}
}

describe("arrayOf") {
it("is arrayOf(Char)") {
@Nested
inner class `arrayOf` {
@Test
fun `is arrayOf(Char)`() {
val code = "fun foo(x: Char) = arrayOf(x)"
assertThat(subject.compileAndLintWithContext(env, code)).hasSize(1)
}

it("is arrayOf(Byte)") {
@Test
fun `is arrayOf(Byte)`() {
val code = "fun foo(x: Byte) = arrayOf(x)"
assertThat(subject.compileAndLintWithContext(env, code)).hasSize(1)
}

it("is arrayOf(Short)") {
@Test
fun `is arrayOf(Short)`() {
val code = "fun foo(x: Short) = arrayOf(x)"
assertThat(subject.compileAndLintWithContext(env, code)).hasSize(1)
}

it("is arrayOf(Int)") {
@Test
fun `is arrayOf(Int)`() {
val code = "fun foo(x: Int) = arrayOf(x)"
assertThat(subject.compileAndLintWithContext(env, code)).hasSize(1)
}

it("is arrayOf(Long)") {
@Test
fun `is arrayOf(Long)`() {
val code = "fun foo(x: Long) = arrayOf(x)"
assertThat(subject.compileAndLintWithContext(env, code)).hasSize(1)
}

it("is arrayOf(Float)") {
@Test
fun `is arrayOf(Float)`() {
val code = "fun foo(x: Float) = arrayOf(x)"
assertThat(subject.compileAndLintWithContext(env, code)).hasSize(1)
}

it("is arrayOf(Double)") {
@Test
fun `is arrayOf(Double)`() {
val code = "fun foo(x: Double) = arrayOf(x)"
assertThat(subject.compileAndLintWithContext(env, code)).hasSize(1)
}

it("is arrayOf(Boolean)") {
@Test
fun `is arrayOf(Boolean)`() {
val code = "fun foo(x: Boolean) = arrayOf(x)"
assertThat(subject.compileAndLintWithContext(env, code)).hasSize(1)
}

it("is arrayOf(String)") {
@Test
fun `is arrayOf(String)`() {
val code = "fun foo(x: String) = arrayOf(x)"
assertThat(subject.compileAndLintWithContext(env, code)).isEmpty()
}

it("is intArrayOf()") {
@Test
fun `is intArrayOf()`() {
val code = "fun test(x: Int) = intArrayOf(x)"
assertThat(subject.compileAndLintWithContext(env, code)).isEmpty()
}
}

describe("emptyArray") {
it("is emptyArray<Char>()") {
@Nested
inner class `emptyArray` {
@Test
@DisplayName("is emptyArray<Char>()")
fun isEmptyArrayChar() {
val code = "val a = emptyArray<Char>()"
assertThat(subject.compileAndLintWithContext(env, code)).hasSize(1)
}

it("is emptyArray<Byte>()") {
@Test
@DisplayName("is emptyArray<Byte>()")
fun isEmptyArrayByte() {
val code = "val a = emptyArray<Byte>()"
assertThat(subject.compileAndLintWithContext(env, code)).hasSize(1)
}

it("is emptyArray<Short>()") {
@Test
@DisplayName("is emptyArray<Short>()")
fun isEmptyArrayShort() {
val code = "val a = emptyArray<Short>()"
assertThat(subject.compileAndLintWithContext(env, code)).hasSize(1)
}

it("is emptyArray<Int>()") {
@Test
@DisplayName("is emptyArray<Int>()")
fun isEmptyArrayInt() {
val code = "val a = emptyArray<Int>()"
assertThat(subject.compileAndLintWithContext(env, code)).hasSize(1)
}

it("is emptyArray<Long>()") {
@Test
@DisplayName("is emptyArray<Long>()")
fun isEmptyArrayLong() {
val code = "val a = emptyArray<Long>()"
assertThat(subject.compileAndLintWithContext(env, code)).hasSize(1)
}

it("is emptyArray<Float>()") {
@Test
@DisplayName("is emptyArray<Float>()")
fun isEmptyArrayFloat() {
val code = "val a = emptyArray<Float>()"
assertThat(subject.compileAndLintWithContext(env, code)).hasSize(1)
}

it("is emptyArray<Double>()") {
@Test
@DisplayName("is emptyArray<Double>()")
fun isEmptyArrayDouble() {
val code = "val a = emptyArray<Double>()"
assertThat(subject.compileAndLintWithContext(env, code)).hasSize(1)
}

it("is emptyArray<Boolean>()") {
@Test
@DisplayName("is emptyArray<Boolean>()")
fun isEmptyArrayBoolean() {
val code = "val a = emptyArray<Boolean>()"
assertThat(subject.compileAndLintWithContext(env, code)).hasSize(1)
}

it("is emptyArray<String>()") {
@Test
@DisplayName("is emptyArray<String>()")
fun isEmptyArrayString() {
val code = "val a = emptyArray<String>()"
assertThat(subject.compileAndLintWithContext(env, code)).isEmpty()
}
}
})
}
Expand Up @@ -2,16 +2,18 @@ package io.gitlab.arturbosch.detekt.rules.performance

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 ForEachOnRangeSpec : Spek({
class ForEachOnRangeSpec {

val subject by memoized { ForEachOnRange() }
val subject = ForEachOnRange()

describe("ForEachOnRange rule") {
@Nested
inner class `ForEachOnRange rule` {

context("using a forEach on a range") {
@Nested
inner class `using a forEach on a range` {
val code = """
fun test() {
(1..10).forEach {
Expand All @@ -29,26 +31,30 @@ class ForEachOnRangeSpec : Spek({
}
"""

it("should report the forEach usage") {
@Test
fun `should report the forEach usage`() {
val findings = subject.compileAndLint(code)
assertThat(findings).hasSize(4)
}
}

context("using any other method on a range") {
@Nested
inner class `using any other method on a range` {
val code = """
fun test() {
(1..10).isEmpty()
}
"""

it("should not report any issues") {
@Test
fun `should not report any issues`() {
val findings = subject.compileAndLint(code)
assertThat(findings).isEmpty()
}
}

context("using a forEach on a list") {
@Nested
inner class `using a forEach on a list` {
val code = """
fun test() {
listOf(1, 2, 3).forEach {
Expand All @@ -57,10 +63,11 @@ class ForEachOnRangeSpec : Spek({
}
"""

it("should not report any issues") {
@Test
fun `should not report any issues`() {
val findings = subject.compileAndLint(code)
assertThat(findings).isEmpty()
}
}
}
})
}

0 comments on commit 7126e4b

Please sign in to comment.