Skip to content

Commit

Permalink
Specmatic String Pattern Tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Samy authored and Samy committed Nov 27, 2024
1 parent 0adddd6 commit 8453faf
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 12 deletions.
16 changes: 9 additions & 7 deletions core/src/main/kotlin/io/specmatic/core/pattern/StringPattern.kt
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,9 @@ data class StringPattern(
throw IllegalArgumentException("maxLength cannot be less than minLength")
}
regex?.let {
regexMinLengthValidation(it)
regexMaxLengthValidation(it)
val regexWithoutCaretAndDollar = it.removePrefix("^").removeSuffix("$")
regexMinLengthValidation(regexWithoutCaretAndDollar)
regexMaxLengthValidation(regexWithoutCaretAndDollar)
}

}
Expand All @@ -46,10 +47,11 @@ data class StringPattern(

private fun regexMaxLengthValidation(it: String) {
maxLength?.let { maxLen ->
val regexWithoutCaretAndDollar = it.removePrefix("^").removeSuffix("$")
runCatching {
StringValue(generateFromRegex(regexWithoutCaretAndDollar, 5, maxLen + 1))
}.getOrNull() ?: throw IllegalArgumentException("Invalid Regex - max cannot be more than regex max size")
val generatedString = generateFromRegex(it, maxLen+1)

if (generatedString.length > maxLen) {
throw IllegalArgumentException("Invalid Regex - max cannot be more than regex max size")
}
}
}

Expand Down Expand Up @@ -185,7 +187,7 @@ data class StringPattern(
override val pattern: Any = "(string)"
override fun toString(): String = pattern.toString()

private fun generateFromRegex(regexWithoutCaretAndDollar: String, minLength: Int, maxLength: Int?): String =
private fun generateFromRegex(regexWithoutCaretAndDollar: String, minLength: Int, maxLength: Int? = null): String =
maxLength?.let {
Generex(regexWithoutCaretAndDollar).random(minLength, it)
} ?: Generex(regexWithoutCaretAndDollar).random(minLength)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ internal class StringPatternTest {
fun regexMinLengthAndMaxLengthAndExpectedLength(): Stream<Arguments> {
return Stream.of(
Arguments.of("^[a-z]*\$", null, null, 5),
Arguments.of("^[a-z0-9]{6,}\$", 3, 10, 6),
Arguments.of("^[a-z0-9]{6,10}\$", 3, 10, 6),
Arguments.of(null, 1, 10, 1),
)
}
Expand Down Expand Up @@ -205,16 +205,54 @@ internal class StringPatternTest {
val result = StringPattern(
minLength = minLength,
maxLength = maxLength,
regex = "^[^0-9]*$"
regex = "^[^0-9]{15}$"
).negativeBasedOn(Row(), Resolver()).map { it.value }.toList()

assertThat(
result.filterIsInstance<StringPattern>().filter {
it.regex == "^[^0-9]*\$_"
it.regex == "^[^0-9]{15}\$_"
}
).hasSize(1)
}

@Test
@Tag(GENERATION)
fun `regex sould throw validation issue for patterns less than min size as per api contract`() {
val minLength = 2
val maxLength = 15

val result = runCatching {
StringPattern(
minLength = minLength,
maxLength = maxLength,
regex = "^.{0,4}$"
).negativeBasedOn(Row(), Resolver()).map { it.value }.toList()
}

result.onFailure { exception ->
assertThat(exception.message).isEqualTo("Invalid Regex - min cannot be less than regex least size")
}
}

@Test
@Tag(GENERATION)
fun `regex sould throw validation issue for patterns more than max size as per api contract`() {
val minLength = 2
val maxLength = 15

val result = runCatching {
StringPattern(
minLength = minLength,
maxLength = maxLength,
regex = "^.{2,14}$"
).negativeBasedOn(Row(), Resolver()).map { it.value }.toList()
}

result.onFailure { exception ->
assertThat(exception.message).isEqualTo("Invalid Regex - max cannot be more than regex max size")
}
}

@Test
@Tag(GENERATION)
fun `should exclude data type based negatives when withDataTypeNegatives config is false`() {
Expand All @@ -224,7 +262,7 @@ internal class StringPatternTest {
val result = StringPattern(
minLength = minLength,
maxLength = maxLength,
regex = "^[^0-9]*$"
regex = "^[^0-9]{15}$"
).negativeBasedOn(
Row(),
Resolver(),
Expand All @@ -239,7 +277,7 @@ internal class StringPatternTest {
).hasSize(0)

assertThat(
result.filterIsInstance<StringPattern>().filter { it.regex == "^[^0-9]*\$_" }
result.filterIsInstance<StringPattern>().filter { it.regex == "^[^0-9]{15}\$_" }
).hasSize(1)

assertThat(
Expand Down

0 comments on commit 8453faf

Please sign in to comment.