Skip to content

Commit 6bcd3cf

Browse files
Adopt Burst for parameterized tests (#1534)
It supports Kotlin/Multiplatform. https://github.com/cashapp/burst Co-authored-by: Jesse Wilson <[email protected]>
1 parent c43c9a6 commit 6bcd3cf

17 files changed

+335
-532
lines changed

build.gradle.kts

+1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ plugins {
2727
buildscript {
2828
dependencies {
2929
classpath(libs.android.gradle.plugin)
30+
classpath(libs.burst.gradle.plugin)
3031
classpath(libs.dokka)
3132
classpath(libs.jmh.gradle.plugin)
3233
classpath(libs.binaryCompatibilityValidator)

gradle/libs.versions.toml

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ androidx-test-ext-junit = { module = "androidx.test.ext:junit", version = "1.2.1
1010
androidx-test-runner = { module = "androidx.test:runner", version = "1.5.2" }
1111
binaryCompatibilityValidator = { module = "org.jetbrains.kotlinx.binary-compatibility-validator:org.jetbrains.kotlinx.binary-compatibility-validator.gradle.plugin", version = "0.16.3" }
1212
bnd = { module = "biz.aQute.bnd:biz.aQute.bnd.gradle", version = "7.0.0" }
13+
burst-gradle-plugin = { module = "app.cash.burst:burst-gradle-plugin", version = "0.5.0" }
1314
dokka = { module = "org.jetbrains.dokka:dokka-gradle-plugin", version = "1.9.20" }
1415
jmh-core = { module = "org.openjdk.jmh:jmh-core", version.ref = "jmh" }
1516
jmh-generator = { module = "org.openjdk.jmh:jmh-generator-annprocess", version.ref = "jmh" }

okio/build.gradle.kts

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.TestExecutable
99

1010
plugins {
1111
kotlin("multiplatform")
12+
id("app.cash.burst")
1213
id("org.jetbrains.dokka")
1314
id("com.vanniktech.maven.publish.base")
1415
id("build-support")

okio/src/commonTest/kotlin/okio/BufferedSourceFactory.kt

+101-121
Original file line numberDiff line numberDiff line change
@@ -16,135 +16,115 @@
1616

1717
package okio
1818

19-
interface BufferedSourceFactory {
20-
class Pipe(
21-
var sink: BufferedSink,
22-
var source: BufferedSource,
23-
)
24-
25-
val isOneByteAtATime: Boolean
26-
27-
fun pipe(): Pipe
28-
29-
companion object {
30-
val BUFFER: BufferedSourceFactory = object : BufferedSourceFactory {
31-
32-
override val isOneByteAtATime: Boolean
33-
get() = false
34-
35-
override fun pipe(): Pipe {
36-
val buffer = Buffer()
37-
return Pipe(
38-
buffer,
39-
buffer,
40-
)
41-
}
19+
enum class BufferedSourceFactory {
20+
BUFFER {
21+
override val isOneByteAtATime: Boolean
22+
get() = false
23+
24+
override fun pipe(): Pipe {
25+
val buffer = Buffer()
26+
return Pipe(
27+
buffer,
28+
buffer,
29+
)
4230
}
43-
44-
val REAL_BUFFERED_SOURCE: BufferedSourceFactory = object :
45-
BufferedSourceFactory {
46-
47-
override val isOneByteAtATime: Boolean
48-
get() = false
49-
50-
override fun pipe(): Pipe {
51-
val buffer = Buffer()
52-
return Pipe(
53-
buffer,
54-
(buffer as Source).buffer(),
55-
)
56-
}
31+
},
32+
33+
REAL_BUFFERED_SOURCE {
34+
override val isOneByteAtATime: Boolean
35+
get() = false
36+
37+
override fun pipe(): Pipe {
38+
val buffer = Buffer()
39+
return Pipe(
40+
buffer,
41+
(buffer as Source).buffer(),
42+
)
5743
}
58-
59-
/**
60-
* A factory deliberately written to create buffers whose internal segments are always 1 byte
61-
* long. We like testing with these segments because are likely to trigger bugs!
62-
*/
63-
val ONE_BYTE_AT_A_TIME_BUFFERED_SOURCE: BufferedSourceFactory = object :
64-
BufferedSourceFactory {
65-
66-
override val isOneByteAtATime: Boolean
67-
get() = true
68-
69-
override fun pipe(): Pipe {
70-
val buffer = Buffer()
71-
return Pipe(
72-
buffer,
73-
object : Source by buffer {
74-
override fun read(sink: Buffer, byteCount: Long): Long {
75-
// Read one byte into a new buffer, then clone it so that the segment is shared.
76-
// Shared segments cannot be compacted so we'll get a long chain of short segments.
44+
},
45+
46+
/**
47+
* A factory deliberately written to create buffers whose internal segments are always 1 byte
48+
* long. We like testing with these segments because are likely to trigger bugs!
49+
*/
50+
ONE_BYTE_AT_A_TIME_BUFFERED_SOURCE {
51+
override val isOneByteAtATime: Boolean
52+
get() = true
53+
54+
override fun pipe(): Pipe {
55+
val buffer = Buffer()
56+
return Pipe(
57+
buffer,
58+
object : Source by buffer {
59+
override fun read(sink: Buffer, byteCount: Long): Long {
60+
// Read one byte into a new buffer, then clone it so that the segment is shared.
61+
// Shared segments cannot be compacted so we'll get a long chain of short segments.
62+
val box = Buffer()
63+
val result = buffer.read(box, minOf(byteCount, 1L))
64+
if (result > 0L) sink.write(box.copy(), result)
65+
return result
66+
}
67+
}.buffer(),
68+
)
69+
}
70+
},
71+
72+
ONE_BYTE_AT_A_TIME_BUFFER {
73+
override val isOneByteAtATime: Boolean
74+
get() = true
75+
76+
override fun pipe(): Pipe {
77+
val buffer = Buffer()
78+
return Pipe(
79+
object : Sink by buffer {
80+
override fun write(source: Buffer, byteCount: Long) {
81+
// Write each byte into a new buffer, then clone it so that the segments are shared.
82+
// Shared segments cannot be compacted so we'll get a long chain of short segments.
83+
for (i in 0 until byteCount) {
7784
val box = Buffer()
78-
val result = buffer.read(box, minOf(byteCount, 1L))
79-
if (result > 0L) sink.write(box.copy(), result)
80-
return result
85+
box.write(source, 1)
86+
buffer.write(box.copy(), 1)
8187
}
82-
}.buffer(),
83-
)
84-
}
88+
}
89+
}.buffer(),
90+
buffer,
91+
)
8592
}
86-
87-
val ONE_BYTE_AT_A_TIME_BUFFER: BufferedSourceFactory = object :
88-
BufferedSourceFactory {
89-
90-
override val isOneByteAtATime: Boolean
91-
get() = true
92-
93-
override fun pipe(): Pipe {
94-
val buffer = Buffer()
95-
return Pipe(
96-
object : Sink by buffer {
97-
override fun write(source: Buffer, byteCount: Long) {
98-
// Write each byte into a new buffer, then clone it so that the segments are shared.
99-
// Shared segments cannot be compacted so we'll get a long chain of short segments.
100-
for (i in 0 until byteCount) {
101-
val box = Buffer()
102-
box.write(source, 1)
103-
buffer.write(box.copy(), 1)
104-
}
105-
}
106-
}.buffer(),
107-
buffer,
108-
)
109-
}
93+
},
94+
95+
PEEK_BUFFER {
96+
override val isOneByteAtATime: Boolean
97+
get() = false
98+
99+
override fun pipe(): Pipe {
100+
val buffer = Buffer()
101+
return Pipe(
102+
buffer,
103+
buffer.peek(),
104+
)
110105
}
111-
112-
val PEEK_BUFFER: BufferedSourceFactory = object : BufferedSourceFactory {
113-
114-
override val isOneByteAtATime: Boolean
115-
get() = false
116-
117-
override fun pipe(): Pipe {
118-
val buffer = Buffer()
119-
return Pipe(
120-
buffer,
121-
buffer.peek(),
122-
)
123-
}
106+
},
107+
108+
PEEK_BUFFERED_SOURCE {
109+
override val isOneByteAtATime: Boolean
110+
get() = false
111+
112+
override fun pipe(): Pipe {
113+
val buffer = Buffer()
114+
return Pipe(
115+
buffer,
116+
(buffer as Source).buffer().peek(),
117+
)
124118
}
119+
},
120+
;
125121

126-
val PEEK_BUFFERED_SOURCE: BufferedSourceFactory = object :
127-
BufferedSourceFactory {
122+
abstract val isOneByteAtATime: Boolean
128123

129-
override val isOneByteAtATime: Boolean
130-
get() = false
124+
abstract fun pipe(): Pipe
131125

132-
override fun pipe(): Pipe {
133-
val buffer = Buffer()
134-
return Pipe(
135-
buffer,
136-
(buffer as Source).buffer().peek(),
137-
)
138-
}
139-
}
140-
141-
val PARAMETERIZED_TEST_VALUES = mutableListOf<Array<Any>>(
142-
arrayOf(BUFFER),
143-
arrayOf(REAL_BUFFERED_SOURCE),
144-
arrayOf(ONE_BYTE_AT_A_TIME_BUFFERED_SOURCE),
145-
arrayOf(ONE_BYTE_AT_A_TIME_BUFFER),
146-
arrayOf(PEEK_BUFFER),
147-
arrayOf(PEEK_BUFFERED_SOURCE),
148-
)
149-
}
126+
class Pipe(
127+
var sink: BufferedSink,
128+
var source: BufferedSource,
129+
)
150130
}

okio/src/jvmTest/kotlin/okio/AwaitSignalTest.kt

+2-10
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
*/
1616
package okio
1717

18+
import app.cash.burst.Burst
1819
import java.io.InterruptedIOException
1920
import java.util.concurrent.TimeUnit
2021
import java.util.concurrent.locks.Condition
@@ -25,11 +26,8 @@ import org.junit.Assert.assertEquals
2526
import org.junit.Assert.assertTrue
2627
import org.junit.Assert.fail
2728
import org.junit.Test
28-
import org.junit.runner.RunWith
29-
import org.junit.runners.Parameterized
30-
import org.junit.runners.Parameterized.Parameters
3129

32-
@RunWith(Parameterized::class)
30+
@Burst
3331
class AwaitSignalTest(
3432
factory: TimeoutFactory,
3533
) {
@@ -215,10 +213,4 @@ class AwaitSignalTest(
215213
TimeUnit.MILLISECONDS,
216214
)
217215
}
218-
219-
companion object {
220-
@Parameters(name = "{0}")
221-
@JvmStatic
222-
fun parameters(): List<Array<out Any?>> = TimeoutFactory.entries.map { arrayOf(it) }
223-
}
224216
}

okio/src/jvmTest/kotlin/okio/BufferCursorKotlinTest.kt

+5-16
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
*/
1616
package okio
1717

18+
import app.cash.burst.Burst
1819
import kotlin.test.assertEquals
1920
import kotlin.test.assertFalse
2021
import kotlin.test.assertNotSame
@@ -24,23 +25,11 @@ import okio.Buffer.UnsafeCursor
2425
import okio.TestUtil.deepCopy
2526
import org.junit.Assume.assumeTrue
2627
import org.junit.Test
27-
import org.junit.runner.RunWith
28-
import org.junit.runners.Parameterized
29-
import org.junit.runners.Parameterized.Parameter
30-
import org.junit.runners.Parameterized.Parameters
31-
32-
@RunWith(Parameterized::class)
33-
class BufferCursorKotlinTest {
34-
companion object {
35-
@Parameters(name = "{0}")
36-
@JvmStatic
37-
fun parameters(): List<Array<out Any?>> {
38-
return BufferFactory.values().map { arrayOf(it) }
39-
}
40-
}
41-
42-
@Parameter lateinit var bufferFactory: BufferFactory
4328

29+
@Burst
30+
class BufferCursorKotlinTest(
31+
private val bufferFactory: BufferFactory,
32+
) {
4433
@Test fun acquireReadOnlyDoesNotCopySharedDataArray() {
4534
val buffer = deepCopy(bufferFactory.newBuffer())
4635
assumeTrue(buffer.size > 0L)

okio/src/jvmTest/kotlin/okio/BufferCursorTest.kt

+2-16
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
*/
1616
package okio
1717

18+
import app.cash.burst.Burst
1819
import java.util.Arrays
1920
import okio.ByteString.Companion.of
2021
import okio.TestUtil.SEGMENT_SIZE
@@ -27,11 +28,8 @@ import org.junit.Assert.assertNull
2728
import org.junit.Assert.fail
2829
import org.junit.Assume.assumeTrue
2930
import org.junit.Test
30-
import org.junit.runner.RunWith
31-
import org.junit.runners.Parameterized
32-
import org.junit.runners.Parameterized.Parameters
3331

34-
@RunWith(Parameterized::class)
32+
@Burst
3533
class BufferCursorTest(
3634
private var bufferFactory: BufferFactory,
3735
) {
@@ -444,16 +442,4 @@ class BufferCursorTest(
444442
assertEquals(originalSize, cursor.offset)
445443
}
446444
}
447-
448-
companion object {
449-
@JvmStatic
450-
@Parameters(name = "{0}")
451-
fun parameters(): List<Array<Any>> {
452-
val result = mutableListOf<Array<Any>>()
453-
for (bufferFactory in BufferFactory.values()) {
454-
result += arrayOf(bufferFactory)
455-
}
456-
return result
457-
}
458-
}
459445
}

0 commit comments

Comments
 (0)