public void requirements() {
    MarketDataFeed marketDataFeed = MarketDataFeed.of("MarketDataVendor");
    MarketDataMappings marketDataMappings =
        DefaultMarketDataMappings.builder()
            .mappings(ImmutableMap.of(TestKey.class, new TestMapping("foo")))
            .marketDataFeed(marketDataFeed)
            .build();
    CalculationTask task =
        new CalculationTask(
            new TestTarget(), 0, 0, new TestFunction(), marketDataMappings, ReportingRules.empty());
    MarketDataRequirements requirements = task.requirements();
    Set<? extends MarketDataId<?>> nonObservables = requirements.getNonObservables();
    ImmutableSet<? extends ObservableId> observables = requirements.getObservables();
    ImmutableSet<ObservableId> timeSeries = requirements.getTimeSeries();

    MarketDataId<?> timeSeriesId = TestObservableKey.of("3").toMarketDataId(marketDataFeed);
    assertThat(timeSeries).hasSize(1);
    assertThat(timeSeries.iterator().next()).isEqualTo(timeSeriesId);

    MarketDataId<?> nonObservableId = TestId.of("1");
    assertThat(nonObservables).hasSize(1);
    assertThat(nonObservables.iterator().next()).isEqualTo(nonObservableId);

    MarketDataId<?> observableId = TestObservableKey.of("2").toMarketDataId(marketDataFeed);
    assertThat(observables).hasSize(1);
    assertThat(observables.iterator().next()).isEqualTo(observableId);
  }
  /** Test a non-convertible result is returned even if there is no reporting currency. */
  public void nonConvertibleResultReturnedWhenNoReportingCurrency() {
    TestFunction fn = new TestFunction();
    CalculationTask task = new CalculationTask(TARGET, 0, 0, fn, MAPPINGS, ReportingRules.empty());
    CalculationEnvironment marketData =
        CalculationEnvironment.builder().valuationDate(date(2011, 3, 8)).build();

    CalculationResult calculationResult = task.execute(marketData);
    Result<?> result = calculationResult.getResult();
    assertThat(result).hasValue("bar");
  }
  /** 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 default reporting
   * currency is taken from the function.
   */
  public void convertResultCurrencyUsingDefaultReportingCurrency() {
    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, Currency.USD);
    CalculationTask task = new CalculationTask(TARGET, 0, 0, fn, MAPPINGS, ReportingRules.empty());

    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);
  }