Skip to content

Commit 2419f48

Browse files
committed
Merge pull request hamcrest#4 from hochraldo/BigDecimal_CloseTo_Matcher
added closeTo matcher for BigDecimal and the corresponding unit tests. This addresses issue 177 (on the googlecode issue tracker).
2 parents 26eadba + 5aa359b commit 2419f48

File tree

2 files changed

+108
-0
lines changed

2 files changed

+108
-0
lines changed
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
package org.hamcrest.number;
2+
3+
import java.math.BigDecimal;
4+
import java.math.MathContext;
5+
6+
import org.hamcrest.Description;
7+
import org.hamcrest.Factory;
8+
import org.hamcrest.Matcher;
9+
import org.hamcrest.TypeSafeMatcher;
10+
11+
public class BigDecimalCloseTo extends TypeSafeMatcher<BigDecimal> {
12+
13+
private final BigDecimal delta;
14+
private final BigDecimal value;
15+
16+
public BigDecimalCloseTo(BigDecimal value, BigDecimal error) {
17+
this.delta = error;
18+
this.value = value;
19+
}
20+
21+
@Override
22+
public boolean matchesSafely(BigDecimal item) {
23+
return actualDelta(item).compareTo(BigDecimal.ZERO) <= 0;
24+
}
25+
26+
@Override
27+
public void describeMismatchSafely(BigDecimal item, Description mismatchDescription) {
28+
mismatchDescription.appendValue(item)
29+
.appendText(" differed by ")
30+
.appendValue(actualDelta(item));
31+
}
32+
33+
@Override
34+
public void describeTo(Description description) {
35+
description.appendText("a numeric value within ")
36+
.appendValue(delta)
37+
.appendText(" of ")
38+
.appendValue(value);
39+
}
40+
41+
private BigDecimal actualDelta(BigDecimal item) {
42+
return item.subtract(value, MathContext.DECIMAL128).abs().subtract(delta, MathContext.DECIMAL128).stripTrailingZeros();
43+
}
44+
45+
/**
46+
* Creates a matcher of {@link BigDecimal}s that matches when an examined BigDecimal is equal
47+
* to the specified <code>operand</code>, within a range of +/- <code>error</code>. The comparison for equality
48+
* is done by BigDecimals {@link BigDecimal#compareTo(BigDecimal))} method.
49+
* <p/>
50+
* For example:
51+
* <pre>assertThat(new BigDecimal("1.03"), is(closeTo(new BigDecimal("1.0"), new BigDecimal("0.03"))))</pre>
52+
*
53+
* @param operand
54+
* the expected value of matching BigDecimals
55+
* @param error
56+
* the delta (+/-) within which matches will be allowed
57+
*/
58+
@Factory
59+
public static Matcher<BigDecimal> closeTo(BigDecimal operand, BigDecimal error) {
60+
return new BigDecimalCloseTo(operand, error);
61+
}
62+
63+
}
64+
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package org.hamcrest.number;
2+
3+
import static org.hamcrest.number.BigDecimalCloseTo.closeTo;
4+
5+
import java.math.BigDecimal;
6+
7+
import org.hamcrest.AbstractMatcherTest;
8+
import org.hamcrest.Matcher;
9+
10+
public class BigDecimalCloseToTest extends AbstractMatcherTest {
11+
12+
@Override
13+
protected Matcher<?> createMatcher() {
14+
BigDecimal irrelevant = new BigDecimal("0.01");
15+
return closeTo(irrelevant, irrelevant);
16+
}
17+
18+
public void testEvaluatesToTrueIfArgumentIsEqualToABigDecimalWithinSomeError() {
19+
Matcher<BigDecimal> p = closeTo(new BigDecimal("1.0"), new BigDecimal("0.5"));
20+
21+
assertTrue(p.matches(new BigDecimal("1.0")));
22+
assertTrue(p.matches(new BigDecimal("0.5")));
23+
assertTrue(p.matches(new BigDecimal("1.5")));
24+
25+
assertDoesNotMatch("too large", p, new BigDecimal("2.0"));
26+
assertMismatchDescription("<2.0> differed by <0.5>", p, new BigDecimal("2.0"));
27+
assertDoesNotMatch("number too small", p, new BigDecimal("0.0"));
28+
assertMismatchDescription("<0.0> differed by <0.5>", p, new BigDecimal("0.0"));
29+
}
30+
31+
public void testEvaluatesToTrueIfArgumentHasDifferentScale() {
32+
Matcher<BigDecimal> p = closeTo(new BigDecimal("1.0"), new BigDecimal("0.5"));
33+
34+
assertTrue(p.matches(new BigDecimal("1.000000")));
35+
assertTrue(p.matches(new BigDecimal("0.500000")));
36+
assertTrue(p.matches(new BigDecimal("1.500000")));
37+
38+
assertDoesNotMatch("too large", p, new BigDecimal("2.000000"));
39+
assertMismatchDescription("<2.000000> differed by <0.5>", p, new BigDecimal("2.000000"));
40+
assertDoesNotMatch("number too small", p, new BigDecimal("0.000000"));
41+
assertMismatchDescription("<0.000000> differed by <0.5>", p, new BigDecimal("0.000000"));
42+
}
43+
44+
}

0 commit comments

Comments
 (0)