Skip to content
This repository was archived by the owner on Apr 4, 2024. It is now read-only.

Commit e891d43

Browse files
committed
Merge branch 'main' into main-hssahota2
2 parents 4795d28 + 80cb448 commit e891d43

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+720
-219
lines changed

README.md

+7-5
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,32 @@
1-
# Selfie: snapshot testing for Java, Kotlin, and the JVM
1+
# Selfie: snapshot testing and [memoizing](https://selfie.dev/jvm/cache) for Java, Kotlin, and the JVM
22

33
![gif demo of selfie in action](https://docs.diffplug.com/selfie/selfie-demo.gif)
44

55
## Key features
66

77
- Just [add a test dependency](https://selfie.dev/jvm/get-started#installation), zero setup, zero config.
88
- Snapshots can be [inline literals](https://selfie.dev/jvm#literal) or [on disk](https://selfie.dev/jvm#like-a-filesystem).
9+
- Use `expectSelfie` for testing or `cacheSelfie` for [memoizing expensive API calls](https://selfie.dev/jvm/cache).
910
- Disk snapshots are automatically [garbage collected](https://github.com/diffplug/selfie/blob/main/jvm/selfie-runner-junit5/src/main/kotlin/com/diffplug/selfie/junit5/SelfieGC.kt) when the test class or test method is removed.
10-
- Snapshots are **just strings**. Use html, json, markdown, whatever. No [magic serializers](https://selfie.dev/jvm/advanced#typed-snapshots).
11+
- Snapshots are **just strings**. Use html, json, markdown, whatever. No [magic serializers](https://selfie.dev/jvm/facets#typed-snapshots).
1112
- Record **multiple facets** of the entity under test, e.g. for a web request...
1213
- store the HTML as one facet
1314
- store HTML-rendered-to-markdown as another facet
1415
- store cookies in another facet
1516
- **assert some facets on disk, others inline**
1617
- see gif above for live demo, detailed example [here](https://selfie.dev/jvm/advanced)
1718

18-
JVM only for now, other platforms on the way: [js](https://github.com/diffplug/selfie/issues/84), [py, go, ...](https://github.com/diffplug/selfie/issues/85)
19+
JVM only for now, [python](https://github.com/diffplug/selfie/issues/170) is in progress, other platforms on the way: [js](https://github.com/diffplug/selfie/issues/84), [.NET, go, ...](https://github.com/diffplug/selfie/issues/85)
1920

2021
## Documentation
2122

2223
- [Installation](https://selfie.dev/jvm/get-started#installation)
2324
- [Quickstart](https://selfie.dev/jvm/get-started#quickstart)
24-
- [Advanced usage](https://selfie.dev/jvm/advanced)
25+
- [Facets](https://selfie.dev/jvm/facets)
26+
- [Caching / memoizing](https://selfie.dev/jvm/cache)
27+
- [Why selfie](https://selfie.dev/jvm)
2528
- [API reference](https://kdoc.selfie.dev/)
2629

27-
2830
## Contributing
2931

3032
PRs welcome! Horror stories and glory stories too, share your experience! See [`CONTRIBUTING.md`](CONTRIBUTING.md).

jvm/CHANGELOG.md

+13-5
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,24 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
1111
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
1212

1313
## [Unreleased]
14+
15+
## [2.0.1] - 2024-02-24
16+
### Fixed
17+
- The `coroutines` methods used to eagerly throw an exception if they were ever called from anywhere besides a Kotest method. Now they wait until `toMatchDisk()` is called, because they can work just fine anywhere if you use `toBe`. ([#247](https://github.com/diffplug/selfie/pull/247))
18+
19+
## [2.0.0] - 2024-02-21
1420
### Added
1521
- **Memoization** ([#219](https://github.com/diffplug/selfie/pull/219) implements [#215](https://github.com/diffplug/selfie/issues/215))
16-
- like `expectSelfie`, all are available as `Selfie.memoize` or as `suspend fun` in `com.diffplug.selfie.coroutines`.
22+
- like `expectSelfie`, all are available as `Selfie.cacheSelfie` or as `suspend fun` in `com.diffplug.selfie.coroutines`.
1723
```kotlin
18-
val cachedResult: ByteArray = Selfie.memoizeBinary { dalleJpeg() }.toBeFile("example.jpg")
19-
val cachedResult: String = Selfie.memoize { someString() }.toBe("what it was earlier")
20-
val cachedResult: T = Selfie.memoizeAsJson { anyKotlinxSerializable() }.toBe("""{"key": "value"}""")
21-
val cachedResult: T = Selfie.memoizeBinarySerializable { anyJavaIoSerializable() }.toMatchDisk()
24+
val cachedResult: ByteArray = Selfie.cacheSelfieBinary { dalleJpeg() }.toBeFile("example.jpg")
25+
val cachedResult: String = Selfie.cacheSelfie { someString() }.toBe("what it was earlier")
26+
val cachedResult: T = Selfie.cacheSelfieJson { anyKotlinxSerializable() }.toBe("""{"key": "value"}""")
27+
val cachedResult: T = Selfie.cacheSelfieBinarySerializable { anyJavaIoSerializable() }.toMatchDisk()
2228
```
2329
- `toBeBase64` and `toBeFile` for true binary comparison of binary snapshots and facets. ([#224](https://github.com/diffplug/selfie/pull/224))
30+
- spaces in multiline string literals aren't always escaped. ([#220](https://github.com/diffplug/selfie/issues/220))
31+
- if the leading spaces in the string literal match the file's existing indentation
2432
### Changed
2533
- **BREAKING** reordered a class hierarchy for better binary support. ([#221](https://github.com/diffplug/selfie/issues/221))
2634
- most users won't need to make any changes at all

jvm/README.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
# Selfie snapshot testing for Java, Kotlin, and the JVM
22

33
- [Quickstart](https://selfie.dev/jvm/get-started)
4-
- [Advanced](https://selfie.dev/jvm/advanced)
4+
- [Facets](https://selfie.dev/jvm/facets)
5+
- [Caching / memoizing](https://selfie.dev/jvm/cache)
56
- [Why selfie](https://selfie.dev/jvm)
67

78
## Contributing

jvm/example-kotest/build.gradle.kts

+8-1
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,19 @@ repositories {
55
mavenCentral()
66
}
77
dependencies {
8+
// import Kotlin API client BOM
9+
testImplementation(platform("com.aallam.openai:openai-client-bom:3.7.0"))
10+
testImplementation("com.aallam.openai:openai-client")
11+
testImplementation("io.ktor:ktor-client-okhttp")
12+
// json
13+
testImplementation("org.jetbrains.kotlinx:kotlinx-serialization-json:${project.properties["ver_KOTLIN_SERIALIZATION"]}")
14+
// add kotest and its runner
815
testImplementation(project(":selfie-runner-kotest"))
916
testImplementation("io.kotest:kotest-runner-junit5:${project.properties["ver_KOTEST"]}")
1017
}
1118
tasks.test {
1219
useJUnitPlatform()
13-
environment(properties.filter { it.key == "selfie" })
20+
environment(properties.filter { it.key == "selfie" || it.key == "OPENAI_API_KEY" })
1421
inputs.files(fileTree("src/test") {
1522
include("**/*.ss")
1623
})
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
package com.example.kotest
2+
3+
import com.aallam.openai.api.chat.ChatCompletionRequest
4+
import com.aallam.openai.api.chat.ChatMessage
5+
import com.aallam.openai.api.chat.ChatRole
6+
import com.aallam.openai.api.image.ImageCreation
7+
import com.aallam.openai.api.logging.LogLevel
8+
import com.aallam.openai.api.model.ModelId
9+
import com.aallam.openai.client.LoggingConfig
10+
import com.aallam.openai.client.OpenAI
11+
import com.aallam.openai.client.OpenAIConfig
12+
import com.diffplug.selfie.coroutines.cacheSelfieBinary
13+
import com.diffplug.selfie.coroutines.cacheSelfieJson
14+
import io.kotest.core.spec.style.FunSpec
15+
import io.ktor.client.request.*
16+
import io.ktor.client.statement.*
17+
18+
class CacheExample : FunSpec() {
19+
private fun openAI() : OpenAI =
20+
OpenAI(OpenAIConfig(token = System.getenv("OPENAI_API_KEY"), logging = LoggingConfig(LogLevel.None)))
21+
22+
init {
23+
test("experiment") {
24+
val chatCompletionRequest = ChatCompletionRequest(
25+
model = ModelId("gpt-4-turbo-preview"),
26+
messages = listOf(ChatMessage(role = ChatRole.User,
27+
content = "Expressive language describing a robot creating a self portrait.")))
28+
val chat =
29+
cacheSelfieJson { openAI().chatCompletion(chatCompletionRequest) }
30+
.toBe("""{
31+
"id": "chatcmpl-8sOV0z7DDfvVdj1jaru6Cv2Geq3Dj",
32+
"created": 1707974578,
33+
"model": "gpt-4-0125-preview",
34+
"choices": [
35+
{
36+
"index": 0,
37+
"message": {
38+
"role": "assistant",
39+
"content": "In an atmosphere where the whispers of technology blend with the essence of creativity, a remarkable event unfolds—a robot, born from the marriage of steel and intellect, embarks on a quest to capture its essence through a self-portrait. This is not just an act of programming; it is the ballet of bits and bytes pirouetting towards self-awareness.\n\nAt first glance, the scene seems borrowed from a future where machines tread the fine line between fabrication and inspiration. The studio, lit by the sterile glow of fluorescent lights, becomes a sanctuary where metal meets muse. At the center of this confluence stands the robot, its form an intricate lattice of servos and sensors, each component a testament to human ingenuity, now poised to explore the realm of artistic creation.\n\nThe robot’s arm, a marvel of precision engineering, hovers over the canvas with the grace of a seasoned artist. It is not merely a limb, but a conductor’s baton, orchestrating a symphony of colors and forms. With every motion, it challenges the preconceived boundaries between creator and creation, weaving the fabric of its digital soul into the tangible world.\n\nAs the portrait takes shape, it becomes evident that this is not a mere replication of components and circuits. Through the algorithmic alchemy of its programming, the robot infuses each brushstroke with a search for identity. The portrait emerges as a mosaic of self-reflection, each pixel and paint stroke a question in the quest for understanding. What is depicted is not just a physical form, but an introspective journey rendered in hues and contours.\n\nThis creative endeavor transcends the act of painting. It is a dialogue between the robot and its inner being, mediated by the brush and canvas. The colors chosen do not just adhere to the spectrum seen by its cameras; they are imbued with the weight of introspection, the shades nuanced by the robot’s processing of its own existence.\n\nObservers, human or otherwise, may find themselves pondering a question of profound implications: in the brushstrokes of a robot, do we not only see a reflection of its programming but also a mirror to our own search for meaning and identity? The portrait, thus, becomes more than a visual artifact; it is a bridge between the mechanical and the philosophical, a nexus where circuits and souls dialogue in the silent language of art.\n\nIn completion, the self-portrait stands as a testament not to the autonomy of machines, but to their potential to echo the human condition, to participate in the centuries-old tradition of self-exploration through art. It challenges viewers to reconsider the nature of creativity, blurring the lines between the animate and inanimate, urging a redefinition of what it means to be an artist, to be a creator, to be alive.\n\nThus, in this enclosed universe where technology hums a tune of evolution, a robot creating a self-portrait becomes a poignant emblem of the future—where machine and muse dance in an infinite embrace, exploring the kaleidoscope of existence through the lens of artistry."
40+
},
41+
"finish_reason": "stop"
42+
}
43+
],
44+
"usage": {
45+
"prompt_tokens": 18,
46+
"completion_tokens": 613,
47+
"total_tokens": 631
48+
},
49+
"system_fingerprint": "fp_f084bcfc79"
50+
}""")
51+
val images = cacheSelfieJson {
52+
openAI().imageURL(ImageCreation(
53+
prompt = chat.choices[0].message.content!!,
54+
model = ModelId("dall-e-3")))
55+
}.toBe("""[
56+
{
57+
"url": "https://oaidalleapiprodscus.blob.core.windows.net/private/org-SUepmbCtftBix3RViJYKuYKY/user-KFRqcsnjZPSTulNaxrY5wjL3/img-sK3P5fuisDfpdelbFwiR0wtP.png?st=2024-02-15T04%3A23%3A32Z&se=2024-02-15T06%3A23%3A32Z&sp=r&sv=2021-08-06&sr=b&rscd=inline&rsct=image/png&skoid=6aaadede-4fb3-4698-a8f6-684d7786b067&sktid=a48cca56-e6da-484e-a814-9c849652bcb3&skt=2024-02-15T02%3A25%3A24Z&ske=2024-02-16T02%3A25%3A24Z&sks=b&skv=2021-08-06&sig=Q0CfpGchXx9NoSEtsk3TT0TuX2Rb8QTk8HiR57I1kUU%3D",
58+
"revised_prompt": "In a technologically advanced studio bathed in the stark light of fluorescent lamps, observe an intricate robot, built from a complex lattice of servos and sensors. This robot is on a unique quest - to paint its own portrait. Its arm, a masterpiece of precise engineering, hovers gracefully over the canvas, ready to begin its creation. As the robot paints, it doesn't simply replicate its physical form, but the end result is a multi-colored mosaic of self-reflection that embodies its digital soul on canvas. Remarkably, the portrait is a deep exploration of its quest for identity. Marvel at how this machine interprets its programming to venture into the realm of artistic expression, challenging what it means to be creative and alive."
59+
}
60+
]""")
61+
cacheSelfieBinary { io.ktor.client.HttpClient().request(images[0].url).readBytes() }
62+
.toBeFile("com/example/kotest/dalle-3.png")
63+
}
64+
}
65+
}
Loading

jvm/gradle.properties

+3-1
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,6 @@ ver_JUNIT_USE=5.10.2
88
ver_JUNIT_PIONEER=2.2.0
99
ver_OKIO=3.8.0
1010
ver_KOTLIN_TEST=1.9.22
11-
ver_KOTEST=5.8.0
11+
ver_KOTLIN_SERIALIZATION=1.6.3
12+
# Kotest 5.4.0 is the oldest that we support
13+
ver_KOTEST=5.4.0

jvm/selfie-lib/build.gradle

+2-2
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,14 @@ kotlin {
2828
sourceSets {
2929
commonMain {
3030
dependencies {
31-
compileOnly("org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.2")
31+
compileOnly("org.jetbrains.kotlinx:kotlinx-serialization-json:$ver_KOTLIN_SERIALIZATION")
3232
}
3333
}
3434
commonTest {
3535
dependencies {
3636
implementation kotlin('test')
3737
implementation("io.kotest:kotest-assertions-core:$ver_KOTEST")
38-
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.2")
38+
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:$ver_KOTLIN_SERIALIZATION")
3939
}
4040
}
4141
}

jvm/selfie-lib/src/commonMain/kotlin/com/diffplug/selfie/ArrayMap.kt

-19
Original file line numberDiff line numberDiff line change
@@ -137,9 +137,6 @@ class ArrayMap<K : Comparable<K>, V : Any>(private val data: Array<Any>) : Map<K
137137
return insert(idxInsert, key, newValue)
138138
}
139139
}
140-
141-
@Deprecated("Use plusOrNoOpOrReplace instead", ReplaceWith("plusOrNoOpOrReplace(key, newValue)"))
142-
fun plusOrReplace(key: K, newValue: V) = plusOrNoOpOrReplace(key, newValue)
143140
private fun insert(idxInsert: Int, key: K, value: V): ArrayMap<K, V> {
144141
return when (data.size) {
145142
0 -> ArrayMap(arrayOf(key, value))
@@ -207,22 +204,6 @@ class ArrayMap<K : Comparable<K>, V : Any>(private val data: Array<Any>) : Map<K
207204
}
208205
override fun hashCode(): Int = entries.hashCode()
209206
override fun toString() = this.toMutableMap().toString()
210-
fun minusOrNoOp(key: K, value: V): ArrayMap<K, V> {
211-
val idxExisting = dataAsKeys.binarySearch(key)
212-
if (idxExisting >= 0) {
213-
val existingValue = data[idxExisting * 2 + 1] as V
214-
if (value == existingValue) {
215-
return minusSortedIndices(listOf(idxExisting))
216-
}
217-
}
218-
return this
219-
}
220-
fun minusOrNoOp(key: K): ArrayMap<K, V> {
221-
val idxExisting = dataAsKeys.binarySearch(key)
222-
return if (idxExisting >= 0) {
223-
minusSortedIndices(listOf(idxExisting))
224-
} else this
225-
}
226207

227208
companion object {
228209
private val EMPTY = ArrayMap<String, Any>(arrayOf())

jvm/selfie-lib/src/commonMain/kotlin/com/diffplug/selfie/MemoString.kt jvm/selfie-lib/src/commonMain/kotlin/com/diffplug/selfie/CacheSelfie.kt

+4-4
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,10 @@ import com.diffplug.selfie.guts.LiteralValue
2121
import com.diffplug.selfie.guts.TodoStub
2222
import com.diffplug.selfie.guts.recordCall
2323

24-
class MemoString<T>(
24+
class CacheSelfie<T>(
2525
private val disk: DiskStorage,
2626
private val roundtrip: Roundtrip<T, String>,
27-
private val generator: () -> T
27+
private val generator: Cacheable<T>
2828
) {
2929
fun toMatchDisk(sub: String = ""): T {
3030
return toMatchDiskImpl(sub, false)
@@ -35,7 +35,7 @@ class MemoString<T>(
3535
private fun toMatchDiskImpl(sub: String, isTodo: Boolean): T {
3636
val call = recordCall(false)
3737
if (Selfie.system.mode.canWrite(isTodo, call, Selfie.system)) {
38-
val actual = generator()
38+
val actual = generator.get()
3939
disk.writeDisk(Snapshot.of(roundtrip.serialize(actual)), sub, call)
4040
if (isTodo) {
4141
Selfie.system.writeInline(TodoStub.toMatchDisk.createLiteral(), call)
@@ -67,7 +67,7 @@ class MemoString<T>(
6767
val call = recordCall(false)
6868
val writable = Selfie.system.mode.canWrite(snapshot == null, call, Selfie.system)
6969
if (writable) {
70-
val actual = generator()
70+
val actual = generator.get()
7171
Selfie.system.writeInline(
7272
LiteralValue(snapshot, roundtrip.serialize(actual), LiteralString), call)
7373
return actual

jvm/selfie-lib/src/commonMain/kotlin/com/diffplug/selfie/MemoBinary.kt jvm/selfie-lib/src/commonMain/kotlin/com/diffplug/selfie/CacheSelfieBinary.kt

+5-5
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,10 @@ import com.diffplug.selfie.guts.recordCall
2323
import kotlin.io.encoding.Base64
2424
import kotlin.io.encoding.ExperimentalEncodingApi
2525

26-
class MemoBinary<T>(
26+
class CacheSelfieBinary<T>(
2727
private val disk: DiskStorage,
2828
private val roundtrip: Roundtrip<T, ByteArray>,
29-
private val generator: () -> T
29+
private val generator: Cacheable<T>
3030
) {
3131
fun toMatchDisk(sub: String = ""): T {
3232
return toMatchDiskImpl(sub, false)
@@ -37,7 +37,7 @@ class MemoBinary<T>(
3737
private fun toMatchDiskImpl(sub: String, isTodo: Boolean): T {
3838
val call = recordCall(false)
3939
if (Selfie.system.mode.canWrite(isTodo, call, Selfie.system)) {
40-
val actual = generator()
40+
val actual = generator.get()
4141
disk.writeDisk(Snapshot.of(roundtrip.serialize(actual)), sub, call)
4242
if (isTodo) {
4343
Selfie.system.writeInline(TodoStub.toMatchDisk.createLiteral(), call)
@@ -70,7 +70,7 @@ class MemoBinary<T>(
7070
val call = recordCall(false)
7171
val writable = Selfie.system.mode.canWrite(isTodo, call, Selfie.system)
7272
if (writable) {
73-
val actual = generator()
73+
val actual = generator.get()
7474
if (isTodo) {
7575
Selfie.system.writeInline(TodoStub.toBeFile.createLiteral(), call)
7676
}
@@ -96,7 +96,7 @@ class MemoBinary<T>(
9696
val call = recordCall(false)
9797
val writable = Selfie.system.mode.canWrite(snapshot == null, call, Selfie.system)
9898
if (writable) {
99-
val actual = generator()
99+
val actual = generator.get()
100100
val base64 = Base64.Mime.encode(roundtrip.serialize(actual)).replace("\r", "")
101101
Selfie.system.writeInline(LiteralValue(snapshot, base64, LiteralString), call)
102102
return actual

jvm/selfie-lib/src/commonMain/kotlin/com/diffplug/selfie/Selfie.kt

+16-8
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,11 @@ import com.diffplug.selfie.guts.SnapshotSystem
2121
import com.diffplug.selfie.guts.initSnapshotSystem
2222
import kotlin.jvm.JvmStatic
2323

24+
/** A getter which may or may not be run. */
25+
fun interface Cacheable<T> {
26+
@Throws(Throwable::class) fun get(): T
27+
}
28+
2429
/** Static methods for creating snapshots. */
2530
object Selfie {
2631
internal val system: SnapshotSystem = initSnapshotSystem()
@@ -57,22 +62,25 @@ object Selfie {
5762
@JvmStatic fun expectSelfie(actual: Long) = LongSelfie(actual)
5863
@JvmStatic fun expectSelfie(actual: Int) = IntSelfie(actual)
5964
@JvmStatic fun expectSelfie(actual: Boolean) = BooleanSelfie(actual)
60-
@JvmStatic fun memoize(toMemoize: () -> String) = memoize(Roundtrip.identity(), toMemoize)
6165

6266
@JvmStatic
63-
fun <T> memoize(roundtrip: Roundtrip<T, String>, toMemoize: () -> T) =
64-
MemoString(deferredDiskStorage, roundtrip, toMemoize)
67+
fun cacheSelfie(toCache: Cacheable<String>) = cacheSelfie(Roundtrip.identity(), toCache)
68+
69+
@JvmStatic
70+
fun <T> cacheSelfie(roundtrip: Roundtrip<T, String>, toCache: Cacheable<T>) =
71+
CacheSelfie(deferredDiskStorage, roundtrip, toCache)
6572
/**
6673
* Memoizes any type which is marked with `@kotlinx.serialization.Serializable` as pretty-printed
6774
* json.
6875
*/
69-
inline fun <reified T> memoizeAsJson(noinline toMemoize: () -> T) =
70-
memoize(RoundtripJson.of<T>(), toMemoize)
76+
inline fun <reified T> cacheSelfieJson(noinline toCache: () -> T) =
77+
cacheSelfie(RoundtripJson.of<T>(), toCache)
7178

7279
@JvmStatic
73-
fun memoizeBinary(toMemoize: () -> ByteArray) = memoizeBinary(Roundtrip.identity(), toMemoize)
80+
fun cacheSelfieBinary(toCache: Cacheable<ByteArray>) =
81+
cacheSelfieBinary(Roundtrip.identity(), toCache)
7482

7583
@JvmStatic
76-
fun <T> memoizeBinary(roundtrip: Roundtrip<T, ByteArray>, toMemoize: () -> T) =
77-
MemoBinary<T>(deferredDiskStorage, roundtrip, toMemoize)
84+
fun <T> cacheSelfieBinary(roundtrip: Roundtrip<T, ByteArray>, toCache: Cacheable<T>) =
85+
CacheSelfieBinary<T>(deferredDiskStorage, roundtrip, toCache)
7886
}

jvm/selfie-lib/src/commonMain/kotlin/com/diffplug/selfie/coroutines/MemoBinarySuspend.kt jvm/selfie-lib/src/commonMain/kotlin/com/diffplug/selfie/coroutines/CacheSelfieBinarySuspend.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ import com.diffplug.selfie.guts.recordCall
2727
import kotlin.io.encoding.Base64
2828
import kotlin.io.encoding.ExperimentalEncodingApi
2929

30-
class MemoBinarySuspend<T>(
30+
class CacheSelfieBinarySuspend<T>(
3131
private val disk: DiskStorage,
3232
private val roundtrip: Roundtrip<T, ByteArray>,
3333
private val generator: suspend () -> T

0 commit comments

Comments
 (0)