Skip to content

Commit

Permalink
Improve errors on invalid ranges in .read
Browse files Browse the repository at this point in the history
  • Loading branch information
iamgio committed Jul 28, 2024
1 parent 3a5c0c7 commit 17705f9
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,30 @@ data class Range(val start: Int?, val end: Int?) : Iterable<NumberValue> {
.iterator()
}

/**
* @param bounds range to check if this range is in. Both its `start` and `end` values must be non-null
* @param lowerBound lower bound of [bounds] to use if [start] is `null`
* @param upperBound upper bound of [bounds] to use if [end] is `null`
* @return whether this range is contained within [bounds]
*/
fun isIn(
bounds: Range,
lowerBound: Int = bounds.start!!,
upperBound: Int = bounds.end!!,
): Boolean {
val start = start ?: lowerBound
val end = end ?: upperBound
return start >= bounds.start!! && end <= bounds.end!!
}

/**
* Checks if this range (bounds) contains another range.
* Both [start] and [end] of the bounds range must be non-null.
* @param range range to check if this range contains
* @return whether this range contains [range].
*/
operator fun contains(range: Range) = range.isIn(this)

override fun toString() = "${start ?: ""}..${end ?: ""}"

companion object {
Expand Down
12 changes: 10 additions & 2 deletions stdlib/src/main/kotlin/eu/iamgio/quarkdown/stdlib/Data.kt
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,17 @@ fun read(
}

// Lines from the file in the given range.
val lines = file.readLines().subList(lineRange)
val lines = file.readLines()

return lines.joinToString(System.lineSeparator()).wrappedAsValue()
// Check if the range is in bounds.
val bounds = Range(1, lines.size)
if (lineRange !in bounds) {
throw FunctionRuntimeException("Invalid range $lineRange in bounds $bounds")
}

return lines.subList(lineRange)
.joinToString(System.lineSeparator())
.wrappedAsValue()
}

/**
Expand Down
7 changes: 7 additions & 0 deletions stdlib/src/test/kotlin/eu/iamgio/quarkdown/stdlib/DataTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import java.io.File
import kotlin.test.BeforeTest
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertFails
import kotlin.test.assertIs

private const val DATA_FOLDER = "src/test/resources/data"
Expand Down Expand Up @@ -53,6 +54,12 @@ class DataTest {
"Line 4${LINE_SEPARATOR}Line 5",
read(context, path, Range(4, null)).unwrappedValue,
)

// Out of bounds ranges.
assertFails { read(context, path, Range(1, 8)) }
assertFails { read(context, path, Range(0, 3)) }
assertFails { read(context, path, Range(null, 9)) }
assertFails { read(context, path, Range(9, null)) }
}

@Test
Expand Down

0 comments on commit 17705f9

Please sign in to comment.