Skip to content

Commit

Permalink
Fix: AbstractOptionalDoubleAssert.hasValue(double) fails with NaN
Browse files Browse the repository at this point in the history
Fix #3401

(cherry picked from commit f086a92)
  • Loading branch information
pbacz authored and joel-costigliola committed May 3, 2024
1 parent 2101c33 commit c067da5
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -115,27 +115,30 @@ public SELF isNotEmpty() {
}

/**
* Verifies that the actual {@link java.util.OptionalDouble} has the value in argument.
* Verifies that the actual {@link java.util.OptionalDouble} has the value in argument. The check is consistent
* with {@link java.util.OptionalDouble#equals(Object)} since 3.26.0.
* <p>
* Assertion will pass :
* <pre><code class='java'> assertThat(OptionalDouble.of(8.0)).hasValue(8.0);
* <pre><code class='java'> // assertions succeed:
* assertThat(OptionalDouble.of(8.0)).hasValue(8.0);
* assertThat(OptionalDouble.of(8.0)).hasValue(Double.valueOf(8.0));
* assertThat(OptionalDouble.of(Double.NaN)).hasValue(Double.NaN); </code></pre>
* <p>
* Assertion will fail :
* <pre><code class='java'> assertThat(OptionalDouble.empty()).hasValue(8.0);
* assertThat(OptionalDouble.of(Double.NaN)).hasValue(Double.NaN);
* assertThat(OptionalDouble.of(Double.POSITIVE_INFINITY)).hasValue(Double.POSITIVE_INFINITY);
* assertThat(OptionalDouble.of(Double.NEGATIVE_INFINITY)).hasValue(Double.NEGATIVE_INFINITY);
*
* // assertions fail:
* assertThat(OptionalDouble.empty()).hasValue(8.0);
* assertThat(OptionalDouble.of(7)).hasValue(8.0);</code></pre>
*
* @param expectedValue the expected value inside the {@link java.util.OptionalDouble}.
* @return this assertion object.
* @throws java.lang.AssertionError if actual value is empty.
* @throws java.lang.AssertionError if actual is null.
* @throws java.lang.AssertionError if actual has not the value as expected.
* @throws java.lang.AssertionError if actual does not have the expected value.
*/
public SELF hasValue(double expectedValue) {
isNotNull();
if (!actual.isPresent()) throwAssertionError(shouldContain(expectedValue));
if (expectedValue != actual.getAsDouble())
if (Double.compare(expectedValue, actual.getAsDouble()) != 0)

Check warning on line 141 in assertj-core/src/main/java/org/assertj/core/api/AbstractOptionalDoubleAssert.java

View workflow job for this annotation

GitHub Actions / Qodana Community for JVM

Optional.get() is called without isPresent() check

`OptionalDouble.getAsDouble()` without 'isPresent()' check
throw Failures.instance().failure(info, shouldContain(actual, expectedValue), actual.getAsDouble(), expectedValue);
return myself;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,53 +13,63 @@
package org.assertj.core.api.optionaldouble;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.catchThrowable;
import static org.assertj.core.api.Assertions.catchThrowableOfType;
import static org.assertj.core.api.BDDAssertions.then;
import static org.assertj.core.error.OptionalShouldContain.shouldContain;
import static org.assertj.core.util.AssertionsUtil.assertThatAssertionErrorIsThrownBy;
import static org.assertj.core.util.AssertionsUtil.expectAssertionError;
import static org.assertj.core.util.FailureMessages.actualIsNull;

import java.util.OptionalDouble;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import org.opentest4j.AssertionFailedError;

class OptionalDoubleAssert_hasValue_Test {

@ParameterizedTest
@ValueSource(doubles = { 10.0, -10.0, 0.0, -0.0, Double.NaN, Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY })
void should_pass_if_optionalDouble_has_the_expected_value(double value) {
assertThat(OptionalDouble.of(value)).hasValue(value);
}

@Test
void should_pass_if_optionalDouble_has_the_expected_value_as_Double() {
assertThat(OptionalDouble.of(10.0)).hasValue(Double.valueOf(10.0));
}

@Test
void should_fail_when_optionalDouble_is_null() {
// GIVEN
OptionalDouble nullActual = null;
// WHEN
AssertionError assertionError = expectAssertionError(() -> assertThat(nullActual).hasValue(10.0));
// THEN
assertThatAssertionErrorIsThrownBy(() -> assertThat(nullActual).hasValue(10.0)).withMessage(actualIsNull());
}

@Test
void should_pass_if_optionalDouble_has_expected_value() {
assertThat(OptionalDouble.of(10.0)).hasValue(10.0);
then(assertionError).hasMessage(actualIsNull());
}

@Test
void should_fail_if_optionalDouble_does_not_have_expected_value() {
void should_fail_if_optionalDouble_does_not_have_the_expected_value() {
// GIVEN
OptionalDouble actual = OptionalDouble.of(5.0);
double expectedValue = 10.0;
// WHEN
AssertionFailedError error = catchThrowableOfType(() -> assertThat(actual).hasValue(expectedValue),
AssertionFailedError.class);
// THEN
assertThat(error).hasMessage(shouldContain(actual, expectedValue).create());
assertThat(error.getActual().getStringRepresentation()).isEqualTo(String.valueOf(actual.getAsDouble()));
assertThat(error.getExpected().getStringRepresentation()).isEqualTo(String.valueOf(expectedValue));
then(error).hasMessage(shouldContain(actual, expectedValue).create());
then(error.getActual().getStringRepresentation()).isEqualTo(String.valueOf(actual.getAsDouble()));
then(error.getExpected().getStringRepresentation()).isEqualTo(String.valueOf(expectedValue));
}

@Test
void should_fail_if_optionalDouble_is_empty() {
// GIVEN
double expectedValue = 10.0;
// WHEN
Throwable error = catchThrowable(() -> assertThat(OptionalDouble.empty()).hasValue(expectedValue));
AssertionError error = expectAssertionError(() -> assertThat(OptionalDouble.empty()).hasValue(expectedValue));
// THEN
assertThat(error).hasMessage(shouldContain(expectedValue).create());
then(error).hasMessage(shouldContain(expectedValue).create());
}
}

0 comments on commit c067da5

Please sign in to comment.