From 68f9a814e3c88d5b1c9c01326b814e04074a26bd Mon Sep 17 00:00:00 2001 From: Soonil Nagarkar Date: Mon, 20 May 2019 14:05:40 -0700 Subject: [PATCH 1/3] Update IsCloseTo to support Number(s) --- .../java/org/hamcrest/number/IsCloseTo.java | 48 ++++++++----------- 1 file changed, 21 insertions(+), 27 deletions(-) diff --git a/hamcrest/src/main/java/org/hamcrest/number/IsCloseTo.java b/hamcrest/src/main/java/org/hamcrest/number/IsCloseTo.java index 3b6967dc..b8bcda81 100644 --- a/hamcrest/src/main/java/org/hamcrest/number/IsCloseTo.java +++ b/hamcrest/src/main/java/org/hamcrest/number/IsCloseTo.java @@ -4,60 +4,54 @@ import org.hamcrest.Matcher; import org.hamcrest.TypeSafeMatcher; -import static java.lang.Math.abs; - - /** - * Is the value a number equal to a value within some range of - * acceptable error? + * Is the value a number equal to a value within some range of acceptable error? */ -public class IsCloseTo extends TypeSafeMatcher { - private final double delta; - private final double value; +public class IsCloseTo extends TypeSafeMatcher { + private final double error; + private final double expected; - public IsCloseTo(double value, double error) { - this.delta = error; - this.value = value; + public IsCloseTo(double expected, double error) { + this.error = Math.abs(error); + this.expected = expected; } @Override - public boolean matchesSafely(Double item) { - return actualDelta(item) <= 0.0; + public boolean matchesSafely(Number actual) { + return calcError(actual) <= error; } @Override - public void describeMismatchSafely(Double item, Description mismatchDescription) { + public void describeMismatchSafely(Number item, Description mismatchDescription) { mismatchDescription.appendValue(item) .appendText(" differed by ") - .appendValue(actualDelta(item)) - .appendText(" more than delta ") - .appendValue(delta); + .appendValue(calcError(item)); } @Override public void describeTo(Description description) { description.appendText("a numeric value within ") - .appendValue(delta) + .appendValue(error) .appendText(" of ") - .appendValue(value); + .appendValue(expected); } - private double actualDelta(Double item) { - return abs(item - value) - delta; + private double calcError(Number actual) { + return Math.abs(expected - actual.doubleValue()); } /** - * Creates a matcher of {@link Double}s that matches when an examined double is equal + * Creates a matcher of {@link Number}s that matches when an examined number is equal * to the specified operand, within a range of +/- error. * For example: *
assertThat(1.03, is(closeTo(1.0, 0.03)))
* - * @param operand - * the expected value of matching doubles + * @param expected + * the expected value of matching numbers * @param error - * the delta (+/-) within which matches will be allowed + * the absolute error (+/-) within which matches will be allowed */ - public static Matcher closeTo(double operand, double error) { - return new IsCloseTo(operand, error); + public static Matcher closeTo(double expected, double error) { + return new IsCloseTo(expected, error); } } From 1ed5ca20e95759c9434a8c3d9581fe90448e0ff6 Mon Sep 17 00:00:00 2001 From: Soonil Nagarkar Date: Mon, 20 May 2019 14:18:56 -0700 Subject: [PATCH 2/3] Add IsRelativelyCloseTo implementation --- .../hamcrest/number/IsRelativelyCloseTo.java | 67 +++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 hamcrest/src/main/java/org/hamcrest/number/IsRelativelyCloseTo.java diff --git a/hamcrest/src/main/java/org/hamcrest/number/IsRelativelyCloseTo.java b/hamcrest/src/main/java/org/hamcrest/number/IsRelativelyCloseTo.java new file mode 100644 index 00000000..1cafc721 --- /dev/null +++ b/hamcrest/src/main/java/org/hamcrest/number/IsRelativelyCloseTo.java @@ -0,0 +1,67 @@ +package org.hamcrest.number; + +import org.hamcrest.Description; +import org.hamcrest.Matcher; +import org.hamcrest.TypeSafeMatcher; + +/** + * Is the value a number equal to a value within some range of acceptable error? + */ +public class IsRelativelyCloseTo extends TypeSafeMatcher { + private final double relativeError; + private final double expected; + + public IsRelativelyCloseTo(double expected, double relativeError) { + if (expected == 0) { + throw new IllegalArgumentException("relative error is undefined with an expected value of zero"); + } + + this.relativeError = Math.abs(relativeError); + this.expected = expected; + } + + @Override + public boolean matchesSafely(Number actual) { + return calcRelativeError(actual) <= relativeError; + } + + @Override + public void describeMismatchSafely(Number item, Description mismatchDescription) { + mismatchDescription.appendValue(item) + .appendText(" differed by ") + .appendValue(calcAbsoluteError(item)); + } + + @Override + public void describeTo(Description description) { + description.appendText("a numeric value within ") + .appendValue(expected * relativeError) + .appendText(" of ") + .appendValue(expected); + } + + private double calcRelativeError(Number actual) { + return Math.abs(calcAbsoluteError(actual) / expected)); + } + + private double calcAbsoluteError(Number actual) { + return Math.abs(expected - actual.doubleValue()); + } + + /** + * Creates a matcher of {@link Number}s that matches when an examined number is equal + * to the specified operand, within a range of +/- relative error. + * The expected number must be measured on a + * ratio scale. + * For example: + *
assertThat(103.0, is(closeTo(100.0, 0.03)))
+ * + * @param expected + * the expected value of matching numbers, which may not be zero + * @param relativeError + * the relative error (+/-) within which matches will be allowed + */ + public static Matcher relativelyCloseTo(double expected, double relativeError) { + return new IsRelativelyCloseTo(expected, relativeError); + } +} From 713ca6ce555fb62a931848b3dbabb32d99a4c6fd Mon Sep 17 00:00:00 2001 From: Soonil Nagarkar Date: Mon, 20 May 2019 14:29:38 -0700 Subject: [PATCH 3/3] Fix build error --- .../src/main/java/org/hamcrest/number/IsRelativelyCloseTo.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hamcrest/src/main/java/org/hamcrest/number/IsRelativelyCloseTo.java b/hamcrest/src/main/java/org/hamcrest/number/IsRelativelyCloseTo.java index 1cafc721..d1fe2491 100644 --- a/hamcrest/src/main/java/org/hamcrest/number/IsRelativelyCloseTo.java +++ b/hamcrest/src/main/java/org/hamcrest/number/IsRelativelyCloseTo.java @@ -41,7 +41,7 @@ public void describeTo(Description description) { } private double calcRelativeError(Number actual) { - return Math.abs(calcAbsoluteError(actual) / expected)); + return Math.abs(calcAbsoluteError(actual) / expected); } private double calcAbsoluteError(Number actual) {