/**
* Copyright (C) 2015 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.strata.calc.marketdata;
import static com.opengamma.strata.collect.TestHelper.assertThrows;
import static org.assertj.core.api.Assertions.assertThat;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableList;
import com.opengamma.strata.basics.ReferenceData;
import com.opengamma.strata.data.MarketDataId;
import com.opengamma.strata.data.scenario.MarketDataBox;
import com.opengamma.strata.data.scenario.ScenarioPerturbation;
@Test
public class ScenarioDefinitionTest {
private static final TestFilter FILTER_A = new TestFilter("a");
private static final TestFilter FILTER_B = new TestFilter("b");
private static final TestFilter FILTER_C = new TestFilter("c");
private static final TestPerturbation PERTURBATION_A1 = new TestPerturbation(1, 2);
private static final TestPerturbation PERTURBATION_B1 = new TestPerturbation(3, 4);
private static final TestPerturbation PERTURBATION_C1 = new TestPerturbation(5, 6);
private static final PerturbationMapping<Object> MAPPING_A =
PerturbationMapping.of(Object.class, FILTER_A, PERTURBATION_A1);
private static final PerturbationMapping<Object> MAPPING_B =
PerturbationMapping.of(Object.class, FILTER_B, PERTURBATION_B1);
private static final PerturbationMapping<Object> MAPPING_C =
PerturbationMapping.of(Object.class, FILTER_C, PERTURBATION_C1);
public void ofMappings() {
List<PerturbationMapping<Object>> mappings = ImmutableList.of(MAPPING_A, MAPPING_B, MAPPING_C);
ScenarioDefinition scenarioDefinition = ScenarioDefinition.ofMappings(mappings);
List<String> scenarioNames = ImmutableList.of("Scenario 1", "Scenario 2");
assertThat(scenarioDefinition.getMappings()).isEqualTo(mappings);
assertThat(scenarioDefinition.getScenarioNames()).isEqualTo(scenarioNames);
}
public void ofMappingsWithNames() {
List<PerturbationMapping<Object>> mappings = ImmutableList.of(MAPPING_A, MAPPING_B, MAPPING_C);
List<String> scenarioNames = ImmutableList.of("foo", "bar");
ScenarioDefinition scenarioDefinition = ScenarioDefinition.ofMappings(mappings, scenarioNames);
assertThat(scenarioDefinition.getMappings()).isEqualTo(mappings);
assertThat(scenarioDefinition.getScenarioNames()).isEqualTo(scenarioNames);
}
/**
* Tests that a scenario definition won't be built if the scenarios names are specified and there
* are the wrong number. The mappings all have 2 perturbations which should mean 2 scenarios, but
* there are 3 scenario names.
*/
@Test(expectedExceptions = IllegalArgumentException.class)
public void ofMappingsWrongNumberOfScenarioNames() {
List<PerturbationMapping<Object>> mappings = ImmutableList.of(MAPPING_A, MAPPING_B, MAPPING_C);
List<String> scenarioNames = ImmutableList.of("foo", "bar", "baz");
ScenarioDefinition.ofMappings(mappings, scenarioNames);
}
/**
* Tests that a scenario definition won't be built if the mappings don't have the same number of scenarios
*/
@Test(expectedExceptions = IllegalArgumentException.class)
public void ofMappingsDifferentNumberOfScenarios() {
PerturbationMapping<Object> mappingC = PerturbationMapping.of(Object.class, FILTER_C, new TestPerturbation(27));
List<PerturbationMapping<Object>> mappings = ImmutableList.of(MAPPING_A, MAPPING_B, mappingC);
ScenarioDefinition.ofMappings(mappings);
}
/**
* Tests that a scenario definition won't be built if the mappings don't have the same number of scenarios
*/
@Test(expectedExceptions = IllegalArgumentException.class)
public void ofMappingsWithNamesDifferentNumberOfScenarios() {
PerturbationMapping<Object> mappingC = PerturbationMapping.of(Object.class, FILTER_C, new TestPerturbation(27));
List<PerturbationMapping<Object>> mappings = ImmutableList.of(MAPPING_A, MAPPING_B, mappingC);
List<String> scenarioNames = ImmutableList.of("foo", "bar");
ScenarioDefinition.ofMappings(mappings, scenarioNames);
}
public void repeatItems() {
List<Integer> inputs = ImmutableList.of(1, 2, 3, 4);
List<Integer> expected1 = ImmutableList.of(1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4);
assertThat(ScenarioDefinition.repeatItems(inputs, 12, 1)).isEqualTo(expected1);
List<Integer> expected2 = ImmutableList.of(1, 1, 2, 2, 3, 3, 4, 4);
assertThat(ScenarioDefinition.repeatItems(inputs, 8, 2)).isEqualTo(expected2);
List<Integer> expected3 = ImmutableList.of(1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4);
assertThat(ScenarioDefinition.repeatItems(inputs, 12, 3)).isEqualTo(expected3);
List<Integer> expected4 = ImmutableList.of(1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4);
assertThat(ScenarioDefinition.repeatItems(inputs, 24, 3)).isEqualTo(expected4);
}
/**
* Tests that exceptions are thrown when the scenario names contain duplicate values.
*/
public void nonUniqueNames() {
List<PerturbationMapping<Object>> mappings2 = ImmutableList.of(MAPPING_A, MAPPING_B, MAPPING_C);
List<String> names2 = ImmutableList.of("foo", "foo");
String msg2 = "Scenario names must be unique but duplicates were found: foo";
assertThrows(() -> ScenarioDefinition.ofMappings(mappings2, names2), IllegalArgumentException.class, msg2);
}
//-------------------------------------------------------------------------
private static final class TestPerturbation implements ScenarioPerturbation<Object> {
private final int[] values;
private TestPerturbation(int... values) {
this.values = values;
}
@Override
public MarketDataBox<Object> applyTo(MarketDataBox<Object> marketData, ReferenceData refData) {
return marketData;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
TestPerturbation that = (TestPerturbation) o;
return Arrays.equals(values, that.values);
}
@Override
public int getScenarioCount() {
return values.length;
}
@Override
public int hashCode() {
return Objects.hash(new Object[] {values});
}
@Override
public String toString() {
return "TestPerturbation [id=" + Arrays.toString(values) + "]";
}
}
private static final class TestFilter implements MarketDataFilter<Object, MarketDataId<Object>> {
private final String name;
private TestFilter(String name) {
this.name = name;
}
@Override
public boolean matches(MarketDataId<Object> marketDataId, MarketDataBox<Object> marketData, ReferenceData refData) {
return false;
}
@Override
public Class<?> getMarketDataIdType() {
return MarketDataId.class;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
TestFilter that = (TestFilter) o;
return Objects.equals(name, that.name);
}
@Override
public int hashCode() {
return Objects.hash(name);
}
@Override
public String toString() {
return "TestFilter [name='" + name + "']";
}
}
}