/**
* Copyright (C) 2014 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.strata.basics;
import org.assertj.core.api.AbstractAssert;
import org.assertj.core.api.Assertions;
import org.assertj.core.data.Offset;
import com.opengamma.strata.basics.currency.Currency;
import com.opengamma.strata.basics.currency.CurrencyAmount;
/**
* An assert helper that provides useful AssertJ assertion
* methods for {@link CurrencyAmount} instances.
* <p>
* These allow {code CurrencyAmount}s to be inspected in tests in the
* same fluent style as other basic classes.
* <p>
* So the following:
* <pre>
* CurrencyAmount result = someMethodCall();
* assertEquals(result.getCurrency(), USD);
* assertEquals(result.getAmount(), 123.45, 1e-6);
* </pre>
* can be replaced with:
* <pre>
* CurrencyAmount result = someMethodCall();
* assertThat(result)
* .hasCurrency(USD)
* .hasAmount(123.45, within(1e-6));
* </pre>
* or:
* <pre>
* CurrencyAmount result = someMethodCall();
* CurrencyAmount expected = CurrencyAmount.of(USD, 123.45);
* assertThat(result).isEqualTo(expected, within(1e-6));
* </pre>
* <p>
* In order to be able to use a statically imported assertThat()
* method for both {@code CurrencyAmount} and other types, statically
* import {@link BasicProjectAssertions#assertThat(CurrencyAmount)}
* rather than this class.
*/
public class CurrencyAmountAssert extends AbstractAssert<CurrencyAmountAssert, CurrencyAmount> {
/**
* Private constructor, use {@link #assertThat(CurrencyAmount)} to
* construct an instance.
*
* @param actual the amount to create an {@code Assert} for
*/
private CurrencyAmountAssert(CurrencyAmount actual) {
super(actual, CurrencyAmountAssert.class);
}
/**
* Create an {@code Assert} instance for the supplied {@code CurrencyAmount}.
*
* @param amount the amount to create an {@code Assert} for
* @return an {@code Assert} instance
*/
public static CurrencyAmountAssert assertThat(CurrencyAmount amount) {
return new CurrencyAmountAssert(amount);
}
/**
* Assert that the {@code CurrencyAmount} is of the expected currency.
*
* @param ccy the expected currency
* @return this if the currency matches the expectation, else
* throw an {@code AssertionError}
*/
public CurrencyAmountAssert hasCurrency(Currency ccy) {
isNotNull();
if (!actual.getCurrency().equals(ccy)) {
failWithMessage("Expected CurrencyAmount with currency: <%s> but was: <%s>",
ccy, actual.getCurrency());
}
return this;
}
/**
* Assert that the {@code CurrencyAmount} is for the expected amount.
*
* @param expectedAmount the expected amount
* @return this if the amount matches the expectation, else
* throw an {@code AssertionError}
*/
public CurrencyAmountAssert hasAmount(double expectedAmount) {
isNotNull();
Assertions.assertThat(actual.getAmount()).isEqualTo(expectedAmount);
return this;
}
/**
* Assert that the {@code CurrencyAmount} is within range
* of an expected amount.
*
* @param expectedAmount the expected amount
* @param tolerance the tolerance to use
* @return this if the amount matches the expectation, else
* throw an {@code AssertionError}
*/
public CurrencyAmountAssert hasAmount(double expectedAmount, Offset<Double> tolerance) {
isNotNull();
Assertions.assertThat(actual.getAmount()).isEqualTo(expectedAmount, tolerance);
return this;
}
/**
* Assert that the {@code CurrencyAmount} has the same currency as
* the supplied {@code CurrencyAmount} and that the amount is within
* range of the supplied {@code CurrencyAmount}'s amount.
*
* @param expected the expected {@code CurrencyAmount}
* @param tolerance the tolerance to use
* @return this if the amount matches the expectation, else
* throw an {@code AssertionError}
*/
public CurrencyAmountAssert isEqualTo(CurrencyAmount expected, Offset<Double> tolerance) {
isNotNull();
hasCurrency(expected.getCurrency());
hasAmount(expected.getAmount(), tolerance);
return this;
}
}