private static <T> Matcher<T[]> everyItemInArray(final Matcher<T> itemMatcher) { return new TypeSafeDiagnosingMatcher<T[]>() { @Override public void describeTo(Description description) { description.appendText("every item in array is ").appendDescriptionOf(itemMatcher); } @Override protected boolean matchesSafely(T[] items, Description mismatchDescription) { for (T item : items) { if (!itemMatcher.matches(item)) { mismatchDescription.appendText("an item "); itemMatcher.describeMismatch(item, mismatchDescription); return false; } } return true; } }; }
private TypeSafeDiagnosingMatcher<Integer> successfulExitCode( final Command cmd, final File workspace) { return new TypeSafeDiagnosingMatcher<Integer>() { @Override protected boolean matchesSafely( final Integer exitCode, final Description mismatchDescription) { if (exitCode != 0) { mismatchDescription .appendText(" exit code was ") .appendValue(exitCode) .appendText("\n") .appendText("Workspace contents: \n") .appendValueList("", "\n", "\n", contents(workspace.toPath())) .appendDescriptionOf(commandDescription(cmd)); return false; } return true; } @Override public void describeTo(final Description description) { description.appendText("successful exit code (0)"); } }; }
public static Matcher<ValidationError> validationError(final String propertyPath, final String message) { return new TypeSafeDiagnosingMatcher<ValidationError>() { @Override protected boolean matchesSafely(ValidationError item, Description mismatchDescription) { if (!item.getErrorMessage().equals(message)) { mismatchDescription.appendText("message was " + item.getErrorMessage()); return false; } if (!item.getFieldPath().equals(propertyPath)) { mismatchDescription.appendText("field path was " + item.getFieldPath()); return false; } return true; } @Override public void describeTo(Description description) { description.appendText("a validation error for field " + propertyPath + " with message " + message); } }; }
public static Matcher<String> matchingPattern(String patternStr) { return new TypeSafeDiagnosingMatcher<String>() { @Override protected boolean matchesSafely(String text, Description mismatchDescription) { Pattern pattern = Pattern.compile(patternStr, Pattern.DOTALL); boolean matches = pattern.matcher(text).matches(); if (!matches) { mismatchDescription.appendText(text); } return matches; } @Override public void describeTo(Description description) { description.appendText("matching '" + patternStr + "'"); } }; }
public static Matcher<Git> hasTag(final String tag) { return new TypeSafeDiagnosingMatcher<Git>() { @Override protected boolean matchesSafely(final Git repo, final Description mismatchDescription) { try { mismatchDescription.appendValueList("a git repo with tags: ", ", ", "", repo.getRepository().getTags().keySet()); for (final Ref ref : repo.tagList().call()) { final String currentTag = ref.getName().replace(REFS_TAGS, ""); if (tag.equals(currentTag)) { return true; } } return false; } catch (final GitAPIException e) { throw new RuntimeException("Couldn't access repo", e); } } @Override public void describeTo(final Description description) { description.appendText("a git repo with the tag " + tag); } }; }
public static Matcher<Git> hasCleanWorkingDirectory() { return new TypeSafeDiagnosingMatcher<Git>() { @Override protected boolean matchesSafely(final Git git, final Description mismatchDescription) { try { final Status status = git.status().call(); if (!status.isClean()) { final String start = "Uncommitted changes in "; final String end = " at " + git.getRepository().getWorkTree().getAbsolutePath(); mismatchDescription.appendValueList(start, ", ", end, status.getUncommittedChanges()); } return status.isClean(); } catch (final GitAPIException e) { throw new RuntimeException("Error checking git status", e); } } @Override public void describeTo(final Description description) { description.appendText("A git directory with no staged or unstaged changes"); } }; }
protected Matcher<CompilationResult> isSuccess() { return new TypeSafeDiagnosingMatcher<CompilationResult>() { @Override public void describeTo(final Description description) { description.appendText("Successful compilation"); } @Override protected boolean matchesSafely(final CompilationResult item, final Description mismatchDescription) { final boolean success = item.isSuccess(); if (!success) mismatchDescription.appendText(Joiner.on('\n').join(item.getErrors())); return success; } ; }; }
protected Matcher<CompilationResult> isFailureWithExpectedMessage(String message) { return new TypeSafeDiagnosingMatcher<CompilationResult>() { @Override public void describeTo(final Description description) { description.appendText("Compilation Failure"); } @Override protected boolean matchesSafely(final CompilationResult item, final Description mismatchDescription) { boolean falseSuccess = item.isSuccess(); final String errorMessagesAsBlock = Joiner.on('\n').join(item.getErrors()); if (!errorMessagesAsBlock.contains(message)) { falseSuccess = true; mismatchDescription.appendText("expected error message: ").appendText(message) .appendText(" but got "); } mismatchDescription.appendText(errorMessagesAsBlock); return !falseSuccess; } ; }; }
private static Matcher<? super ConfigurableEnvironment> containsPropertySource( final String sourceName) { return new TypeSafeDiagnosingMatcher<ConfigurableEnvironment>() { @Override public void describeTo(Description description) { description.appendText("environment containing property source ") .appendValue(sourceName); } @Override protected boolean matchesSafely(ConfigurableEnvironment item, Description mismatchDescription) { MutablePropertySources sources = new MutablePropertySources( item.getPropertySources()); ConfigurationPropertySources.finishAndRelocate(sources); mismatchDescription.appendText("Not matched against: ") .appendValue(sources); return sources.contains(sourceName); } }; }
private static Matcher<? super ConfigurableEnvironment> acceptsProfiles( final String... profiles) { return new TypeSafeDiagnosingMatcher<ConfigurableEnvironment>() { @Override public void describeTo(Description description) { description.appendText("environment accepting profiles ") .appendValue(profiles); } @Override protected boolean matchesSafely(ConfigurableEnvironment item, Description mismatchDescription) { mismatchDescription.appendText("Not matched against: ") .appendValue(item.getActiveProfiles()); return item.acceptsProfiles(profiles); } }; }
public static Matcher<Git> hasTag(final String tag) { return new TypeSafeDiagnosingMatcher<Git>() { @Override protected boolean matchesSafely(Git repo, Description mismatchDescription) { try { mismatchDescription.appendValueList("a git repo with tags: ", ", ", "", repo.getRepository().getTags().keySet()); return GitHelper.hasLocalTag(repo, tag); } catch (GitAPIException e) { throw new RuntimeException("Couldn't access repo", e); } } @Override public void describeTo(Description description) { description.appendText("a git repo with the tag " + tag); } }; }
public static Matcher<Git> hasCleanWorkingDirectory() { return new TypeSafeDiagnosingMatcher<Git>() { @Override protected boolean matchesSafely(Git git, Description mismatchDescription) { try { Status status = git.status().call(); if (!status.isClean()) { String start = "Uncommitted changes in "; String end = " at " + git.getRepository().getWorkTree().getAbsolutePath(); mismatchDescription.appendValueList(start, ", ", end, status.getUncommittedChanges()); } return status.isClean(); } catch (GitAPIException e) { throw new RuntimeException("Error checking git status", e); } } @Override public void describeTo(Description description) { description.appendText("A git directory with no staged or unstaged changes"); } }; }
@SafeVarargs public static <T> Matcher<T> allOf(Matcher<? super T>... matchers) { return new TypeSafeDiagnosingMatcher<T>() { @Override protected boolean matchesSafely(T item, Description mismatchDescription) { boolean matches = true; for (Matcher<? super T> matcher : matchers) { if (!matcher.matches(item)) { if (!matches) mismatchDescription.appendText(", "); matcher.describeMismatch(item, mismatchDescription); matches = false; } } return matches; } @Override public void describeTo(Description description) { description.appendList("(", " " + "and" + " ", ")", Arrays.asList(matchers)); } }; }
public static Matcher<Exception> hasCause(Matcher<? extends Throwable> causeMatcher) { return new TypeSafeDiagnosingMatcher<Exception>() { @Override public void describeTo(Description description) { description.appendText("cause should ").appendDescriptionOf(causeMatcher); } @Override protected boolean matchesSafely(Exception e, Description mismatchDescription) { Throwable cause = e.getCause(); boolean matches = causeMatcher.matches(cause); if (!matches) { mismatchDescription.appendValue(e).appendText(" had cause ").appendValue(cause); } return matches; } }; }
private static <T, U> Matcher<U> cast(Class<T> clazz, Matcher<? super T> downcastMatcher) { return new TypeSafeDiagnosingMatcher<U>() { @Override public void describeTo(Description description) { downcastMatcher.describeTo(description); } @Override protected boolean matchesSafely(Object item, Description mismatchDescription) { if (!clazz.isInstance(item)) { mismatchDescription.appendText("was a " + item.getClass().getSimpleName()); return false; } if (downcastMatcher.matches(item)) { return true; } else { downcastMatcher.describeMismatch(item, mismatchDescription); return false; } } }; }
/** * Match a value/property derived from an object. * * @param entityDescription a description of the object the matched value is derived from. * @param propertyDescription a description of the derived value. * @param property the function which resolves the derived value to match. * @param matcher the {@code Matcher} for the derived value. */ public static <I, O> Matcher<I> where(String entityDescription, String propertyDescription, Function<? super I, O> property, Matcher<? super O> matcher) { return new TypeSafeDiagnosingMatcher<I>() { @Override public void describeTo(Description description) { description.appendText(entityDescription).appendText(" with ").appendText(withPrefixedArticle(propertyDescription)) .appendText(" which ").appendDescriptionOf(matcher); } @Override protected boolean matchesSafely(I objectToMatch, Description mismatch) { O actual = property.apply(objectToMatch); boolean match = matcher.matches(actual); if (!match) { mismatch.appendText("had the ").appendText(propertyDescription).appendText(" ").appendValue(actual); } return match; } }; }
public static <T> Matcher<? super Collection<T>> hasSize(final int expectedSize) { return new TypeSafeDiagnosingMatcher<Collection<?>>() { @Override protected boolean matchesSafely(final Collection<?> actual, final Description mismatchDescription) { final int actualSize = actual.size(); if (actualSize == expectedSize) { return true; } else { mismatchDescription.appendText("size was ").appendValue(actualSize); return false; } } @Override public void describeTo(final Description description) { description.appendText("with size ").appendValue(expectedSize); } }; }
public static Matcher<? super CharSequence> empty() { return new TypeSafeDiagnosingMatcher<CharSequence>() { @Override protected boolean matchesSafely(final CharSequence item, final Description mismatchDescription) { if (item.length() == 0) { return true; } else { mismatchDescription.appendText("was ").appendValue(item); return false; } } @Override public void describeTo(final Description description) { description.appendText("empty string"); } }; }
public static Matcher<Violation> hasType(final String expectedType) { return new TypeSafeDiagnosingMatcher<Violation>() { @Override protected boolean matchesSafely(final Violation violation, final Description mismatchDescription) { final String actualType = violation.getViolationType(); if (!Objects.equals(actualType, expectedType)) { mismatchDescription.appendText("type was ").appendValue(actualType); return false; } else { return true; } } @Override public void describeTo(final Description description) { description.appendText("violation of type ").appendValue(expectedType); } }; }
/** * Creates a matcher that matches if the examined lambda does no accept {@code null} * in its input values. The examined lambda takes an array as only argument and is * expected to throw a {@link NullPointerException} if this array is {@code null} and * an {@link IllegalArgumentException} if the array contains {@code null}. * * @param <CONSUMED_TYPE> type of the elements of the array the examined lambda takes * as its argument. * @param testValues An array of valid values that can be passed to the examined * lambda without it throwing an exception. * @return A matcher, as described above. */ public static <CONSUMED_TYPE> Matcher<Consumer<CONSUMED_TYPE[]>> notAcceptingNull( final CONSUMED_TYPE[] testValues) { final NotAcceptingNullInListMatcher<CONSUMED_TYPE> listMatcher = THIZ.new NotAcceptingNullInListMatcher<>(Arrays.asList(testValues)); // hack to get an empty array of CONSUMED_TYPE without SurpressWarnings final CONSUMED_TYPE[] copyInstance = ArrayUtils.clone(testValues); ArrayUtils.removeElements(copyInstance, copyInstance); return new TypeSafeDiagnosingMatcher<Consumer<CONSUMED_TYPE[]>>() { @Override public void describeTo(final Description description) { listMatcher.describeTo(description); } @Override protected boolean matchesSafely(final Consumer<CONSUMED_TYPE[]> item, final Description mismatchDescription) { return listMatcher.matchesSafely((list) -> item.accept(list.toArray(copyInstance)), mismatchDescription); } }; }
private static Matcher<VariantEvaluation> isAssignedTo(final Gene gene) { return new TypeSafeDiagnosingMatcher<VariantEvaluation>() { @Override public void describeTo(final Description description) { description.appendText("variant with geneSymbol=").appendValue(gene.getGeneSymbol()); description.appendText(" geneId=").appendValue(gene.getEntrezGeneID()); } @Override protected boolean matchesSafely(final VariantEvaluation variantEvaluation, final Description mismatchDescription) { mismatchDescription.appendText("was variant with geneSymbol=").appendValue(variantEvaluation.getGeneSymbol()); mismatchDescription.appendText(" geneId=").appendValue(variantEvaluation.getGeneId()); return gene.getGeneId() == variantEvaluation.getGeneId() && gene.getGeneSymbol() .equals(variantEvaluation.getGeneSymbol()); } }; }
public static Matcher<Diagnostic<? extends JavaFileObject>> diagnosticMessage( final Matcher<String> matcher) { return new TypeSafeDiagnosingMatcher<Diagnostic<? extends JavaFileObject>>() { @Override public boolean matchesSafely( Diagnostic<? extends JavaFileObject> item, Description mismatchDescription) { if (!matcher.matches(item.getMessage(Locale.getDefault()))) { mismatchDescription .appendText("diagnostic message does not match ") .appendDescriptionOf(matcher); return false; } return true; } @Override public void describeTo(Description description) { description.appendText("a diagnostic with message ").appendDescriptionOf(matcher); } }; }
public static Matcher<Person> containsSiblings(final Person... siblings) { return new TypeSafeDiagnosingMatcher<Person>() { @Override public void describeTo(Description description) { description.appendText("Person should have siblings ").appendValue(siblings); } @Override protected boolean matchesSafely(Person person, Description mismatchDescription) { if (!person.getSiblings().containsAll(Arrays.asList(siblings))) { mismatchDescription.appendText("The person has size of siblings equal to ") .appendValue(person.getSiblings().size()) .appendText(" and the person has siblings ") .appendValue(person.getSiblings()); return false; } return true; } }; }
private static Matcher<WebElement> wrapMatcher(final String tagName) { return new TypeSafeDiagnosingMatcher<WebElement>() { @Override public void describeTo(Description description) { description.appendText("has tagname \"" + tagName + "\""); } @Override protected boolean matchesSafely(WebElement actualItem, Description mismatchDescription) { return matchAndDiagnose(isString(tagName), actualItem.getTagName(), mismatchDescription, "tagName "); } }; }
public static Matcher<JsonElement> withCharsLessOrEqualTo(final int value) { return new TypeSafeDiagnosingMatcher<JsonElement>() { @Override protected boolean matchesSafely(JsonElement item, Description mismatchDescription) { //we do not care for the properties if parent item is not String if (!item.isString()) return true; if (item.asString().length() > value) { mismatchDescription.appendText("String length more than maximum value: " + value); return false; } return true; } @Override public void describeTo(Description description) { description.appendText("String maximum length"); } }; }
public static Matcher<JsonElement> withCharsMoreOrEqualTo(final int value) { return new TypeSafeDiagnosingMatcher<JsonElement>() { @Override protected boolean matchesSafely(JsonElement item, Description mismatchDescription) { //we do not care for the properties if parent item is not String if (!item.isString()) return true; if (item.asString().length() < value) { mismatchDescription.appendText("String length less than minimum value: " + value); return false; } return true; } @Override public void describeTo(Description description) { description.appendText("String minimum length"); } }; }
public static Matcher<JsonElement> matchesPattern(final String value) { return new TypeSafeDiagnosingMatcher<JsonElement>() { @Override protected boolean matchesSafely(JsonElement item, Description mismatchDescription) { //we do not care for the properties if parent item is not String if (!item.isString()) return true; if (!Pattern.matches(value, item.asString())) { mismatchDescription.appendText("Pattern '" + value + "' does not match '" + item.asString() + "'"); return false; } return true; } @Override public void describeTo(Description description) { description.appendText("Pattern match"); } }; }
public static Matcher<JsonElement> isLessThan(final double value) { return new TypeSafeDiagnosingMatcher<JsonElement>() { @Override protected boolean matchesSafely(JsonElement item, Description mismatchDescription) { //we do not care for the properties if parent item is not Number if (!item.isNumber()) return true; if (!(item.asDouble() < value)) { mismatchDescription.appendText("value is not less than exclusive maximum " + value); return false; } return true; } @Override public void describeTo(Description description) { description.appendText("exclusive maximum"); } }; }
public static Matcher<JsonElement> isLessOrEqualThan(final double value) { return new TypeSafeDiagnosingMatcher<JsonElement>() { @Override protected boolean matchesSafely(JsonElement item, Description mismatchDescription) { //we do not care for the properties if parent item is not Number if (!item.isNumber()) return true; if (!(item.asDouble() <= value)) { mismatchDescription.appendText("value is not less than maximum " + value); return false; } return true; } @Override public void describeTo(Description description) { description.appendText("maximum"); } }; }
public static Matcher<JsonElement> isMoreThan(final double value) { return new TypeSafeDiagnosingMatcher<JsonElement>() { @Override protected boolean matchesSafely(JsonElement item, Description mismatchDescription) { //we do not care for the properties if parent item is not Number if (!item.isNumber()) return true; if (!(item.asDouble() > value)) { mismatchDescription.appendText("value is not more than exclusive minimum " + value); return false; } return true; } @Override public void describeTo(Description description) { description.appendText("exclusive minimum"); } }; }
public static Matcher<JsonElement> isMoreOrEqualThan(final double value) { return new TypeSafeDiagnosingMatcher<JsonElement>() { @Override protected boolean matchesSafely(JsonElement item, Description mismatchDescription) { //we do not care for the properties if parent item is not Number if (!item.isNumber()) return true; if (!(item.asDouble() >= value)) { mismatchDescription.appendText("value is not more than minimum " + value); return false; } return true; } @Override public void describeTo(Description description) { description.appendText("minimum"); } }; }
public static Matcher<JsonElement> isMultipleOf(final double value) { return new TypeSafeDiagnosingMatcher<JsonElement>() { @Override protected boolean matchesSafely(JsonElement item, Description mismatchDescription) { //we do not care for the properties if parent item is not Number if (!item.isNumber()) return true; Number remainder = item.asDouble() % value; if (!remainder.equals(0) && !remainder.equals(0.0)) { mismatchDescription.appendText("value is not multipleOf " + value); return false; } return true; } @Override public void describeTo(Description description) { description.appendText("multipleOf"); } }; }
public static Matcher<JsonElement> isOfType(final String type) { return new TypeSafeDiagnosingMatcher<JsonElement>() { @Override protected boolean matchesSafely(JsonElement item, Description mismatchDescription) { if (type.equals(item.getJsonType())) return true; else { mismatchDescription.appendText(", mismatch type '" + item.getJsonType() + "'"); return false; } } @Override public void describeTo(Description description) { description.appendText("\nMatch to type: " + type); } }; }
public static Matcher<JsonElement> isOfType(final List<String> types) { return new TypeSafeDiagnosingMatcher<JsonElement>() { @Override protected boolean matchesSafely(JsonElement item, Description mismatchDescription) { if (types.contains(item.getJsonType()) || (item.getJsonType().equals(TYPE_INTEGER) && types.contains(TYPE_NUMBER))) return true; else { mismatchDescription.appendText(", mismatch type '" + item.getJsonType() + "'"); return false; } } @Override public void describeTo(Description description) { description.appendText("\nMatch to one of types: " + types.toString()); } }; }
public static Matcher<JsonElement> isInEnums(final JsonArray enums) { return new TypeSafeDiagnosingMatcher<JsonElement>() { @Override protected boolean matchesSafely(JsonElement item, Description mismatchDescription) { if (enums.contains(item)) { return true; } mismatchDescription.appendText(", mismatch value '" + item.toString() + "'"); return false; } @Override public void describeTo(Description description) { description.appendText("\nMatch to one of enum values: " + enums.toString()); } }; }
public static Matcher<JsonElement> areItemsValid(final Validator validator) { return new TypeSafeDiagnosingMatcher<JsonElement>() { @Override protected boolean matchesSafely(JsonElement item, Description mismatchDescription) { //we do not care for the properties if parent item is not JsonArray if (!item.isJsonArray()) return true; for (int i = 0; i < item.asJsonArray().length(); i++) { StringBuilder sb = new StringBuilder(); if (!validator.validate(item.asJsonArray().opt(i), sb)) { mismatchDescription.appendText("item at pos: " + i + ", does not validate by validator " + validator.getTitle()) .appendText("\nDetails: ") .appendText(sb.toString()); return false; } } return true; } @Override public void describeTo(Description description) { description.appendText("are array items valid"); } }; }
public static Matcher<JsonElement> doesItemCountMatches(final int itemsCount) { return new TypeSafeDiagnosingMatcher<JsonElement>() { @Override protected boolean matchesSafely(JsonElement item, Description mismatchDescription) { //we do not care for the properties if parent item is not JsonArray if (!item.isJsonArray()) return true; if (item.asJsonArray().length() > itemsCount) { mismatchDescription.appendText("items in Json array more than defined"); return false; } return true; } @Override public void describeTo(Description description) { description.appendText("array items max count"); } }; }
public static Matcher<JsonElement> areItemsUnique() { return new TypeSafeDiagnosingMatcher<JsonElement>() { @Override protected boolean matchesSafely(JsonElement item, Description mismatchDescription) { //we do not care for the items if parent item is not JsonArray if (!item.isJsonArray()) return true; JsonElement prevEl = null; for (JsonElement el : item.asJsonArray()) { if (prevEl != null && el.equals(prevEl)) { mismatchDescription.appendText("items in Json array are not unique"); return false; } prevEl = el; } return true; } @Override public void describeTo(Description description) { description.appendText("unique items"); } }; }
public static Matcher<JsonElement> isPropertyPresent(final String property) { return new TypeSafeDiagnosingMatcher<JsonElement>() { @Override protected boolean matchesSafely(JsonElement item, Description mismatchDescription) { //we do not care for the properties if parent item is not JsonObject if (!item.isJsonObject()) return true; if (!item.asJsonObject().has(property)) { mismatchDescription.appendText(", does not exist in : " + item); return false; } return true; } @Override public void describeTo(Description description) { description.appendText("\nCheck if property '" + property + "' exists"); } }; }
public static Matcher<JsonElement> isPropertyValid(final Validator validator, final String property) { return new TypeSafeDiagnosingMatcher<JsonElement>() { @Override protected boolean matchesSafely(JsonElement item, Description mismatchDescription) { //we do not care for the properties if parent item is not JsonObject if (!item.isJsonObject()) return true; //we also dont care if the property is not actually there //if it is needed it will be handled by the "required" constraint on another matcher if (!item.asJsonObject().has(property)) return true; StringBuilder sb = new StringBuilder(); if (!validator.validate(item.asJsonObject().opt(property), sb)) { mismatchDescription.appendText(", mismatch value: " + item.asJsonObject().opt(property)) .appendText("\nDetails: ") .appendText(sb.toString()); return false; } return true; } @Override public void describeTo(Description description) { description.appendText("\nMatch object property '" + property + "' with schema: " + ((SchemaValidator) validator).getSchema()); } }; }