From 97e8b93617439a22d83129edc072375fcc4a0335 Mon Sep 17 00:00:00 2001 From: Alberto Scotto Date: Sun, 19 Apr 2020 02:08:09 +0200 Subject: [PATCH] Fix FeatureMacther: featureValueOf may throw Right now, that may happen in: - HasToString, if the actual object has a custom toString method which may throw - FileMatchers.aFileWithCanonicalPath and siblings --- .../java/org/hamcrest/FeatureMatcher.java | 18 ++++++++++++------ .../java/org/hamcrest/io/FileMatchers.java | 8 ++------ .../java/org/hamcrest/FeatureMatcherTest.java | 19 +++++++++++++++++++ 3 files changed, 33 insertions(+), 12 deletions(-) diff --git a/hamcrest/src/main/java/org/hamcrest/FeatureMatcher.java b/hamcrest/src/main/java/org/hamcrest/FeatureMatcher.java index 385cf999..6bad17d2 100644 --- a/hamcrest/src/main/java/org/hamcrest/FeatureMatcher.java +++ b/hamcrest/src/main/java/org/hamcrest/FeatureMatcher.java @@ -33,17 +33,23 @@ public FeatureMatcher(Matcher subMatcher, String featureDescription, * @param actual the target object * @return the feature to be matched */ - protected abstract U featureValueOf(T actual); + protected abstract U featureValueOf(T actual) throws Exception; @Override protected boolean matchesSafely(T actual, Description mismatch) { - final U featureValue = featureValueOf(actual); - if (!subMatcher.matches(featureValue)) { - mismatch.appendText(featureName).appendText(" "); - subMatcher.describeMismatch(featureValue, mismatch); + try { + final U featureValue = featureValueOf(actual); + if (!subMatcher.matches(featureValue)) { + mismatch.appendText(featureName).appendText(" "); + subMatcher.describeMismatch(featureValue, mismatch); + return false; + } + return true; + } catch (Exception e) { // catches exceptions thrown by featureValueOf(), if any + mismatch.appendText("an exception was thrown: "); + mismatch.appendText(e.toString()); //TODO + stacktrace (?) return false; } - return true; } @Override diff --git a/hamcrest/src/main/java/org/hamcrest/io/FileMatchers.java b/hamcrest/src/main/java/org/hamcrest/io/FileMatchers.java index 0b76fb14..9ea93574 100644 --- a/hamcrest/src/main/java/org/hamcrest/io/FileMatchers.java +++ b/hamcrest/src/main/java/org/hamcrest/io/FileMatchers.java @@ -50,12 +50,8 @@ public static Matcher aFileNamed(final Matcher expected) { public static Matcher aFileWithCanonicalPath(final Matcher expected) { return new FeatureMatcher(expected, "A file with canonical path", "path") { - @Override protected String featureValueOf(File actual) { - try { - return actual.getCanonicalPath(); - } catch (IOException e) { - return "Exception: " + e.getMessage(); - } + @Override protected String featureValueOf(File actual) throws IOException { + return actual.getCanonicalPath(); } }; } diff --git a/hamcrest/src/test/java/org/hamcrest/FeatureMatcherTest.java b/hamcrest/src/test/java/org/hamcrest/FeatureMatcherTest.java index 8d864eb8..e0209627 100644 --- a/hamcrest/src/test/java/org/hamcrest/FeatureMatcherTest.java +++ b/hamcrest/src/test/java/org/hamcrest/FeatureMatcherTest.java @@ -33,6 +33,14 @@ public final class FeatureMatcherTest { assertEquals("was ShouldNotMatch ", mismatchDescription.toString()); } + @Test public void + canRecoverFromFaultyFeature() { + assertMismatchDescription( + "an exception was thrown: java.lang.UnsupportedOperationException: make the feature fail!", + resultMatcher, new FaultyThingy()); + } + + public static class Match extends IsEqual { public Match(String equalArg) { super(equalArg); } @Override public void describeMismatch(Object item, Description description) { @@ -52,6 +60,17 @@ public String getResult() { } } + public static class FaultyThingy extends Thingy { + public FaultyThingy() { + super("thingy with failing feature"); + } + + @Override + public String getResult() { + throw new UnsupportedOperationException("make the feature fail!"); + } + } + public static class ShouldNotMatch { @Override public String toString() { return "ShouldNotMatch"; } }