Skip to content

Commit ebfaa97

Browse files
authored
Sprinkle the suspend keyword wherever it makes sense. (#835)
1 parent b9c2d2e commit ebfaa97

File tree

23 files changed

+263
-186
lines changed

23 files changed

+263
-186
lines changed

buildSrc/src/main/kotlin/Dependencies.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ object Dependencies {
1919
val kotlinCoroutinesCoreCommon = "org.jetbrains.kotlinx:kotlinx-coroutines-core-common:1.3.3"
2020
val kotlinCoroutinesCore = "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.3"
2121
val kotlinCoroutinesNative = "org.jetbrains.kotlinx:kotlinx-coroutines-core-native:1.3.3"
22+
val kotlinCoroutinesTest = "org.jetbrains.kotlinx:kotlinx-coroutines-test:1.3.3"
2223

2324
val autoService = "com.google.auto.service:auto-service:1.0-rc4"
2425
}

integration-test/build.gradle.kts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ kotlin {
2222
implementation(project(":spek-dsl"))
2323
implementation(project(":spek-runtime"))
2424
implementation(kotlin("test"))
25+
implementation(Dependencies.kotlinCoroutinesCoreCommon)
26+
implementation(Dependencies.kotlinCoroutinesTest)
2527
}
2628
}
2729

@@ -36,6 +38,7 @@ kotlin {
3638
dependencies {
3739
implementation(Dependencies.mockitoKotlin)
3840
implementation(Dependencies.mockitoCore)
41+
implementation(Dependencies.kotlinCoroutinesCore)
3942
runtimeOnly(kotlin("reflect"))
4043
runtimeOnly(project(":spek-runner-junit5"))
4144
}
@@ -48,6 +51,9 @@ kotlin {
4851

4952
val nativeTest by creating {
5053
dependsOn(commonTest)
54+
dependencies {
55+
implementation(Dependencies.kotlinCoroutinesNative)
56+
}
5157
}
5258

5359
linuxX64("linux") {

integration-test/src/commonTest/kotlin/org/spekframework/spek2/TestSupport.kt

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
package org.spekframework.spek2
22

3+
import kotlinx.coroutines.CoroutineScope
4+
import kotlinx.coroutines.Dispatchers
5+
import kotlinx.coroutines.async
36
import org.spekframework.spek2.dsl.Root
47
import org.spekframework.spek2.runtime.SpekRuntime
58
import org.spekframework.spek2.runtime.discovery.DiscoveryContext
@@ -114,17 +117,17 @@ class SpekTestHelper {
114117
return builder.build()
115118
}
116119

117-
fun executeTests(context: DiscoveryContext, vararg paths: Path): ExecutionRecorder {
120+
suspend fun executeTests(context: DiscoveryContext, vararg paths: Path): ExecutionRecorder {
118121
val runtime = SpekRuntime()
119122
val recorder = ExecutionRecorder()
120123

121124
val discoveryResult = runtime.discover(DiscoveryRequest(context, listOf(*paths)))
122-
runtime.execute(ExecutionRequest(discoveryResult.roots, recorder))
125+
runtime.executeAsync(ExecutionRequest(discoveryResult.roots, recorder))
123126

124127
return recorder
125128
}
126129

127-
fun<T: Spek> executeTest(test: T): ExecutionRecorder {
130+
suspend fun <T: Spek> executeTest(test: T): ExecutionRecorder {
128131
val path = PathBuilder.from(test::class)
129132
.build()
130133

integration-test/src/jvmTest/kotlin/org/spekframework/spek2/FakeGroupBody.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,10 @@ class FakeGroupBody : GroupBody {
2222
override val defaultCachingMode: CachingMode
2323
get() = throw UnsupportedOperationException()
2424

25-
override fun <T> memoized(mode: CachingMode, factory: () -> T): MemoizedValue<T> =
25+
override fun <T> memoized(mode: CachingMode, factory: suspend () -> T): MemoizedValue<T> =
2626
throw UnsupportedOperationException()
2727

28-
override fun <T> memoized(mode: CachingMode, factory: () -> T, destructor: (T) -> Unit): MemoizedValue<T> =
28+
override fun <T> memoized(mode: CachingMode, factory: suspend () -> T, destructor: suspend (T) -> Unit): MemoizedValue<T> =
2929
throw UnsupportedOperationException()
3030

3131
override fun beforeEachTest(fixture: Fixture) {
@@ -56,5 +56,5 @@ class FakeGroupBody : GroupBody {
5656

5757
override var defaultTimeout: Long = 0L
5858

59-
override fun test(description: String, skip: Skip, timeout: Long, body: TestBody.() -> Unit) = throw UnsupportedOperationException()
59+
override fun test(description: String, skip: Skip, timeout: Long, body: suspend TestBody.() -> Unit) = throw UnsupportedOperationException()
6060
}

integration-test/src/jvmTest/kotlin/org/spekframework/spek2/FeatureBodyAliasesTest.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,25 +9,25 @@ object FeatureBodyAliasesTest : Spek({
99
val featureBody by memoized { FeatureBody(groupBody) }
1010

1111
test("beforeEachScenario should call beforeEachGroup") {
12-
val fixture = { println("hello") }
12+
val fixture = suspend { println("hello") }
1313
featureBody.beforeEachScenario(fixture)
1414
assertSame(fixture, groupBody.beforeEachGroup)
1515
}
1616

1717
test("afterEachScenario should call AfterEachGroup") {
18-
val fixture = { println("hello") }
18+
val fixture = suspend { println("hello") }
1919
featureBody.afterEachScenario(fixture)
2020
assertSame(fixture, groupBody.afterEachGroup)
2121
}
2222

2323
test("beforeFeature should call BeforeGroup") {
24-
val fixture = { println("hello") }
24+
val fixture = suspend { println("hello") }
2525
featureBody.beforeFeature(fixture)
2626
assertSame(fixture, groupBody.beforeGroup)
2727
}
2828

2929
test("afterFeature should call AfterGroup") {
30-
val fixture = { println("hello") }
30+
val fixture = suspend { println("hello") }
3131
featureBody.afterFeature(fixture)
3232
assertSame(fixture, groupBody.afterGroup)
3333
}

integration-test/src/jvmTest/kotlin/org/spekframework/spek2/ScenarioBodyAliasesTest.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,25 +10,25 @@ object ScenarioBodyAliasesTest : Spek({
1010
val scenarioBody by memoized { ScenarioBody(groupBody) }
1111

1212
test("beforeEachScenario should call BeforeEachGroup") {
13-
val fixture = { println("hello") }
13+
val fixture = suspend { println("hello") }
1414
scenarioBody.beforeScenario(fixture)
1515
assertSame(fixture, groupBody.beforeGroup)
1616
}
1717

1818
test("afterEachScenario should call AfterEachGroup") {
19-
val fixture = { println("hello") }
19+
val fixture = suspend { println("hello") }
2020
scenarioBody.afterScenario(fixture)
2121
assertSame(fixture, groupBody.afterGroup)
2222
}
2323

2424
test("beforeEachStep should call BeforeEachTest") {
25-
val fixture = { println("hello") }
25+
val fixture = suspend { println("hello") }
2626
scenarioBody.beforeEachStep(fixture)
2727
assertSame(fixture, groupBody.beforeEachTest)
2828
}
2929

3030
test("afterEachStep should call AfterEachTest") {
31-
val fixture = { println("hello") }
31+
val fixture = suspend { println("hello") }
3232
scenarioBody.afterEachStep(fixture)
3333
assertSame(fixture, groupBody.afterEachTest)
3434
}
Lines changed: 74 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,65 +1,100 @@
11
package org.spekframework.spek2
22

3+
import kotlinx.coroutines.async
4+
import kotlinx.coroutines.channels.Channel
5+
import kotlinx.coroutines.test.runBlockingTest
36
import org.spekframework.spek2.style.specification.describe
47

58
object TimeoutTest: AbstractSpekTest({ helper ->
69
describe("test timeouts") {
7-
it("should timeout using default settings", timeout = 0) {
8-
val recorder = helper.executeTest(testData.timeoutTest.DefaultTimeoutTest)
10+
it("specification style timeouts") {
11+
runBlockingTest {
12+
val latch = Channel<Int>()
13+
val recorder = async {
14+
helper.executeTest(testData.timeoutTest.SpecificationStyleTimeoutTests(latch))
15+
}
916

10-
helper.assertExecutionEquals(
11-
recorder.events()
12-
) {
13-
group("DefaultTimeoutTest") {
14-
test("should timeout", false)
15-
group("timeout specification style") {
16-
test("should timeout", false)
17-
}
18-
group("Feature: timeout gherkin style") {
19-
group("Scenario: some scenario") {
20-
test("Then: should timeout", false)
17+
advanceTimeBy(10_000)
18+
advanceTimeBy(300)
19+
advanceTimeBy(9_000)
20+
latch.send(0)
21+
advanceTimeBy(400)
22+
latch.send(0)
23+
24+
helper.assertExecutionEquals(
25+
recorder.await().events()
26+
) {
27+
group("SpecificationStyleTimeoutTests") {
28+
group("timeouts") {
29+
test("tests running pass the default timeout should fail", false)
30+
test("tests running pass 300ms should fail", false)
31+
test("tests running less than default timeout should succeed")
32+
test("tests running less than 500ms should succeed")
2133
}
2234
}
2335
}
2436
}
2537
}
26-
}
2738

28-
describe("custom timeouts") {
29-
it("should timeout using specified settings") {
30-
val recorder = helper.executeTest(testData.timeoutTest.CustomTimeoutTest)
39+
it("gherkin style timeouts") {
40+
runBlockingTest {
41+
val latch = Channel<Int>()
42+
val recorder = async {
43+
helper.executeTest(testData.timeoutTest.GherkinStyleTimeoutTests(latch))
44+
}
3145

32-
helper.assertExecutionEquals(
33-
recorder.events()
34-
) {
35-
group("CustomTimeoutTest") {
36-
test("should timeout", false)
37-
group("timeout specification style") {
38-
test("should timeout", false)
39-
}
40-
group("Feature: timeout gherkin style") {
41-
group("Scenario: some scenario") {
42-
test("Then: should timeout", false)
46+
advanceTimeBy(10_000)
47+
advanceTimeBy(600)
48+
advanceTimeBy(9_000)
49+
latch.send(0)
50+
advanceTimeBy(1150)
51+
latch.send(0)
52+
53+
helper.assertExecutionEquals(
54+
recorder.await().events()
55+
) {
56+
group("GherkinStyleTimeoutTests") {
57+
group("Feature: Timeouts") {
58+
group("Scenario: Running more than default") {
59+
test("Then: It should fail", false)
60+
}
61+
group("Scenario: Running more than 600ms") {
62+
test("Then: It should fail", false)
63+
}
64+
group("Scenario: Running less than default") {
65+
test("Then: It should succeed")
66+
}
67+
group("Scenario: Running less than 1200ms") {
68+
test("Then: It should succeed")
69+
}
4370
}
4471
}
4572
}
4673
}
4774
}
48-
}
4975

50-
describe("global timeouts") {
51-
it("should use specified global timeout", timeout = 0) {
52-
System.setProperty("SPEK_TIMEOUT", 15000L.toString())
53-
val recorder = helper.executeTest(testData.timeoutTest.GlobalTimeoutTest)
76+
describe("global timeouts") {
77+
it("should use specified global timeout") {
78+
runBlockingTest {
79+
System.setProperty("SPEK_TIMEOUT", 15000L.toString())
80+
val latch = Channel<Int>()
81+
val recorder = async {
82+
helper.executeTest(testData.timeoutTest.GlobalTimeoutTest(latch))
83+
}
84+
85+
advanceTimeBy(14_500)
86+
latch.send(0)
5487

55-
helper.assertExecutionEquals(
56-
recorder.events()
57-
) {
58-
group("GlobalTimeoutTest") {
59-
test("this should run for 10 seconds and pass since global timeout is 20")
88+
helper.assertExecutionEquals(
89+
recorder.await().events()
90+
) {
91+
group("GlobalTimeoutTest") {
92+
test("this should run for 10s and pass since global timeout is 15s")
93+
}
94+
}
95+
System.clearProperty("SPEK_TIMEOUT")
6096
}
6197
}
62-
System.clearProperty("SPEK_TIMEOUT")
6398
}
6499
}
65100
})

integration-test/src/jvmTest/kotlin/testData/timeoutTest/CustomTimeoutTest.kt

Lines changed: 0 additions & 26 deletions
This file was deleted.

integration-test/src/jvmTest/kotlin/testData/timeoutTest/DefaultTimeoutTest.kt

Lines changed: 0 additions & 25 deletions
This file was deleted.
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package testData.timeoutTest
2+
3+
import kotlinx.coroutines.channels.ReceiveChannel
4+
import org.spekframework.spek2.Spek
5+
import org.spekframework.spek2.style.gherkin.Feature
6+
import org.spekframework.spek2.style.specification.describe
7+
8+
class GherkinStyleTimeoutTests(latch: ReceiveChannel<Int>): Spek({
9+
Feature("Timeouts") {
10+
Scenario("Running more than default") {
11+
Then("It should fail") {
12+
latch.receive()
13+
}
14+
}
15+
16+
Scenario("Running more than 600ms") {
17+
defaultTimeout = 600
18+
Then("It should fail") {
19+
latch.receive()
20+
}
21+
}
22+
23+
Scenario("Running less than default") {
24+
Then("It should succeed") {
25+
latch.receive()
26+
}
27+
}
28+
29+
Scenario("Running less than 1200ms") {
30+
defaultTimeout = 1200
31+
Then("It should succeed") {
32+
latch.receive()
33+
}
34+
}
35+
}
36+
})
Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
package testData.timeoutTest
22

3+
import kotlinx.coroutines.channels.ReceiveChannel
34
import org.spekframework.spek2.Spek
45

5-
object GlobalTimeoutTest : Spek({
6-
test("this should run for 10 seconds and pass since global timeout is 20") {
7-
sleep(10000)
6+
class GlobalTimeoutTest(latch: ReceiveChannel<Int>): Spek({
7+
test("this should run for 10s and pass since global timeout is 15s") {
8+
latch.receive()
89
}
910
})

0 commit comments

Comments
 (0)