Skip to content

Commit

Permalink
toMatchDisk_TODO (#76)
Browse files Browse the repository at this point in the history
  • Loading branch information
nedtwigg authored Jan 4, 2024
2 parents 8ec6cc1 + 5e00fc3 commit f9670c7
Show file tree
Hide file tree
Showing 6 changed files with 140 additions and 19 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2023 DiffPlug
* Copyright (C) 2023-2024 DiffPlug
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -172,3 +172,10 @@ object LiteralBoolean : LiteralFormat<Boolean> {
return str.toBooleanStrict()
}
}

// wish this were internal
object DiskSnapshotTodo : LiteralFormat<Unit> {
override fun encode(value: Unit, language: Language) = throw UnsupportedOperationException()
override fun parse(str: String, language: Language) = throw UnsupportedOperationException()
fun createLiteral() = LiteralValue(null, Unit, DiskSnapshotTodo)
}
10 changes: 10 additions & 0 deletions selfie-lib/src/commonMain/kotlin/com/diffplug/selfie/Selfie.kt
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,16 @@ object Selfie {
}
return this
}

@JvmOverloads
fun toMatchDisk_TODO(sub: String = ""): DiskSelfie {
if (!storage.isWrite) {
throw storage.assertFailed("Can't call `toMatchDisk_TODO` in readonly mode!")
}
storage.readWriteDisk(actual, sub)
storage.writeInline(DiskSnapshotTodo.createLiteral())
return this
}
}

open class LiteralStringSelfie
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2023 DiffPlug
* Copyright (C) 2023-2024 DiffPlug
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -78,6 +78,19 @@ class SourceFile(filename: String, content: String) {
slice.subSequence(valueStart, slice.length - 1).toString(), language)
}
}
private fun findOnLine(toFind: String, lineOneIndexed: Int): Slice {
val lineContent = contentSlice.unixLine(lineOneIndexed)
val idx = lineContent.indexOf(toFind)
if (idx == -1) {
throw AssertionError(
"Expected to find `$toFind` on line $lineOneIndexed, but there was only `${lineContent}`")
}
return lineContent.subSequence(idx, idx + toFind.length)
}
fun replaceToMatchDisk_TODO(lineOneIndexed: Int) {
val slice = findOnLine(".toMatchDisk_TODO(", lineOneIndexed)
contentSlice = Slice(slice.replaceSelfWith(".toMatchDisk("))
}
fun parseToBe_TODO(lineOneIndexed: Int): ToBeLiteral {
return parseToBeLike(".toBe_TODO(", lineOneIndexed)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2023 DiffPlug
* Copyright (C) 2023-2024 DiffPlug
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -15,6 +15,7 @@
*/
package com.diffplug.selfie.junit5

import com.diffplug.selfie.DiskSnapshotTodo
import com.diffplug.selfie.LiteralValue
import com.diffplug.selfie.Snapshot
import com.diffplug.selfie.SourceFile
Expand Down Expand Up @@ -48,13 +49,12 @@ data class CallLocation(val clazz: String, val method: String, val file: String?
}
/** Represents the callstack above a given CallLocation. */
class CallStack(val location: CallLocation, val restOfStack: List<CallLocation>) {
fun ideLink(layout: SnapshotFileLayout): String {
val list = buildList {
add(location)
addAll(restOfStack)
}
return list.joinToString("\n") { it.ideLink(layout) }
}
fun ideLink(layout: SnapshotFileLayout) =
sequence<CallLocation> {
yield(location)
yieldAll(restOfStack)
}
.joinToString("\n") { it.ideLink(layout) }
}

/** Generates a CallLocation and the CallStack behind it. */
Expand All @@ -78,12 +78,12 @@ internal open class WriteTracker<K : Comparable<K>, V> {
val existing = writes.putIfAbsent(key, FirstWrite(snapshot, call))
if (existing != null) {
if (existing.snapshot != snapshot) {
throw org.opentest4j.AssertionFailedError(
throw AssertionFailedError(
"Snapshot was set to multiple values!\n first time: ${existing.callStack.location.ideLink(layout)}\n this time: ${call.location.ideLink(layout)}",
existing.snapshot,
snapshot)
} else if (RW.isWriteOnce) {
throw org.opentest4j.AssertionFailedError(
throw AssertionFailedError(
"Snapshot was set to the same value multiple times.",
existing.callStack.ideLink(layout),
call.ideLink(layout))
Expand Down Expand Up @@ -150,13 +150,17 @@ internal class InlineWriteTracker : WriteTracker<CallLocation, LiteralValue<*>>(
}
// parse the location within the file
val line = write.line + deltaLineNumbers
val toBe =
if (write.literal.expected == null) {
content.parseToBe_TODO(line)
} else {
content.parseToBe(line)
}
deltaLineNumbers += toBe.setLiteralAndGetNewlineDelta(write.literal)
if (write.literal.format == DiskSnapshotTodo) {
content.replaceToMatchDisk_TODO(line)
} else {
val toBe =
if (write.literal.expected == null) {
content.parseToBe_TODO(line)
} else {
content.parseToBe(line)
}
deltaLineNumbers += toBe.setLiteralAndGetNewlineDelta(write.literal)
}
}
Files.writeString(file, content.asString)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
/*
* Copyright (C) 2024 DiffPlug
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.diffplug.selfie.junit5

import io.kotest.matchers.shouldBe
import io.kotest.matchers.string.shouldContain
import kotlin.test.Test
import org.junit.jupiter.api.MethodOrderer
import org.junit.jupiter.api.Order
import org.junit.jupiter.api.TestMethodOrder
import org.junitpioneer.jupiter.DisableIfTestFails

@TestMethodOrder(MethodOrderer.OrderAnnotation::class)
@DisableIfTestFails
class DiskTodo : Harness("undertest-junit5") {
companion object {
var lineNoArg = ""
var constantArg = ""
var variableArg = ""
}

@Test @Order(1)
fun initialState() {
ut_snapshot().deleteIfExists()
ut_snapshot().assertDoesNotExist()

lineNoArg = ut_mirror().lineWith("noArg").content()
constantArg = ut_mirror().lineWith("constantArg").content()
variableArg = ut_mirror().lineWith("variableArg").content()

lineNoArg shouldContain "_TODO"
constantArg shouldContain "_TODO"
variableArg shouldContain "_TODO"
}

@Test @Order(2)
fun writeRemovesTODO() {
gradleWriteSS()
ut_mirror().lineWith("noArg").content() shouldBe lineNoArg.replace("_TODO", "")
ut_mirror().lineWith("constantArg").content() shouldBe constantArg.replace("_TODO", "")
ut_mirror().lineWith("variableArg").content() shouldBe variableArg.replace("_TODO", "")
}

@Test @Order(3)
fun nowItPasses() {
gradleReadSS()
}

@Test @Order(4)
fun ifTodoComesBackItDoesntPass() {
ut_mirror().lineWith("noArg").setContent(lineNoArg)
ut_mirror().lineWith("constantArg").setContent(constantArg)
ut_mirror().lineWith("variableArg").setContent(variableArg)
gradleReadSSFail()
}

@Test @Order(5)
fun cleanup() {
ut_snapshot().deleteIfExists()
}
}
13 changes: 13 additions & 0 deletions undertest-junit5/src/test/kotlin/undertest/junit5/UT_DiskTodo.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package undertest.junit5

import com.diffplug.selfie.Selfie.expectSelfie
import kotlin.test.Test

class UT_DiskTodo {
@Test fun selfie() {
expectSelfie("noArg").toMatchDisk_TODO()
expectSelfie("constantArg").toMatchDisk_TODO("constantArg")
val theArg = "variable" + " " + "arg"
expectSelfie("variableArg").toMatchDisk_TODO(theArg)
}
}

0 comments on commit f9670c7

Please sign in to comment.