CommonChecks.java
package org.klojang.check;
import org.klojang.check.extra.Emptyable;
import org.klojang.check.extra.Result;
import org.klojang.check.types.*;
import org.klojang.check.x.CheckImpls;
import org.klojang.check.x.StringCheckImpls;
import java.io.File;
import java.nio.file.Files;
import java.util.*;
import java.util.regex.Pattern;
import static java.util.regex.Pattern.*;
/**
* Defines various common checks on arguments, variables, object state, program input, etc. The checks have
* short, informative error messages associated with them, so you don't have to invent them yourself. Unless
* specified otherwise they
* <i>only</i> test what they are documented to be testing. Many of them do nothing
* but return a method reference (e.g. {@link Collection#contains(Object) Collection::contains}). More
* specifically:
* <b>the checks will not execute a preliminary null check</b> on the argument
* before proceeding with the actual check. If the argument might be {@code null}, always perform a
* {@link #notNull()} check first. Otherwise, a raw, unprocessed {@link NullPointerException} <i>can and
* will</i> be thrown from the code underlying Klojang Check.
*
* <blockquote><pre>{@code
* Check.notNull(file).is(readable());
* }</pre></blockquote>
*
* <p>For ease of reading, the documentation for the checks will mostly use the term
* "argument" for the value being tested. Constantly repeating "argument, field, variable, program argument,
* system property, environment variable, etc." would not improve the quality and clarity of the
* documentation.
*
* @author Ayco Holleman
*/
public final class CommonChecks {
private CommonChecks() {
throw new UnsupportedOperationException();
}
//////////////////////////////////////////////////////////////////////////////////
// Predicate
//////////////////////////////////////////////////////////////////////////////////
/**
* Verifies that the argument is null. Equivalent to {@link Objects#isNull(Object) Objects::isNull}.
*
* @param <T> the type of the argument
* @return a function implementing the test described above
*/
public static <T> ComposablePredicate<T> NULL() {
return Objects::isNull;
}
/**
* Verifies that the argument is not null. Equivalent to {@link Objects#nonNull(Object) Objects::nonNull}.
* Note that {@link #NULL()}, {@link #yes()} and {@link #empty()} are the only checks that come with their
* negation: {@code notNull()}, {@link #no()} and {@link #notEmpty()}. The other checks need to be inverted
* using the {@code isNot(...)} and {@code notHas(...)} methods of {@link ObjectCheck} and
* {@link IntCheck}.
*
* @param <T> the type of the argument
* @return a function implementing the test described above
*/
public static <T> ComposablePredicate<T> notNull() {
return Objects::nonNull;
}
/**
* Verifies that a condition evaluates to {@code true}.
*
* <blockquote><pre>{@code
* Check.that(connection.isOpen()).is(yes());
* }</pre></blockquote>
*
* @return a function implementing the test described above
*/
public static ComposablePredicate<Boolean> yes() {
return x -> x;
}
/**
* Verifies that a condition evaluates to {@code false}.
*
* @return a function implementing the test described above
*/
public static ComposablePredicate<Boolean> no() {
return x -> !x;
}
/**
* Verifies that the argument is empty.
*
* <blockquote><pre>{@code
* Check.that(list).isNot(empty());
* }</pre></blockquote>
*
* <p>
* A value is defined to be empty if any of the following applies:
*
* <ul>
* <li>it is {@code null}
* <li>it is an empty {@link CharSequence}
* <li>it is an empty {@link Collection}
* <li>it is an empty {@link Map}
* <li>it is an empty {@link Emptyable}
* <li>it is a {@link File} representing an existing but empty file or directory
* <li>it is a zero-length array
* <li>it is an empty {@link Optional}
* </ul>
*
* <p>This check (implicitly) performs a null check and can be safely executed
* without or instead of executing the {@link #notNull()} check first.
*
* @param <T> the type of the argument
* @return a function implementing the test described above
*/
public static <T> ComposablePredicate<T> empty() {
return CheckImpls::isEmpty;
}
/**
* Verifies that the argument is either null or an empty string.
*
* <p>This check (implicitly) performs a null check and can be safely executed
* without or instead of executing the {@link #notNull()} check first.
*
* @return a function implementing the test described above
*/
public static ComposablePredicate<String> emptyString() {
return s -> s == null || s.isEmpty();
}
/**
* Verifies that the argument is not empty. More precisely: it verifies the negation of the {@link #empty()}
* test.
*
* <p>This check (implicitly) performs a null check and can be safely executed
* without or instead of executing the {@link #notNull()} check first.
*
* @param <T> the type of the argument
* @return a function implementing the test described above
*/
public static <T> ComposablePredicate<T> notEmpty() {
return CheckImpls::isNotEmpty;
}
/**
* Verifies that the argument is not {@code null} and, if it is an array, collection or map, that it does
* not contain any {@code null} values. It could still be a zero-length array or zero-size collection or
* map, however. For maps, both keys and values are tested for {@code null}.
*
* <p>This check (implicitly) performs a null check and can be safely executed
* without or instead of executing the {@link #notNull()} check first.
*
* @param <T> the type of the argument
* @return a function implementing the test described above
*/
public static <T> ComposablePredicate<T> deepNotNull() {
return CheckImpls::isDeepNotNull;
}
/**
* Verifies that the argument is recursively non-empty. A value is defined to be deep-not-empty if any of
* the following applies:
*
* <ul>
* <li>it is a non-empty {@link CharSequence}
* <li>it is a non-empty {@link Collection} containing only
* <i>deep-not-empty</i> elements
* <li>it is a non-empty {@link Map} containing only <i>deep-not-empty</i> keys
* and values
* <li>it is a deep-not-empty {@link Emptyable}
* <li>it is a non-zero-length {@code Object[]} containing only
* <i>deep-not-empty</i> elements
* <li>it is a non-zero-length array of primitive values
* <li>it is a non-empty {@link Optional} containing a <i>deep-not-empty</i>
* value
* <li>it is a {@link File} containing at least one non-whitespace character.
* Consequently, this check could be expensive if the argument is a large
* {@code File}. Also note that this check will not verify that the file
* exists in the first place. If in doubt, execute the {@link #file()} check
* first.
* <li>it is a non-null object of any other type
* </ul>
*
* <p>This check (implicitly) performs a null check and can be safely executed
* without or instead of executing the {@link #notNull()} check first.
*
* @param <T> the type of the argument
* @return a function implementing the test described above
*/
public static <T> ComposablePredicate<T> deepNotEmpty() {
return CheckImpls::isDeepNotEmpty;
}
/**
* Verifies that the argument is {@code null} or contains whitespace only. Probably more useful when called
* from an {@code isNot} method.
*
* <p>This check (implicitly) performs a null check and can be safely executed
* without or instead of executing the {@link #notNull()} check first.
*
* @return a function implementing the test described above
*/
public static ComposablePredicate<String> blank() {
return s -> s == null || s.isBlank();
}
/**
* Verifies that a string consists of digits only (without '+' or '-' sign), no leading zeros, and can be
* parsed into an integer (by implication non-negative).
*
* @return a function implementing the test described above
*/
public static ComposablePredicate<String> plainInt() {
return StringCheckImpls::isPlainInt;
}
/**
* Verifies that a string consists of digits only (without '+' or '-' sign), no leading zeros, and can be
* parsed into a half-precision integer (by implication non-negative). Useful, for example, for validating
* TCP port numbers.
*
* @return a function implementing the test described above
*/
public static ComposablePredicate<String> plainShort() {
return StringCheckImpls::isPlainShort;
}
/**
* Verifies that the argument either is an array <i>object</i> or an array <i>type</i>.
*
* <blockquote><pre>{@code
* Object array = new int[] {1, 2, 3, 4, 5};
* Check.that(array).is(array()); // true
* Check.that(int[].class).is(array()); // true
* Check.that(Employee[].class).is(array()); // true
* Check.that(new Employee()).is(array()); // false
* Check.that("foo").is(array()); // false
* }</pre></blockquote>
*
* @param <T> the type of the argument
* @return a function implementing the test described above
*/
public static <T> ComposablePredicate<T> array() {
return x -> x.getClass() == Class.class
? ((Class<?>) x).isArray()
: x.getClass().isArray();
}
/**
* Verifies that the argument is an existing, regular file.
*
* @return a function implementing the test described above
*/
public static ComposablePredicate<File> file() {
return f -> Files.isRegularFile(f.toPath());
}
/**
* Verifies that the argument is an existing directory.
*
* @return a function implementing the test described above
*/
public static ComposablePredicate<File> directory() {
return f -> Files.isDirectory(f.toPath());
}
/**
* Verifies that the argument is a symbolic link.
*
* @return a function implementing the test described above
*/
public static ComposablePredicate<File> symlink() {
return f -> Files.isSymbolicLink(f.toPath());
}
/**
* Verifies that a file is readable. Implies that the file exists. Equivalent to
* {@link File#canRead() File::canRead}.
*
* @return a function implementing the test described above
*/
public static ComposablePredicate<File> readable() {
return File::canRead;
}
/**
* Verifies that a file is writable. Implies that the file exists. Equivalent to
* {@link File#canWrite() File::canWrite}.
*
* @return a function implementing the test described above
*/
public static ComposablePredicate<File> writable() {
return File::canWrite;
}
/**
* Verifies that the argument is a non-empty {@code Optional}.
*
* @param <T> the type of the value contained in the {@code Optional}
* @return a function implementing the test described above
*/
public static <T> ComposablePredicate<Optional<T>> present() {
return Optional::isPresent;
}
/**
* Verifies that a {@linkplain Result result} is available.
*
* @param <T> the type of the value contained in the {@code Result}
* @return a function implementing the test described above
*/
public static <T> ComposablePredicate<Result<T>> available() {
return Result::isAvailable;
}
//////////////////////////////////////////////////////////////////////////////////
// IntPredicate
//////////////////////////////////////////////////////////////////////////////////
/**
* Verifies that the argument is an even integer.
*
* @return a function implementing the test described above
*/
public static ComposableIntPredicate even() {
return x -> x % 2 == 0;
}
/**
* Verifies that the argument is an odd integer.
*
* @return a function implementing the test described above
*/
public static ComposableIntPredicate odd() {
return x -> x % 2 == 1;
}
/**
* Verifies that the argument is a positive integer.
*
* @return a function implementing the test described above
*/
public static ComposableIntPredicate positive() {
return x -> x > 0;
}
/**
* Verifies that the argument is a negative integer.
*
* @return a function implementing the test described above
*/
public static ComposableIntPredicate negative() {
return x -> x < 0;
}
/**
* Verifies that the argument is zero (0).
*
* @return a function implementing the test described above
*/
public static ComposableIntPredicate zero() {
return x -> x == 0;
}
/**
* Verifies that the argument equals 1.
*
* @return a function implementing the test described above
*/
public static ComposableIntPredicate one() {
return x -> x == 1;
}
//////////////////////////////////////////////////////////////////////////////////
// IntRelation
//////////////////////////////////////////////////////////////////////////////////
/**
* Verifies that the argument equals the specified {@code int} value.
*
* @return a function implementing the test described above
*/
public static IntRelation eq() {
return (x, y) -> x == y;
}
/**
* Verifies that the argument does not equal the specified {@code int} value.
*
* @return a function implementing the test described above
*/
public static IntRelation ne() {
return (x, y) -> x != y;
}
/**
* Verifies that the argument is greater than the specified {@code int} value.
*
* @return a function implementing the test described above
*/
public static IntRelation gt() {
return (x, y) -> x > y;
}
/**
* Verifies that the argument is greater than or equal to the specified {@code int} value.
*
* @return a function implementing the test described above
*/
public static IntRelation gte() {
return (x, y) -> x >= y;
}
/**
* Verifies that the argument is less than the specified {@code int} value.
*
* @return a function implementing the test described above
*/
public static IntRelation lt() {
return (x, y) -> x < y;
}
/**
* Verifies that the argument is less than or equal to the specified {@code int} value.
*
* @return a function implementing the test described above
*/
public static IntRelation lte() {
return (x, y) -> x <= y;
}
/**
* Verifies that the argument is a multiple of the specified {@code int} value.
*
* @return a function implementing the test described above
*/
public static IntRelation multipleOf() {
return (x, y) -> x % y == 0;
}
//////////////////////////////////////////////////////////////////////////////////
// Relation
//////////////////////////////////////////////////////////////////////////////////
/**
* Verifies that the argument equals the provided value. Equivalent to
* {@link Object#equals(Object) Object::equals}. Note that this method is
* <i>not</i> equivalent to {@link Objects#equals(Object, Object) Objects::equals}
* and is therefore not null-safe. Execute a {@linkplain #notNull() null check} first, if necessary.
*
* @param <S> the type of the subject of the relationship (which is the value being tested)
* @param <O> the type of the object of the relationship
* @return a function implementing the test described above
*/
public static <S, O> Relation<S, O> EQ() {
return Object::equals;
}
/**
* Verifies that the argument equals some value. Equivalent to {@link Object#equals(Object) Object::equals}.
* Use this check instead of {@link #EQ()} if you want the compiler to enforce type equality between subject
* and object.
*
* @param <T> the type of the objects being compared
* @return a function implementing the test described above
*/
public static <T> Relation<T, T> equalTo() {
return Object::equals;
}
/**
* Verifies that the argument is greater than another value.
*
* @param <T> the type of the values being compared
* @return a function implementing the test described above
* @see #gt()
*/
public static <T extends Comparable<T>> Relation<T, T> GT() {
return (x, y) -> x.compareTo(y) > 0;
}
/**
* Verifies that the argument is less than another value.
*
* @param <T> the type of the values being compared
* @return a function implementing the test described above
* @see CommonProperties#unbox()
* @see #lt()
*/
public static <T extends Comparable<T>> Relation<T, T> LT() {
return (x, y) -> x.compareTo(y) < 0;
}
/**
* Verifies that the argument is greater than or equal to another value.
*
* @param <T> the type of the values being compared
* @return a function implementing the test described above
* @see CommonProperties#unbox()
* @see #gte()
*/
public static <T extends Comparable<T>> Relation<T, T> GTE() {
return (x, y) -> x.compareTo(y) >= 0;
}
/**
* Verifies that the argument is less than or equal to another value.
*
* @param <T> the type of the values being compared
* @return a function implementing the test described above
* @see CommonProperties#unbox()
* @see #lte()
*/
public static <T extends Comparable<T>> Relation<T, T> LTE() {
return (x, y) -> x.compareTo(y) <= 0;
}
/**
* Verifies that a value references the same object as another value.
*
* @param <S> the type of the subject of the relationship (which is the value being tested) (the subject
* of the {@code Relation})
* @param <O> the type of the value to compare it with (the object of the {@code Relation})
* @return a function implementing the test described above
*/
public static <S, O> Relation<S, O> sameAs() {
return (x, y) -> x == y;
}
/**
* Verifies that the argument is either null or equals a particular value.
*
* <p>This check (implicitly) performs a null check and can be safely executed
* without or instead of executing the {@link #notNull()} check first.
*
* @param <T> the type of the subject of the relationship (which is the value being tested)
* @return a function implementing the test described above
*/
public static <T> Relation<T, T> nullOr() {
return (x, y) -> x == null || x.equals(y);
}
/**
* Verifies that the argument is an instance of a particular class or interface.
*
* @param <S> the type of the subject of the relation (which is the value being tested)
* @return a function implementing the test described above
*/
public static <S> Relation<S, Class<?>> instanceOf() {
return (x, y) -> y.isInstance(x);
}
/**
* Verifies that the argument is a supertype of the provided type. Equivalent to
* {@link Class#isAssignableFrom(Class) Class::isAssignableFrom}.
* <blockquote><pre>{@code
* Check.that(Map.class).is(superTypeOf(), HashMap.class); // OK
* Check.that(AbstractMap.class).is(superTypeOf(), HashMap.class); // OK
* Check.that(HashMap.class).is(superTypeOf(), HashMap.class); // OK
* Check.that(HashMap.class).is(superTypeOf(), Map.class); // IllegalArgumentException
* }</pre></blockquote>
*
* @param <S> the type of the subject's class
* @param <O> the type of the object's class
* @return a function that implements the test described above
*/
public static <S, O> Relation<Class<S>, Class<O>> supertypeOf() {
return Class::isAssignableFrom;
}
/**
* Verifies that the argument is a subtype of the provided type. In other words, the argument should extend,
* implement or equal the provided type.
*
* @param <S> the type of the subject's class
* @param <O> the type of the object's class
* @return a function that implements the test described above
*/
public static <S, O> Relation<Class<S>, Class<O>> subtypeOf() {
return (x, y) -> y.isAssignableFrom(x);
}
/**
* Verifies that a collection contains a particular value. Equivalent to
* {@link Collection#contains(Object) Collection::contains}.
*
* @param <O> the type of the elements in the {@code Collection}
* @param <S> the type of the collection
* @return a function implementing the test described above
*/
public static <O, S extends Collection<? super O>> Relation<S, O> contains() {
return Collection::contains;
}
/**
* Verifies that a map contains a particular key. Equivalent to
* {@link Map#containsKey(Object) Map::containsKey}.
*
* @param <O> the type of the keys within the map
* @param <S> the Type of the {@code Map}
* @return a function implementing the test described above
*/
public static <O, S extends Map<? super O, ?>> Relation<S, O> containsKey() {
return Map::containsKey;
}
/**
* Verifies that a map contains a particular value. Equivalent to
* {@link Map#containsValue(Object) Map::containsValue}.
*
* @param <O> the type of the values within the map
* @param <S> the Type of the {@code Map}
* @return a function implementing the test described above
*/
public static <O, S extends Map<?, ? super O>> Relation<S, O> containsValue() {
return Map::containsValue;
}
/**
* Verifies that the argument is an element of a collection.
*
* @param <S> the type of the argument
* @param <O> the type of the {@code Collection}
* @return a function implementing the test described above
*/
public static <S, O extends Collection<? super S>> Relation<S, O> in() {
return (x, y) -> y.contains(x);
}
/**
* Alias for {@link #in()}. Note that this method will even report itself to be the "in" check.
*
* @param <S> the type of the argument
* @param <O> the type of the {@code Collection}
* @return a function implementing the test described above
*/
public static <S, O extends Collection<? super S>> Relation<S, O> elementOf() {
return in();
}
/**
* Verifies the presence of a key within a map.
*
* @param <S> the type of the keys within the map
* @param <O> the Type of the {@code Map}
* @return a function implementing the test described above
*/
public static <S, O extends Map<? super S, ?>> Relation<S, O> keyIn() {
return (x, y) -> y.containsKey(x);
}
/**
* Verifies the presence of a value within a map.
*
* @param <S> the type of the keys within the map
* @param <O> the Type of the {@code Map}
* @return a function implementing the test described above
*/
public static <S, O extends Map<?, ? super S>> Relation<S, O> valueIn() {
return (x, y) -> y.containsValue(x);
}
/**
* Verifies that the argument is an element of an array.
*
* @param <S> the type of the subject of the relationship (which is the value being tested)
* @param <O> the component type of the array
* @return a function implementing the test described above
*/
public static <O, S extends O> Relation<S, O[]> inArray() {
return CheckImpls::inArray;
}
/**
* Verifies that a {@code Collection} argument contains all the elements of the specified collection.
* Equivalent to {@link Collection#containsAll(Collection) Collection::containsAll}.
*
* <blockquote><pre>{@code
* Check.that(List.of(1, 2, 3)).is(enclosing(), Set.of(1, 2)); // true
* Check.that(List.of(1, 2)).is(enclosing(), Set.of(1, 2, 3)); // false
* }</pre></blockquote>
*
* @param <E> The type of the elements in the {@code Collection}
* @param <C0> The type of the argument (the subject of the {@code Relation})
* @param <C1> The type of the object of the {@code Relation}
* @return a function implementing the test described above
*/
public static <E, C0 extends Collection<? super E>, C1 extends Collection<E>>
Relation<C0, C1> containsAll() {
return Collection::containsAll;
}
/**
* Verifies that the argument contains the specified substring. Equivalent to
* {@link String#contains(CharSequence) String::contains}.
*
* @return a function implementing the test described above
*/
public static Relation<String, CharSequence> hasSubstring() {
return String::contains;
}
/**
* Verifies that the argument is a substring of the specified string.
*
* @return a function implementing the test described above
*/
public static Relation<String, String> substringOf() {
return (x, y) -> y.contains(x);
}
/**
* Verifies that the argument starts with the specified substring. Equivalent to
* {@link String#startsWith(String) String::startsWith}.
*
* @return a function implementing the test described above
*/
public static Relation<String, String> startsWith() {
return String::startsWith;
}
/**
* Verifies that the argument ends with the specified substring. Equivalent to
* {@link String#endsWith(String) String::endsWith}.
*
* @return a function implementing the test described above
*/
public static Relation<String, String> endsWith() {
return String::endsWith;
}
/**
* Verifies that the argument matches the specified pattern (that is, the pattern <i>fully</i> describes the
* string). The subject of the returned {@code Relation} is the string to match; the object of the
* {@code Relation} is a regular expression to be compiled into a {@link Pattern}.
*
* <blockquote><pre>{@code
* Check.that("abcd123").is(matching(), "^\\w{4}\\d{3}$"); // yes
* Check.that("abcd123").is(matching(), "\\d{3}"); // no
* }</pre></blockquote>
*
* @return a function implementing the test described above
*/
public static Relation<String, String> matching() {
return (string, pattern) -> Pattern.compile(pattern).matcher(string).matches();
}
/**
* Verifies that the argument matches the specified pattern (that is, the pattern <i>fully</i> describes the
* string).
*
* @return a function implementing the test described above
* @see #matching()
*/
public static Relation<String, Pattern> matchingPattern() {
return (string, pattern) -> pattern.matcher(string).matches();
}
/**
* Verifies that the argument contains the specified pattern (that is, the pattern can be found
* <i>somewhere</i> in the string).
*
* @return a function implementing the test described above
* @see #containsMatch()
*/
public static Relation<String, Pattern> containingPattern() {
return (string, pattern) -> pattern.matcher(string).find();
}
/**
* Verifies that the argument contains the specified pattern (that is, the pattern can be found somewhere in
* the string). The subject of the returned {@code Relation} is the string to match; the object of the
* {@code Relation} is a regular expression to be compiled into a {@link Pattern}.
*
* <blockquote><pre>{@code
* Check.that("abcd123").is(containsMatch(), "\\d{3}"); // yes
* Check.that("abcd123").is(containsMatch(), "\\d{4}"); // no
* }</pre></blockquote>
*
* @return a function implementing the test described above
*/
public static Relation<String, String> containsMatch() {
return (string, pattern) -> containingPattern().exists(string, compile(pattern));
}
/**
* Verifies that a string value equals, ignoring case, the specified string. Equivalent to
* {@link String#equalsIgnoreCase(String) String::equalsIgnoreCase}.
*
* @return a function implementing the test described above
*/
public static Relation<String, String> equalsIgnoreCase() {
return String::equalsIgnoreCase;
}
/**
* Verifies that a string value starts with, ignoring case, the specified string.
*
* @return a function implementing the test described above
*/
public static Relation<String, String> startsWithIgnoreCase() {
return (s, o) -> s.regionMatches(true, 0, o, 0, o.length());
}
/**
* Verifies that a string value starts with, ignoring case, the specified string.
*
* @return a function implementing the test described above
*/
public static Relation<String, String> endsWithIgnoreCase() {
return (s, o) -> s.regionMatches(true, s.length() - o.length(), o, 0, o.length());
}
/**
* Verifies that a string value contains, ignoring case, the specified string.
*
* @return a function implementing the test described above
*/
public static Relation<String, String> hasSubstringIgnoreCase() {
return (s, o) -> Pattern.compile(o, CASE_INSENSITIVE | LITERAL).matcher(s).find();
}
//////////////////////////////////////////////////////////////////////////////////
// IntObjRelation
//////////////////////////////////////////////////////////////////////////////////
/**
* Verifies that the argument is a valid index into the specified array, {@code List} or {@code String}. No
* preliminary check is done to ensure the provided object actually is an array, {@code List} or
* {@code String}. A {@link CorruptCheckException} is thrown if it is not. Execute the {@link #instanceOf()}
* or {@link #array()} check first, if necessary.
*
* @param <T> the type of the object of the {@code IntObjRelation} - must be a {@code String},
* {@code List} or array
* @return a function implementing the test described above
*/
public static <T> IntObjRelation<T> indexOf() {
return CheckImpls::isIndexOf;
}
/**
* Alias for {@link #indexOf()}. Can be used if the class you are working in already contains an
* {@code indexOf()} method. Note that this check will report itself to be the {@code indexOf()} check:
*
* <blockquote><pre>{@code
* Check.that(42, "foo").is(indexExclusiveOf(), new int[10], "${tag} did not pass the ${test}() test");
* // "foo did not pass the indexOf() test"
* }</pre></blockquote>
*
* @param <T> the type of the object of the {@code IntObjRelation} - must be a {@code String},
* {@code List} or array
* @return a function implementing the test described above
*/
public static <T> IntObjRelation<T> indexExclusiveOf() {
return indexOf();
}
/**
* Verifies that a value can be used as a "from" or "to" index in operations like
* {@link Arrays#copyOfRange(int[], int, int) Arrays.copyOfRange()},
* {@link String#substring(int, int) String.substring()} and {@link List#subList(int, int) List.subList()}.
* These operations allow both the "from" index and the "to" index to be equal to the length of the array,
* string or list. No preliminary check is done to ensure the provided object actually is an array,
* {@code List} or {@code String}. A {@link CorruptCheckException} is thrown if it is not. Execute the
* {@link #instanceOf()} or {@link #array()} check first, if necessary.
*
* @param <T> the type of the object of the {@code IntObjRelation} - must be a {@code String},
* {@code List} or array
* @return a function implementing the test described above
* @see Check#fromTo(Object[], int, int)
*/
public static <T> IntObjRelation<T> indexInclusiveOf() {
return CheckImpls::isIndexInclusiveOf;
}
/**
* Verifies that the argument is present in the specified {@code int} array.
*
* @return a function implementing the test described above
*/
public static IntObjRelation<int[]> inIntArray() {
return (x, y) -> {
for (int i : y) {
if (x == i) {
return true;
}
}
return false;
};
}
//////////////////////////////////////////////////////////////////////////////////
// Special
//////////////////////////////////////////////////////////////////////////////////
/**
* Returns a {@code ComposablePredicate} that always evaluates to {@code true}. Can be used as the first of
* a series of AND-joined checks:
*
* <blockquote><pre>{@code
* Check.that(color).is(valid().and(equalTo(), noneOf(), GREEN, BLUE, YELLOW));
* }</pre></blockquote>
*
* @param <T> the type of the value being tested (which is ignored by the returned
* {@code ComposablePredicate})
* @return a {@code ComposablePredicate} that always evaluates to {@code true}
*/
public static <T> ComposablePredicate<T> valid() {
return x -> true;
}
/**
* Returns a {@code ComposableIntPredicate} that always evaluates to {@code true}. Can be used as the first
* of a series of AND-joined checks.
*
* @return a {@code ComposableIntPredicate} that always evaluates to {@code true}
*/
public static ComposableIntPredicate validInt() {
return x -> true;
}
/**
* Returns a {@code ComposablePredicate} that always evaluates to {@code false}. Can be used as the first of
* a series of OR-joined checks:
*
* <blockquote><pre>{@code
* Check.that(color).is(invalid().or(equalTo(), anyOf(), GREEN, BLUE, YELLOW));
* }</pre></blockquote>
*
* @param <T> the type of the value being tested (which is ignored by the returned
* {@code ComposablePredicate})
* @return a {@code ComposablePredicate} that always evaluates to {@code false}
*/
public static <T> ComposablePredicate<T> invalid() {
return x -> false;
}
/**
* Returns a {@code ComposableIntPredicate} that always evaluates to {@code false}. Can be used as the first
* of a series of OR-joined checks.
*
* @return a {@code ComposableIntPredicate} that always evaluates to {@code false}
*/
public static ComposableIntPredicate invalidInt() {
return x -> false;
}
}