Skip to content

Commit

Permalink
tests
Browse files Browse the repository at this point in the history
  • Loading branch information
sksamuel committed Mar 10, 2024
1 parent 76bd9c8 commit db520cd
Show file tree
Hide file tree
Showing 13 changed files with 207 additions and 84 deletions.
3 changes: 3 additions & 0 deletions documentation/docs/framework/config_props.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ object KotestEngineProperties {
*/
const val filterSpecs = "kotest.filter.specs"

/**
* If set to "true" then private classes (specs) will be included in the test suite.
*/
const val includePrivateClasses = "kotest.include.private.classes"

const val propertiesFilename = "kotest.properties.filename"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ import io.kotest.engine.interceptors.EngineContext
import io.kotest.engine.spec.interceptors.ClassVisibilitySpecRefInterceptor

internal actual fun platformInterceptors(context: EngineContext): List<SpecRefInterceptor> {
return listOf(ClassVisibilitySpecRefInterceptor(context.configuration))
return listOf(ClassVisibilitySpecRefInterceptor(context))
}
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
package io.kotest.engine.spec.interceptors

import io.kotest.core.config.ProjectConfiguration
import io.kotest.core.internal.KotestEngineProperties
import io.kotest.core.spec.SpecRef
import io.kotest.core.test.TestCase
import io.kotest.core.test.TestResult
import io.kotest.engine.interceptors.EngineContext
import io.kotest.engine.spec.interceptor.SpecRefInterceptor
import kotlin.reflect.KVisibility

/**
* A [SpecRefInterceptor] which will ignore private specs unless the include private flag
* is true in project config.
*/
class ClassVisibilitySpecRefInterceptor(private val config: ProjectConfiguration) : SpecRefInterceptor {
class ClassVisibilitySpecRefInterceptor(private val context: EngineContext) : SpecRefInterceptor {

override suspend fun intercept(
ref: SpecRef,
Expand All @@ -26,7 +26,13 @@ class ClassVisibilitySpecRefInterceptor(private val config: ProjectConfiguration
}
}

/**
* We allow private classes if the JVM system property is set, if the configuration flag is set, or if
* the test suite contains only a single class.
*/
private fun allowPrivate(): Boolean {
return config.includePrivateClasses || System.getProperty(KotestEngineProperties.includePrivateClasses) == "true"
return context.configuration.includePrivateClasses ||
System.getProperty(KotestEngineProperties.includePrivateClasses) == "true" ||
context.suite.specs.size < 2
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ class BeforeAndAfterProjectConfigCallbackTest : WordSpec() {
}

"beforeAll / afterAll" {
beforeAfterAll = ""
beforeAfterAll = ""
TestEngineLauncher(NoopTestEngineListener)
// two classes so we know these callbacks are only invoked once
.withClasses(A::class, B::class)
Expand All @@ -56,7 +56,7 @@ class BeforeAndAfterProjectConfigCallbackTest : WordSpec() {
}
}

private class A : FunSpec() {
class A : FunSpec() {
init {
test("a") {
beforeAfterProject += "a"
Expand All @@ -65,7 +65,7 @@ private class A : FunSpec() {
}
}

private class B : FunSpec() {
class B : FunSpec() {
init {
test("b") {
beforeAfterProject += "b"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ class AnnotationExtensionTest : FunSpec() {
test("a spec annotated with multiple ApplyExtension's should have all extensions applied") {
TestEngineLauncher(NoopTestEngineListener)
.withClasses(MyAnnotatedSpec2::class)
.withConfiguration(ProjectConfiguration().also { it.includePrivateClasses = true })
.launch()
instantiations.shouldBe(2)
beforeSpec.shouldBe(2)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ private class StringSpecWithAfterTestError : StringSpec({
afterTest {
error("boom")
}
"string test"{}
"string test" {}
})

private class ShouldSpecWithAfterTestError : ShouldSpec({
Expand Down Expand Up @@ -114,55 +114,84 @@ class AfterAnyExceptionTest : WordSpec({

"an exception in before test" should {
"fail the test for behavior spec" {
val executor = SpecExecutor(NoopCoroutineDispatcherFactory, EngineContext(ProjectConfiguration(), Platform.JVM).withListener(listener))
val executor = SpecExecutor(
NoopCoroutineDispatcherFactory,
EngineContext(ProjectConfiguration().also { it.includePrivateClasses = true }, Platform.JVM).withListener(
listener
)
)
executor.execute(BehaviorSpecWithAfterTestError::class)
error.shouldBeInstanceOf<ExtensionException.AfterAnyException>()
error!!.cause!!.shouldHaveMessage("boom")
}
"fail the test for feature spec" {
val executor = SpecExecutor(NoopCoroutineDispatcherFactory, EngineContext(ProjectConfiguration(), Platform.JVM).withListener(listener))
val executor = SpecExecutor(
NoopCoroutineDispatcherFactory,
EngineContext(ProjectConfiguration().also { it.includePrivateClasses = true }, Platform.JVM).withListener(listener)
)
executor.execute(FeatureSpecWithAfterTestError::class)
error.shouldBeInstanceOf<ExtensionException.AfterAnyException>()
error!!.cause!!.shouldHaveMessage("boom")
}
"fail the test for word spec" {
val executor = SpecExecutor(NoopCoroutineDispatcherFactory, EngineContext(ProjectConfiguration(), Platform.JVM).withListener(listener))
val executor = SpecExecutor(
NoopCoroutineDispatcherFactory,
EngineContext(ProjectConfiguration().also { it.includePrivateClasses = true }, Platform.JVM).withListener(listener)
)
executor.execute(WordSpecWithAfterTestError::class)
error.shouldBeInstanceOf<ExtensionException.AfterAnyException>()
error!!.cause!!.shouldHaveMessage("boom")
}
"fail the test for should spec" {
val executor = SpecExecutor(NoopCoroutineDispatcherFactory, EngineContext(ProjectConfiguration(), Platform.JVM).withListener(listener))
val executor = SpecExecutor(
NoopCoroutineDispatcherFactory,
EngineContext(ProjectConfiguration().also { it.includePrivateClasses = true }, Platform.JVM).withListener(listener)
)
executor.execute(ShouldSpecWithAfterTestError::class)
error.shouldBeInstanceOf<ExtensionException.AfterAnyException>()
error!!.cause!!.shouldHaveMessage("boom")
}
"fail the test for string spec" {
val executor = SpecExecutor(NoopCoroutineDispatcherFactory, EngineContext(ProjectConfiguration(), Platform.JVM).withListener(listener))
val executor = SpecExecutor(
NoopCoroutineDispatcherFactory,
EngineContext(ProjectConfiguration().also { it.includePrivateClasses = true }, Platform.JVM).withListener(listener)
)
executor.execute(StringSpecWithAfterTestError::class)
error.shouldBeInstanceOf<ExtensionException.AfterAnyException>()
error!!.cause!!.shouldHaveMessage("boom")
}
"fail the test for describe spec" {
val executor = SpecExecutor(NoopCoroutineDispatcherFactory, EngineContext(ProjectConfiguration(), Platform.JVM).withListener(listener))
val executor = SpecExecutor(
NoopCoroutineDispatcherFactory,
EngineContext(ProjectConfiguration().also { it.includePrivateClasses = true }, Platform.JVM).withListener(listener)
)
executor.execute(DescribeSpecWithAfterTestError::class)
error.shouldBeInstanceOf<ExtensionException.AfterAnyException>()
error!!.cause!!.shouldHaveMessage("boom")
}
"fail the test for free spec" {
val executor = SpecExecutor(NoopCoroutineDispatcherFactory, EngineContext(ProjectConfiguration(), Platform.JVM).withListener(listener))
val executor = SpecExecutor(
NoopCoroutineDispatcherFactory,
EngineContext(ProjectConfiguration().also { it.includePrivateClasses = true }, Platform.JVM).withListener(listener)
)
executor.execute(FreeSpecWithAfterTestError::class)
error.shouldBeInstanceOf<ExtensionException.AfterAnyException>()
error!!.cause!!.shouldHaveMessage("boom")
}
"fail the test for fun spec" {
val executor = SpecExecutor(NoopCoroutineDispatcherFactory, EngineContext(ProjectConfiguration(), Platform.JVM).withListener(listener))
val executor = SpecExecutor(
NoopCoroutineDispatcherFactory,
EngineContext(ProjectConfiguration().also { it.includePrivateClasses = true }, Platform.JVM).withListener(listener)
)
executor.execute(FunSpecWithAfterTestError::class)
error.shouldBeInstanceOf<ExtensionException.AfterAnyException>()
error!!.cause!!.shouldHaveMessage("boom")
}
"fail the test for expect spec" {
val executor = SpecExecutor(NoopCoroutineDispatcherFactory, EngineContext(ProjectConfiguration(), Platform.JVM).withListener(listener))
val executor = SpecExecutor(
NoopCoroutineDispatcherFactory,
EngineContext(ProjectConfiguration().also { it.includePrivateClasses = true }, Platform.JVM).withListener(listener)
)
executor.execute(ExpectSpecWithAfterTestError::class)
error.shouldBeInstanceOf<ExtensionException.AfterAnyException>()
error!!.cause!!.shouldHaveMessage("boom")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ private class StringSpecWithBeforeTestError : StringSpec({
beforeTest {
error("boom")
}
"string test"{}
"string test" {}
})

private class ShouldSpecWithBeforeTestError : ShouldSpec({
Expand Down Expand Up @@ -117,55 +117,84 @@ class BeforeAnyExceptionTest : WordSpec({

"an exception in before test" should {
"fail the test for behavior spec" {
val executor = SpecExecutor(NoopCoroutineDispatcherFactory, EngineContext(ProjectConfiguration(), Platform.JVM).withListener(listener))
val executor = SpecExecutor(
NoopCoroutineDispatcherFactory,
EngineContext(ProjectConfiguration().also { it.includePrivateClasses = true }, Platform.JVM).withListener(
listener
)
)
executor.execute(BehaviorSpecWithBeforeTestError::class)
error.shouldBeInstanceOf<ExtensionException.BeforeAnyException>()
error!!.cause!!.shouldHaveMessage("boom")
}
"fail the test for feature spec" {
val executor = SpecExecutor(NoopCoroutineDispatcherFactory, EngineContext(ProjectConfiguration(), Platform.JVM).withListener(listener))
val executor = SpecExecutor(
NoopCoroutineDispatcherFactory,
EngineContext(ProjectConfiguration().also { it.includePrivateClasses = true }, Platform.JVM).withListener(listener)
)
executor.execute(FeatureSpecWithBeforeTestError::class)
error.shouldBeInstanceOf<ExtensionException.BeforeAnyException>()
error!!.cause!!.shouldHaveMessage("boom")
}
"fail the test for word spec" {
val executor = SpecExecutor(NoopCoroutineDispatcherFactory, EngineContext(ProjectConfiguration(), Platform.JVM).withListener(listener))
val executor = SpecExecutor(
NoopCoroutineDispatcherFactory,
EngineContext(ProjectConfiguration().also { it.includePrivateClasses = true }, Platform.JVM).withListener(listener)
)
executor.execute(WordSpecWithBeforeTestError::class)
error.shouldBeInstanceOf<ExtensionException.BeforeAnyException>()
error!!.cause!!.shouldHaveMessage("boom")
}
"fail the test for should spec" {
val executor = SpecExecutor(NoopCoroutineDispatcherFactory, EngineContext(ProjectConfiguration(), Platform.JVM).withListener(listener))
val executor = SpecExecutor(
NoopCoroutineDispatcherFactory,
EngineContext(ProjectConfiguration().also { it.includePrivateClasses = true }, Platform.JVM).withListener(listener)
)
executor.execute(ShouldSpecWithBeforeTestError::class)
error.shouldBeInstanceOf<ExtensionException.BeforeAnyException>()
error!!.cause!!.shouldHaveMessage("boom")
}
"fail the test for string spec" {
val executor = SpecExecutor(NoopCoroutineDispatcherFactory, EngineContext(ProjectConfiguration(), Platform.JVM).withListener(listener))
val executor = SpecExecutor(
NoopCoroutineDispatcherFactory,
EngineContext(ProjectConfiguration().also { it.includePrivateClasses = true }, Platform.JVM).withListener(listener)
)
executor.execute(StringSpecWithBeforeTestError::class)
error.shouldBeInstanceOf<ExtensionException.BeforeAnyException>()
error!!.cause!!.shouldHaveMessage("boom")
}
"fail the test for describe spec" {
val executor = SpecExecutor(NoopCoroutineDispatcherFactory, EngineContext(ProjectConfiguration(), Platform.JVM).withListener(listener))
val executor = SpecExecutor(
NoopCoroutineDispatcherFactory,
EngineContext(ProjectConfiguration().also { it.includePrivateClasses = true }, Platform.JVM).withListener(listener)
)
executor.execute(DescribeSpecWithBeforeTestError::class)
error.shouldBeInstanceOf<ExtensionException.BeforeAnyException>()
error!!.cause!!.shouldHaveMessage("boom")
}
"fail the test for free spec" {
val executor = SpecExecutor(NoopCoroutineDispatcherFactory, EngineContext(ProjectConfiguration(), Platform.JVM).withListener(listener))
val executor = SpecExecutor(
NoopCoroutineDispatcherFactory,
EngineContext(ProjectConfiguration().also { it.includePrivateClasses = true }, Platform.JVM).withListener(listener)
)
executor.execute(FreeSpecWithBeforeTestError::class)
error.shouldBeInstanceOf<ExtensionException.BeforeAnyException>()
error!!.cause!!.shouldHaveMessage("boom")
}
"fail the test for fun spec" {
val executor = SpecExecutor(NoopCoroutineDispatcherFactory, EngineContext(ProjectConfiguration(), Platform.JVM).withListener(listener))
val executor = SpecExecutor(
NoopCoroutineDispatcherFactory,
EngineContext(ProjectConfiguration().also { it.includePrivateClasses = true }, Platform.JVM).withListener(listener)
)
executor.execute(FunSpecWithBeforeTestError::class)
error.shouldBeInstanceOf<ExtensionException.BeforeAnyException>()
error!!.cause!!.shouldHaveMessage("boom")
}
"fail the test for expect spec" {
val executor = SpecExecutor(NoopCoroutineDispatcherFactory, EngineContext(ProjectConfiguration(), Platform.JVM).withListener(listener))
val executor = SpecExecutor(
NoopCoroutineDispatcherFactory,
EngineContext(ProjectConfiguration().also { it.includePrivateClasses = true }, Platform.JVM).withListener(listener)
)
executor.execute(ExpectSpecWithBeforeTestError::class)
error.shouldBeInstanceOf<ExtensionException.BeforeAnyException>()
error!!.cause!!.shouldHaveMessage("boom")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,27 +1,13 @@
package com.sksamuel.kotest.engine.interceptors

import io.kotest.assertions.fail
import io.kotest.core.descriptors.Descriptor
import io.kotest.core.descriptors.DescriptorId
import io.kotest.core.names.TestName
import io.kotest.core.spec.style.FreeSpec
import io.kotest.core.test.TestCase
import io.kotest.core.test.TestResult
import io.kotest.core.test.TestType
import io.kotest.engine.TestEngineLauncher
import io.kotest.engine.interceptors.MarkAbortedExceptionsAsSkippedTestInterceptor
import io.kotest.engine.listener.CollectingTestEngineListener
import io.kotest.inspectors.forOne
import io.kotest.matchers.booleans.shouldBeTrue
import io.kotest.matchers.collections.shouldContainExactly
import io.kotest.matchers.collections.shouldMatchEach
import io.kotest.matchers.maps.shouldContainAll
import io.kotest.matchers.maps.shouldMatchAll
import io.kotest.matchers.result.shouldBeSuccess
import io.kotest.matchers.shouldBe
import io.kotest.matchers.types.shouldBeInstanceOf
import org.opentest4j.TestAbortedException
import kotlin.time.Duration.Companion.milliseconds

class AbortedExceptionTest : FreeSpec({
"TestAbortedException is handled" {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.sksamuel.kotest.engine.spec

import io.kotest.core.config.ProjectConfiguration
import io.kotest.core.spec.style.FunSpec
import io.kotest.engine.TestEngineLauncher
import io.kotest.engine.listener.CollectingTestEngineListener
Expand All @@ -10,7 +11,9 @@ class SpecInitializationErrorTest : FunSpec() {
init {
test("errors in fields should fail the spec in the engine") {
val collector = CollectingTestEngineListener()
TestEngineLauncher(collector).withClasses(FieldInitErrorSpec::class).launch()
TestEngineLauncher(collector)
.withClasses(FieldInitErrorSpec::class)
.launch()
collector.specs[FieldInitErrorSpec::class]!!.errorOrNull.shouldBeInstanceOf<SpecInstantiationException>()
}
}
Expand Down

0 comments on commit db520cd

Please sign in to comment.