Skip to content

Commit

Permalink
Fix bugs in Numbers#assertIsCloseToPercentage, #assertIsNotCloseToPer…
Browse files Browse the repository at this point in the history
…centage and #assertIsNotCloseTo related to Float/Double#NaN, #POSITIVE_INFINITY and #NEGATIVE_INFINITY (#984)
  • Loading branch information
PascalSchumacher authored and joel-costigliola committed May 13, 2017
1 parent e36a667 commit 59fc365
Show file tree
Hide file tree
Showing 31 changed files with 405 additions and 80 deletions.
22 changes: 14 additions & 8 deletions src/main/java/org/assertj/core/internal/Numbers.java
Expand Up @@ -14,8 +14,8 @@

import static java.lang.Math.abs;
import static org.assertj.core.error.ShouldBeEqualWithinOffset.shouldBeEqual;
import static org.assertj.core.error.ShouldNotBeEqualWithinOffset.shouldNotBeEqual;
import static org.assertj.core.error.ShouldBeEqualWithinPercentage.shouldBeEqualWithinPercentage;
import static org.assertj.core.error.ShouldNotBeEqualWithinOffset.shouldNotBeEqual;
import static org.assertj.core.error.ShouldNotBeEqualWithinPercentage.shouldNotBeEqualWithinPercentage;
import static org.assertj.core.internal.CommonValidations.checkNumberIsNotNull;
import static org.assertj.core.internal.CommonValidations.checkOffsetIsNotNull;
Expand Down Expand Up @@ -173,11 +173,11 @@ public void assertIsStrictlyBetween(AssertionInfo info, NUMBER actual, NUMBER st
* @param offset the given positive offset.
*/
public void assertIsCloseTo(final AssertionInfo info, final NUMBER actual, final NUMBER expected,
final Offset<NUMBER> offset) {
final Offset<NUMBER> offset) {
assertNotNull(info, actual);
checkOffsetIsNotNull(offset);
checkNumberIsNotNull(expected);

if (Objects.areEqual(actual, expected)) return; // handles correctly NaN comparison
if (isGreaterThan(absDiff(actual, expected), offset.value))
throw failures.failure(info, shouldBeEqual(actual, expected, offset, absDiff(actual, expected)));
Expand All @@ -197,7 +197,7 @@ public void assertIsNotCloseTo(final AssertionInfo info, final NUMBER actual, fi
checkNumberIsNotNull(expected);

NUMBER diff = absDiff(actual, expected);
if (!isGreaterThan(diff, offset.value))
if (!isGreaterThan(diff, offset.value) || Objects.areEqual(actual, expected))
throw failures.failure(info, shouldNotBeEqual(actual, expected, offset, diff));
}

Expand All @@ -214,8 +214,11 @@ public void assertIsCloseToPercentage(final AssertionInfo info, final NUMBER act
assertNotNull(info, actual);
checkPercentageIsNotNull(percentage);
checkNumberIsNotNull(other);

if (Objects.areEqual(actual, other)) return;
double acceptableDiff = abs(percentage.value * other.doubleValue() / 100d);
if (absDiff(actual, other).doubleValue() > acceptableDiff)
double actualDiff = absDiff(actual, other).doubleValue();
if (actualDiff > acceptableDiff || Double.isNaN(actualDiff) || Double.isInfinite(actualDiff))
throw failures.failure(info, shouldBeEqualWithinPercentage(actual, other, percentage, absDiff(actual, other)));
}

Expand All @@ -232,13 +235,16 @@ public void assertIsNotCloseToPercentage(final AssertionInfo info, final NUMBER
assertNotNull(info, actual);
checkPercentageIsNotNull(percentage);
checkNumberIsNotNull(other);

double diff = abs(percentage.value * other.doubleValue() / 100d);
if (absDiff(actual, other).doubleValue() <= diff)
boolean areEqual = Objects.areEqual(actual, other);
if (!areEqual && Double.isInfinite(diff)) return;
if (absDiff(actual, other).doubleValue() <= diff || areEqual)
throw failures.failure(info, shouldNotBeEqualWithinPercentage(actual, other, percentage, absDiff(actual, other)));
}

protected abstract NUMBER absDiff(final NUMBER actual, final NUMBER other);

protected abstract boolean isGreaterThan(final NUMBER value, final NUMBER other);

}
Expand Up @@ -16,8 +16,6 @@
import static org.assertj.core.test.TestData.someInfo;
import static org.assertj.core.test.TestFailures.failBecauseExpectedAssertionErrorWasNotThrown;
import static org.assertj.core.util.FailureMessages.actualIsNull;


import static org.mockito.Mockito.verify;

import org.assertj.core.api.AssertionInfo;
Expand Down
Expand Up @@ -17,8 +17,6 @@
import static org.assertj.core.internal.ErrorMessages.offsetIsNull;
import static org.assertj.core.test.TestData.someInfo;
import static org.assertj.core.test.TestFailures.failBecauseExpectedAssertionErrorWasNotThrown;


import static org.mockito.Mockito.verify;

import org.assertj.core.api.AssertionInfo;
Expand Down
Expand Up @@ -17,8 +17,6 @@
import static org.assertj.core.internal.ErrorMessages.offsetIsNull;
import static org.assertj.core.test.TestData.someInfo;
import static org.assertj.core.test.TestFailures.failBecauseExpectedAssertionErrorWasNotThrown;


import static org.mockito.Mockito.verify;

import org.assertj.core.api.AssertionInfo;
Expand Down
Expand Up @@ -16,8 +16,6 @@
import static org.assertj.core.test.TestData.someInfo;
import static org.assertj.core.test.TestFailures.failBecauseExpectedAssertionErrorWasNotThrown;
import static org.assertj.core.util.FailureMessages.actualIsNull;


import static org.mockito.Mockito.verify;

import org.assertj.core.api.AssertionInfo;
Expand Down
Expand Up @@ -16,8 +16,6 @@
import static org.assertj.core.test.TestData.someInfo;
import static org.assertj.core.test.TestFailures.failBecauseExpectedAssertionErrorWasNotThrown;
import static org.assertj.core.util.FailureMessages.actualIsNull;


import static org.mockito.Mockito.verify;

import org.assertj.core.api.AssertionInfo;
Expand Down
Expand Up @@ -16,8 +16,6 @@
import static org.assertj.core.test.TestData.someInfo;
import static org.assertj.core.test.TestFailures.failBecauseExpectedAssertionErrorWasNotThrown;
import static org.assertj.core.util.FailureMessages.actualIsNull;


import static org.mockito.Mockito.verify;

import org.assertj.core.api.AssertionInfo;
Expand Down
Expand Up @@ -12,6 +12,9 @@
*/
package org.assertj.core.internal.doubles;

import static java.lang.Double.NEGATIVE_INFINITY;
import static java.lang.Double.NaN;
import static java.lang.Double.POSITIVE_INFINITY;
import static org.assertj.core.api.Assertions.withinPercentage;
import static org.assertj.core.data.Percentage.withPercentage;
import static org.assertj.core.error.ShouldBeEqualWithinPercentage.shouldBeEqualWithinPercentage;
Expand Down Expand Up @@ -97,4 +100,49 @@ public void should_fail_if_actual_is_not_close_enough_to_expected_value() {
}
failBecauseExpectedAssertionErrorWasNotThrown();
}

@Test
public void should_fail_if_actual_is_NaN_and_expected_is_not() {
thrown.expectAssertionError();
doubles.assertIsCloseToPercentage(someInfo(), NaN, ONE, withPercentage(ONE));
}

@Test
public void should_pass_if_actual_and_expected_are_NaN() {
doubles.assertIsCloseToPercentage(someInfo(), NaN, Double.NaN, withPercentage(ONE));
}

@Test
public void should_fail_if_actual_is_POSITIVE_INFINITY_and_expected_is_not() {
thrown.expectAssertionError();
doubles.assertIsCloseToPercentage(someInfo(), POSITIVE_INFINITY, ONE, withPercentage(ONE));
}

@Test
public void should_pass_if_actual_and_expteced_are_POSITIVE_INFINITY() {
doubles.assertIsCloseToPercentage(someInfo(), POSITIVE_INFINITY, POSITIVE_INFINITY, withPercentage(ONE));
}

@Test
public void should_fail_if_actual_is_NEGATIVE_INFINITY_and_expected_is_not() {
thrown.expectAssertionError();
doubles.assertIsCloseToPercentage(someInfo(), NEGATIVE_INFINITY, ONE, withPercentage(ONE));
}

@Test
public void should_pass_if_actual_and_expted_are_NEGATIVE_INFINITY() {
doubles.assertIsCloseToPercentage(someInfo(), NEGATIVE_INFINITY, NEGATIVE_INFINITY, withPercentage(ONE));
}

@Test
public void should_fail_if_actual_is_POSITIVE_INFINITY_and_expected_is_NEGATIVE_INFINITY() {
thrown.expectAssertionError();
doubles.assertIsCloseToPercentage(someInfo(), POSITIVE_INFINITY, NEGATIVE_INFINITY, withPercentage(ONE));
}

@Test
public void should_fail_if_actual_is_NEGATIVE_INFINITY_and_expected_is_POSITIVE_INFINITY() {
thrown.expectAssertionError();
doubles.assertIsCloseToPercentage(someInfo(), NEGATIVE_INFINITY, POSITIVE_INFINITY, withPercentage(ONE));
}
}
Expand Up @@ -12,6 +12,9 @@
*/
package org.assertj.core.internal.doubles;

import static java.lang.Double.NEGATIVE_INFINITY;
import static java.lang.Double.NaN;
import static java.lang.Double.POSITIVE_INFINITY;
import static org.assertj.core.api.Assertions.within;
import static org.assertj.core.error.ShouldBeEqualWithinOffset.shouldBeEqual;
import static org.assertj.core.test.TestData.someInfo;
Expand Down Expand Up @@ -58,7 +61,7 @@ public void should_pass_if_difference_is_equal_to_given_offset() {
doubles.assertIsCloseTo(someInfo(), ONE, ZERO, within(ONE));
doubles.assertIsCloseTo(someInfo(), ONE, TWO, within(ONE));
}

@Test
public void should_fail_if_actual_is_not_close_enough_to_expected_value() {
AssertionInfo info = someInfo();
Expand All @@ -70,4 +73,49 @@ public void should_fail_if_actual_is_not_close_enough_to_expected_value() {
}
failBecauseExpectedAssertionErrorWasNotThrown();
}

@Test
public void should_fail_if_actual_is_NaN_and_expected_is_not() {
thrown.expectAssertionError();
doubles.assertIsCloseTo(someInfo(), NaN, ONE, within(ONE));
}

@Test
public void should_pass_if_actual_and_expected_are_NaN() {
doubles.assertIsCloseTo(someInfo(), NaN, NaN, within(ONE));
}

@Test
public void should_fail_if_actual_is_POSITIVE_INFINITY_and_expected_is_not() {
thrown.expectAssertionError();
doubles.assertIsCloseTo(someInfo(), POSITIVE_INFINITY, ONE, within(ONE));
}

@Test
public void should_pass_if_actual_and_expected_are_POSITIVE_INFINITY() {
doubles.assertIsCloseTo(someInfo(), POSITIVE_INFINITY, POSITIVE_INFINITY, within(ONE));
}

@Test
public void should_fail_if_actual_is_NEGATIVE_INFINITY_and_expected_is_not() {
thrown.expectAssertionError();
doubles.assertIsCloseTo(someInfo(), NEGATIVE_INFINITY, ONE, within(ONE));
}

@Test
public void should_pass_if_actual_and_expected_are_NEGATIVE_INFINITY() {
doubles.assertIsCloseTo(someInfo(), NEGATIVE_INFINITY, NEGATIVE_INFINITY, within(ONE));
}

@Test
public void should_fail_if_actual_is_POSITIVE_INFINITY_and_expected_is_NEGATIVE_INFINITY() {
thrown.expectAssertionError();
doubles.assertIsCloseTo(someInfo(), POSITIVE_INFINITY, NEGATIVE_INFINITY, within(ONE));
}

@Test
public void should_fail_if_actual_is_NEGATIVE_INFINITY_and_expected_is_POSITIVE_INFINITY() {
thrown.expectAssertionError();
doubles.assertIsCloseTo(someInfo(), NEGATIVE_INFINITY, POSITIVE_INFINITY, within(ONE));
}
}
Expand Up @@ -12,13 +12,9 @@
*/
package org.assertj.core.internal.doubles;

import com.tngtech.java.junit.dataprovider.DataProvider;
import com.tngtech.java.junit.dataprovider.DataProviderRunner;
import org.assertj.core.api.AssertionInfo;
import org.assertj.core.internal.DoublesBaseTest;
import org.junit.Test;
import org.junit.runner.RunWith;

import static java.lang.Double.NEGATIVE_INFINITY;
import static java.lang.Double.NaN;
import static java.lang.Double.POSITIVE_INFINITY;
import static java.lang.Math.abs;
import static org.assertj.core.api.Assertions.withinPercentage;
import static org.assertj.core.data.Percentage.withPercentage;
Expand All @@ -28,6 +24,14 @@
import static org.assertj.core.util.FailureMessages.actualIsNull;
import static org.mockito.Mockito.verify;

import org.assertj.core.api.AssertionInfo;
import org.assertj.core.internal.DoublesBaseTest;
import org.junit.Test;
import org.junit.runner.RunWith;

import com.tngtech.java.junit.dataprovider.DataProvider;
import com.tngtech.java.junit.dataprovider.DataProviderRunner;

@RunWith(DataProviderRunner.class)
public class Doubles_assertIsNotCloseToPercentage_Test extends DoublesBaseTest {

Expand Down Expand Up @@ -104,4 +108,42 @@ public void should_fail_if_actual_is_too_close_to_expected_value() {
}
failBecauseExpectedAssertionErrorWasNotThrown();
}

@Test
public void should_fail_if_actual_and_expected_are_NaN() {
thrown.expectAssertionError();
doubles.assertIsNotCloseToPercentage(someInfo(), NaN, NaN, withPercentage(ONE));
}

@Test
public void should_fail_if_actual_and_expected_are_POSITIVE_INFINITY() {
thrown.expectAssertionError();
doubles.assertIsNotCloseToPercentage(someInfo(), POSITIVE_INFINITY, POSITIVE_INFINITY, withPercentage(ONE));
}

@Test
public void should_fail_if_actual_and_expected_are_NEGATIVE_INFINITY() {
thrown.expectAssertionError();
doubles.assertIsNotCloseToPercentage(someInfo(), NEGATIVE_INFINITY, NEGATIVE_INFINITY, withPercentage(ONE));
}

@Test
public void should_pass_if_actual_is_POSITIVE_INFINITY_and_expected_is_not() {
doubles.assertIsNotCloseToPercentage(someInfo(), POSITIVE_INFINITY, ONE, withPercentage(ONE));
}

@Test
public void should_pass_if_actual_is_POSITIVE_INFINITY_and_expected_is_NEGATIVE_INFINITY() {
doubles.assertIsNotCloseToPercentage(someInfo(), POSITIVE_INFINITY, NEGATIVE_INFINITY, withPercentage(ONE));
}

@Test
public void should_pass_if_actual_is_NEGATIVE_INFINITY_and_expected_is_not() {
doubles.assertIsNotCloseToPercentage(someInfo(), NEGATIVE_INFINITY, ONE, withPercentage(ONE));
}

@Test
public void should_pass_if_actual_is_NEGATIVE_INFINITY_and_expected_is_POSITIVE_INFINITY() {
doubles.assertIsNotCloseToPercentage(someInfo(), NEGATIVE_INFINITY, POSITIVE_INFINITY, withPercentage(ONE));
}
}
Expand Up @@ -12,14 +12,9 @@
*/
package org.assertj.core.internal.doubles;

import org.assertj.core.api.AssertionInfo;
import org.assertj.core.internal.DoublesBaseTest;
import org.junit.Test;
import org.junit.runner.RunWith;

import com.tngtech.java.junit.dataprovider.DataProvider;
import com.tngtech.java.junit.dataprovider.DataProviderRunner;

import static java.lang.Double.NEGATIVE_INFINITY;
import static java.lang.Double.NaN;
import static java.lang.Double.POSITIVE_INFINITY;
import static java.lang.Math.abs;
import static org.assertj.core.api.Assertions.byLessThan;
import static org.assertj.core.error.ShouldNotBeEqualWithinOffset.shouldNotBeEqual;
Expand All @@ -28,6 +23,14 @@
import static org.assertj.core.util.FailureMessages.actualIsNull;
import static org.mockito.Mockito.verify;

import org.assertj.core.api.AssertionInfo;
import org.assertj.core.internal.DoublesBaseTest;
import org.junit.Test;
import org.junit.runner.RunWith;

import com.tngtech.java.junit.dataprovider.DataProvider;
import com.tngtech.java.junit.dataprovider.DataProviderRunner;

@RunWith(DataProviderRunner.class)
public class Doubles_assertIsNotCloseTo_Test extends DoublesBaseTest {

Expand Down Expand Up @@ -87,4 +90,42 @@ public void should_fail_if_actual_is_too_close_to_expected_value() {
}
failBecauseExpectedAssertionErrorWasNotThrown();
}

@Test
public void should_fail_if_actual_and_expected_are_NaN() {
thrown.expectAssertionError();
doubles.assertIsNotCloseTo(someInfo(), NaN, NaN, byLessThan(ONE));
}

@Test
public void should_fail_if_actual_and_expected_are_POSITIVE_INFINITY() {
thrown.expectAssertionError();
doubles.assertIsNotCloseTo(someInfo(), POSITIVE_INFINITY, POSITIVE_INFINITY, byLessThan(ONE));
}

@Test
public void should_fail_if_actual_and_expected_are_NEGATIVE_INFINITY() {
thrown.expectAssertionError();
doubles.assertIsNotCloseTo(someInfo(), NEGATIVE_INFINITY, NEGATIVE_INFINITY, byLessThan(ONE));
}

@Test
public void should_pass_if_actual_is_POSITIVE_INFINITY_and_expected_is_not() {
doubles.assertIsNotCloseTo(someInfo(), POSITIVE_INFINITY, ONE, byLessThan(ONE));
}

@Test
public void should_pass_if_actual_is_POSITIVE_INFINITY_and_expected_is_NEGATIVE_INFINITY() {
doubles.assertIsNotCloseTo(someInfo(), POSITIVE_INFINITY, NEGATIVE_INFINITY, byLessThan(ONE));
}

@Test
public void should_pass_if_actual_is_NEGATIVE_INFINITY_and_expected_is_not() {
doubles.assertIsNotCloseTo(someInfo(), NEGATIVE_INFINITY, ONE, byLessThan(ONE));
}

@Test
public void should_pass_if_actual_is_NEGATIVE_INFINITY_and_expected_is_POSITIVE_INFINITY() {
doubles.assertIsNotCloseTo(someInfo(), NEGATIVE_INFINITY, POSITIVE_INFINITY, byLessThan(ONE));
}
}

0 comments on commit 59fc365

Please sign in to comment.