Skip to content

Commit

Permalink
Vary number of array elements per caret
Browse files Browse the repository at this point in the history
  • Loading branch information
FWDekker committed Dec 6, 2023
1 parent 6927340 commit 0d782ea
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 20 deletions.
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# Changelog
## Unreleased
(empty)
### Changed
* When inserting arrays at multiple carets, the number of elements per array is now independently chosen for each array.
([#450](https://github.com/FWDekker/intellij-randomness/issues/450))


## 3.0.0 -- 2023-11-17
Expand Down
16 changes: 13 additions & 3 deletions src/main/kotlin/com/fwdekker/randomness/array/ArrayDecorator.kt
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,19 @@ data class ArrayDecorator(


override fun generateUndecoratedStrings(count: Int): List<String> {
val partsPerString = random.nextInt(minCount, maxCount + 1)
return generator(count * partsPerString)
.chunked(partsPerString) { it.joinToString(if (separatorEnabled) separator.replace("\\n", "\n") else "") }
val partsPerString = List(count) { random.nextInt(minCount, maxCount + 1) }
val parts = generator(partsPerString.sum())

return partsPerString
.fold(Pair(parts, emptyList<String>())) { (remainingParts, createdStrings), nextPartCount ->
val nextString =
remainingParts
.take(nextPartCount)
.joinToString(if (separatorEnabled) separator.replace("\\n", "\n") else "")

Pair(remainingParts.drop(nextPartCount), createdStrings + nextString)
}
.second
}


Expand Down
43 changes: 27 additions & 16 deletions src/test/kotlin/com/fwdekker/randomness/array/ArrayDecoratorTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import com.fwdekker.randomness.testhelpers.shouldValidateAsBundle
import io.kotest.core.spec.style.FunSpec
import io.kotest.data.row
import io.kotest.datatest.withData
import io.kotest.matchers.collections.shouldHaveAtLeastSize
import io.kotest.matchers.ints.shouldBeInRange
import io.kotest.matchers.shouldBe

Expand All @@ -24,59 +25,69 @@ object ArrayDecoratorTest : FunSpec({
"returns default input if disabled" to
row(
ArrayDecorator(enabled = false, minCount = 3),
"[i0]",
"{i0}",
),
"returns a single value" to
row(
ArrayDecorator(enabled = true, minCount = 1, maxCount = 1),
"[[i0]]",
"[{i0}]",
),
"returns a fixed number of values" to
row(
ArrayDecorator(enabled = true, minCount = 3, maxCount = 3),
"[[i0], [i1], [i2]]",
"[{i0}, {i1}, {i2}]",
),
"returns array with multi-char separator" to
row(
ArrayDecorator(enabled = true, separator = ";;"),
"[[i0];;[i1];;[i2]]",
"[{i0};;{i1};;{i2}]",
),
"retains leading whitespace in separator" to
row(
ArrayDecorator(enabled = true, separator = ", "),
"[[i0], [i1], [i2]]",
"[{i0}, {i1}, {i2}]",
),
"converts escaped 'n' in separator to newline" to
row(
ArrayDecorator(enabled = true, separator = """\n"""),
"[[i0]\n[i1]\n[i2]]",
"[{i0}\n{i1}\n{i2}]",
),
"applies affix decorator" to
row(
ArrayDecorator(enabled = true, affixDecorator = AffixDecorator(enabled = true, "(@)")),
"([i0], [i1], [i2])",
"({i0}, {i1}, {i2})",
),
)
) { (scheme, output) ->
scheme.generator = { count -> List(count) { "[i$it]" } }
scheme.generator = { count -> List(count) { "{i$it}" } }

scheme.generateStrings()[0] shouldBe output
}

test("generates the desired number of entries") {
test("generates the desired number of parts in each string") {
val scheme = ArrayDecorator(enabled = true, minCount = 3, maxCount = 8)
scheme.generator = { count -> List(count) { "[i$it]" } }
scheme.generator = { count -> List(count) { "{i$it}" } }

scheme.generateStrings(count = 50).map { string -> string.count { it == ',' } + 1 }
scheme.generateStrings(count = 50)
.map { string -> string.count { it == ',' } + 1 }
.forEach { it shouldBeInRange 3..8 }
}

test("appropriately chunks generator outputs") {
test("generates an independently random number of parts per string") {
val scheme = ArrayDecorator(enabled = true, minCount = 1, maxCount = 8)
scheme.generator = { count -> List(count) { "{i$it}" } }

scheme.generateStrings(count = 50)
.map { string -> string.count { it == ',' } + 1 }
.distinct() shouldHaveAtLeastSize 2
}

test("appropriately splits parts into strings") {
val scheme = ArrayDecorator(enabled = true)
var i = 0
scheme.generator = { count -> List(count) { "[i${i++}]" } }
var partIdx = 0
scheme.generator = { count -> List(count) { "{i${partIdx++}}" } }

scheme.generateStrings(count = 2) shouldBe listOf("[[i0], [i1], [i2]]", "[[i3], [i4], [i5]]")
scheme.generateStrings(count = 2) shouldBe listOf("[{i0}, {i1}, {i2}]", "[{i3}, {i4}, {i5}]")
}
}

Expand All @@ -97,7 +108,7 @@ object ArrayDecoratorTest : FunSpec({
row(ArrayDecorator(affixDecorator = AffixDecorator(descriptor = """\""")), ""),
)
) { (scheme, validation) ->
scheme.generator = { count -> List(count) { "[i$it]" } }
scheme.generator = { count -> List(count) { "{i$it}" } }

scheme shouldValidateAsBundle validation
}
Expand Down

0 comments on commit 0d782ea

Please sign in to comment.