1
+ package com.regnosys.rosetta.interpreternew
2
+
3
+ import org.junit.jupiter.api.^extension.ExtendWith
4
+ import org.eclipse.xtext.testing.InjectWith
5
+ import org.eclipse.xtext.testing.extensions.InjectionExtension
6
+ import com.regnosys.rosetta.tests.RosettaInjectorProvider
7
+ import org.junit.jupiter.api.Test
8
+ import javax.inject.Inject
9
+ import com.regnosys.rosetta.tests.util.CodeGeneratorTestHelper
10
+
11
+ import static com.google.common.collect.ImmutableMap.*
12
+ import static org.junit.jupiter.api.Assertions.*
13
+ import com.google.inject.AbstractModule
14
+ import com.google.inject.Guice
15
+ import com.google.inject.Injector
16
+ import com.regnosys.rosetta.rosetta.RosettaModel
17
+ import com.regnosys.rosetta.rosetta.simple.Function
18
+ import com.regnosys.rosetta.tests.util.CodeGeneratorTestHelper
19
+ import com.regnosys.rosetta.tests.util.ModelHelper
20
+ import com.rosetta.model.lib.functions.ConditionValidator
21
+ import com.rosetta.model.lib.functions.DefaultConditionValidator
22
+ import com.rosetta.model.lib.functions.ModelObjectValidator
23
+ import com.rosetta.model.lib.functions.NoOpModelObjectValidator
24
+ import com.rosetta.model.lib.functions.RosettaFunction
25
+ import java.util.Map
26
+ import java.util.function.Consumer
27
+ import org.eclipse.xtext.xbase.testing.RegisteringFileSystemAccess
28
+
29
+ import static org.junit.jupiter.api.Assertions.*
30
+ import com.regnosys.rosetta.generator.java.RosettaJavaPackages.RootPackage
31
+ import java.lang.reflect.InvocationTargetException
32
+ import javax.inject.Inject
33
+ import com.regnosys.rosetta.generator.java.function.FunctionGenerator
34
+ import com.regnosys.rosetta.rosetta.expression.RosettaExpression
35
+ import com.regnosys.rosetta.rosetta.interpreter.RosettaInterpreterValue
36
+ import com.regnosys.rosetta.tests.util.ExpressionParser
37
+ import static org.junit.jupiter.api.Assertions.* ;
38
+
39
+ import javax.inject.Inject ;
40
+
41
+ import org.eclipse.xtext.testing.InjectWith ;
42
+ import org.eclipse.xtext.testing.extensions.InjectionExtension ;
43
+ import org.junit.jupiter.api.BeforeEach ;
44
+ import org.junit.jupiter.api.Test ;
45
+
46
+ import com.regnosys.rosetta.interpreternew.values.RosettaInterpreterBooleanValue ;
47
+ import com.regnosys.rosetta.interpreternew.values.RosettaInterpreterError ;
48
+ import com.regnosys.rosetta.interpreternew.values.RosettaInterpreterErrorValue ;
49
+ import com.regnosys.rosetta.rosetta.expression.ExpressionFactory ;
50
+ import com.regnosys.rosetta.rosetta.expression.RosettaExpression ;
51
+ import com.regnosys.rosetta.rosetta.expression.impl.ExpressionFactoryImpl ;
52
+ import com.regnosys.rosetta.rosetta.interpreter.RosettaInterpreterValue ;
53
+ import com.regnosys.rosetta.tests.RosettaInjectorProvider ;
54
+ import com.regnosys.rosetta.tests.util.ExpressionParser ;
55
+ import com.regnosys.rosetta.interpreternew.values.RosettaInterpreterNumberValue
56
+ import com.regnosys.rosetta.rosetta.simple.impl.FunctionImpl
57
+ import com.regnosys.rosetta.interpreternew.values.RosettaInterpreterEnvironment
58
+ import java.math.BigDecimal
59
+ import com.regnosys.rosetta.interpreternew.values.RosettaInterpreterNumberValue
60
+ import com.regnosys.rosetta.rosetta.expression.impl.RosettaSymbolReferenceImpl
61
+
62
+ @ExtendWith (InjectionExtension )
63
+ @InjectWith (RosettaInjectorProvider )
64
+ class RosettaInterpreterCompilerComparisonTest2 {
65
+
66
+ @Inject extension CodeGeneratorTestHelper
67
+ @Inject extension FunctionGeneratorHelper
68
+
69
+ @Inject
70
+ ExpressionParser parser;
71
+ @Inject
72
+ RosettaInterpreterNew interpreter;
73
+
74
+ @Inject
75
+ ModelHelper mh;
76
+
77
+ @Test
78
+ def void simpleTest2 () {
79
+ val model = ' ' '
80
+ func Foo:
81
+ output: b int (1..1)
82
+ set b: 5
83
+ ' ' ' . generateCode
84
+
85
+ // Biggest problem I see is that there's no just way to run a piece of code
86
+ // from the code text itself
87
+ // You need to tell it specifically what function its supposed to be
88
+ // creating, running and getting output from
89
+ // Though I guess it could be standardised by calling all functions
90
+ // the same and passing some arguments?
91
+ // This would require writing a lot of code manually and testing it for
92
+ // both runtime options
93
+ val classes = model. compileToClasses
94
+ val foo = classes. createFunc(' Foo' )
95
+ val output = foo. invokeFunc(Integer )
96
+
97
+ val expr = parser. parseExpression(" 5" )
98
+ val value = interpreter. interp(expr)
99
+
100
+ // If actually doing this then better approach would be
101
+ // To have like a helper method that converts a primitive type
102
+ // Into some value domain type to avoid having to manually set it
103
+ assertEquals(value, new RosettaInterpreterNumberValue (output))
104
+ }
105
+
106
+ @Test
107
+ def void simpleTest () {
108
+ val code = " func Add:\r\n "
109
+ + " inputs:"
110
+ + " a number (1..1)\r\n "
111
+ + " b int (1..1)\r\n "
112
+ + " output: result number (1..1)\r\n "
113
+ + " set result:\r\n "
114
+ + " a + b\r\n "
115
+ + " func MyTest:\r\n "
116
+ + " output: result number (1..1)\r\n "
117
+ + " set result:\r\n "
118
+ + " Add(1.0, 2.0)\r\n "
119
+ val model = mh. parseRosettaWithNoErrors(code)
120
+ val function = model. getElements(). get(0 ) as FunctionImpl
121
+ val ref = (model. getElements(). get(1 ) as FunctionImpl ). getOperations(). get(0 ). getExpression() as RosettaSymbolReferenceImpl
122
+ val env = interpreter. interp(function) as RosettaInterpreterEnvironment
123
+ val res = interpreter. interp(ref, env)
124
+
125
+ val classes = code. generateCode. compileToClasses
126
+ val myTest = classes. createFunc(' MyTest' )
127
+ val output = myTest. invokeFunc(BigDecimal )
128
+ println(output)
129
+
130
+ assertEquals(res, new RosettaInterpreterNumberValue (output))
131
+ }
132
+ }
133
+
134
+ // I couldn't get a way to import this so I just put it here??????
135
+ class FunctionGeneratorHelper {
136
+
137
+ @Inject FunctionGenerator generator
138
+ @Inject extension ModelHelper
139
+ @Inject extension CodeGeneratorTestHelper
140
+ @Inject RegisteringFileSystemAccess fsa
141
+
142
+ final Injector injector
143
+
144
+ new () {
145
+ injector = Guice . createInjector(new AbstractModule () {
146
+ override protected configure() {
147
+ bind(ConditionValidator ). toInstance(new DefaultConditionValidator )
148
+ bind(ModelObjectValidator ). toInstance(new NoOpModelObjectValidator )
149
+ }
150
+ })
151
+ }
152
+
153
+ def createFunc (Map<String , Class<?> > classes , String funcName ) {
154
+ injector. getInstance(classes. get(rootPackage. functions + ' .' + funcName)) as RosettaFunction
155
+ }
156
+
157
+ def < T > invokeFunc(RosettaFunction func, Class<T > resultClass, Object .. . inputs) {
158
+ val evaluateMethod = func. class. getMatchingMethod(" evaluate" , inputs. map[it ? . class])
159
+ try {
160
+ evaluateMethod. invoke(func, inputs) as T
161
+ } catch (InvocationTargetException e) {
162
+ throw e. cause
163
+ }
164
+ }
165
+
166
+ def void assertToGeneratedFunction (CharSequence actualModel , CharSequence expected ) throws AssertionError {
167
+ actualModel. assertToGenerated(expected, [
168
+ generator. generate(new RootPackage (it ), fsa, it . elements. filter(Function ). filter[operations. nullOrEmpty]. head, " test" )
169
+ ])
170
+ }
171
+
172
+ def void assertToGeneratedCalculation (CharSequence actualModel , CharSequence expected ) throws AssertionError {
173
+ actualModel. assertToGenerated(expected, [
174
+ generator. generate(new RootPackage (it ), fsa, it . elements. filter(Function ). filter[! operations. nullOrEmpty]. head, " test" )
175
+ ])
176
+ }
177
+
178
+ def protected void assertToGenerated (CharSequence actualModel , CharSequence expected ,
179
+ Consumer<RosettaModel > genCall ) throws AssertionError {
180
+ val model = actualModel. parseRosettaWithNoErrors
181
+ genCall. accept(model)
182
+ assertEquals(expected. toString, fsa. textFiles. entrySet. head. value)
183
+ }
184
+ }
0 commit comments