package TestUtil;

import org.hamcrest.BaseMatcher;
import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.junit.Assert;

public class TestUtil {
    public static void assertThrows(CheckedFunction fn, Class<? extends Exception> exceptionType, Matcher<Exception>
            exceptionMatcher) throws Exception {
        try {
            fn.apply();
            Assert.fail();
        } catch (Exception maybeExpected) {
            if (!exceptionType.isInstance(maybeExpected)) {
                throw maybeExpected;
            }
            Assert.assertThat(maybeExpected, exceptionMatcher);
        }
    }

    public static Matcher<Exception> exceptionMessageMatches(String pattern) {
        return new BaseMatcher<Exception>() {
            @Override
            public void describeTo(Description description) {
                description.appendText("Should match pattern " + pattern);
            }

            @Override
            public boolean
            matches(Object item) {
                return ((Exception) item).getMessage().matches(pattern);
            }
        };
    }

    @FunctionalInterface
    public interface CheckedFunction {
        void apply() throws Exception;
    }

    private TestUtil() {}
}

@@ -157,16 +157,485 @@
 tUtil %7B%0A
+    private static final Matcher%3CException%3E ANY_MATCHER = new BaseMatcher%3CException%3E() %7B%0A        @Override%0A        public void describeTo(Description description) %7B%0A        %7D%0A%0A        @Override%0A        public boolean%0A        matches(Object item) %7B%0A            return true;%0A        %7D%0A    %7D;%0A%0A    public static void assertThrows(CheckedFunction fn, Class%3C? extends Exception%3E exceptionType) throws Exception %7B%0A        assertThrows(fn, exceptionType, ANY_MATCHER);%0A    %7D%0A%0A
     publ
@@ -1715,12 +1715,17 @@
 Util() %7B
+%0A    
 %7D%0A%7D%0A

add an assertion that doesn't care about message