159 lines
3.9 KiB
Kotlin
159 lines
3.9 KiB
Kotlin
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() {
|
|
checkRegex("a") {
|
|
"a".shouldMatch()
|
|
"b".shouldNotMatch()
|
|
"".shouldNotMatch()
|
|
}
|
|
}
|
|
@Test
|
|
fun testCharacterWithPlus() {
|
|
checkRegex("a+") {
|
|
"a".shouldMatch()
|
|
"aa".shouldMatch()
|
|
"b".shouldNotMatch()
|
|
"".shouldNotMatch()
|
|
}
|
|
}
|
|
@Test
|
|
fun testCharacterWithStar() {
|
|
checkRegex("b*") {
|
|
"b".shouldMatch()
|
|
"bb".shouldMatch()
|
|
"".shouldMatch() // 빈 문자열도 매칭됨
|
|
}
|
|
}
|
|
@Test
|
|
fun testCharacterWithQuestion() {
|
|
checkRegex("c?") {
|
|
"c".shouldMatch()
|
|
"".shouldMatch() // 빈 문자열도 매칭됨
|
|
}
|
|
}
|
|
@Test
|
|
fun testDot() {
|
|
checkRegex(".") {
|
|
"a".shouldMatch()
|
|
"1".shouldMatch()
|
|
"".shouldNotMatch() // 빈 문자열은 매칭되지 않음
|
|
}
|
|
}
|
|
|
|
@Test
|
|
fun testAlternation() {
|
|
checkRegex("a|b") {
|
|
"a".shouldMatch()
|
|
"b".shouldMatch()
|
|
"c".shouldNotMatch()
|
|
"".shouldNotMatch() // 빈 문자열은 매칭되지 않음
|
|
}
|
|
}
|
|
@Test
|
|
fun testParentheses() {
|
|
checkRegex("(d)") {
|
|
"d".shouldMatch()
|
|
"e".shouldNotMatch()
|
|
"".shouldNotMatch() // 빈 문자열은 매칭되지 않음
|
|
}
|
|
}
|
|
|
|
@Test
|
|
fun testComplexExpression() {
|
|
checkRegex("a(b|c)*d+") {
|
|
"ad".shouldMatch()
|
|
"ab".shouldNotMatch()
|
|
"acd".shouldMatch()
|
|
"abbbd".shouldMatch()
|
|
"a".shouldNotMatch()
|
|
"b".shouldNotMatch()
|
|
}
|
|
}
|
|
@Test
|
|
fun testAndThen() {
|
|
checkRegex("ab") {
|
|
"ab".shouldMatch()
|
|
"a".shouldNotMatch()
|
|
"b".shouldNotMatch()
|
|
}
|
|
}
|
|
@Test
|
|
fun testDotAndPlus() {
|
|
checkRegex(".+a") {
|
|
"a".shouldNotMatch()
|
|
"ba".shouldMatch()
|
|
"bca".shouldMatch()
|
|
}
|
|
}
|
|
@Test
|
|
fun testEscapedCharacter() {
|
|
checkRegex("\\+") {
|
|
"+".shouldMatch()
|
|
"a".shouldNotMatch()
|
|
}
|
|
}
|
|
@Test
|
|
fun testBracketContent() {
|
|
checkRegex("[abc]") {
|
|
"a".shouldMatch()
|
|
"b".shouldMatch()
|
|
"c".shouldMatch()
|
|
"d".shouldNotMatch()
|
|
}
|
|
}
|
|
@Test
|
|
fun testNestedGroups() {
|
|
checkRegex("(a(b|c)d)+") {
|
|
"ad".shouldNotMatch()
|
|
"abd".shouldMatch()
|
|
"acd".shouldMatch()
|
|
"a".shouldNotMatch()
|
|
}
|
|
}
|
|
@Test
|
|
fun testAnchorOperators() {
|
|
checkRegex("^abc$") {
|
|
"abc".shouldMatch()
|
|
"ab".shouldNotMatch()
|
|
"abcd".shouldNotMatch()
|
|
"xabc".shouldNotMatch()
|
|
}
|
|
}
|
|
@Test
|
|
fun testCaptureGroups() {
|
|
val input = "(a)(b)"
|
|
val result = compileRegex(input)
|
|
assertEquals("(a)(b)", result.toString())
|
|
val matchResult = result.match("ab")
|
|
assert(matchResult.isSuccess)
|
|
val captures = matchResult.available.first();
|
|
assertEquals("a", captures.captures.get("0"))
|
|
assertEquals("b", captures.captures.get("1"))
|
|
}
|
|
}
|