refactor: simplify regex tests by introducing checkRegex utility function

This commit is contained in:
monoid 2025-06-29 14:26:39 +09:00
parent 5536b872b4
commit 45150236c3

View file

@ -3,127 +3,140 @@ package org.example
import kotlin.test.Test
import kotlin.test.assertEquals
private fun checkRegex(
pattern: String,
block: RegexTestAsserter .() -> Unit
) {
val regex = compileRegex(pattern)
// 나중에는 안 같겠지만, 일단은 같다고 가정
assertEquals(pattern, regex.toString())
block(RegexTestAsserter(regex))
}
private class RegexTestAsserter(private val regex: RegexItem) {
fun String.shouldMatch() {
assert(regex.test(this)) { "Expected '$this' to match" }
}
fun String.shouldNotMatch() {
assert(!regex.test(this)) { "Expected '$this' not to match" }
}
}
class ParserTest {
@Test
fun testSimpleCharacter() {
val input = "a"
val result = compileRegex(input)
assertEquals("a", result.toString())
checkRegex("a") {
"a".shouldMatch()
"b".shouldNotMatch()
"".shouldNotMatch()
}
}
@Test
fun testCharacterWithPlus() {
val input = "a+"
val result = compileRegex(input)
assertEquals("a+", result.toString())
assert(result.match("a").isSuccess)
assert(result.match("aa").isSuccess)
assert(!result.match("b").isSuccess)
checkRegex("a+") {
"a".shouldMatch()
"aa".shouldMatch()
"b".shouldNotMatch()
"".shouldNotMatch()
}
}
@Test
fun testCharacterWithStar() {
val input = "b*"
val result = compileRegex(input)
assertEquals("b*", result.toString())
assert(result.match("").isSuccess)
assert(result.match("b").isSuccess)
assert(result.match("bb").isSuccess)
assert(result.match("a").isSuccess)
checkRegex("b*") {
"b".shouldMatch()
"bb".shouldMatch()
"".shouldMatch() // 빈 문자열도 매칭됨
}
}
@Test
fun testCharacterWithQuestion() {
val input = "c?"
val result = compileRegex(input)
assertEquals("c?", result.toString())
assert(result.match("").isSuccess)
assert(result.match("c").isSuccess)
assert(result.match("cc").isSuccess)
checkRegex("c?") {
"c".shouldMatch()
"".shouldMatch() // 빈 문자열도 매칭됨
"cc".shouldMatch() // c가 0번 또는 1번 나타날 수 있음
"d".shouldNotMatch()
}
}
@Test
fun testDot() {
val input = "."
val result = compileRegex(input)
assertEquals(".", result.toString())
assert(result.match("a").isSuccess)
assert(result.match("1").isSuccess)
assert(!result.match("").isSuccess)
checkRegex(".") {
"a".shouldMatch()
"1".shouldMatch()
"".shouldNotMatch() // 빈 문자열은 매칭되지 않음
}
}
@Test
fun testAlternation() {
val input = "a|b"
val result = compileRegex(input)
assertEquals("a|b", result.toString())
assert(result.match("a").isSuccess)
assert(result.match("b").isSuccess)
assert(!result.match("c").isSuccess)
checkRegex("a|b") {
"a".shouldMatch()
"b".shouldMatch()
"c".shouldNotMatch()
"".shouldNotMatch() // 빈 문자열은 매칭되지 않음
}
}
@Test
fun testParentheses() {
val input = "(d)"
val result = compileRegex(input)
assertEquals("(d)", result.toString())
assert(result.match("d").isSuccess)
assert(!result.match("e").isSuccess)
checkRegex("(d)") {
"d".shouldMatch()
"e".shouldNotMatch()
"".shouldNotMatch() // 빈 문자열은 매칭되지 않음
}
}
@Test
fun testComplexExpression() {
val input = "a(b|c)*d+"
val result = compileRegex(input)
assertEquals("a(b|c)*d+", result.toString())
assert(result.match("ad").isSuccess)
assert(!result.match("ab").isSuccess)
assert(result.match("acd").isSuccess)
assert(result.match("abbbd").isSuccess)
assert(!result.match("a").isSuccess)
assert(!result.match("b").isSuccess)
checkRegex("a(b|c)*d+") {
"ad".shouldMatch()
"ab".shouldNotMatch()
"acd".shouldMatch()
"abbbd".shouldMatch()
"a".shouldNotMatch()
"b".shouldNotMatch()
}
}
@Test
fun testAndThen() {
val input = "ab"
val result = compileRegex(input)
assertEquals("ab", result.toString())
assert(result.match("ab").isSuccess)
assert(!result.match("a").isSuccess)
assert(!result.match("b").isSuccess)
checkRegex("ab") {
"ab".shouldMatch()
"a".shouldNotMatch()
"b".shouldNotMatch()
}
}
@Test
fun testDotAndPlus() {
val input = ".+a"
val result = compileRegex(input)
assertEquals(".+a", result.toString())
assert(!result.match("a").isSuccess)
assert(result.match("ba").isSuccess)
assert(result.match("bca").isSuccess)
checkRegex(".+a") {
"a".shouldNotMatch()
"ba".shouldMatch()
"bca".shouldMatch()
}
}
@Test
fun testEscapedCharacter() {
val input = "\\+"
val result = compileRegex(input)
assertEquals("\\+", result.toString())
assert(result.match("+").isSuccess)
assert(!result.match("a").isSuccess)
checkRegex("\\+") {
"+".shouldMatch()
"a".shouldNotMatch()
}
}
@Test
fun testBracketContent() {
val input = "[abc]"
val result = compileRegex(input)
assertEquals("[abc]", result.toString())
assert(result.match("a").isSuccess)
assert(result.match("b").isSuccess)
assert(result.match("c").isSuccess)
assert(!result.match("d").isSuccess)
checkRegex("[abc]") {
"a".shouldMatch()
"b".shouldMatch()
"c".shouldMatch()
"d".shouldNotMatch()
}
}
@Test
fun testNestedGroups() {
val input = "(a(b|c)d)+"
val result = compileRegex(input)
assertEquals("(a(b|c)d)+", result.toString())
assert(!result.match("ad").isSuccess)
assert(result.match("abd").isSuccess)
assert(result.match("acd").isSuccess)
assert(!result.match("a").isSuccess)
checkRegex("(a(b|c)d)+") {
"ad".shouldNotMatch()
"abd".shouldMatch()
"acd".shouldMatch()
"a".shouldNotMatch()
}
}
@Test
fun testCaptureGroups() {