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.Test
import kotlin.test.assertEquals 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 { class ParserTest {
@Test @Test
fun testSimpleCharacter() { fun testSimpleCharacter() {
val input = "a" checkRegex("a") {
val result = compileRegex(input) "a".shouldMatch()
assertEquals("a", result.toString()) "b".shouldNotMatch()
"".shouldNotMatch()
}
} }
@Test @Test
fun testCharacterWithPlus() { fun testCharacterWithPlus() {
val input = "a+" checkRegex("a+") {
val result = compileRegex(input) "a".shouldMatch()
assertEquals("a+", result.toString()) "aa".shouldMatch()
assert(result.match("a").isSuccess) "b".shouldNotMatch()
assert(result.match("aa").isSuccess) "".shouldNotMatch()
assert(!result.match("b").isSuccess) }
} }
@Test @Test
fun testCharacterWithStar() { fun testCharacterWithStar() {
val input = "b*" checkRegex("b*") {
val result = compileRegex(input) "b".shouldMatch()
assertEquals("b*", result.toString()) "bb".shouldMatch()
assert(result.match("").isSuccess) "".shouldMatch() // 빈 문자열도 매칭됨
assert(result.match("b").isSuccess) }
assert(result.match("bb").isSuccess)
assert(result.match("a").isSuccess)
} }
@Test @Test
fun testCharacterWithQuestion() { fun testCharacterWithQuestion() {
val input = "c?" checkRegex("c?") {
val result = compileRegex(input) "c".shouldMatch()
assertEquals("c?", result.toString()) "".shouldMatch() // 빈 문자열도 매칭됨
assert(result.match("").isSuccess) "cc".shouldMatch() // c가 0번 또는 1번 나타날 수 있음
assert(result.match("c").isSuccess) "d".shouldNotMatch()
assert(result.match("cc").isSuccess) }
} }
@Test @Test
fun testDot() { fun testDot() {
val input = "." checkRegex(".") {
val result = compileRegex(input) "a".shouldMatch()
assertEquals(".", result.toString()) "1".shouldMatch()
assert(result.match("a").isSuccess) "".shouldNotMatch() // 빈 문자열은 매칭되지 않음
assert(result.match("1").isSuccess) }
assert(!result.match("").isSuccess)
} }
@Test @Test
fun testAlternation() { fun testAlternation() {
val input = "a|b" checkRegex("a|b") {
val result = compileRegex(input) "a".shouldMatch()
assertEquals("a|b", result.toString()) "b".shouldMatch()
assert(result.match("a").isSuccess) "c".shouldNotMatch()
assert(result.match("b").isSuccess) "".shouldNotMatch() // 빈 문자열은 매칭되지 않음
assert(!result.match("c").isSuccess) }
} }
@Test @Test
fun testParentheses() { fun testParentheses() {
val input = "(d)" checkRegex("(d)") {
val result = compileRegex(input) "d".shouldMatch()
assertEquals("(d)", result.toString()) "e".shouldNotMatch()
assert(result.match("d").isSuccess) "".shouldNotMatch() // 빈 문자열은 매칭되지 않음
assert(!result.match("e").isSuccess) }
} }
@Test @Test
fun testComplexExpression() { fun testComplexExpression() {
val input = "a(b|c)*d+" checkRegex("a(b|c)*d+") {
val result = compileRegex(input) "ad".shouldMatch()
assertEquals("a(b|c)*d+", result.toString()) "ab".shouldNotMatch()
assert(result.match("ad").isSuccess) "acd".shouldMatch()
assert(!result.match("ab").isSuccess) "abbbd".shouldMatch()
assert(result.match("acd").isSuccess) "a".shouldNotMatch()
assert(result.match("abbbd").isSuccess) "b".shouldNotMatch()
assert(!result.match("a").isSuccess) }
assert(!result.match("b").isSuccess)
} }
@Test @Test
fun testAndThen() { fun testAndThen() {
val input = "ab" checkRegex("ab") {
val result = compileRegex(input) "ab".shouldMatch()
assertEquals("ab", result.toString()) "a".shouldNotMatch()
assert(result.match("ab").isSuccess) "b".shouldNotMatch()
assert(!result.match("a").isSuccess) }
assert(!result.match("b").isSuccess)
} }
@Test @Test
fun testDotAndPlus() { fun testDotAndPlus() {
val input = ".+a" checkRegex(".+a") {
val result = compileRegex(input) "a".shouldNotMatch()
assertEquals(".+a", result.toString()) "ba".shouldMatch()
assert(!result.match("a").isSuccess) "bca".shouldMatch()
assert(result.match("ba").isSuccess) }
assert(result.match("bca").isSuccess)
} }
@Test @Test
fun testEscapedCharacter() { fun testEscapedCharacter() {
val input = "\\+" checkRegex("\\+") {
val result = compileRegex(input) "+".shouldMatch()
assertEquals("\\+", result.toString()) "a".shouldNotMatch()
assert(result.match("+").isSuccess) }
assert(!result.match("a").isSuccess)
} }
@Test @Test
fun testBracketContent() { fun testBracketContent() {
val input = "[abc]" checkRegex("[abc]") {
val result = compileRegex(input) "a".shouldMatch()
assertEquals("[abc]", result.toString()) "b".shouldMatch()
assert(result.match("a").isSuccess) "c".shouldMatch()
assert(result.match("b").isSuccess) "d".shouldNotMatch()
assert(result.match("c").isSuccess) }
assert(!result.match("d").isSuccess)
} }
@Test @Test
fun testNestedGroups() { fun testNestedGroups() {
val input = "(a(b|c)d)+" checkRegex("(a(b|c)d)+") {
val result = compileRegex(input) "ad".shouldNotMatch()
assertEquals("(a(b|c)d)+", result.toString()) "abd".shouldMatch()
assert(!result.match("ad").isSuccess) "acd".shouldMatch()
assert(result.match("abd").isSuccess) "a".shouldNotMatch()
assert(result.match("acd").isSuccess) }
assert(!result.match("a").isSuccess)
} }
@Test @Test
fun testCaptureGroups() { fun testCaptureGroups() {