tech.sirwellington.alchemy.arguments.assertions.StringAssertions Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of alchemy-arguments Show documentation
Show all versions of alchemy-arguments Show documentation
Part of the Alchemy Collection.
Easy, Simple, and Robust argument checking logic
for your Services, Libraries, and Scripts.
/*
* Copyright 2015 SirWellington Tech.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package tech.sirwellington.alchemy.arguments.assertions;
import java.util.UUID;
import java.util.regex.Pattern;
import tech.sirwellington.alchemy.annotations.access.NonInstantiable;
import tech.sirwellington.alchemy.annotations.arguments.NonEmpty;
import tech.sirwellington.alchemy.arguments.AlchemyAssertion;
import tech.sirwellington.alchemy.arguments.Checks;
import tech.sirwellington.alchemy.arguments.FailedAssertionException;
import static java.lang.String.format;
import static tech.sirwellington.alchemy.arguments.Checks.Internal.isNullOrEmpty;
/**
*
* @author SirWellington
*/
@NonInstantiable
public final class StringAssertions
{
StringAssertions() throws IllegalAccessException
{
throw new IllegalAccessException("cannot instantiate");
}
/**
* Asserts that the argument String matches the specified pattern.
*
* @param pattern The pattern to match against.
*
* @return
*/
public static AlchemyAssertion stringThatMatches(Pattern pattern)
{
Checks.Internal.checkNotNull(pattern, "missing pattern");
return (String string) ->
{
if (!pattern.matcher(string).matches())
{
throw new FailedAssertionException("Expected String to match pattern: " + pattern);
}
};
}
/**
* Asserts that a given string is empty (that it has no value).
*
* @return
*/
public static AlchemyAssertion emptyString()
{
return (String string) ->
{
if (!Checks.Internal.isNullOrEmpty(string))
{
throw new FailedAssertionException("Expected empty string but got: " + string);
}
};
}
/**
* Asserts that the argument string has a length {@code >= minimumLength}.
*
* @param minimumLength The length of the argument string must {@code >= minimumLength}
*
* @return
*/
public static AlchemyAssertion stringWithLengthGreaterThanOrEqualTo(int minimumLength)
{
Checks.Internal.checkThat(minimumLength >= 0);
return (String string) ->
{
Assertions.notNull().check(string);
if (string.length() < minimumLength)
{
throw new FailedAssertionException("Expecting a String with length >= " + minimumLength);
}
};
}
/**
* Asserts that the argument String does not have any whitespace characters whatsoever.
*
* @return
*/
public static AlchemyAssertion stringWithNoWhitespace()
{
return (String string) ->
{
Assertions.notNull().check(string);
for (char character : string.toCharArray())
{
if (Character.isWhitespace(character))
{
throw new FailedAssertionException("Argument should not have whitespace.");
}
}
};
}
/**
* Asserts that the argument string has a length of exactly {@code expectedLength}
*
* @param expectedLength The expected length of the string.
*
* @return
*/
public static AlchemyAssertion stringWithLength(int expectedLength)
{
Checks.Internal.checkThat(expectedLength >= 0, "expectedLength must be >= 0");
return (String string) ->
{
Assertions.notNull().check(string);
if (string.length() != expectedLength)
{
throw new FailedAssertionException("Expecting a String with length " + expectedLength);
}
};
}
/**
* Asserts that the length of the argument string is less than the specified upper bound.
*
* @param upperBound The length of the string must be {@code stringWithLengthLessThan(int upperBound)
{
Checks.Internal.checkThat(upperBound > 0, "upperBound must be > 0");
return (String string) ->
{
nonEmptyString().check(string);
if (string.length() >= upperBound)
{
throw new FailedAssertionException("Expecting a String with length < " + upperBound);
}
};
}
/**
* Assert that the argument String starts with a particular prefix.
*
* @param prefix The prefix to check that argument against.
*
* @return
*/
public static AlchemyAssertion stringBeginningWith(String prefix)
{
Checks.Internal.checkThat(!isNullOrEmpty(prefix), "missing prefix");
return (String string) ->
{
nonEmptyString().check(string);
if (!string.startsWith(prefix))
{
String message = String.format("Expected \"%s\" to start with \"%s\"", string, prefix);
throw new FailedAssertionException(message);
}
};
}
/**
* Asserts that the length of the argument string is at most maximumLength.
*
* @param maximumLength The length of the argument must be {@code <= maximumLength}
*
* @return
*/
public static AlchemyAssertion stringWithLengthLessThanOrEqualTo(int maximumLength)
{
Checks.Internal.checkThat(maximumLength >= 0);
return (String string) ->
{
Assertions.notNull().check(string);
if (string == null || string.length() > maximumLength)
{
throw new FailedAssertionException("Argument exceeds the maximum string length of: " + maximumLength);
}
};
}
/**
* Asserts that the argument string has a length {@code > minimumLength}
*
* @param minimumLength The exclusive lower bound for the size of the argument string.
*
* @return
*/
public static AlchemyAssertion stringWithLengthGreaterThan(int minimumLength)
{
Checks.Internal.checkThat(minimumLength > 0, "minimumLength must be > 0");
Checks.Internal.checkThat(minimumLength < Integer.MAX_VALUE, "not possible to have a String larger than Integer.MAX_VALUE");
return (String string) ->
{
nonEmptyString().check(string);
if (string.length() <= minimumLength)
{
throw new FailedAssertionException("Expected a String with length > " + minimumLength);
}
};
}
/**
* Asserts that a given string is not empty (neither null nor completely empty).
*
* @return
*/
public static AlchemyAssertion nonEmptyString()
{
return (String string) ->
{
if (Checks.Internal.isNullOrEmpty(string))
{
throw new FailedAssertionException("String argument is empty");
}
};
}
/**
* Asserts that the argument string's length is between the specified lengths, inclusively.
*
* @param minimumLength Minimum String Length, inclusive.
* @param maximumLength Maximum String Length, inclusive.
*
* @return
*/
public static AlchemyAssertion stringWithLengthBetween(int minimumLength, int maximumLength)
{
Checks.Internal.checkThat(minimumLength >= 0, "Minimum length must be at least 0");
Checks.Internal.checkThat(minimumLength < maximumLength, "Minimum length must be < maximum length.");
return string ->
{
Assertions.notNull().check(string);
if (string.length() < minimumLength || string.length() > maximumLength)
{
String message = String.format("Argument size is not between acceptable range of [%d -> %d]", minimumLength, maximumLength);
throw new FailedAssertionException(message);
}
};
}
/**
* Checks that a string contains another.
*
* @param substring
* @throws IllegalArgumentException If {@code substring} is null or empty.
*/
public static AlchemyAssertion stringContaining(@NonEmpty String substring) throws IllegalArgumentException
{
Checks.Internal.checkNotNullOrEmpty(substring, "substring cannot be empty");
return string ->
{
nonEmptyString().check(string);
if (!string.contains(substring))
{
throw new FailedAssertionException(format("Expected %s to contain %s", string, substring));
}
};
}
/**
* Checks that a String has All Upper-Cased characters (also known as ALL-CAPS).
*
* @return
*/
public static AlchemyAssertion allUpperCaseString()
{
return string ->
{
nonEmptyString().check(string);
for (char character : string.toCharArray())
{
if (!Character.isUpperCase(character))
{
throw new FailedAssertionException(format("Expected %s to be all upper-case, but %s isn't",
string,
character));
}
}
};
}
/**
* Checks that a String has All Lower-Cased characters.
*
* @return
*/
public static AlchemyAssertion allLowerCaseString()
{
return string ->
{
nonEmptyString().check(string);
for (char character : string.toCharArray())
{
if (!Character.isLowerCase(character))
{
throw new FailedAssertionException(format("Expected %s to be all lower-case, but %s isn't",
string,
character));
}
}
};
}
/**
* Checks that a String ends with the specified non-empty string, as determined by
* {@link String#endsWith(java.lang.String)}. In other words, the Argument String must have this suffix.
*
* @param suffix The Argument String must end with this non-empty String.
* @return
* @throws IllegalArgumentException If {@code substring} is empty or null.
*/
public static AlchemyAssertion stringEndingWith(@NonEmpty String suffix) throws IllegalArgumentException
{
Checks.Internal.checkNotNullOrEmpty(suffix, "string should not be empty");
return string ->
{
nonEmptyString().check(string);
if(!string.endsWith(suffix))
{
throw new FailedAssertionException(format("Expected %s to end with %s", string, suffix));
}
};
}
/**
* Checks that a String is composed only of Alphabetic Characters, as determined by
* {@link Character#isAlphabetic(int) }.
*
* @return
*/
public static AlchemyAssertion alphabeticString()
{
return string ->
{
nonEmptyString().check(string);
for (char character : string.toCharArray())
{
if (!Character.isAlphabetic(character))
{
throw new FailedAssertionException(format("Expected alphabetic string, but '%s' is not alphabetic",
character));
}
}
};
}
/**
* Checks that a String is composed of only Alphanumeric Characters, as determined by
* {@link Character#isDigit(char) } and {@link Character#isAlphabetic(int) }.
*
* @return
*/
public static AlchemyAssertion alphanumericString()
{
return string ->
{
nonEmptyString().check(string);
for (char character : string.toCharArray())
{
if (!Character.isAlphabetic(character) && !Character.isDigit(character))
{
throw new FailedAssertionException(format("Expected alphanumeric string, but chracter '%s' is not",
character));
}
}
};
}
/**
* Checks that a String represents a valid {@linkplain UUID#fromString(java.lang.String) Type-4 UUID}.
*
* @return
*/
public static AlchemyAssertion validUUID()
{
return string ->
{
nonEmptyString().check(string);
try
{
UUID.fromString(string);
}
catch(Exception ex)
{
throw new FailedAssertionException("String is not a valid UUID: " + string);
}
};
}
/**
* Checks that a String represents an {@link Integer}, as determined by {@link Integer#parseInt(java.lang.String) }.
* In other words, that it contains only Digits, as determined by 2
* {@link Character#isDigit(char) }, or the characters {@code -} (negative sign),
* {@code +} (positive sign)
*
* Valid examples include:
*
* 0
* -054
* 954
* -674572
*
*
* @return
*/
public static AlchemyAssertion stringRepresentingInteger()
{
return string ->
{
nonEmptyString().check(string);
for(int i = 0; i < string.length(); ++i)
{
char character = string.charAt(i);
//The first character is allowed to be a sign character '-' or '+'
if (i == 0 && isSignCharacter(character))
{
continue;
}
if (!Character.isDigit(character))
{
throw new FailedAssertionException(format("Expected an Integer String, but %s is not a digi",
character));
}
}
};
};
private static boolean isSignCharacter(char character)
{
return character == '-' || character == '+';
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy