/**
   * Tests that requirements are added for the FX rates needed to convert the results into the
   * reporting currency.
   */
  public void fxConversionRequirements() {
    OutputCurrenciesFunction fn = new OutputCurrenciesFunction();
    CalculationTask task = new CalculationTask(TARGET, 0, 0, fn, MAPPINGS, REPORTING_RULES);
    MarketDataRequirements requirements = task.requirements();

    assertThat(requirements.getNonObservables())
        .containsOnly(
            FxRateId.of(Currency.GBP, Currency.USD), FxRateId.of(Currency.EUR, Currency.USD));
  }
  public void convertCurrencyAmount() {
    List<FxRate> rates =
        ImmutableList.of(
            FxRate.of(Currency.GBP, Currency.USD, 1.61),
            FxRate.of(Currency.GBP, Currency.USD, 1.62),
            FxRate.of(Currency.GBP, Currency.USD, 1.63));
    CalculationEnvironment marketData =
        MarketEnvironment.builder()
            .valuationDate(date(2011, 3, 8))
            .addValue(FxRateId.of(Currency.GBP, Currency.USD), rates)
            .build();
    MarketDataMappings mappings = MarketDataMappings.of(MarketDataFeed.NONE);
    DefaultCalculationMarketData calculationMarketData =
        DefaultCalculationMarketData.of(marketData, mappings);

    SingleScenarioResult<CurrencyAmount> test =
        SingleScenarioResult.of(3, CurrencyAmount.of(Currency.GBP, 2));

    ScenarioResult<?> convertedList = test.convertedTo(Currency.USD, calculationMarketData);
    List<CurrencyAmount> expectedValues =
        ImmutableList.of(
            CurrencyAmount.of(Currency.USD, 2 * 1.61),
            CurrencyAmount.of(Currency.USD, 2 * 1.62),
            CurrencyAmount.of(Currency.USD, 2 * 1.63));
    DefaultScenarioResult<CurrencyAmount> expectedList = DefaultScenarioResult.of(expectedValues);
    assertThat(convertedList).isEqualTo(expectedList);
  }
  /** 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.*");
  }
  /**
   * 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);
  }