Skip to content

Commit

Permalink
Optional matchers
Browse files Browse the repository at this point in the history
  • Loading branch information
seregamorph committed Aug 27, 2024
1 parent 6bb90de commit 25d7501
Show file tree
Hide file tree
Showing 5 changed files with 196 additions and 0 deletions.
25 changes: 25 additions & 0 deletions hamcrest/src/main/java/org/hamcrest/optional/OptionalEmpty.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package org.hamcrest.optional;

import org.hamcrest.Description;
import org.hamcrest.TypeSafeDiagnosingMatcher;

import java.util.Optional;

/**
* Matcher that expects empty {@link Optional}.
* @param <T>
*/
public class OptionalEmpty<T> extends TypeSafeDiagnosingMatcher<Optional<T>> {

@Override
protected boolean matchesSafely(Optional<T> value, Description mismatchDescription) {
mismatchDescription.appendText("is " + value);
return !value.isPresent();
}

@Override
public void describeTo(Description description) {
description.appendText("empty");
}
}
37 changes: 37 additions & 0 deletions hamcrest/src/main/java/org/hamcrest/optional/OptionalMatchers.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package org.hamcrest.optional;

import org.hamcrest.Matcher;

import java.util.Optional;

/**
* Matchers for {@link Optional}.
*/
public class OptionalMatchers {

/**
* Matcher for {@link Optional} that expects that value is present.
*/
public static <T> Matcher<Optional<T>> optionalWithValue() {
return new OptionalWithValue<>();
}

/**
* Matcher for {@link Optional} that expects that it presents and applies passed <code>matcher</code>
*
* @param matcher matcher to validate present optional value
*/
public static <T> Matcher<Optional<T>> optionalWithValue(Matcher<T> matcher) {
return new OptionalWithMatchingValue<>(matcher);
}

/**
* Matcher that expects empty optional.
*/
public static <T> Matcher<Optional<T>> emptyOptional() {
return new OptionalEmpty<>();
}

private OptionalMatchers() {
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package org.hamcrest.optional;

import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.hamcrest.TypeSafeDiagnosingMatcher;

import java.util.Optional;

/**
* Matcher for {@link Optional} that expects that value is present and matches the given matcher.
*
* @param <T>
*/
public class OptionalWithMatchingValue<T> extends TypeSafeDiagnosingMatcher<Optional<T>> {

private final Matcher<T> matcher;

public OptionalWithMatchingValue(Matcher<T> matcher) {
this.matcher = matcher;
}

@Override
protected boolean matchesSafely(Optional<T> value, Description mismatchDescription) {
mismatchDescription.appendText("is " + value);
return value.isPresent() && matcher.matches(value.get());
}

@Override
public void describeTo(Description description) {
description.appendText("present and matches ")
.appendDescriptionOf(matcher);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package org.hamcrest.optional;

import org.hamcrest.Description;
import org.hamcrest.TypeSafeDiagnosingMatcher;

import java.util.Optional;

/**
* Matcher for {@link Optional} that expects that value is present.
*
* @param <T>
*/
public class OptionalWithValue<T> extends TypeSafeDiagnosingMatcher<Optional<T>> {

@Override
protected boolean matchesSafely(Optional<T> value, Description mismatchDescription) {
mismatchDescription.appendText("is " + value);
return value.isPresent();
}

@Override
public void describeTo(Description description) {
description.appendText("present");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package org.hamcrest.optional;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.optional.OptionalMatchers.emptyOptional;
import static org.hamcrest.optional.OptionalMatchers.optionalWithValue;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThrows;

import java.util.Optional;

import org.junit.Test;

public class OptionalMatchersTest {

@Test
public void checkEmptyOptional() {
assertThat(Optional.empty(), is(emptyOptional()));
assertThat(Optional.of(1), not(emptyOptional()));
}

@Test
public void checkEmptyOptionalIsFailure() {
AssertionError failure = assertThrows(AssertionError.class, () -> {
assertThat(Optional.of(1), is(emptyOptional()));
});
assertEquals("\n" +
"Expected: is empty\n" +
" but: is Optional[1]", failure.getMessage());
}

@Test
public void checkEmptyOptionalFailure() {
AssertionError failure = assertThrows(AssertionError.class, () -> {
assertThat(Optional.of(1), emptyOptional());
});
assertEquals("\n" +
"Expected: empty\n" +
" but: is Optional[1]", failure.getMessage());
}

@Test
public void checkWithValue() {
assertThat(Optional.empty(), not(optionalWithValue()));
assertThat(Optional.of(1), is(optionalWithValue()));
}

@Test
public void checkWithMatchingValue() {
assertThat(Optional.empty(), not(optionalWithValue(equalTo(1))));
assertThat(Optional.of(1), is(optionalWithValue(equalTo(1))));
assertThat(Optional.of(1), not(optionalWithValue(equalTo(1L))));
}

@Test
public void checkWithValueFailure() {
AssertionError failure = assertThrows(AssertionError.class, () -> {
assertThat(Optional.empty(), is(optionalWithValue()));
});
assertEquals("\n" +
"Expected: is present\n" +
" but: is Optional.empty", failure.getMessage());
}

@Test
public void checkWithMatchingValueFailure() {
AssertionError failure = assertThrows(AssertionError.class, () -> {
assertThat(Optional.empty(), is(optionalWithValue(equalTo(1))));
});
assertEquals("\n" +
"Expected: is present and matches <1>\n" +
" but: is Optional.empty", failure.getMessage());
}
}

0 comments on commit 25d7501

Please sign in to comment.