unruly / java-8-matchers

Hamcrest Matchers for Java 8 features
MIT License
23 stars 5 forks source link

Switch OptionalMatchers to be TypeSafeDiagnosingMatcher #7

Open CliveEvans opened 8 years ago

CliveEvans commented 8 years ago

We're relying on the toString to give meaningful errors, which works ok while the thing that's being wrapped has a nice toString implementation, but fails horribly when it doesn't, even if the matcher being passed in returns a nice message ...

    int[] wanted = { 1, 2, 3};
    int[] got = {2,3,4};

    @Test
    public void shouldBeDiagnosing() throws Exception {
        StringDescription mismatchDescription = new StringDescription();
        arrayMatcher(wanted).describeMismatch(got, mismatchDescription);
        assertThat(mismatchDescription.toString(), is("[<2>, <3>, <4>]"));
    }

    @Test
    public void optionalMatchersShouldAlsoBeSelfDiagnosing() throws Exception {
        StringDescription mismatchDescription = new StringDescription();
        OptionalMatchers.contains(arrayMatcher(wanted)).describeMismatch(Optional.of(got), mismatchDescription);
        assertThat(mismatchDescription.toString(), is("an Optional with an item [<2>, <3>, <4>]"));
    }

    private TypeSafeDiagnosingMatcher<int[]> arrayMatcher(int ... expected) {
        return new TypeSafeDiagnosingMatcher<int[]>() {

            @Override
            public void describeTo(Description description) {
                description
                        .appendText("an int array equal to ")
                        .appendValue(expected);
            }

            @Override
            protected boolean matchesSafely(int[] item, Description mismatchDescription) {
                boolean matches = Arrays.equals(expected, item);
                if(!matches) {
                    mismatchDescription.appendValue(item);
                }
                return matches;
            }
        };

    }
bruceeddy commented 8 years ago

This is a good suggestion. I've started making the change, and will finish it when I get a break from my busy life.

CliveEvans commented 8 years ago

I started work on it and got a little hung up trying to make the output look nice. It turns out describing matchers don't really generate language that neatly strings together and I stalled trying to be too much of a perfectionist.