Skip to content
Permalink
Browse files

Listener to run before/after a set of tests #458

  • Loading branch information
sksamuel committed Jan 12, 2020
1 parent 803167b commit 776fc64533c6ac591b3948bae88d4fd114a1336b
Showing with 1,027 additions and 862 deletions.
  1. +4 −4 kotest-assertions/src/jvmTest/kotlin/com/sksamuel/kotest/assertions/AssertionCounterTest.kt
  2. +5 −0 kotest-core/src/commonMain/kotlin/io/kotest/SpecClass.kt
  3. +1 −0 kotest-core/src/commonMain/kotlin/io/kotest/core/ProjectConfiguration.kt
  4. +0 −10 kotest-core/src/commonMain/kotlin/io/kotest/core/TestCaseOrder.kt
  5. +36 −0 kotest-core/src/commonMain/kotlin/io/kotest/core/factory/factory.kt
  6. +29 −0 kotest-core/src/commonMain/kotlin/io/kotest/core/factory/generate.kt
  7. +0 −22 kotest-core/src/commonMain/kotlin/io/kotest/core/focusbang.kt
  8. +2 −0 kotest-core/src/commonMain/kotlin/io/kotest/core/spec/CompositeSpec.kt
  9. +1 −1 kotest-core/src/commonMain/kotlin/io/kotest/core/{ → spec}/IsolationMode.kt
  10. +160 −0 kotest-core/src/commonMain/kotlin/io/kotest/core/spec/Spec.kt
  11. +1 −2 kotest-core/src/commonMain/kotlin/io/kotest/core/{ → spec}/SpecExecutionOrder.kt
  12. +1 −6 kotest-core/src/commonMain/kotlin/io/kotest/core/spec/compatibility.kt
  13. +13 −96 ...t-core/src/commonMain/kotlin/io/kotest/core/spec/{TestFactoryConfiguration.kt → configuration.kt}
  14. +4 −1 kotest-core/src/commonMain/kotlin/io/kotest/core/{ → spec}/descriptions.kt
  15. +3 −3 kotest-core/src/commonMain/kotlin/io/kotest/core/spec/dsl.kt
  16. +12 −0 kotest-core/src/commonMain/kotlin/io/kotest/core/spec/focusbang.kt
  17. +5 −4 kotest-core/src/commonMain/kotlin/io/kotest/core/spec/funSpec.kt
  18. +5 −4 kotest-core/src/commonMain/kotlin/io/kotest/core/spec/stringSpec.kt
  19. +5 −4 kotest-core/src/commonMain/kotlin/io/kotest/core/specs/AbstractDescribeSpec.kt
  20. +10 −9 kotest-core/src/commonMain/kotlin/io/kotest/core/specs/AbstractExpectSpec.kt
  21. +5 −4 kotest-core/src/commonMain/kotlin/io/kotest/core/specs/AbstractFeatureSpec.kt
  22. +7 −5 kotest-core/src/commonMain/kotlin/io/kotest/core/specs/AbstractFreeSpec.kt
  23. +7 −5 kotest-core/src/commonMain/kotlin/io/kotest/core/specs/AbstractShouldSpec.kt
  24. +4 −1 kotest-core/src/commonMain/kotlin/io/kotest/core/specs/AbstractSpec.kt
  25. +5 −0 kotest-core/src/commonMain/kotlin/io/kotest/core/specs/AbstractSpecDsl.kt
  26. +2 −3 kotest-core/src/commonMain/kotlin/io/kotest/core/specs/AbstractWordSpec.kt
  27. +14 −11 kotest-core/src/commonMain/kotlin/io/kotest/core/specs/SuiteSpec.kt
  28. +1 −1 kotest-core/src/commonMain/kotlin/io/kotest/core/{ → test}/AssertionMode.kt
  29. +1 −1 kotest-core/src/commonMain/kotlin/io/kotest/core/{ → test}/Description.kt
  30. +24 −12 kotest-core/src/commonMain/kotlin/io/kotest/core/{ → test}/TestCase.kt
  31. +2 −1 kotest-core/src/commonMain/kotlin/io/kotest/core/{ → test}/TestCaseConfig.kt
  32. +3 −2 kotest-core/src/commonMain/kotlin/io/kotest/core/{ → test}/TestCaseFilter.kt
  33. +17 −0 kotest-core/src/commonMain/kotlin/io/kotest/core/test/TestCaseOrder.kt
  34. +30 −18 kotest-core/src/commonMain/kotlin/io/kotest/core/{ → test}/TestContext.kt
  35. +1 −1 kotest-core/src/commonMain/kotlin/io/kotest/core/{ → test}/TestResult.kt
  36. +1 −1 kotest-core/src/commonMain/kotlin/io/kotest/core/{ → test}/TestType.kt
  37. +8 −2 kotest-core/src/commonMain/kotlin/io/kotest/core/{ → test}/active.kt
  38. +12 −0 kotest-core/src/commonMain/kotlin/io/kotest/core/test/focused.kt
  39. +2 −2 kotest-core/src/commonMain/kotlin/io/kotest/extensions/TestCaseExtension.kt
  40. +7 −9 kotest-core/src/commonMain/kotlin/io/kotest/extensions/TestListener.kt
  41. +5 −4 kotest-core/src/commonMain/kotlin/io/kotest/specs/BehaviorSpec.kt
  42. +3 −3 kotest-core/src/commonMain/kotlin/io/kotest/specs/FunSpec.kt
  43. +5 −12 kotest-core/src/jsMain/kotlin/io/kotest/core/specs/markers.kt
  44. +1 −0 kotest-core/src/jsMain/kotlin/io/kotest/core/tagExtensions.kt
  45. +1 −1 kotest-core/src/jsMain/kotlin/io/kotest/core/{ → test}/timeout.kt
  46. +6 −2 kotest-core/src/jvmMain/kotlin/io/kotest/AbstractProjectConfig.kt
  47. +6 −0 kotest-core/src/jvmMain/kotlin/io/kotest/Project.kt
  48. +1 −1 kotest-core/src/jvmMain/kotlin/io/kotest/{ → core}/futures.kt
  49. +1 −2 kotest-core/src/jvmMain/kotlin/io/kotest/core/{ → spec}/FailureFirstSpecExecutionOrder.kt
  50. +1 −1 kotest-core/src/jvmMain/kotlin/io/kotest/core/specs/markers.kt
  51. +1 −0 kotest-core/src/jvmMain/kotlin/io/kotest/core/tagExtensions.kt
  52. +2 −1 kotest-core/src/jvmMain/kotlin/io/kotest/core/{ → test}/timeout.kt
  53. +1 −1 kotest-core/src/jvmMain/kotlin/io/kotest/extensions/SpecExtension.kt
  54. +1 −1 kotest-core/src/jvmMain/kotlin/io/kotest/specs/AbstractAnnotationSpec.kt
  55. +4 −1 ...nsions/kotest-extensions-allure/src/jvmMain/kotlin/io/kotest/extensions/allure/AllureExtension.kt
  56. +2 −2 kotest-extensions/kotest-extensions-koin/src/jvmMain/kotlin/io/kotest/koin/KoinListener.kt
  57. +3 −3 ...t-extensions/kotest-extensions-koin/src/jvmTest/kotlin/com/sksamuel/kt/koin/KotlinListenerTest.kt
  58. +5 −5 ...ensions-robolectric/src/jvmMain/kotlin/io/kotest/experimental/robolectric/RobolectricExtension.kt
  59. +2 −2 kotest-extensions/kotest-extensions-spring/src/jvmMain/kotlin/io/kotest/spring/SpringListener.kt
  60. +2 −2 ...st-extensions-spring/src/jvmTest/kotlin/com/sksamuel/kt/spring/SpringTestExecutionListenerTest.kt
  61. +2 −2 kotest-extensions/src/jvmMain/kotlin/io/kotest/extensions/locale/LocaleExtensions.kt
  62. +2 −2 kotest-extensions/src/jvmMain/kotlin/io/kotest/extensions/locale/TimezoneExtensions.kt
  63. +2 −2 kotest-extensions/src/jvmMain/kotlin/io/kotest/extensions/system/SecurityManagerExtensions.kt
  64. +2 −2 kotest-extensions/src/jvmMain/kotlin/io/kotest/extensions/system/SystemEnvironmentExtensions.kt
  65. +2 −2 kotest-extensions/src/jvmMain/kotlin/io/kotest/extensions/system/SystemExitExtensions.kt
  66. +2 −2 kotest-extensions/src/jvmMain/kotlin/io/kotest/extensions/system/SystemPropertiesExtensions.kt
  67. +2 −2 kotest-extensions/src/jvmMain/kotlin/io/kotest/extensions/system/wireListeners.kt
  68. +2 −2 kotest-extensions/src/jvmMain/kotlin/io/kotest/extensions/time/ConstantNowExtensions.kt
  69. +2 −3 kotest-extensions/src/jvmTest/kotlin/com/sksamuel/kt/extensions/locale/LocaleExtensionTest.kt
  70. +2 −3 kotest-extensions/src/jvmTest/kotlin/com/sksamuel/kt/extensions/locale/TimeZoneListenerTest.kt
  71. +2 −2 ...extensions/src/jvmTest/kotlin/com/sksamuel/kt/extensions/system/SecurityManagerExtensionsTests.kt
  72. +2 −2 ...extensions/src/jvmTest/kotlin/com/sksamuel/kt/extensions/system/SystemEnvironmentExtensionTest.kt
  73. +2 −2 ...xtensions/src/jvmTest/kotlin/com/sksamuel/kt/extensions/system/SystemPropertiesExtensionsTests.kt
  74. +2 −2 kotest-extensions/src/jvmTest/kotlin/com/sksamuel/kt/extensions/time/ConstantNowExtensionsTests.kt
  75. +8 −0 kotest-fp/src/commonMain/kotlin/io/kotest/fp/Try.kt
  76. +5 −5 kotest-plugins/kotest-plugins-pitest/src/jvmMain/kotlin/io/kotest/plugin/pitest/KotestUnit.kt
  77. +1 −1 ...nner/kotest-runner-junit5/src/jvmMain/kotlin/io/kotest/runner/junit5/ClassMethodAdaptingFilter.kt
  78. +3 −2 ...runner/kotest-runner-junit5/src/jvmMain/kotlin/io/kotest/runner/junit5/JUnitTestRunnerListener.kt
  79. +4 −0 ...runner-junit5/src/jvmTest/kotlin/com/sksamuel/kotest/runner/junit5/JUnitTestRunnerListenerTest.kt
  80. +1 −1 kotest-runner/kotest-runner-jvm/src/jvmMain/kotlin/io/kotest/runner/jvm/Asserter.kt
  81. +7 −4 ...t-runner/kotest-runner-jvm/src/jvmMain/kotlin/io/kotest/runner/jvm/IsolationTestEngineListener.kt
  82. +8 −26 kotest-runner/kotest-runner-jvm/src/jvmMain/kotlin/io/kotest/runner/jvm/KotestEngine.kt
  83. +3 −3 kotest-runner/kotest-runner-jvm/src/jvmMain/kotlin/io/kotest/runner/jvm/TestEngineListener.kt
  84. +29 −5 kotest-runner/kotest-runner-jvm/src/jvmMain/kotlin/io/kotest/runner/jvm/TestExecutor.kt
  85. +5 −5 ...unner/kotest-runner-jvm/src/jvmMain/kotlin/io/kotest/runner/jvm/spec/InstancePerLeafSpecRunner.kt
  86. +5 −5 ...unner/kotest-runner-jvm/src/jvmMain/kotlin/io/kotest/runner/jvm/spec/InstancePerTestSpecRunner.kt
  87. +30 −37 ...runner/kotest-runner-jvm/src/jvmMain/kotlin/io/kotest/runner/jvm/spec/SingleInstanceSpecRunner.kt
  88. +82 −118 kotest-runner/kotest-runner-jvm/src/jvmMain/kotlin/io/kotest/runner/jvm/spec/SpecExecutor.kt
  89. +0 −101 kotest-runner/kotest-runner-jvm/src/jvmMain/kotlin/io/kotest/runner/jvm/spec/SpecExecutor2.kt
  90. +45 −23 kotest-runner/kotest-runner-jvm/src/jvmMain/kotlin/io/kotest/runner/jvm/spec/SpecRunner.kt
  91. +0 −38 kotest-runner/kotest-runner-jvm/src/jvmMain/kotlin/io/kotest/runner/jvm/spec/materialize.kt
  92. +1 −1 kotest-tests/kotest-tests-core/src/jvmTest/kotlin/com/sksamuel/kotest/BeforeTestThreadsTest.kt
  93. +3 −2 kotest-tests/kotest-tests-core/src/jvmTest/kotlin/com/sksamuel/kotest/ConfigTest.kt
  94. +1 −1 kotest-tests/kotest-tests-core/src/jvmTest/kotlin/com/sksamuel/kotest/DescriptionTest.kt
  95. +35 −0 kotest-tests/kotest-tests-core/src/jvmTest/kotlin/com/sksamuel/kotest/FocusBangTest.kt
  96. +4 −4 kotest-tests/kotest-tests-core/src/jvmTest/kotlin/com/sksamuel/kotest/IsActiveTest.kt
  97. +1 −1 kotest-tests/kotest-tests-core/src/jvmTest/kotlin/com/sksamuel/kotest/OneInstancePerTestTest.kt
  98. +3 −3 kotest-tests/kotest-tests-core/src/jvmTest/kotlin/com/sksamuel/kotest/TagExtensionTest.kt
  99. +4 −4 kotest-tests/kotest-tests-core/src/jvmTest/kotlin/com/sksamuel/kotest/TestCaseExecutorTest.kt
  100. +6 −6 kotest-tests/kotest-tests-core/src/jvmTest/kotlin/com/sksamuel/kotest/TestCaseFilterTest.kt
  101. +0 −35 kotest-tests/kotest-tests-core/src/jvmTest/kotlin/com/sksamuel/kotest/TestCasePrefixTest.kt
  102. +14 −14 kotest-tests/kotest-tests-core/src/jvmTest/kotlin/com/sksamuel/kotest/WhenReadyTest.kt
  103. +1 −1 ...st-tests/kotest-tests-core/src/jvmTest/kotlin/com/sksamuel/kotest/extensions/SpecExtensionTest.kt
  104. +2 −2 ...tests-core/src/jvmTest/kotlin/com/sksamuel/kotest/extensions/TestCaseExtensionAroundAdviceTest.kt
  105. +2 −2 ...kotest-tests-core/src/jvmTest/kotlin/com/sksamuel/kotest/extensions/TestCaseExtensionChainTest.kt
  106. +2 −2 ...ests/kotest-tests-core/src/jvmTest/kotlin/com/sksamuel/kotest/extensions/TestCaseExtensionTest.kt
  107. +31 −0 ...t-tests-core/src/jvmTest/kotlin/com/sksamuel/kotest/factory/TestCallbackInFactoryIsolationTest.kt
  108. +35 −0 ...tests/kotest-tests-core/src/jvmTest/kotlin/com/sksamuel/kotest/factory/TestFactoryCallbackTest.kt
  109. +20 −0 kotest-tests/kotest-tests-core/src/jvmTest/kotlin/com/sksamuel/kotest/factory/TestFactoryTest.kt
  110. +1 −1 ...t-tests-core/src/jvmTest/kotlin/com/sksamuel/kotest/listeners/LateInitBeforeSpecStringSpecTest.kt
  111. +1 −1 ...est-tests-core/src/jvmTest/kotlin/com/sksamuel/kotest/listeners/LateInitBeforeTestWordSpecTest.kt
  112. +1 −1 ...s/kotest-tests-core/src/jvmTest/kotlin/com/sksamuel/kotest/listeners/TestListenerAfterSpecTest.kt
  113. +1 −1 ...-tests-core/src/jvmTest/kotlin/com/sksamuel/kotest/listeners/TestListenerBeforeSpecStartedTest.kt
  114. +3 −3 .../kotest-tests-core/src/jvmTest/kotlin/com/sksamuel/kotest/listeners/TestListenerBeforeSpecTest.kt
  115. +2 −2 .../kotest-tests-core/src/jvmTest/kotlin/com/sksamuel/kotest/listeners/TestListenerBeforeTestTest.kt
  116. +3 −3 ...st-tests-core/src/jvmTest/kotlin/com/sksamuel/kotest/runner/junit5/JUnitTestRunnerListenerTest.kt
  117. +1 −1 ...st-tests/kotest-tests-core/src/jvmTest/kotlin/com/sksamuel/kotest/runner/jvm/TopLevelTestsTest.kt
  118. +4 −4 ...s/kotest-tests-core/src/jvmTest/kotlin/com/sksamuel/kotest/specs/annotation/AnnotationSpecTest.kt
  119. +1 −1 ...t-tests-core/src/jvmTest/kotlin/com/sksamuel/kotest/specs/behavior/BehaviorSpecOneInstanceTest.kt
  120. +2 −2 ...tests/kotest-tests-core/src/jvmTest/kotlin/com/sksamuel/kotest/specs/behavior/BehaviorSpecTest.kt
  121. +1 −1 ...t-tests-core/src/jvmTest/kotlin/com/sksamuel/kotest/specs/describe/DescribeSpecOneInstanceTest.kt
  122. +1 −1 ...otest-tests-core/src/jvmTest/kotlin/com/sksamuel/kotest/specs/expect/ExpectSpecOneInstanceTest.kt
  123. +2 −2 ...mTest/kotlin/com/sksamuel/kotest/specs/feature/FeatureSpecCoroutineSingleTestIsolationModeTest.kt
  124. +1 −1 ...est-tests-core/src/jvmTest/kotlin/com/sksamuel/kotest/specs/feature/FeatureSpecOneInstanceTest.kt
  125. +3 −3 ...t-tests-core/src/jvmTest/kotlin/com/sksamuel/kotest/specs/freespec/FreeSpecInstancePerLeafTest.kt
  126. +1 −1 ...t-tests-core/src/jvmTest/kotlin/com/sksamuel/kotest/specs/freespec/FreeSpecInstancePerNodeTest.kt
  127. +1 −1 ...src/jvmTest/kotlin/com/sksamuel/kotest/specs/freespec/FreeSpecInstancePerTestDuplicateNameTest.kt
  128. +3 −3 ...t-tests-core/src/jvmTest/kotlin/com/sksamuel/kotest/specs/freespec/FreeSpecInstancePerTestTest.kt
  129. +2 −2 ...src/jvmTest/kotlin/com/sksamuel/kotest/specs/freespec/FreeSpecIsolationModeInstancePerLeafTest.kt
  130. +2 −2 .../src/jvmTest/kotlin/com/sksamuel/kotest/specs/freespec/FreeSpecIsolationModeSingleInstanceTest.kt
  131. +4 −4 ...st-tests/kotest-tests-core/src/jvmTest/kotlin/com/sksamuel/kotest/specs/funspec/FunSpecExample.kt
  132. +3 −3 ...ts/kotest-tests-core/src/jvmTest/kotlin/com/sksamuel/kotest/specs/funspec/FunSpecExampleNewDsl.kt
  133. +3 −3 ...sts-core/src/jvmTest/kotlin/com/sksamuel/kotest/specs/shouldspec/ShouldSpecInstancePerLeafTest.kt
  134. +3 −3 ...sts-core/src/jvmTest/kotlin/com/sksamuel/kotest/specs/shouldspec/ShouldSpecInstancePerTestTest.kt
  135. +3 −3 ...src/jvmTest/kotlin/com/sksamuel/kotest/specs/stringspec/StringSpecCoroutineInstancePerLeafTest.kt
  136. +3 −3 ...est/kotlin/com/sksamuel/kotest/specs/stringspec/StringSpecCoroutineSingleTestIsolationModeTest.kt
  137. +3 −3 .../src/jvmTest/kotlin/com/sksamuel/kotest/specs/stringspec/StringSpecInstancePerLeafOrderingTest.kt
  138. +1 −1 ...jvmTest/kotlin/com/sksamuel/kotest/specs/stringspec/StringSpecInstancePerTestDuplicateNameTest.kt
  139. +3 −3 .../src/jvmTest/kotlin/com/sksamuel/kotest/specs/stringspec/StringSpecInstancePerTestOrderingTest.kt
  140. +2 −2 .../jvmTest/kotlin/com/sksamuel/kotest/specs/stringspec/StringSpecSingleInstanceDuplicateNameTest.kt
  141. +3 −3 ...mTest/kotlin/com/sksamuel/kotest/specs/stringspec/WordSpecCoroutineSingleTestIsolationModeTest.kt
  142. +1 −1 ...otest-tests-core/src/jvmTest/kotlin/com/sksamuel/kotest/specs/wordspec/WordSpecOneInstanceTest.kt
  143. +3 −2 .../src/jvmTest/kotlin/com/sksamuel/kotest/specs/wordspec/WordSpecSharedInstanceDuplicateNameTest.kt
  144. +3 −3 kotest-tests/kotest-tests-core/src/jvmTest/kotlin/io/kotest/provided/ProjectConfig.kt
  145. +2 −2 ...tests/kotest-tests-junit5/src/jvmTest/kotlin/com/sksamuel/kotest/junit5/InitErrorEngineKitTest.kt
  146. +2 −2 ...test-tests-junit5/src/jvmTest/kotlin/com/sksamuel/kotest/junit5/StringSpecExceptionInAfterTest.kt
  147. +1 −1 ...est-tests-junit5/src/jvmTest/kotlin/com/sksamuel/kotest/junit5/StringSpecExceptionInBeforeTest.kt
  148. +3 −3 ...st-tests/kotest-tests-timeout/src/jvmTest/kotlin/com/sksamuel/kotest/timeout/GlobalTimeoutTest.kt
  149. +9 −6 ...otest-tests-timeout/src/jvmTest/kotlin/com/sksamuel/kotest/timeout/TestCaseTimeoutListenerTest.kt
  150. +3 −3 kotest-tests/kotest-tests-timeout/src/jvmTest/kotlin/com/sksamuel/kotest/timeout/TimeoutTest.kt
@@ -1,9 +1,9 @@
package com.sksamuel.kotest.assertions

import io.kotest.core.AssertionMode
import io.kotest.core.TestCase
import io.kotest.core.TestResult
import io.kotest.core.TestStatus
import io.kotest.core.test.AssertionMode
import io.kotest.core.test.TestCase
import io.kotest.core.test.TestResult
import io.kotest.core.test.TestStatus
import io.kotest.assertions.AssertionCounter
import io.kotest.extensions.TestCaseExtension
import io.kotest.matchers.string.shouldHaveLength
@@ -1,6 +1,11 @@
package io.kotest

import io.kotest.core.*
import io.kotest.core.spec.IsolationMode
import io.kotest.core.test.AssertionMode
import io.kotest.core.test.Description
import io.kotest.core.test.TestCase
import io.kotest.core.test.TestCaseOrder
import io.kotest.extensions.SpecLevelExtension
import io.kotest.extensions.TestListener

@@ -1,5 +1,6 @@
package io.kotest.core

import io.kotest.core.test.TestCaseFilter
import io.kotest.extensions.TagExtension
import io.kotest.extensions.TestCaseExtension

This file was deleted.

@@ -0,0 +1,36 @@
package io.kotest.core.factory

import io.kotest.core.test.AssertionMode
import io.kotest.core.SourceRef
import io.kotest.core.Tag
import io.kotest.core.spec.SpecConfiguration
import io.kotest.core.test.*
import io.kotest.extensions.SpecLevelExtension
import io.kotest.extensions.TestListener

/**
* A [TestFactory] is a generator of tests along with optional configuration and
* callbacks related to those tests. A test factory can be added to a [SpecConfiguration] and the
* tests generated by the factory will be included in that spec.
*/
data class TestFactory(
val tests: List<DynamicTest>,
val tags: Set<Tag>,
val assertionMode: AssertionMode?,
val listeners: List<TestListener>,
val extensions: List<SpecLevelExtension>,
val factories: List<TestFactory>
)

/**
* A [DynamicTest] is an intermediate test state held by a factory. Once the factory is added to a
* [SpecConfiguration] and the spec is created, the factories dynamic tests will be added to the spec
* as fully fledged [TestCase]s.
*/
data class DynamicTest(
val name: String,
val test: suspend TestContext.() -> Unit,
val config: TestCaseConfig,
val type: TestType,
val source: SourceRef
)
@@ -0,0 +1,29 @@
package io.kotest.core.factory

import io.kotest.core.spec.SpecConfiguration
import io.kotest.core.test.Description
import io.kotest.core.test.TestCase

/**
* Generates a [TestCase] for each [DynamicTest] in this factory.
* Tags and assertion mode are applied to the tests.
* Any included factories are recursively called and their generated
* tests included in the returned list.
*
* @param description the parent description for the generated tests.
* @param spec the [SpecConfiguration] that will contain the generated tests.
*/
fun TestFactory.generate(description: Description, spec: SpecConfiguration): List<TestCase> {
return tests.map { dyn ->
TestCase(
description = description.append(dyn.name),
spec = spec,
test = dyn.test,
type = dyn.type,
source = dyn.source,
config = dyn.config.copy(tags = dyn.config.tags + this.tags),
factory = this,
assertionMode = this.assertionMode
)
} + factories.flatMap { it.generate(description, spec) }
}

This file was deleted.

@@ -1,5 +1,7 @@
package io.kotest.core.spec

import io.kotest.core.factory.TestFactory

abstract class CompositeSpec(vararg factories: TestFactory) : SpecConfiguration() {
init {
factories.forEach { include(it) }
@@ -1,4 +1,4 @@
package io.kotest.core
package io.kotest.core.spec

enum class IsolationMode {

@@ -0,0 +1,160 @@
package io.kotest.core.spec

import io.kotest.core.factory.generate
import io.kotest.core.test.TestCase
import io.kotest.core.test.TestCaseOrder
import io.kotest.core.test.TestResult
import io.kotest.extensions.SpecLevelExtension
import io.kotest.extensions.TestListener
import io.kotest.extensions.RootTest
import io.kotest.fp.Tuple2

/**
* A [Spec] is the unit of execution in Kotest. It contains one or more
* [TestCase]s which are executed individually. All tests in a spec must
* pass for the spec itself to be considered passing.
*
* Tests can either be root level, or nested inside other tests, depending
* on the style of spec in use.
*
* Specs also contain [TestListener]s and [SpecLevelExtension]s which are used
* to hook into the test lifecycle and interface with the test engine.
*
* A spec can define an [IsolationMode] used to control the instantiation of
* classes for test cases in that spec.
*
* A spec can define the [TestCaseOrder] which controls the ordering of the
* execution of root level tests in that spec.
*/
data class Spec(
val rootTests: List<RootTest>,
val listeners: List<TestListener>,
val extensions: List<SpecLevelExtension>,
val isolationMode: IsolationMode?,
val testCaseOrder: TestCaseOrder?
)

/**
* Returns the resolved listeners for a given [SpecConfiguration].
* That is, the listeners defined directly on the spec, listeners generated from the
* callback-dsl methods, and listeners defined in any included [TestFactory]s.
*/
fun SpecConfiguration.resolvedListeners(): List<TestListener> {

// listeners from the spec callbacks need to be wrapped into a TestListener
val callbacks = object : TestListener {
override suspend fun beforeTest(testCase: TestCase) {
this@resolvedListeners.beforeTests.forEach { it(testCase) }
}

override suspend fun afterTest(testCase: TestCase, result: TestResult) {
this@resolvedListeners.afterTests.forEach { it(Tuple2(testCase, result)) }
}

override fun afterSpec(spec: SpecConfiguration) {
this@resolvedListeners.afterSpecs.forEach { it(emptyMap()) }
}

override fun beforeSpec(spec: SpecConfiguration) {
this@resolvedListeners.beforeSpecs.forEach { it() }
}
}

return this.listeners + this.listeners() + callbacks + factories.flatMap { it.listeners }
}

fun SpecConfiguration.resolvedTestCaseOrder() =
this.testOrder ?: this.testCaseOrder() ?: TestCaseOrder.Sequential

fun SpecConfiguration.resolvedIsolationMode() =
this.isolation ?: this.isolationMode() ?: IsolationMode.InstancePerLeaf

fun SpecConfiguration.materializeRootTests(): List<RootTest> {

val order = resolvedTestCaseOrder()
val allTests = this.rootTestCases + factories
.flatMap { it.generate(this::class.description(), this) }

// materialize the tests in the factories at this time
// and apply the configuration from the spec config
// then order by the test case order
return allTests
.map {
it.copy(
assertionMode = it.assertionMode ?: this.assertionMode ?: this.assertionMode(),
config = it.config.copy(tags = it.config.tags + this.tags + this.tags())
)
}
.ordered(order)
.withIndex()
.map { RootTest(it.value, it.index) }
}

/**
* Builds an immutable [Spec] from the given [SpecConfiguration].
*
* The returning spec combines tests defined directly in a spec configuration class as well
* as tests generated from any included factories.
*
* Callbacks added via the callback-dsl will be converted into a [TestListener].
*/
fun SpecConfiguration.build(): Spec {

// test are ordered by the value set in the spec or falling back to the project
val order = testOrder ?: testCaseOrder() ?: TestCaseOrder.Sequential // todo ?: Project.testCaseOrder()

val allTests = this.rootTestCases + factories
.flatMap { it.generate(this::class.description(), this) }

// materialize the tests in the factories at this time
// and apply the configuration from the spec config
val rootTests = allTests
.map {
it.copy(
assertionMode = it.assertionMode ?: this.assertionMode ?: this.assertionMode(),
config = it.config.copy(tags = it.config.tags + this.tags + this.tags())
)
}
.ordered(order)
.withIndex()
.map { RootTest(it.value, it.index) }

// listeners from the spec callbacks need to be wrapped into a TestListener
val callbacks = object : TestListener {
override suspend fun beforeTest(testCase: TestCase) {
this@build.beforeTests.forEach { it(testCase) }
}

override suspend fun afterTest(testCase: TestCase, result: TestResult) {
this@build.afterTests.forEach { it(Tuple2(testCase, result)) }
}

override fun afterSpec(spec: SpecConfiguration) {
this@build.afterSpecs.forEach { it(emptyMap()) }
}

override fun beforeSpec(spec: SpecConfiguration) {
this@build.beforeSpecs.forEach { it() }
}
}

return Spec(
rootTests = rootTests,
listeners = this.listeners + this.listeners() + callbacks,
extensions = this.extensions + this.extensions(),
isolationMode = this.isolation ?: this.isolationMode(),
testCaseOrder = this.testOrder ?: this.testCaseOrder()
)
}


/**
* Orders the collection of [TestCase]s based on the provided [TestCaseOrder].
*/
fun List<TestCase>.ordered(spec: TestCaseOrder): List<TestCase> {
return when (spec) {
TestCaseOrder.Sequential -> this
TestCaseOrder.Random -> this.shuffled()
TestCaseOrder.Lexicographic -> this.sortedBy { it.name.toLowerCase() }
}
}
@@ -1,6 +1,5 @@
package io.kotest.core
package io.kotest.core.spec

import io.kotest.core.spec.SpecConfiguration
import kotlin.reflect.KClass

interface SpecExecutionOrder {
@@ -2,9 +2,9 @@ package io.kotest.core.spec

import io.kotest.SpecClass
import io.kotest.core.*
import io.kotest.core.test.*
import io.kotest.extensions.SpecLevelExtension
import io.kotest.extensions.TestListener
import io.kotest.shouldBe

/**
* Contains functions which can be overriden to set config in the same way that KotlinTest 3.x allowed.
@@ -21,7 +21,6 @@ interface CompatibilitySpecConfiguration {
* If you wish to register an extension across the project
* then use [AbstractProjectConfig.extensions].
*/
@Deprecated("Use the spec DSL", ReplaceWith("extensions(myextension)"))
fun extensions(): List<SpecLevelExtension> = listOf()

/**
@@ -32,29 +31,25 @@ interface CompatibilitySpecConfiguration {
* If you wish to register a listener that will be notified
* for all specs, then use [AbstractProjectConfig.listeners].
*/
@Deprecated("Use the spec DSL", ReplaceWith("listener(mylistener)"))
fun listeners(): List<TestListener> = emptyList()

/**
* Sets the order of top level [TestCase]s in this spec.
* If this function returns a null value, then the value set in
* the [AbstractProjectConfig] will be used.
*/
@Deprecated("Use the spec DSL", ReplaceWith("testCaseOrder = myTestCaseOrder"))
fun testCaseOrder(): TestCaseOrder? = null

/**
* Any tags added here will be in applied to all [TestCase]s defined
* in this [SpecClass] in addition to any defined on the individual
* tests themselves.
*/
@Deprecated("Use the spec DSL", ReplaceWith("tags(mytag)"))
fun tags(): Set<Tag> = emptySet()

// @Deprecated("Use the spec DSL", ReplaceWith("isolationMode = myIsolationMode"))
fun isolationMode(): IsolationMode? = null

@Deprecated("Use the spec DSL", ReplaceWith("assertionMode = myAssertionMode"))
fun assertionMode(): AssertionMode? = null

@Deprecated("Use the spec DSL", ReplaceWith("beforeTest { test -> }"))

0 comments on commit 776fc64

Please sign in to comment.
You can’t perform that action at this time.