Skip to content

Commit

Permalink
Fix TestFactory does not close AutoCloseable objects (#3739)
Browse files Browse the repository at this point in the history
* Fix TestFactory does not close AutoCloseable objects

* Added test

* Api dumps

* Fix nested testfactory bug

* Change test to assert nested test factory
  • Loading branch information
kshired committed Oct 20, 2023
1 parent eab0f88 commit 1b0188e
Show file tree
Hide file tree
Showing 7 changed files with 76 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ public abstract class io/kotest/core/TestConfiguration {
public final fun setAssertSoftly (Ljava/lang/Boolean;)V
public final fun setAssertions (Lio/kotest/core/test/AssertionMode;)V
public final fun setDefaultTestConfig (Lio/kotest/core/test/config/TestCaseConfig;)V
public final fun setParentConfiguration (Lio/kotest/core/TestConfiguration;)V
public final fun tags ([Lio/kotest/core/Tag;)V
}

Expand Down Expand Up @@ -1474,16 +1475,18 @@ public final class io/kotest/core/factory/FactoryId$Companion {
}

public final class io/kotest/core/factory/TestFactory {
public fun <init> (Lio/kotest/core/factory/FactoryId;Ljava/util/List;Ljava/util/Set;Lio/kotest/core/test/AssertionMode;Ljava/util/List;)V
public fun <init> (Lio/kotest/core/factory/FactoryId;Ljava/util/List;Ljava/util/Set;Lio/kotest/core/test/AssertionMode;Ljava/util/List;Lio/kotest/core/factory/TestFactoryConfiguration;)V
public final fun component1 ()Lio/kotest/core/factory/FactoryId;
public final fun component2 ()Ljava/util/List;
public final fun component3 ()Ljava/util/Set;
public final fun component4 ()Lio/kotest/core/test/AssertionMode;
public final fun component5 ()Ljava/util/List;
public final fun copy (Lio/kotest/core/factory/FactoryId;Ljava/util/List;Ljava/util/Set;Lio/kotest/core/test/AssertionMode;Ljava/util/List;)Lio/kotest/core/factory/TestFactory;
public static synthetic fun copy$default (Lio/kotest/core/factory/TestFactory;Lio/kotest/core/factory/FactoryId;Ljava/util/List;Ljava/util/Set;Lio/kotest/core/test/AssertionMode;Ljava/util/List;ILjava/lang/Object;)Lio/kotest/core/factory/TestFactory;
public final fun component6 ()Lio/kotest/core/factory/TestFactoryConfiguration;
public final fun copy (Lio/kotest/core/factory/FactoryId;Ljava/util/List;Ljava/util/Set;Lio/kotest/core/test/AssertionMode;Ljava/util/List;Lio/kotest/core/factory/TestFactoryConfiguration;)Lio/kotest/core/factory/TestFactory;
public static synthetic fun copy$default (Lio/kotest/core/factory/TestFactory;Lio/kotest/core/factory/FactoryId;Ljava/util/List;Ljava/util/Set;Lio/kotest/core/test/AssertionMode;Ljava/util/List;Lio/kotest/core/factory/TestFactoryConfiguration;ILjava/lang/Object;)Lio/kotest/core/factory/TestFactory;
public fun equals (Ljava/lang/Object;)Z
public final fun getAssertionMode ()Lio/kotest/core/test/AssertionMode;
public final fun getConfiguration ()Lio/kotest/core/factory/TestFactoryConfiguration;
public final fun getExtensions ()Ljava/util/List;
public final fun getFactoryId ()Lio/kotest/core/factory/FactoryId;
public final fun getTags ()Ljava/util/Set;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ abstract class TestConfiguration {

private var _autoCloseables = emptyList<Lazy<AutoCloseable>>()

private var _parentConfiguration: TestConfiguration? = null

/**
* Config applied to each test case if not overridden per test case.
* If null, then defaults to the project level default.
Expand Down Expand Up @@ -165,6 +167,7 @@ abstract class TestConfiguration {
* Registers a lazy [AutoCloseable] to be closed when the spec is completed.
*/
fun <T : AutoCloseable> autoClose(closeable: Lazy<T>): Lazy<T> {
_parentConfiguration?.autoClose(closeable)
_autoCloseables = listOf(closeable) + _autoCloseables
return closeable
}
Expand Down Expand Up @@ -370,4 +373,8 @@ abstract class TestConfiguration {
fun registeredExtensions(): List<Extension> {
return _extensions.toList()
}

fun setParentConfiguration(configuration: TestConfiguration) {
_parentConfiguration = configuration
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,5 @@ data class TestFactory(
val tags: Set<Tag>,
val assertionMode: AssertionMode?,
val extensions: List<Extension>,
val configuration: TestFactoryConfiguration
)
Original file line number Diff line number Diff line change
Expand Up @@ -34,5 +34,7 @@ abstract class TestFactoryConfiguration : TestConfiguration(), RootScope {
*/
fun include(factory: TestFactory) {
factory.tests.forEach { add(it) }
factory.configuration.setParentConfiguration(this)
register(factory.extensions)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ internal fun TestFactoryConfiguration.build(): TestFactory {
}
},
assertionMode = assertions,
tests = tests
tests = tests,
configuration = this
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ abstract class DslDrivenSpec : Spec(), RootScope {
*/
fun include(factory: TestFactory) {
factory.tests.forEach { add(it.copy(factoryId = factory.factoryId)) }
factory.configuration.setParentConfiguration(this)
register(factory.extensions)
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package com.sksamuel.kotest.engine.factory

import io.kotest.core.spec.style.ShouldSpec
import io.kotest.core.spec.style.shouldSpec
import io.kotest.matchers.shouldBe
import java.util.concurrent.atomic.AtomicInteger

class AutoCloseableTestFactoryTest : ShouldSpec({
include(
shouldSpec {
include(
shouldSpec {
should("close is called in nested test factory") {
autoClose(FirstAutoClose)
}
}
)
should("close is called in test factory") {
autoClose(SecondAutoClose)
}
}
)
should("close is called") {
autoClose(ThirdAutoClose)
}
afterSpec {
FirstAutoClose.closed shouldBe 3
SecondAutoClose.closed shouldBe 2
ThirdAutoClose.closed shouldBe 1
}
})

private object FirstAutoClose : AutoCloseable {
var closed = -1

override fun close() {
closed = closedNumber.incrementAndGet()
}
}

private object SecondAutoClose : AutoCloseable {
var closed = -1

override fun close() {
closed = closedNumber.incrementAndGet()
}
}

private object ThirdAutoClose : AutoCloseable {
var closed = -1

override fun close() {
closed = closedNumber.incrementAndGet()
}
}

private var closedNumber = AtomicInteger(0)

0 comments on commit 1b0188e

Please sign in to comment.