diff --git a/lib/src/test/kotlin/org/example/ParserTest.kt b/lib/src/test/kotlin/org/example/ParserTest.kt index 0c10bcb..1bd5b8c 100644 --- a/lib/src/test/kotlin/org/example/ParserTest.kt +++ b/lib/src/test/kotlin/org/example/ParserTest.kt @@ -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() {