Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement toBe(LITERAL), not just toBe_TODO() #49

Merged
merged 6 commits into from
Dec 27, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 36 additions & 10 deletions selfie-lib/src/commonMain/kotlin/com/diffplug/selfie/SourceFile.kt
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ class SourceFile(filename: String, content: String) {
* Represents a section of the sourcecode which is a `.toBe(LITERAL)` call. It might also be
* `.toBe_TODO()` or ` toBe LITERAL` (infix notation).
*/
inner class ToBeLiteral internal constructor(private val slice: Slice) {
inner class ToBeLiteral
internal constructor(private val slice: Slice, private val valueStart: Int) {
/**
* Modifies the parent [SourceFile] to set the value within the `toBe` call, and returns the net
* change in newline count.
Expand All @@ -48,7 +49,7 @@ class SourceFile(filename: String, content: String) {
throw Error(
"There is an error in " +
literalValue.format::class.simpleName +
", the following value isn't roundtripping.\n" +
", the following value isn't round tripping.\n" +
"Please this error and the data below at https://github.com/diffplug/selfie/issues/new\n" +
"```\n" +
"ORIGINAL\n" +
Expand All @@ -73,20 +74,45 @@ class SourceFile(filename: String, content: String) {
* `toBe_TODO()`.
*/
fun <T : Any> parseLiteral(literalFormat: LiteralFormat<T>): T {
// this won't work, because we need to find the `.toBe` and parens
TODO("return literalFormat.parse(slice.toString())")
return literalFormat.parse(
slice.subSequence(valueStart, slice.length - 1).toString(), language)
}
}
fun parseToBe_TODO(lineOneIndexed: Int): ToBeLiteral {
return parseToBeLike(".toBe_TODO(", lineOneIndexed)
}
fun parseToBe(lineOneIndexed: Int): ToBeLiteral {
return parseToBeLike(".toBe(", lineOneIndexed)
}
private fun parseToBeLike(prefix: String, lineOneIndexed: Int): ToBeLiteral {
val lineContent = contentSlice.unixLine(lineOneIndexed)
val idx = lineContent.indexOf(".toBe_TODO()")
val idx = lineContent.indexOf(prefix)
if (idx == -1) {
throw AssertionError(
"Expected to find `.toBe_TODO()` on line $lineOneIndexed, but there was only `${lineContent}`")
"Expected to find `$prefix)` on line $lineOneIndexed, but there was only `${lineContent}`")
}
return ToBeLiteral(lineContent.subSequence(idx, idx + ".toBe_TODO()".length))
}
fun parseToBe(lineOneIndexed: Int): ToBeLiteral {
TODO("More complicated because we have to actually parse the literal")
var opened = 0
val startIndex = idx + prefix.length
var endIndex = -1
// TODO: do we need to detect paired parenthesis ( ( ) )?
Copy link
Member Author

@nedtwigg nedtwigg Dec 27, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cases we need to handle:

.toBe("""
(((
"
(((
""")
// or
.toBe(
  "(((\n" +
  "\"\n" +
   "(((")

Cases we do not need to handle

.toBe(("a" + "b") + "c")

We should add support for these in future PRs, there are many hard cases, we should do the easy stuff first (""" literals) and then solve problems as they come.

for (i in startIndex ..< lineContent.length) {
val ch = lineContent[i]
// TODO: handle () inside string literal
if (ch == '(') {
opened += 1
} else if (ch == ')') {
if (opened == 0) {
endIndex = i
break
} else {
opened -= 1
}
}
}
if (endIndex == -1) {
throw AssertionError(
"Expected to find `$prefix)` on line $lineOneIndexed, but there was only `${lineContent}`")
}
return ToBeLiteral(lineContent.subSequence(idx, endIndex + 1), prefix.length)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@ import kotlin.test.Test

class UT_InlineIntTest {
@Test fun singleInt() {
expectSelfie(1234).toBe(1234)
expectSelfie(7777).toBe(7777)
}
}