diff --git a/src/main/java/io/skelp/verifier/type/StringVerifier.java b/src/main/java/io/skelp/verifier/type/StringVerifier.java index 3dc7e20..86b1241 100644 --- a/src/main/java/io/skelp/verifier/type/StringVerifier.java +++ b/src/main/java/io/skelp/verifier/type/StringVerifier.java @@ -814,6 +814,136 @@ public StringVerifier match(final Pattern pattern) { return this; } + /** + *
+ * Verifies that the value matches all of the regular expressions provided. + *
+ *+ * {@literal null} references are handled gracefully without exceptions. + *
+ *
+ * Verifier.verify(*).matchAll() => PASS
+ * Verifier.verify(*).matchAll((CharSequence[]) null) => PASS
+ * Verifier.verify(*).matchAll(*, null) => FAIL
+ * Verifier.verify((String) null).matchAll(*) => FAIL
+ * Verifier.verify("foo").matchAll(".*", "fo{2}") => PASS
+ * Verifier.verify("foo").matchAll(".*", "fiz{2}") => FAIL
+ *
+ *
+ * @param regexes
+ * the regular expressions to be matched against of the value (may be {@literal null} or contain {@literal
+ * null} references)
+ * @return A reference to this {@link StringVerifier} for chaining purposes.
+ * @throws VerifierException
+ * If the verification fails while not negated or passes while negated.
+ * @see #matchAll(Pattern...)
+ */
+ public StringVerifier matchAll(final CharSequence... regexes) {
+ final String value = verification().getValue();
+ final boolean result = value != null && matchAll(regexes, input -> input != null && value.matches(input.toString()));
+
+ verification().report(result, MessageKeys.MATCH_ALL, (Object) regexes);
+
+ return this;
+ }
+
+ /**
+ * + * Verifies that the value matches all of the regular expression {@code patterns} provided. + *
+ *+ * {@literal null} references are handled gracefully without exceptions. + *
+ *
+ * Verifier.verify(*).matchAll() => PASS
+ * Verifier.verify(*).matchAll((Pattern[]) null) => PASS
+ * Verifier.verify(*).matchAll(*, null) => FAIL
+ * Verifier.verify((String) null).matchAll(*) => FAIL
+ * Verifier.verify("foo").matchAll(Pattern.compile(".*"), Pattern.compile("fo{2}")) => PASS
+ * Verifier.verify("foo").matchAll(Pattern.compile(".*"), Pattern.compile("fiz{2}")) => FAIL
+ *
+ *
+ * @param patterns
+ * the regular expression {@code Patterns} to be matched against of the value (may be {@literal null} or
+ * contain {@literal null} references)
+ * @return A reference to this {@link StringVerifier} for chaining purposes.
+ * @throws VerifierException
+ * If the verification fails while not negated or passes while negated.
+ * @see #matchAll(CharSequence...)
+ */
+ public StringVerifier matchAll(final Pattern... patterns) {
+ final String value = verification().getValue();
+ final boolean result = value != null && matchAll(patterns, input -> input != null && input.matcher(value).matches());
+
+ verification().report(result, MessageKeys.MATCH_ALL, (Object) patterns);
+
+ return this;
+ }
+
+ /**
+ * + * Verifies that the value matches any of the regular expressions provided. + *
+ *+ * {@literal null} references are handled gracefully without exceptions. + *
+ *
+ * Verifier.verify(*).matchAny() => FAIL
+ * Verifier.verify(*).matchAny((CharSequence[]) null) => FAIL
+ * Verifier.verify((String) null).matchAny(*) => FAIL
+ * Verifier.verify("foo").matchAny("fo{2}", "fiz{2}") => PASS
+ * Verifier.verify("foo").matchAny("fiz{2}", "buz{2}") => FAIL
+ *
+ *
+ * @param regexes
+ * the regular expressions to be matched against of the value (may be {@literal null} or contain {@literal
+ * null} references)
+ * @return A reference to this {@link StringVerifier} for chaining purposes.
+ * @throws VerifierException
+ * If the verification fails while not negated or passes while negated.
+ * @see #matchAny(Pattern...)
+ */
+ public StringVerifier matchAny(final CharSequence... regexes) {
+ final String value = verification().getValue();
+ final boolean result = value != null && matchAny(regexes, input -> input != null && value.matches(input.toString()));
+
+ verification().report(result, MessageKeys.MATCH_ANY, (Object) regexes);
+
+ return this;
+ }
+
+ /**
+ * + * Verifies that the value matches any of the regular expression {@code patterns} provided. + *
+ *+ * {@literal null} references are handled gracefully without exceptions. + *
+ *
+ * Verifier.verify(*).matchAny() => FAIL
+ * Verifier.verify(*).matchAny((Pattern[]) null) => FAIL
+ * Verifier.verify((String) null).matchAny(*) => FAIL
+ * Verifier.verify("foo").matchAny(Pattern.compile("fo{2}"), Pattern.compile("fiz{2}")) => PASS
+ * Verifier.verify("foo").matchAny(Pattern.compile("fiz{2}"), Pattern.compile("buz{2}")) => FAIL
+ *
+ *
+ * @param patterns
+ * the regular expression {@code Patterns} to be matched against of the value (may be {@literal null} or
+ * contain {@literal null} references)
+ * @return A reference to this {@link StringVerifier} for chaining purposes.
+ * @throws VerifierException
+ * If the verification fails while not negated or passes while negated.
+ * @see #matchAny(CharSequence...)
+ */
+ public StringVerifier matchAny(final Pattern... patterns) {
+ final String value = verification().getValue();
+ final boolean result = value != null && matchAny(patterns, input -> input != null && input.matcher(value).matches());
+
+ verification().report(result, MessageKeys.MATCH_ANY, (Object) patterns);
+
+ return this;
+ }
+
/**
*
* Verifies that the value contains only digits.
@@ -1096,6 +1226,8 @@ enum MessageKeys implements MessageKey {
EQUAL_TO_IGNORE_CASE("io.skelp.verifier.type.StringVerifier.equalToIgnoreCase"),
LOWER_CASE("io.skelp.verifier.type.StringVerifier.lowerCase"),
MATCH("io.skelp.verifier.type.StringVerifier.match"),
+ MATCH_ALL("io.skelp.verifier.type.StringVerifier.matchAll"),
+ MATCH_ANY("io.skelp.verifier.type.StringVerifier.matchAny"),
NUMERIC("io.skelp.verifier.type.StringVerifier.numeric"),
NUMERIC_SPACE("io.skelp.verifier.type.StringVerifier.numericSpace"),
SIZE_OF("io.skelp.verifier.type.StringVerifier.sizeOf"),
diff --git a/src/main/resources/Verifier.properties b/src/main/resources/Verifier.properties
index e1250c7..03602ee 100644
--- a/src/main/resources/Verifier.properties
+++ b/src/main/resources/Verifier.properties
@@ -133,6 +133,8 @@ io.skelp.verifier.type.StringVerifier.equalToAnyIgnoreCase=be equal to any {0} (
io.skelp.verifier.type.StringVerifier.equalToIgnoreCase=be equal to ''{0}'' (ignore case)
io.skelp.verifier.type.StringVerifier.lowerCase=be all lower case
io.skelp.verifier.type.StringVerifier.match=match ''{0}''
+io.skelp.verifier.type.StringVerifier.matchAll=match all {0}
+io.skelp.verifier.type.StringVerifier.matchAny=match any {0}
io.skelp.verifier.type.StringVerifier.numeric=contain only digits
io.skelp.verifier.type.StringVerifier.numericSpace=contain only digits or space
io.skelp.verifier.type.StringVerifier.sizeOf=have a size of ''{0,number,integer}''
diff --git a/src/test/java/io/skelp/verifier/type/StringVerifierTest.java b/src/test/java/io/skelp/verifier/type/StringVerifierTest.java
index 423d242..0592059 100644
--- a/src/test/java/io/skelp/verifier/type/StringVerifierTest.java
+++ b/src/test/java/io/skelp/verifier/type/StringVerifierTest.java
@@ -1501,7 +1501,7 @@ public void testMatchWhenValueIsEmptyAndNotMatch() {
}
@Test
- public void testMatchWhenValueIsEmptyAndNotMatchAndOtherIsCharSequence() {
+ public void testMatchWhenValueIsEmptyAndNotMatchAndRegexIsCharSequence() {
testMatchHelper(EMPTY, new StringWrapper("fo{2}"), false);
}
@@ -1511,7 +1511,7 @@ public void testMatchWhenValueIsMatch() {
}
@Test
- public void testMatchWhenValueIsMatchAndOtherIsCharSequence() {
+ public void testMatchWhenValueIsMatchAndRegexIsCharSequence() {
testMatchHelper("foo", new StringWrapper("fo{2}"), true);
}
@@ -1535,6 +1535,122 @@ private void testMatchHelper(String value, CharSequence regex, boolean expected)
assertSame("Passes regex for message formatting", regex, getArgsCaptor().getValue());
}
+ @Test
+ public void testMatchAllWhenNoRegularExpressions() {
+ testMatchAllHelper("foo", createEmptyArray(CharSequence.class), true);
+ }
+
+ @Test
+ public void testMatchAllWhenRegularExpressionIsNull() {
+ testMatchAllHelper("foo", createArray((CharSequence) null), false);
+ }
+
+ @Test
+ public void testMatchAllWhenRegularExpressionsIsNull() {
+ testMatchAllHelper("foo", null, true);
+ }
+
+ @Test
+ public void testMatchAllWhenValueMatchesAllRegularExpressions() {
+ testMatchAllHelper("foo", createArray("fo{2}", ".*"), true);
+ }
+
+ @Test
+ public void testMatchAllWhenValueMatchesAllRegularExpressionsWhenNotCharSequences() {
+ testMatchAllHelper("foo", createArray(new StringWrapper("fo{2}"), new StringWrapper(".*")), true);
+ }
+
+ @Test
+ public void testMatchAllWhenValueMatchesSomeRegularExpressions() {
+ testMatchAllHelper("foo", createArray("fo{2}", "fiz{2}"), false);
+ }
+
+ @Test
+ public void testMatchAllWhenValueMatchesSomeRegularExpressionsWhenNotCharSequences() {
+ testMatchAllHelper("foo", createArray(new StringWrapper("fo{2}"), new StringWrapper("fiz{2}")), false);
+ }
+
+ @Test
+ public void testMatchAllWhenValueDoesNotMatchAnyRegularExpression() {
+ testMatchAllHelper("foo", createArray("fiz{2}", "buz{2}"), false);
+ }
+
+ @Test
+ public void testMatchAllWhenValueDoesNotMatchAnyRegularExpressionWhenNotCharSequences() {
+ testMatchAllHelper("foo", createArray(new StringWrapper("fiz{2}"), new StringWrapper("buz{2}")), false);
+ }
+
+ @Test
+ public void testMatchAllWhenValueIsNull() {
+ testMatchAllHelper(null, createArray(".*"), false);
+ }
+
+ private void testMatchAllHelper(String value, CharSequence[] regexes, boolean expected) {
+ setValue(value);
+
+ assertSame("Chains reference", getCustomVerifier(), getCustomVerifier().matchAll(regexes));
+
+ verify(getMockVerification()).report(expected, StringVerifier.MessageKeys.MATCH_ALL, (Object) regexes);
+ }
+
+ @Test
+ public void testMatchAnyWhenNoRegularExpressions() {
+ testMatchAnyHelper("foo", createEmptyArray(CharSequence.class), false);
+ }
+
+ @Test
+ public void testMatchAnyWhenRegularExpressionIsNull() {
+ testMatchAnyHelper("foo", createArray((CharSequence) null), false);
+ }
+
+ @Test
+ public void testMatchAnyWhenRegularExpressionsIsNull() {
+ testMatchAnyHelper("foo", null, false);
+ }
+
+ @Test
+ public void testMatchAnyWhenValueMatchesAllRegularExpressions() {
+ testMatchAnyHelper("foo", createArray("fo{2}", ".*"), true);
+ }
+
+ @Test
+ public void testMatchAnyWhenValueMatchesAllRegularExpressionsWhenNotCharSequences() {
+ testMatchAnyHelper("foo", createArray(new StringWrapper("fo{2}"), new StringWrapper(".*")), true);
+ }
+
+ @Test
+ public void testMatchAnyWhenValueMatchesSomeRegularExpressions() {
+ testMatchAnyHelper("foo", createArray("fo{2}", "fiz{2}"), true);
+ }
+
+ @Test
+ public void testMatchAnyWhenValueMatchesSomeRegularExpressionsWhenNotCharSequences() {
+ testMatchAnyHelper("foo", createArray(new StringWrapper("fo{2}"), new StringWrapper("fiz{2}")), true);
+ }
+
+ @Test
+ public void testMatchAnyWhenValueDoesNotMatchAnyRegularExpression() {
+ testMatchAnyHelper("foo", createArray("fiz{2}", "buz{2}"), false);
+ }
+
+ @Test
+ public void testMatchAnyWhenValueDoesNotMatchAnyRegularExpressionWhenNotCharSequences() {
+ testMatchAnyHelper("foo", createArray(new StringWrapper("fiz{2}"), new StringWrapper("buz{2}")), false);
+ }
+
+ @Test
+ public void testMatchAnyWhenValueIsNull() {
+ testMatchAnyHelper(null, createArray(".*"), false);
+ }
+
+ private void testMatchAnyHelper(String value, CharSequence[] regexes, boolean expected) {
+ setValue(value);
+
+ assertSame("Chains reference", getCustomVerifier(), getCustomVerifier().matchAny(regexes));
+
+ verify(getMockVerification()).report(expected, StringVerifier.MessageKeys.MATCH_ANY, (Object) regexes);
+ }
+
@Test
public void testMatchWithPatternWhenPatternIsNull() {
testMatchWithPatternHelper("foo", null, false);
@@ -1575,6 +1691,92 @@ private void testMatchWithPatternHelper(String value, Pattern pattern, boolean e
assertSame("Passes pattern for message formatting", pattern, getArgsCaptor().getValue());
}
+ @Test
+ public void testMatchAllWithPatternsWhenNoPatterns() {
+ testMatchAllWithPatternsHelper("foo", createEmptyArray(Pattern.class), true);
+ }
+
+ @Test
+ public void testMatchAllWithPatternsWhenPatternIsNull() {
+ testMatchAllWithPatternsHelper("foo", createArray((Pattern) null), false);
+ }
+
+ @Test
+ public void testMatchAllWithPatternsWhenPatternsIsNull() {
+ testMatchAllWithPatternsHelper("foo", null, true);
+ }
+
+ @Test
+ public void testMatchAllWithPatternsWhenValueMatchesAllPatterns() {
+ testMatchAllWithPatternsHelper("foo", createArray(Pattern.compile("fo{2}"), Pattern.compile(".*")), true);
+ }
+
+ @Test
+ public void testMatchAllWithPatternsWhenValueMatchesSomePatterns() {
+ testMatchAllWithPatternsHelper("foo", createArray(Pattern.compile("fo{2}"), Pattern.compile("fiz{2}")), false);
+ }
+
+ @Test
+ public void testMatchAllWithPatternsWhenValueDoesNotMatchAnyPattern() {
+ testMatchAllWithPatternsHelper("foo", createArray(Pattern.compile("fiz{2}"), Pattern.compile("buz{2}")), false);
+ }
+
+ @Test
+ public void testMatchAllWithPatternsWhenValueIsNull() {
+ testMatchAllWithPatternsHelper(null, createArray(Pattern.compile(".*")), false);
+ }
+
+ private void testMatchAllWithPatternsHelper(String value, Pattern[] patterns, boolean expected) {
+ setValue(value);
+
+ assertSame("Chains reference", getCustomVerifier(), getCustomVerifier().matchAll(patterns));
+
+ verify(getMockVerification()).report(expected, StringVerifier.MessageKeys.MATCH_ALL, (Object) patterns);
+ }
+
+ @Test
+ public void testMatchAnyWithPatternsWhenNoPatterns() {
+ testMatchAnyWithPatternsHelper("foo", createEmptyArray(Pattern.class), false);
+ }
+
+ @Test
+ public void testMatchAnyWithPatternsWhenPatternIsNull() {
+ testMatchAnyWithPatternsHelper("foo", createArray((Pattern) null), false);
+ }
+
+ @Test
+ public void testMatchAnyWithPatternsWhenPatternsIsNull() {
+ testMatchAnyWithPatternsHelper("foo", null, false);
+ }
+
+ @Test
+ public void testMatchAnyWithPatternsWhenValueMatchesAllPatterns() {
+ testMatchAnyWithPatternsHelper("foo", createArray(Pattern.compile("fo{2}"), Pattern.compile(".*")), true);
+ }
+
+ @Test
+ public void testMatchAnyWithPatternsWhenValueMatchesSomePatterns() {
+ testMatchAnyWithPatternsHelper("foo", createArray(Pattern.compile("fo{2}"), Pattern.compile("fiz{2}")), true);
+ }
+
+ @Test
+ public void testMatchAnyWithPatternsWhenValueDoesNotMatchAnyPattern() {
+ testMatchAnyWithPatternsHelper("foo", createArray(Pattern.compile("fiz{2}"), Pattern.compile("buz{2}")), false);
+ }
+
+ @Test
+ public void testMatchAnyWithPatternsWhenValueIsNull() {
+ testMatchAnyWithPatternsHelper(null, createArray(Pattern.compile(".*")), false);
+ }
+
+ private void testMatchAnyWithPatternsHelper(String value, Pattern[] patterns, boolean expected) {
+ setValue(value);
+
+ assertSame("Chains reference", getCustomVerifier(), getCustomVerifier().matchAny(patterns));
+
+ verify(getMockVerification()).report(expected, StringVerifier.MessageKeys.MATCH_ANY, (Object) patterns);
+ }
+
@Test
public void testNumericWhenValueIsEmpty() {
testNumericHelper(EMPTY, true);
@@ -2112,6 +2314,8 @@ protected Map