/** * Copyright (C) 2013 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.sesame.config; import static com.opengamma.sesame.config.ConfigBuilder.argument; import static com.opengamma.sesame.config.ConfigBuilder.arguments; import static com.opengamma.sesame.config.ConfigBuilder.config; import static com.opengamma.sesame.config.ConfigBuilder.function; import static com.opengamma.sesame.config.ConfigBuilder.implementations; import static org.testng.AssertJUnit.assertEquals; import java.lang.annotation.Annotation; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import javax.annotation.Nullable; import org.testng.annotations.Test; import com.opengamma.sesame.function.AvailableImplementations; import com.opengamma.sesame.function.AvailableImplementationsImpl; import com.opengamma.sesame.function.Output; import com.opengamma.sesame.function.Parameter; import com.opengamma.sesame.function.scenarios.ScenarioArgument; import com.opengamma.sesame.function.scenarios.ScenarioFunction; import com.opengamma.sesame.graph.FunctionModel; import com.opengamma.util.test.TestGroup; @Test(groups = TestGroup.UNIT) public class FunctionModelConfigTest { private static final Map<Class<?>, Annotation> ANNOTATIONS = Collections.emptyMap(); private static final Parameter DECORATOR1_PARAM = new Parameter(Decorator1.class, "delegate", Fn.class, 0, ANNOTATIONS); private static final Parameter DECORATOR2_PARAM = new Parameter(Decorator2.class, "fn", Fn.class, 0, ANNOTATIONS); @Test public void mergedWithImpls() { FunctionModelConfig config1 = config(implementations(Object.class, String.class, Map.class, HashMap.class)); FunctionModelConfig config2 = config(implementations(Object.class, Integer.class, Number.class, Double.class)); FunctionModelConfig config3 = config(implementations(Set.class, HashSet.class, Set.class, HashSet.class)); FunctionModelConfig config4 = config(implementations(Object.class, Long.class, List.class, ArrayList.class)); FunctionModelConfig config = config1.mergedWith(config2, config3, config4); assertEquals(String.class, config.getFunctionImplementation(null, Object.class)); assertEquals(Double.class, config.getFunctionImplementation(null, Number.class)); assertEquals(HashMap.class, config.getFunctionImplementation(null, Map.class)); assertEquals(HashSet.class, config.getFunctionImplementation(null, Set.class)); assertEquals(ArrayList.class, config.getFunctionImplementation(null, List.class)); } public void mergedWithArgs() { FunctionModelConfig config1 = config(arguments(function(Object.class, argument("foo", 123)), function(String.class, argument("bar", 1.0)))); FunctionModelConfig config2 = config(arguments(function(Object.class, argument("foo", 321)), function(Object.class, argument("baz", "xyz")))); FunctionModelConfig config3 = config(arguments(function(Double.class, argument("aaa", "AAA")))); FunctionModelConfig config = config1.mergedWith(config2, config3); assertEquals(123, config.getFunctionArguments(Object.class).getArgument("foo")); assertEquals("xyz", config.getFunctionArguments(Object.class).getArgument("baz")); assertEquals(1.0, config.getFunctionArguments(String.class).getArgument("bar")); assertEquals("AAA", config.getFunctionArguments(Double.class).getArgument("aaa")); } @Test public void decoratedWithSingle() { FunctionModelConfig config = config(implementations(Fn.class, Impl.class)); FunctionModelConfig decoratedConfig = config.decoratedWith(Decorator1.class); assertEquals(Decorator1.class, decoratedConfig.getFunctionImplementation(null, Fn.class)); assertEquals(Impl.class, decoratedConfig.getFunctionImplementation(DECORATOR1_PARAM, Fn.class)); } @Test public void decoratedWithMultiple() { FunctionModelConfig config = config(implementations(Fn.class, Impl.class)); FunctionModelConfig decoratedConfig = config.decoratedWith(Decorator2.class).decoratedWith(Decorator1.class); assertEquals(Decorator1.class, decoratedConfig.getFunctionImplementation(null, Fn.class)); assertEquals(Decorator2.class, decoratedConfig.getFunctionImplementation(DECORATOR1_PARAM, Fn.class)); assertEquals(Impl.class, decoratedConfig.getFunctionImplementation(DECORATOR2_PARAM, Fn.class)); } @Test public void orderingOfDecorators() { FunctionModelConfig config = config(implementations(Fn.class, Impl.class)); FunctionModelConfig decoratedConfig = config.decoratedWith(Decorator1.class).decoratedWith(Decorator2.class); assertEquals(Decorator2.class, decoratedConfig.getFunctionImplementation(null, Fn.class)); assertEquals(Decorator1.class, decoratedConfig.getFunctionImplementation(DECORATOR2_PARAM, Fn.class)); assertEquals(Impl.class, decoratedConfig.getFunctionImplementation(DECORATOR1_PARAM, Fn.class)); } @Test public void chainedDecoratorConfig() { FunctionModelConfig config = config(implementations(Fn.class, Impl.class)); FunctionModelConfig decoratedConfig = config.decoratedWith(Decorator2.class).decoratedWith(Decorator1.class); assertEquals(Decorator1.class, decoratedConfig.getFunctionImplementation(null, Fn.class)); assertEquals(Decorator2.class, decoratedConfig.getFunctionImplementation(DECORATOR1_PARAM, Fn.class)); assertEquals(Impl.class, decoratedConfig.getFunctionImplementation(DECORATOR2_PARAM, Fn.class)); } @Test public void multipleDecoratorConfigs() { FunctionModelConfig config = config(implementations(Fn.class, Impl.class)); FunctionModelConfig decoratedConfig1 = FunctionModelConfig.EMPTY.decoratedWith(Decorator1.class); FunctionModelConfig decoratedConfig2 = FunctionModelConfig.EMPTY.decoratedWith(Decorator2.class); FunctionModelConfig mergedConfig = decoratedConfig1.mergedWith(decoratedConfig2, config); assertEquals(Decorator1.class, mergedConfig.getFunctionImplementation(null, Fn.class)); assertEquals(Decorator2.class, mergedConfig.getFunctionImplementation(DECORATOR1_PARAM, Fn.class)); assertEquals(Impl.class, mergedConfig.getFunctionImplementation(DECORATOR2_PARAM, Fn.class)); } @Test public void undecoratedConfig() { FunctionModelConfig config = config(implementations(Fn.class, Impl.class, Fn2.class, Impl2.class)); FunctionModelConfig decoratedConfig = config.decoratedWith(Decorator1.class); assertEquals(Impl2.class, decoratedConfig.getFunctionImplementation(null, Fn2.class)); } @Test public void defaultImplementationProvider() { AvailableImplementations availableImplementations = new AvailableImplementationsImpl(); availableImplementations.register(Impl.class); FunctionModelConfig config = new FunctionModelConfig(availableImplementations.getDefaultImplementations()); FunctionModelConfig decoratedConfig = config.decoratedWith(Decorator1.class); assertEquals(Decorator1.class, decoratedConfig.getFunctionImplementation(null, Fn.class)); assertEquals(Impl.class, decoratedConfig.getFunctionImplementation(DECORATOR1_PARAM, Fn.class)); FunctionModel.build(Fn.class, decoratedConfig); } @Test public void decoratorInFirstConfigImplInSecondConfig() { AvailableImplementations availableImplementations = new AvailableImplementationsImpl(); availableImplementations.register(Impl.class); FunctionModelConfig defaultImpls = new FunctionModelConfig(availableImplementations.getDefaultImplementations()); FunctionModelConfig decoratedConfig = FunctionModelConfig.EMPTY.decoratedWith(Decorator1.class); FunctionModelConfig compositeConfig = decoratedConfig.mergedWith(defaultImpls); assertEquals(Decorator1.class, compositeConfig.getFunctionImplementation(null, Fn.class)); assertEquals(Impl.class, compositeConfig.getFunctionImplementation(DECORATOR1_PARAM, Fn.class)); FunctionModel.build(Fn.class, compositeConfig); } @Test public void implInFirstConfigDecoratorInSecondConfig() { AvailableImplementations availableImplementations = new AvailableImplementationsImpl(); availableImplementations.register(Impl.class); FunctionModelConfig defaultImpls = new FunctionModelConfig(availableImplementations.getDefaultImplementations()); FunctionModelConfig decoratedConfig = FunctionModelConfig.EMPTY.decoratedWith(Decorator1.class); FunctionModelConfig compositeConfig = defaultImpls.mergedWith(decoratedConfig); assertEquals(Decorator1.class, compositeConfig.getFunctionImplementation(null, Fn.class)); assertEquals(Impl.class, compositeConfig.getFunctionImplementation(DECORATOR1_PARAM, Fn.class)); FunctionModel.build(Fn.class, compositeConfig); } public interface Fn { @Output("Foo") String foo(Double d); } public static class Impl implements Fn { @Override public String foo(Double d) { return null; } } public static class Decorator1 implements Fn, ScenarioFunction<Arg1, Decorator1> { public Decorator1(Fn delegate) { } @Override public String foo(Double d) { return null; } @Nullable @Override public Class<Arg1> getArgumentType() { return Arg1.class; } } public static class Decorator2 implements Fn, ScenarioFunction<Arg2, Decorator2> { public Decorator2(Fn fn) { } @Override public String foo(Double d) { return null; } @Nullable @Override public Class<Arg2> getArgumentType() { return Arg2.class; } } public interface Fn2 { @Output("Bar") String bar(Double d); } public static class Impl2 implements Fn2 { @Override public String bar(Double d) { return null; } } public static class Arg1 implements ScenarioArgument<Arg1, Decorator1> { @Override public Class<Decorator1> getFunctionType() { return Decorator1.class; } } public static class Arg2 implements ScenarioArgument<Arg2, Decorator2> { @Override public Class<Decorator2> getFunctionType() { return Decorator2.class; } } }