/** Test that a failure is returned if currency conversion fails. */
  public void convertResultCurrencyConversionFails() {
    DoubleArray values = DoubleArray.of(1, 2, 3);
    CurrencyValuesArray list = CurrencyValuesArray.of(Currency.GBP, values);
    // Market data doesn't include FX rates, conversion to USD will fail
    CalculationEnvironment marketData =
        CalculationEnvironment.builder().valuationDate(date(2011, 3, 8)).build();
    ConvertibleFunction fn = ConvertibleFunction.of(() -> list);
    CalculationTask task = new CalculationTask(TARGET, 0, 0, fn, MAPPINGS, REPORTING_RULES);

    CalculationResult calculationResult = task.execute(marketData);
    Result<?> result = calculationResult.getResult();
    assertThat(result).hasFailureMessageMatching("Failed to convert value .* to currency USD");
  }
  /**
   * Test that the result is converted to the reporting currency if it implements
   * CurrencyConvertible and the FX rates are available in the market data. The reporting currency
   * is taken from the reporting rules.
   */
  public void convertResultCurrencyUsingReportingRules() {
    DoubleArray values = DoubleArray.of(1, 2, 3);
    List<FxRate> rates =
        ImmutableList.of(1.61, 1.62, 1.63)
            .stream()
            .map(rate -> FxRate.of(Currency.GBP, Currency.USD, rate))
            .collect(toImmutableList());
    CurrencyValuesArray list = CurrencyValuesArray.of(Currency.GBP, values);
    CalculationEnvironment marketData =
        CalculationEnvironment.builder()
            .valuationDate(date(2011, 3, 8))
            .addValue(FxRateId.of(Currency.GBP, Currency.USD), rates)
            .build();
    ConvertibleFunction fn = ConvertibleFunction.of(() -> list);
    CalculationTask task = new CalculationTask(TARGET, 0, 0, fn, MAPPINGS, REPORTING_RULES);

    DoubleArray expectedValues = DoubleArray.of(1 * 1.61, 2 * 1.62, 3 * 1.63);
    CurrencyValuesArray expectedArray = CurrencyValuesArray.of(Currency.USD, expectedValues);

    CalculationResult calculationResult = task.execute(marketData);
    Result<?> result = calculationResult.getResult();
    assertThat(result).hasValue(expectedArray);
  }
  /** Test a failure is returned for a convertible value if there is no reporting currency. */
  public void convertResultCurrencyNoReportingCurrency() {
    DoubleArray values = DoubleArray.of(1, 2, 3);
    List<FxRate> rates =
        ImmutableList.of(1.61, 1.62, 1.63)
            .stream()
            .map(rate -> FxRate.of(Currency.GBP, Currency.USD, rate))
            .collect(toImmutableList());
    CurrencyValuesArray list = CurrencyValuesArray.of(Currency.GBP, values);
    CalculationEnvironment marketData =
        CalculationEnvironment.builder()
            .valuationDate(date(2011, 3, 8))
            .addValue(FxRateId.of(Currency.GBP, Currency.USD), rates)
            .build();
    ConvertibleFunction fn = ConvertibleFunction.of(() -> list);
    ReportingRules reportingRules = ReportingRules.empty();
    CalculationTask task = new CalculationTask(TARGET, 0, 0, fn, MAPPINGS, reportingRules);

    CalculationResult calculationResult = task.execute(marketData);
    Result<?> result = calculationResult.getResult();
    assertThat(result).hasFailureMessageMatching("No reporting currency available.*");
  }