Skip to content

Commit 32cc879

Browse files
committed
[#761] Module jdmn-runtime-api: Add extra test coverage
1 parent 0a563f0 commit 32cc879

File tree

10 files changed

+367
-53
lines changed

10 files changed

+367
-53
lines changed

dmn-runtime-api/src/main/java/com/gs/dmn/runtime/external/DefaultExternalFunctionExecutor.java

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -18,37 +18,11 @@
1818

1919
import java.lang.reflect.Method;
2020
import java.lang.reflect.Modifier;
21-
import java.util.Arrays;
2221
import java.util.List;
23-
import java.util.stream.Collectors;
2422

2523
public class DefaultExternalFunctionExecutor implements ExternalFunctionExecutor {
2624
private static final Logger LOGGER = LoggerFactory.getLogger(DefaultExternalFunctionExecutor.class);
2725

28-
@Override
29-
public Object execute(String className, String methodName, Object[] args) {
30-
try {
31-
Class<?> cls = Class.forName(className);
32-
Method[] methods = cls.getMethods();
33-
for(Method m: methods) {
34-
if (methodName.equals(m.getName())) {
35-
Object instance = null;
36-
if (!Modifier.isStatic(m.getModifiers())) {
37-
instance = cls.getDeclaredConstructor().newInstance();
38-
}
39-
return m.invoke(instance, args);
40-
}
41-
}
42-
throw new DMNRuntimeException(String.format("Cannot execute external function '%s.%s(%s)'", className, methodName, argsToString(args)));
43-
} catch (Exception e) {
44-
throw new DMNRuntimeException(String.format("Cannot execute external function '%s.%s(%s)'", className, methodName, argsToString(args)), e);
45-
}
46-
}
47-
48-
private String argsToString(Object[] args) {
49-
return Arrays.stream(args).map(o -> o == null ? "null" : o.toString()).collect(Collectors.joining(", "));
50-
}
51-
5226
@Override
5327
public Object execute(JavaFunctionInfo info, List<Object> argList) {
5428
String className = info.getClassName();

dmn-runtime-api/src/main/java/com/gs/dmn/runtime/external/ExternalFunctionExecutor.java

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,5 @@
1515
import java.util.List;
1616

1717
public interface ExternalFunctionExecutor {
18-
@Deprecated
19-
Object execute(String className, String methodName, Object[] args);
20-
2118
Object execute(JavaFunctionInfo info, List<Object> argList);
2219
}

dmn-runtime-api/src/main/java/com/gs/dmn/runtime/external/JavaFunctionInfo.java

Lines changed: 14 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -75,55 +75,45 @@ public List<Object> convertArguments(List<Object> argList) {
7575
Object arg = argList.get(i);
7676
String javaParamType = javaParamTypes.get(i);
7777
if ("double".equals(javaParamType)) {
78-
if (arg instanceof BigDecimal) {
79-
convertedArgList.add(((BigDecimal) arg).doubleValue());
80-
} else if (arg instanceof Double) {
81-
convertedArgList.add(arg);
78+
if (arg instanceof Number) {
79+
convertedArgList.add(((Number) arg).doubleValue());
8280
} else {
8381
throw new DMNRuntimeException(String.format("Conversion from '%s' to '%s' is not supported yet", arg.getClass().getSimpleName(), javaParamType));
8482
}
8583
} else if ("float".equals(javaParamType)) {
86-
if (arg instanceof BigDecimal) {
87-
convertedArgList.add((float) ((BigDecimal) arg).doubleValue());
88-
} else if (arg instanceof Double) {
89-
convertedArgList.add((float) ((Double) arg).doubleValue());
84+
if (arg instanceof Number) {
85+
convertedArgList.add((float) ((Number) arg).doubleValue());
9086
} else {
9187
throw new DMNRuntimeException(String.format("Conversion from '%s' to '%s' is not supported yet", arg.getClass().getSimpleName(), javaParamType));
9288
}
9389
} else if ("long".equals(javaParamType)) {
94-
if (arg instanceof BigDecimal) {
90+
if (arg instanceof Number) {
9591
convertedArgList.add((long)((BigDecimal) arg).intValue());
96-
} else if (arg instanceof Double) {
97-
convertedArgList.add(((Double) arg).intValue());
9892
} else {
9993
throw new DMNRuntimeException(String.format("Conversion from '%s' to '%s' is not supported yet", arg.getClass().getSimpleName(), javaParamType));
10094
}
10195
} else if ("int".equals(javaParamType)) {
102-
if (arg instanceof BigDecimal) {
103-
convertedArgList.add(((BigDecimal) arg).intValue());
104-
} else if (arg instanceof Double) {
105-
convertedArgList.add(((Double) arg).intValue());
96+
if (arg instanceof Number) {
97+
convertedArgList.add(((Number) arg).intValue());
10698
} else {
10799
throw new DMNRuntimeException(String.format("Conversion from '%s' to '%s' is not supported yet", arg.getClass().getSimpleName(), javaParamType));
108100
}
109101
} else if ("short".equals(javaParamType)) {
110-
if (arg instanceof BigDecimal) {
111-
convertedArgList.add((short)((BigDecimal) arg).intValue());
112-
} else if (arg instanceof Double) {
113-
convertedArgList.add((short)((Double) arg).intValue());
102+
if (arg instanceof Number) {
103+
convertedArgList.add((short)((Number) arg).intValue());
114104
} else {
115105
throw new DMNRuntimeException(String.format("Conversion from '%s' to '%s' is not supported yet", arg.getClass().getSimpleName(), javaParamType));
116106
}
117107
} else if ("byte".equals(javaParamType)) {
118-
if (arg instanceof BigDecimal) {
119-
convertedArgList.add((byte)((BigDecimal) arg).intValue());
120-
} else if (arg instanceof Double) {
121-
convertedArgList.add((byte)((Double) arg).intValue());
108+
if (arg instanceof Number) {
109+
convertedArgList.add((byte)((Number) arg).intValue());
122110
} else {
123111
throw new DMNRuntimeException(String.format("Conversion from '%s' to '%s' is not supported yet", arg.getClass().getSimpleName(), javaParamType));
124112
}
125113
} else if ("char".equals(javaParamType)) {
126-
if (arg instanceof String) {
114+
if (arg instanceof Character) {
115+
convertedArgList.add(arg);
116+
} else if (arg instanceof String) {
127117
if (((String) arg).length() == 1) {
128118
convertedArgList.add(((String) arg).charAt(0));
129119
} else {
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/*
2+
* Copyright 2016 Goldman Sachs.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.
5+
*
6+
* You may obtain a copy of the License at
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an
10+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
11+
* specific language governing permissions and limitations under the License.
12+
*/
13+
package com.gs.dmn.runtime;
14+
15+
import com.gs.dmn.runtime.discovery.ModelElementRegistry;
16+
import org.junit.jupiter.api.Test;
17+
18+
import java.util.Map;
19+
20+
import static org.junit.jupiter.api.Assertions.*;
21+
22+
class ExecutorTest {
23+
@Test
24+
void testExecute() {
25+
ModelElementRegistry registry = new ModelElementRegistry();
26+
registry.register("className", "com.gs.dmn.runtime.ExecutableElement");
27+
28+
Executor executor = new Executor(registry);
29+
Object result = executor.execute("className", null, null);
30+
assertEquals("123", result);
31+
}
32+
33+
@Test
34+
void testExecuteWhenNotRegistered() {
35+
ModelElementRegistry registry = new ModelElementRegistry();
36+
37+
Executor executor = new Executor(registry);
38+
DMNRuntimeException exception = assertThrows(DMNRuntimeException.class, () -> executor.execute("className", null, null));
39+
assertEquals("Element 'className' is not registered. Registered elements are []", exception.getMessage());
40+
}
41+
42+
@Test
43+
void testExecuteWhenRegisteredClassDoesNotExist() {
44+
ModelElementRegistry registry = new ModelElementRegistry();
45+
registry.register("className", "com.gs.dmn.runtime.MissingExecutableElement");
46+
47+
Executor executor = new Executor(registry);
48+
DMNRuntimeException exception = assertThrows(DMNRuntimeException.class, () -> executor.execute("className", null, null));
49+
assertEquals("Cannot instantiate class 'com.gs.dmn.runtime.MissingExecutableElement' for name 'className'", exception.getMessage());
50+
}
51+
}
52+
53+
class ExecutableElement implements ExecutableDRGElement {
54+
public ExecutableElement() {
55+
}
56+
57+
@Override
58+
public Object applyMap(Map<String, String> input_, ExecutionContext context_) {
59+
return "123";
60+
}
61+
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/*
2+
* Copyright 2016 Goldman Sachs.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.
5+
*
6+
* You may obtain a copy of the License at
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an
10+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
11+
* specific language governing permissions and limitations under the License.
12+
*/
13+
package com.gs.dmn.runtime.cache;
14+
15+
import org.junit.jupiter.api.Test;
16+
17+
import static org.junit.jupiter.api.Assertions.*;
18+
19+
class DefaultCacheTest {
20+
private final String key = "key";
21+
private final String value = "value";
22+
23+
@Test
24+
void testContains() {
25+
Cache cache = new DefaultCache();
26+
cache.bind(key, value);
27+
28+
assertTrue(cache.contains(key));
29+
assertFalse(cache.contains("otherKey"));
30+
}
31+
32+
@Test
33+
void testBind() {
34+
Cache cache = new DefaultCache();
35+
36+
assertFalse(cache.contains(key));
37+
cache.bind(key, value);
38+
assertTrue(cache.contains(key));
39+
}
40+
41+
@Test
42+
void testLookup() {
43+
Cache cache = new DefaultCache();
44+
45+
assertNull(cache.lookup(key));
46+
cache.bind(key, value);
47+
assertEquals(value, cache.lookup(key));
48+
}
49+
50+
@Test
51+
void testClear() {
52+
Cache cache = new DefaultCache();
53+
cache.bind(key, value);
54+
55+
assertEquals(value, cache.lookup(key));
56+
cache.clear();
57+
assertNull(cache.lookup(key));
58+
}
59+
}

dmn-runtime-api/src/test/java/com/gs/dmn/runtime/discovery/ModelElementDiscoveryTest.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,13 @@ public void testGetDRGElementAnnotation() {
3939

4040
@Test
4141
public void testGetRuleAnnotation() {
42+
Rule ruleAnnotation = this.modelElementDiscovery.getRuleAnnotation(NopDecision.class, 0);
43+
assertEquals("abc", ruleAnnotation.annotation());
44+
assertEquals(0, ruleAnnotation.index());
45+
}
46+
47+
@Test
48+
public void testGetRuleAnnotationWhenMissing() {
4249
Rule ruleAnnotation = this.modelElementDiscovery.getRuleAnnotation(Decision.class, 0);
4350
assertNull(ruleAnnotation);
4451
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/*
2+
* Copyright 2016 Goldman Sachs.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.
5+
*
6+
* You may obtain a copy of the License at
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an
10+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
11+
* specific language governing permissions and limitations under the License.
12+
*/
13+
package com.gs.dmn.runtime.discovery;
14+
15+
import com.gs.dmn.runtime.DMNRuntimeException;
16+
import org.junit.jupiter.api.Assertions;
17+
import org.junit.jupiter.api.Test;
18+
19+
import java.util.Collections;
20+
import java.util.LinkedHashSet;
21+
import java.util.Set;
22+
23+
import static org.junit.jupiter.api.Assertions.*;
24+
25+
class ModelElementRegistryTest {
26+
private final String qName = "qName";
27+
private final String className = "className";
28+
29+
@Test
30+
void testRegistration() {
31+
ModelElementRegistry registry = new ModelElementRegistry();
32+
registry.register(qName, className);
33+
34+
assertEquals(className, registry.discover(qName));
35+
Set<String> expectKeys = new LinkedHashSet<>(Collections.singletonList(qName));
36+
assertEquals(expectKeys, registry.keys());
37+
}
38+
39+
@Test
40+
void testRegistrationForNulls() {
41+
ModelElementRegistry registry = new ModelElementRegistry();
42+
43+
Assertions.assertThrows(NullPointerException.class, () -> registry.register(null, className));
44+
45+
Assertions.assertThrows(NullPointerException.class, () -> registry.register(qName, null));
46+
}
47+
48+
@Test
49+
void testRegistrationForExistingWithDifferentValue() {
50+
ModelElementRegistry registry = new ModelElementRegistry();
51+
52+
registry.register(qName, "otherName");
53+
Assertions.assertThrows(DMNRuntimeException.class, () -> registry.register(qName, className));
54+
55+
}
56+
57+
@Test
58+
void testRegistrationForExistingWithSameValue() {
59+
ModelElementRegistry registry = new ModelElementRegistry();
60+
61+
registry.register(qName, className);
62+
assertEquals(1, registry.keys().size());
63+
registry.register(qName, className);
64+
assertEquals(1, registry.keys().size());
65+
}
66+
}

dmn-runtime-api/src/test/java/com/gs/dmn/runtime/discovery/NopDecision.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,8 @@
2424
rulesCount = -1
2525
)
2626
public class NopDecision {
27+
@com.gs.dmn.runtime.annotation.Rule(index = 0, annotation = "abc")
28+
public int rule0() {
29+
return 0;
30+
}
2731
}

0 commit comments

Comments
 (0)