Skip to content

Commit

Permalink
Add OptionalDoubleAssert.hasValueCloseTo percentage. Fixes #1422
Browse files Browse the repository at this point in the history
  • Loading branch information
j-kitch authored and joel-costigliola committed Feb 10, 2019
1 parent 83bb091 commit 56d8291
Show file tree
Hide file tree
Showing 7 changed files with 383 additions and 23 deletions.
Expand Up @@ -13,14 +13,16 @@
package org.assertj.core.api;

import static java.lang.Math.abs;
import static org.assertj.core.error.OptionalDoubleShouldHaveValueCloseTo.shouldHaveValueCloseTo;
import static org.assertj.core.error.OptionalDoubleShouldHaveValueCloseToOffset.shouldHaveValueCloseToOffset;
import static org.assertj.core.error.OptionalDoubleShouldHaveValueCloseToPercentage.shouldHaveValueCloseToPercentage;
import static org.assertj.core.error.OptionalShouldBeEmpty.shouldBeEmpty;
import static org.assertj.core.error.OptionalShouldBePresent.shouldBePresent;
import static org.assertj.core.error.OptionalShouldContain.shouldContain;

import java.util.OptionalDouble;

import org.assertj.core.data.Offset;
import org.assertj.core.data.Percentage;
import org.assertj.core.internal.Doubles;
import org.assertj.core.internal.Failures;
import org.assertj.core.util.VisibleForTesting;
Expand Down Expand Up @@ -163,12 +165,45 @@ public SELF hasValue(double expectedValue) {
*/
public SELF hasValueCloseTo(Double expectedValue, Offset<Double> offset) {
isNotNull();
if (!actual.isPresent()) throwAssertionError(shouldHaveValueCloseTo(expectedValue));
if (!actual.isPresent()) throwAssertionError(shouldHaveValueCloseToOffset(expectedValue));
// Reuses doubles functionality, catches potential assertion error and throw correct one
try {
doubles.assertIsCloseTo(info, actual.getAsDouble(), expectedValue, offset);
} catch (AssertionError assertionError) {
throwAssertionError(shouldHaveValueCloseTo(actual, expectedValue, offset, abs(expectedValue - actual.getAsDouble())));
throwAssertionError(shouldHaveValueCloseToOffset(actual, expectedValue, offset, abs(expectedValue - actual.getAsDouble())));
}
return myself;
}

/**
* Verifies that the actual {@link java.util.OptionalDouble} has a value close to the expected value, within the given
* percentage.<br>
* If the difference is equal to the percentage value, the assertion is considered valid.
*
* <pre><code class='java'>// The assertion will pass:
* assertThat(OptionalDouble.of(11)).hasValueCloseTo(10.0, withinPercentage(20));
*
* // If the difference is exactly equals to the computed offset (1.0), the assertion will pass:
* assertThat(OptionalDouble.of(11)).hasValueCloseTo(10.0, withinPercentage(10));
*
* // The assertions will fail:
* assertThat(OptionalDouble.of(11)).hasValueCloseTo(10.0, withinPercentage(5));
* assertThat(OptionalDouble.empty()).hasValueCloseTo(10.0, withinPercentage(5));</code></pre>
*
* @param expectedValue the expected value inside the {@link java.util.OptionalDouble}
* @param percentage the given positive percentage
* @return the assertion object
* @throws java.lang.AssertionError if actual value is empty
* @throws java.lang.AssertionError if actual is null
* @throws java.lang.AssertionError if the actual value is not close to the given one
*/
public SELF hasValueCloseTo(Double expectedValue, Percentage percentage) {
isNotNull();
if (!actual.isPresent()) throwAssertionError(shouldHaveValueCloseToPercentage(expectedValue));
try {
doubles.assertIsCloseToPercentage(info, actual.getAsDouble(), expectedValue, percentage);
} catch (AssertionError assertionError) {
throwAssertionError(shouldHaveValueCloseToPercentage(actual, expectedValue, percentage, abs(expectedValue - actual.getAsDouble())));
}
return myself;
}
Expand Down
Expand Up @@ -22,17 +22,17 @@
* @author Jean-Christophe Gay
* @author Alexander Bischof
*/
public class OptionalDoubleShouldHaveValueCloseTo extends BasicErrorMessageFactory {
public class OptionalDoubleShouldHaveValueCloseToOffset extends BasicErrorMessageFactory {

private OptionalDoubleShouldHaveValueCloseTo(OptionalDouble actual, double expected, Offset<Double> offset,
double difference) {
private OptionalDoubleShouldHaveValueCloseToOffset(OptionalDouble actual, double expected, Offset<Double> offset,
double difference) {
super("%nExpecting:%n <%s>%nto be close to:%n <%s>%n" +
"by less than <%s> but difference was <%s>.%n" +
"(a difference of exactly <%s> being considered valid)",
actual, expected, offset.value, difference, offset.value);
}

private OptionalDoubleShouldHaveValueCloseTo(double expected) {
private OptionalDoubleShouldHaveValueCloseToOffset(double expected) {
super("%nExpecting an OptionalDouble with value:%n <%s>%nbut was empty.", expected);
}

Expand All @@ -45,11 +45,11 @@ private OptionalDoubleShouldHaveValueCloseTo(double expected) {
* @param difference the effective difference between actual and expected.
* @return a error message factory
*/
public static OptionalDoubleShouldHaveValueCloseTo shouldHaveValueCloseTo(OptionalDouble optional,
double expectedValue,
Offset<Double> offset,
double difference) {
return new OptionalDoubleShouldHaveValueCloseTo(optional, expectedValue, offset, difference);
public static OptionalDoubleShouldHaveValueCloseToOffset shouldHaveValueCloseToOffset(OptionalDouble optional,
double expectedValue,
Offset<Double> offset,
double difference) {
return new OptionalDoubleShouldHaveValueCloseToOffset(optional, expectedValue, offset, difference);
}

/**
Expand All @@ -58,7 +58,7 @@ public static OptionalDoubleShouldHaveValueCloseTo shouldHaveValueCloseTo(Option
* @param expectedValue the value we expect to be in an {@link java.util.OptionalDouble}.
* @return a error message factory.
*/
public static OptionalDoubleShouldHaveValueCloseTo shouldHaveValueCloseTo(double expectedValue) {
return new OptionalDoubleShouldHaveValueCloseTo(expectedValue);
public static OptionalDoubleShouldHaveValueCloseToOffset shouldHaveValueCloseToOffset(double expectedValue) {
return new OptionalDoubleShouldHaveValueCloseToOffset(expectedValue);
}
}
@@ -0,0 +1,72 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
* Copyright 2012-2018 the original author or authors.
*/
package org.assertj.core.error;

import org.assertj.core.data.Percentage;

import java.util.OptionalDouble;

/**
* Build error message when an {@link java.util.OptionalDouble} should be close to an expected value within a positive
* percentage.
*
* @author Joshua Kitchen
*/
public class OptionalDoubleShouldHaveValueCloseToPercentage extends BasicErrorMessageFactory {

private OptionalDoubleShouldHaveValueCloseToPercentage(double expected) {
super("%nExpecting an OptionalDouble with value:%n" +
" <%s>%n" +
"but was empty.",
expected);
}

private OptionalDoubleShouldHaveValueCloseToPercentage(OptionalDouble actual, double expected, Percentage percentage,
double expectedPercentage) {
super("%nExpecting:%n" +
" <%s>%n" +
"to be close to:%n" +
" <%s>%n" +
"by less than %s but difference was %s%%.%n" +
"(a difference of exactly %s being considered valid)",
actual, expected, percentage, expectedPercentage, percentage);
}

/**
* Indicates that the provided {@link java.util.OptionalDouble} is empty so it doesn't have the expected value.
*
* @param expectedValue the value we expect to be in an {@link java.util.OptionalDouble}.
* @return a error message factory.
*/
public static OptionalDoubleShouldHaveValueCloseToPercentage shouldHaveValueCloseToPercentage(double expectedValue) {
return new OptionalDoubleShouldHaveValueCloseToPercentage(expectedValue);
}

/**
* Indicates that the provided {@link java.util.OptionalDouble} has a value, but it is not within the given positive
* percentage.
*
* @param optional the {@link java.util.OptionalDouble} which has a value
* @param expectedValue the value we expect to be in the provided {@link java.util.OptionalDouble}
* @param percentage the given positive percentage
* @param difference the effective distance between actual and expected
* @return an error message factory
*/
public static OptionalDoubleShouldHaveValueCloseToPercentage shouldHaveValueCloseToPercentage(OptionalDouble optional,
double expectedValue,
Percentage percentage,
double difference) {
double actualPercentage = difference / expectedValue * 100d;
return new OptionalDoubleShouldHaveValueCloseToPercentage(optional, expectedValue, percentage, actualPercentage);
}
}
Expand Up @@ -17,16 +17,17 @@
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.assertj.core.api.Assertions.assertThatNullPointerException;
import static org.assertj.core.api.Assertions.within;
import static org.assertj.core.error.OptionalDoubleShouldHaveValueCloseTo.shouldHaveValueCloseTo;
import static org.assertj.core.error.OptionalDoubleShouldHaveValueCloseToOffset.shouldHaveValueCloseToOffset;
import static org.assertj.core.util.FailureMessages.actualIsNull;

import java.util.OptionalDouble;

import org.assertj.core.api.BaseTest;
import org.assertj.core.data.Offset;
import org.assertj.core.error.OptionalDoubleShouldHaveValueCloseToOffset;
import org.junit.jupiter.api.Test;

public class OptionalDoubleAssert_hasValueCloseTo_Test extends BaseTest {
public class OptionalDoubleAssert_hasValueCloseToOffset_Test extends BaseTest {

@Test
public void should_fail_when_optionaldouble_is_null() {
Expand All @@ -39,7 +40,7 @@ public void should_fail_if_optionaldouble_is_empty() {
double expectedValue = 10.0;

assertThatExceptionOfType(AssertionError.class).isThrownBy(() -> assertThat(OptionalDouble.empty()).hasValueCloseTo(expectedValue, within(2.0)))
.withMessage(shouldHaveValueCloseTo(expectedValue).create());
.withMessage(shouldHaveValueCloseToOffset(expectedValue).create());
}

@Test
Expand All @@ -50,14 +51,15 @@ public void should_fail_if_actual_is_not_close_enough_to_expected_value() {

assertThatExceptionOfType(AssertionError.class).isThrownBy(() -> assertThat(actual).hasValueCloseTo(expectedValue,
offset))
.withMessage(shouldHaveValueCloseTo(actual, expectedValue, offset,
.withMessage(shouldHaveValueCloseToOffset(actual, expectedValue, offset,
abs(expectedValue
- actual.getAsDouble())).create());
}

@Test
public void should_fail_if_offset_is_null() {
assertThatNullPointerException().isThrownBy(() -> assertThat(OptionalDouble.of(10.0)).hasValueCloseTo(10.0, null));
Offset<Double> offset = null;
assertThatNullPointerException().isThrownBy(() -> assertThat(OptionalDouble.of(10.0)).hasValueCloseTo(10.0, offset));
}

@Test
Expand Down

0 comments on commit 56d8291

Please sign in to comment.