From 404c29110a96a53214d87cc780bbb67288ba24ea Mon Sep 17 00:00:00 2001 From: bncriju Date: Thu, 20 Feb 2025 20:16:09 +0530 Subject: [PATCH 01/20] null returned from lambda -issue fixed and added tests --- .../kie/dmn/feel/lang/types/GenFnType.java | 25 ++++---- .../feel/runtime/functions/AbsFunction.java | 2 +- .../dmn/feel/lang/types/GenFnTypeTest.java | 61 +++++++++++++++++++ 3 files changed, 75 insertions(+), 13 deletions(-) create mode 100644 kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/lang/types/GenFnTypeTest.java diff --git a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/types/GenFnType.java b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/types/GenFnType.java index fa14a9b8b22..3c4d5f731d1 100644 --- a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/types/GenFnType.java +++ b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/types/GenFnType.java @@ -16,11 +16,11 @@ * specific language governing permissions and limitations * under the License. */ + package org.kie.dmn.feel.lang.types; import java.util.ArrayList; import java.util.List; -import java.util.stream.Collectors; import java.util.stream.IntStream; import org.kie.dmn.feel.lang.SimpleType; @@ -40,18 +40,20 @@ public GenFnType(List argsGen, Type returnGen) { @Override public boolean isInstanceOf(Object o) { - if (o instanceof FEELFunction) { - FEELFunction oFn = (FEELFunction) o; - List> signatures = oFn.getParameters().stream().filter(signature -> signature.size() == argsGen.size()).collect(Collectors.toList()); + if (o instanceof FEELFunction oFn) { + List> parameters = oFn.getParameters(); + if(parameters.isEmpty()){ + /* this is used to consider function as parameter*/ + return true; + } + List> signatures = parameters.stream().filter(signature -> signature.size() == argsGen.size()).toList(); for (List signature : signatures) { if (signature.size() == argsGen.size() && IntStream.range(0, argsGen.size()).allMatch(i -> argsGen.get(i).conformsTo(signature.get(i).type))) { return true; } } - return false; - } else { - return false; } + return false; } @Override @@ -69,13 +71,12 @@ public String getName() { @Override public boolean conformsTo(Type t) { - if (t instanceof GenFnType) { - GenFnType fnT = (GenFnType) t; + if (t instanceof GenFnType fnT) { return fnT.argsGen.size() == this.argsGen.size() && - IntStream.range(0, argsGen.size()).allMatch(i -> fnT.argsGen.get(i).conformsTo(this.argsGen.get(i))) && - this.returnGen.conformsTo(fnT.returnGen); + IntStream.range(0, argsGen.size()).allMatch(i -> fnT.argsGen.get(i).conformsTo(this.argsGen.get(i))) && + this.returnGen.conformsTo(fnT.returnGen); } else { return t == BuiltInType.FUNCTION; } } -} +} \ No newline at end of file diff --git a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/functions/AbsFunction.java b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/functions/AbsFunction.java index aa302246c41..4131f9e261d 100644 --- a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/functions/AbsFunction.java +++ b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/functions/AbsFunction.java @@ -31,7 +31,7 @@ public class AbsFunction extends BaseFEELFunction implements FEELNumberFunction { public static final AbsFunction INSTANCE = new AbsFunction(); - private AbsFunction() { + public AbsFunction() { super( "abs" ); } diff --git a/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/lang/types/GenFnTypeTest.java b/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/lang/types/GenFnTypeTest.java new file mode 100644 index 00000000000..775ec2f58f1 --- /dev/null +++ b/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/lang/types/GenFnTypeTest.java @@ -0,0 +1,61 @@ +package org.kie.dmn.feel.lang.types; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.jupiter.api.Test; +import org.kie.dmn.feel.runtime.functions.AbsFunction; +import org.kie.dmn.feel.runtime.functions.AnyFunction; +import org.kie.dmn.feel.runtime.functions.FEELFnResult; + +import java.util.Arrays; +import java.util.Collections; + +class GenFnTypeTest { + + private static final AnyFunction anyFunction = AnyFunction.INSTANCE; + private final GenFnType genFnType = new GenFnType(Arrays.asList(null, null), null);; + + @Test + public void testIsInstanceOfWithNoParameters() { + AbsFunction functionWithNoParams = new AbsFunction(); + assertThat(genFnType.isInstanceOf(functionWithNoParams)).isTrue(); + } + + @Test + public void testIsInstanceOfWithNonMatchingParameters() { + FEELFnResult feelFn = anyFunction.invoke(new Object[]{Boolean.TRUE, Boolean.TRUE}); + assertThat(genFnType.isInstanceOf(feelFn)).isFalse(); + } + + + @Test + public void testIsInstanceOfWithMatchingFunctionSignature() { + GenFnType matchingGenFnType = new GenFnType(Arrays.asList(null, null), null); + AbsFunction matchingFunction = new AbsFunction(); + assertThat(matchingGenFnType.isInstanceOf(matchingFunction)).isTrue(); + } + + @Test + public void testIsAssignableValueWithNullValue() { + assertThat(genFnType.isAssignableValue(null)).isTrue(); + } + + @Test + public void testIsAssignableValueWithFunction() { + AbsFunction functionWithNoParams = new AbsFunction(); + assertThat(genFnType.isAssignableValue(functionWithNoParams)).isTrue(); + } + + + @Test + public void testConformsToWithSignature() { + GenFnType matchingGenFnType = new GenFnType(Collections.singletonList(null), null); + assertThat(genFnType.conformsTo(matchingGenFnType)).isFalse(); + } + + @Test + public void testConformsToWithFunctionType() { + assertThat(genFnType.conformsTo(BuiltInType.FUNCTION)).isTrue(); + } + +} \ No newline at end of file From f5731cddf6f0d23700c1633f6687e4c599ad1c82 Mon Sep 17 00:00:00 2001 From: bncriju Date: Thu, 20 Feb 2025 20:42:46 +0530 Subject: [PATCH 02/20] Restored singleton patterns for functions used for test --- .../dmn/feel/runtime/functions/AbsFunction.java | 2 +- .../org/kie/dmn/feel/lang/types/GenFnTypeTest.java | 14 ++++++-------- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/functions/AbsFunction.java b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/functions/AbsFunction.java index 4131f9e261d..aa302246c41 100644 --- a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/functions/AbsFunction.java +++ b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/functions/AbsFunction.java @@ -31,7 +31,7 @@ public class AbsFunction extends BaseFEELFunction implements FEELNumberFunction { public static final AbsFunction INSTANCE = new AbsFunction(); - public AbsFunction() { + private AbsFunction() { super( "abs" ); } diff --git a/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/lang/types/GenFnTypeTest.java b/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/lang/types/GenFnTypeTest.java index 775ec2f58f1..272824e39a6 100644 --- a/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/lang/types/GenFnTypeTest.java +++ b/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/lang/types/GenFnTypeTest.java @@ -12,18 +12,18 @@ class GenFnTypeTest { - private static final AnyFunction anyFunction = AnyFunction.INSTANCE; + private static final AbsFunction absFunctionInstance = AbsFunction.INSTANCE; + private static final AnyFunction anyFunctionInstance = AnyFunction.INSTANCE; private final GenFnType genFnType = new GenFnType(Arrays.asList(null, null), null);; @Test public void testIsInstanceOfWithNoParameters() { - AbsFunction functionWithNoParams = new AbsFunction(); - assertThat(genFnType.isInstanceOf(functionWithNoParams)).isTrue(); + assertThat(genFnType.isInstanceOf(absFunctionInstance)).isTrue(); } @Test public void testIsInstanceOfWithNonMatchingParameters() { - FEELFnResult feelFn = anyFunction.invoke(new Object[]{Boolean.TRUE, Boolean.TRUE}); + FEELFnResult feelFn = anyFunctionInstance.invoke(new Object[]{Boolean.TRUE, Boolean.TRUE}); assertThat(genFnType.isInstanceOf(feelFn)).isFalse(); } @@ -31,8 +31,7 @@ public void testIsInstanceOfWithNonMatchingParameters() { @Test public void testIsInstanceOfWithMatchingFunctionSignature() { GenFnType matchingGenFnType = new GenFnType(Arrays.asList(null, null), null); - AbsFunction matchingFunction = new AbsFunction(); - assertThat(matchingGenFnType.isInstanceOf(matchingFunction)).isTrue(); + assertThat(matchingGenFnType.isInstanceOf(absFunctionInstance)).isTrue(); } @Test @@ -42,8 +41,7 @@ public void testIsAssignableValueWithNullValue() { @Test public void testIsAssignableValueWithFunction() { - AbsFunction functionWithNoParams = new AbsFunction(); - assertThat(genFnType.isAssignableValue(functionWithNoParams)).isTrue(); + assertThat(genFnType.isAssignableValue(absFunctionInstance)).isTrue(); } From 367f0e1919ca8ccbe1301ba185291711adc3b44b Mon Sep 17 00:00:00 2001 From: bncriju Date: Mon, 24 Feb 2025 12:08:27 +0530 Subject: [PATCH 03/20] Refactored test class and added more tests --- .../kie/dmn/feel/lang/types/GenFnType.java | 19 ++- .../dmn/feel/lang/types/GenFnTypeTest.java | 159 +++++++++++++++++- 2 files changed, 166 insertions(+), 12 deletions(-) diff --git a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/types/GenFnType.java b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/types/GenFnType.java index 3c4d5f731d1..6a3671dbb7f 100644 --- a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/types/GenFnType.java +++ b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/types/GenFnType.java @@ -43,15 +43,10 @@ public boolean isInstanceOf(Object o) { if (o instanceof FEELFunction oFn) { List> parameters = oFn.getParameters(); if(parameters.isEmpty()){ - /* this is used to consider function as parameter*/ + //this is used to consider function as parameter return true; } - List> signatures = parameters.stream().filter(signature -> signature.size() == argsGen.size()).toList(); - for (List signature : signatures) { - if (signature.size() == argsGen.size() && IntStream.range(0, argsGen.size()).allMatch(i -> argsGen.get(i).conformsTo(signature.get(i).type))) { - return true; - } - } + return checkSignatures(parameters,argsGen); } return false; } @@ -79,4 +74,14 @@ public boolean conformsTo(Type t) { return t == BuiltInType.FUNCTION; } } + + static boolean checkSignatures(List> parameters, List argsGen){ + List> signatures = parameters.stream().filter(signature -> signature.size() == argsGen.size()).toList(); + for (List signature : signatures) { + if (signature.size() == argsGen.size() && IntStream.range(0, argsGen.size()).allMatch(i -> argsGen.get(i).conformsTo(signature.get(i).type))) { + return true; + } + } + return false; + } } \ No newline at end of file diff --git a/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/lang/types/GenFnTypeTest.java b/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/lang/types/GenFnTypeTest.java index 272824e39a6..15b56985738 100644 --- a/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/lang/types/GenFnTypeTest.java +++ b/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/lang/types/GenFnTypeTest.java @@ -3,18 +3,26 @@ import static org.assertj.core.api.Assertions.assertThat; import org.junit.jupiter.api.Test; +import org.kie.dmn.feel.lang.Type; import org.kie.dmn.feel.runtime.functions.AbsFunction; import org.kie.dmn.feel.runtime.functions.AnyFunction; import org.kie.dmn.feel.runtime.functions.FEELFnResult; +import org.kie.dmn.feel.runtime.FEELFunction.Param; import java.util.Arrays; import java.util.Collections; +import java.util.List; +import java.util.ArrayList; class GenFnTypeTest { private static final AbsFunction absFunctionInstance = AbsFunction.INSTANCE; private static final AnyFunction anyFunctionInstance = AnyFunction.INSTANCE; - private final GenFnType genFnType = new GenFnType(Arrays.asList(null, null), null);; + + private final GenFnType genFnType = new GenFnType( + Arrays.asList(new SomeType(), new AnotherType()), + new SomeType() + ); @Test public void testIsInstanceOfWithNoParameters() { @@ -27,10 +35,12 @@ public void testIsInstanceOfWithNonMatchingParameters() { assertThat(genFnType.isInstanceOf(feelFn)).isFalse(); } - @Test public void testIsInstanceOfWithMatchingFunctionSignature() { - GenFnType matchingGenFnType = new GenFnType(Arrays.asList(null, null), null); + GenFnType matchingGenFnType = new GenFnType( + Arrays.asList(new SomeType(), new AnotherType()), + new SomeType() + ); assertThat(matchingGenFnType.isInstanceOf(absFunctionInstance)).isTrue(); } @@ -44,10 +54,12 @@ public void testIsAssignableValueWithFunction() { assertThat(genFnType.isAssignableValue(absFunctionInstance)).isTrue(); } - @Test public void testConformsToWithSignature() { - GenFnType matchingGenFnType = new GenFnType(Collections.singletonList(null), null); + GenFnType matchingGenFnType = new GenFnType( + Collections.singletonList(new SomeType()), + new SomeType() + ); assertThat(genFnType.conformsTo(matchingGenFnType)).isFalse(); } @@ -56,4 +68,141 @@ public void testConformsToWithFunctionType() { assertThat(genFnType.conformsTo(BuiltInType.FUNCTION)).isTrue(); } + @Test + void testCheckSignatures_withMatchingSignatures() { + List argsGen = Arrays.asList(new SomeType(), new AnotherType()); + List paramTypes = Arrays.asList(new SomeType(), new AnotherType()); + List paramNames = Arrays.asList("param1", "param2"); + List> params = createParams(paramTypes, paramNames); + + assertThat(GenFnType.checkSignatures(params, argsGen)).isTrue(); + } + + @Test + void testCheckSignatures_withNonMatchingSignatures() { + List argsGen = Arrays.asList(new SomeType(), new AnotherType()); + List paramTypes = Arrays.asList(new SomeType(), new YetAnotherType()); + List paramNames = Arrays.asList("param1", "param2"); + List> params = createParams(paramTypes, paramNames); + + assertThat(GenFnType.checkSignatures(params, argsGen)).isFalse(); + } + + @Test + void testCheckSignatures_withSignatureSizeMismatch() { + List argsGen = Arrays.asList(new SomeType(), new AnotherType()); + List paramTypes = List.of(new SomeType()); + List paramNames = List.of("param1"); + List> params = createParams(paramTypes, paramNames); + + assertThat(GenFnType.checkSignatures(params, argsGen)).isFalse(); + } + + @Test + void testCheckSignatures_withEmptyParams() { + List argsGen = Arrays.asList(new SomeType(), new AnotherType()); + List> params = List.of(); + + assertThat(GenFnType.checkSignatures(params, argsGen)).isFalse(); + } + + @Test + void testCheckSignatures_withEmptyArgsGen() { + List argsGen = List.of(); + List paramTypes = Arrays.asList(new SomeType(), new AnotherType()); + List paramNames = Arrays.asList("param1", "param2"); + List> params = createParams(paramTypes, paramNames); + + assertThat(GenFnType.checkSignatures(params, argsGen)).isFalse(); + } + + @Test + void testCheckSignatures_withMatchingEmptySignature() { + List argsGen = List.of(); + List> params = List.of(); + + assertThat(GenFnType.checkSignatures(params, argsGen)).isFalse(); + } + + static class SomeType implements Type { + @Override + public String getName() { + return "SomeType"; + } + + @Override + public boolean isInstanceOf(Object o) { + return o instanceof SomeType; + } + + @Override + public boolean isAssignableValue(Object value) { + return value instanceof SomeType; + } + + @Override + public boolean conformsTo(Type t) { + return t instanceof SomeType; + } + } + + static class AnotherType implements Type { + @Override + public String getName() { + return "AnotherType"; + } + + @Override + public boolean isInstanceOf(Object o) { + return o instanceof AnotherType; + } + + @Override + public boolean isAssignableValue(Object value) { + return value instanceof AnotherType; + } + + @Override + public boolean conformsTo(Type t) { + return t instanceof AnotherType; + } + } + + static class YetAnotherType implements Type { + @Override + public String getName() { + return "YetAnotherType"; + } + + @Override + public boolean isInstanceOf(Object o) { + return o instanceof YetAnotherType; + } + + @Override + public boolean isAssignableValue(Object value) { + return value instanceof YetAnotherType; + } + + @Override + public boolean conformsTo(Type t) { + return t instanceof YetAnotherType; + } + } + + private List> createParams(List types, List names) { + if (types.size() != names.size()) { + throw new IllegalArgumentException("The number of types and names must match"); + } + + List> params = new ArrayList<>(); + List paramList = new ArrayList<>(); + + for (int i = 0; i < types.size(); i++) { + paramList.add(new Param(names.get(i), types.get(i))); + } + + params.add(paramList); + return params; + } } \ No newline at end of file From 8bc77b260464db2c6b797b83f489bd05b843c4a3 Mon Sep 17 00:00:00 2001 From: bncriju Date: Mon, 24 Feb 2025 14:26:37 +0530 Subject: [PATCH 04/20] Added apache header on new class --- .../dmn/feel/lang/types/GenFnTypeTest.java | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/lang/types/GenFnTypeTest.java b/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/lang/types/GenFnTypeTest.java index 15b56985738..9fe912f83af 100644 --- a/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/lang/types/GenFnTypeTest.java +++ b/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/lang/types/GenFnTypeTest.java @@ -1,3 +1,22 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + package org.kie.dmn.feel.lang.types; import static org.assertj.core.api.Assertions.assertThat; From 5d4b68ff41e25b7de5daf63c7d0b22acf35af4de Mon Sep 17 00:00:00 2001 From: bncriju Date: Mon, 24 Feb 2025 18:23:00 +0530 Subject: [PATCH 05/20] making doc correct --- .../src/main/java/org/kie/dmn/feel/lang/types/GenFnType.java | 3 ++- .../test/java/org/kie/dmn/feel/lang/types/GenFnTypeTest.java | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/types/GenFnType.java b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/types/GenFnType.java index 6a3671dbb7f..923d4894e69 100644 --- a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/types/GenFnType.java +++ b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/types/GenFnType.java @@ -1,4 +1,5 @@ -/** +/* + * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information diff --git a/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/lang/types/GenFnTypeTest.java b/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/lang/types/GenFnTypeTest.java index 9fe912f83af..2bb6b803155 100644 --- a/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/lang/types/GenFnTypeTest.java +++ b/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/lang/types/GenFnTypeTest.java @@ -1,4 +1,5 @@ -/** +/* + * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information From c0123fbceffb650f963b13e6fa1e6b81b8be8c37 Mon Sep 17 00:00:00 2001 From: bncriju Date: Wed, 26 Feb 2025 19:19:49 +0530 Subject: [PATCH 06/20] checking invoke method and incorporating review comments --- .../kie/dmn/feel/lang/types/GenFnType.java | 41 +++++++----- .../runtime/functions/BaseFEELFunction.java | 39 +++++++++++ .../functions/BaseFEELFunctionHelper.java | 24 +++++++ .../dmn/feel/lang/types/GenFnTypeTest.java | 66 ++++++++++++++++++- 4 files changed, 152 insertions(+), 18 deletions(-) diff --git a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/types/GenFnType.java b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/types/GenFnType.java index 923d4894e69..1eb0091321b 100644 --- a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/types/GenFnType.java +++ b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/types/GenFnType.java @@ -1,5 +1,4 @@ /* - * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information @@ -19,42 +18,50 @@ */ package org.kie.dmn.feel.lang.types; - import java.util.ArrayList; import java.util.List; import java.util.stream.IntStream; +import org.kie.dmn.feel.lang.EvaluationContext; import org.kie.dmn.feel.lang.SimpleType; import org.kie.dmn.feel.lang.Type; import org.kie.dmn.feel.runtime.FEELFunction; import org.kie.dmn.feel.runtime.FEELFunction.Param; +import org.kie.dmn.feel.runtime.functions.BaseFEELFunction; + public class GenFnType implements SimpleType { - private final List argsGen; - private final Type returnGen; + private final List evaluatedTypeArgs; + private final Type functionReturnType; - public GenFnType(List argsGen, Type returnGen) { - this.argsGen = new ArrayList<>(argsGen); - this.returnGen = returnGen; + public GenFnType(List evaluatedTypeArgs, Type functionReturnType) { + this.evaluatedTypeArgs = new ArrayList<>(evaluatedTypeArgs); + this.functionReturnType = functionReturnType; } @Override public boolean isInstanceOf(Object o) { if (o instanceof FEELFunction oFn) { - List> parameters = oFn.getParameters(); - if(parameters.isEmpty()){ + BaseFEELFunction baseFEELFunction=new BaseFEELFunction("Base Feel Function") { + @Override + public CandidateMethod getCandidateMethod(EvaluationContext ctx, Type[] types, boolean isNamedParams) { + return super.getCandidateMethod(ctx, types, isNamedParams); + } + }; + List> currentGenFnTypeParams = oFn.getParameters(); + if (currentGenFnTypeParams.isEmpty()) { //this is used to consider function as parameter return true; } - return checkSignatures(parameters,argsGen); + return checkSignatures(currentGenFnTypeParams, evaluatedTypeArgs) && baseFEELFunction.getCandidateMethod(oFn, evaluatedTypeArgs, currentGenFnTypeParams); } return false; } @Override public boolean isAssignableValue(Object value) { - if ( value == null ) { + if (value == null) { return true; // a null-value can be assigned to any type. } return isInstanceOf(value); @@ -68,18 +75,18 @@ public String getName() { @Override public boolean conformsTo(Type t) { if (t instanceof GenFnType fnT) { - return fnT.argsGen.size() == this.argsGen.size() && - IntStream.range(0, argsGen.size()).allMatch(i -> fnT.argsGen.get(i).conformsTo(this.argsGen.get(i))) && - this.returnGen.conformsTo(fnT.returnGen); + return fnT.evaluatedTypeArgs.size() == this.evaluatedTypeArgs.size() && + IntStream.range(0, evaluatedTypeArgs.size()).allMatch(i -> fnT.evaluatedTypeArgs.get(i).conformsTo(this.evaluatedTypeArgs.get(i))) && + this.functionReturnType.conformsTo(fnT.functionReturnType); } else { return t == BuiltInType.FUNCTION; } } - static boolean checkSignatures(List> parameters, List argsGen){ - List> signatures = parameters.stream().filter(signature -> signature.size() == argsGen.size()).toList(); + static boolean checkSignatures(List> currentGenFnTypeParams, List evaluatedTypeArgs) { + List> signatures = currentGenFnTypeParams.stream().filter(signature -> signature.size() == evaluatedTypeArgs.size()).toList(); for (List signature : signatures) { - if (signature.size() == argsGen.size() && IntStream.range(0, argsGen.size()).allMatch(i -> argsGen.get(i).conformsTo(signature.get(i).type))) { + if (signature.size() == evaluatedTypeArgs.size() && IntStream.range(0, evaluatedTypeArgs.size()).allMatch(i -> evaluatedTypeArgs.get(i).conformsTo(signature.get(i).type))) { return true; } } diff --git a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/functions/BaseFEELFunction.java b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/functions/BaseFEELFunction.java index b8b33bbe21a..aaca91227c1 100644 --- a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/functions/BaseFEELFunction.java +++ b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/functions/BaseFEELFunction.java @@ -34,6 +34,7 @@ import org.kie.dmn.feel.lang.EvaluationContext; import org.kie.dmn.feel.lang.FEELDialect; import org.kie.dmn.feel.lang.Symbol; +import org.kie.dmn.feel.lang.Type; import org.kie.dmn.feel.lang.impl.NamedParameter; import org.kie.dmn.feel.lang.types.FunctionSymbol; import org.kie.dmn.feel.runtime.FEELFunction; @@ -186,6 +187,26 @@ protected CandidateMethod getCandidateMethod(EvaluationContext ctx, Object[] ori return toReturn; } + protected CandidateMethod getCandidateMethod(EvaluationContext ctx, Type[] types, boolean isNamedParams) { + CandidateMethod toReturn = null; + for (Method method : getClass().getDeclaredMethods()) { + if (Modifier.isPublic(method.getModifiers()) && method.getName().equals("invoke")) { + CandidateMethod candidateMethod = getCandidateMethod(ctx, types, isNamedParams, method); + if (candidateMethod == null) { + continue; + } + if (toReturn == null) { + toReturn = candidateMethod; + } else if (candidateMethod.score > toReturn.score) { + toReturn = candidateMethod; + } else if (candidateMethod.score == toReturn.score) { + toReturn = getBestScoredCandidateMethod(types, candidateMethod, toReturn); + } + } + } + return toReturn; + } + private CandidateMethod getCandidateMethod(EvaluationContext ctx, Object[] originalInput, boolean isNamedParams, Method m) { Object[] adaptedInput = BaseFEELFunctionHelper.getAdjustedParametersForMethod(ctx, originalInput, @@ -204,6 +225,24 @@ private CandidateMethod getCandidateMethod(EvaluationContext ctx, Object[] origi return new CandidateMethod(m, ScoreHelper.grossScore(compares), adaptedInput); } + private CandidateMethod getCandidateMethod(EvaluationContext ctx, Type[] types, + boolean isNamedParams, Method m) { + Object[] adaptedType = BaseFEELFunctionHelper.getAdjustedParametersForMethod(ctx, types, + isNamedParams, m); + if (adaptedType == null) { + // incompatible method + return null; + } + + Class[] parameterTypes = m.getParameterTypes(); + if (parameterTypes.length != adaptedType.length) { + return null; + } + + ScoreHelper.Compares compares = new ScoreHelper.Compares(types, adaptedType, parameterTypes); + return new CandidateMethod(m, ScoreHelper.grossScore(compares), adaptedType); + } + /** * Returns the left CandidateMethod if its fineScore is greater than the right one, * otherwise returns the right CandidateMethod diff --git a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/functions/BaseFEELFunctionHelper.java b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/functions/BaseFEELFunctionHelper.java index 327f3fb98cb..4a0d5787e92 100644 --- a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/functions/BaseFEELFunctionHelper.java +++ b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/functions/BaseFEELFunctionHelper.java @@ -27,6 +27,7 @@ import java.util.Optional; import org.kie.dmn.feel.lang.EvaluationContext; +import org.kie.dmn.feel.lang.Type; import org.kie.dmn.feel.lang.impl.NamedParameter; import org.kie.dmn.feel.util.NumberEvalHelper; import org.slf4j.Logger; @@ -62,6 +63,29 @@ static Object[] getAdjustedParametersForMethod(EvaluationContext ctx, Object[] p return toReturn; } + static Object[] getAdjustedParametersForMethod(EvaluationContext ctx, Type[] types, boolean isNamedParams, + Method m) { + logger.trace("getAdjustedParametersForMethod {} {} {} {}", ctx, types, isNamedParams, m); + Object[] toReturn = addCtxParamIfRequired(ctx, types, isNamedParams, m); + Class[] parameterTypes = m.getParameterTypes(); + if (isNamedParams) { + // This is inherently frail because it expects that, if, the first parameter is NamedParameter and the + // function is a CustomFunction, then all parameters are NamedParameter + NamedParameter[] namedParams = + Arrays.stream(toReturn).map(NamedParameter.class::cast).toArray(NamedParameter[]::new); + toReturn = BaseFEELFunctionHelper.calculateActualParams(m, namedParams); + if (toReturn == null) { + // incompatible method + return null; + } + } else if (toReturn.length > 0) { + // if named parameters, then it has been adjusted already in the calculateActualParams method, + // otherwise adjust here + toReturn = adjustForVariableParameters(toReturn, parameterTypes); + } + toReturn = adjustByCoercion(parameterTypes, toReturn); + return toReturn; + } /** * This method check if the input parameters, set inside the given CandidateMethod, * could match the given parameterTypes, eventually coerced. diff --git a/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/lang/types/GenFnTypeTest.java b/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/lang/types/GenFnTypeTest.java index 2bb6b803155..8a18c729c9d 100644 --- a/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/lang/types/GenFnTypeTest.java +++ b/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/lang/types/GenFnTypeTest.java @@ -1,5 +1,4 @@ /* - * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information @@ -23,12 +22,16 @@ import static org.assertj.core.api.Assertions.assertThat; import org.junit.jupiter.api.Test; +import org.kie.dmn.feel.lang.EvaluationContext; +import org.kie.dmn.feel.lang.Symbol; import org.kie.dmn.feel.lang.Type; +import org.kie.dmn.feel.runtime.FEELFunction; import org.kie.dmn.feel.runtime.functions.AbsFunction; import org.kie.dmn.feel.runtime.functions.AnyFunction; import org.kie.dmn.feel.runtime.functions.FEELFnResult; import org.kie.dmn.feel.runtime.FEELFunction.Param; +import java.math.BigDecimal; import java.util.Arrays; import java.util.Collections; import java.util.List; @@ -144,6 +147,67 @@ void testCheckSignatures_withMatchingEmptySignature() { assertThat(GenFnType.checkSignatures(params, argsGen)).isFalse(); } + /* @Test + void testMatchesFunctionSignature_withMatchingSignature() { + assertThat(GenFnType.matchesFunctionSignature(absFunctionInstance)).isTrue(); + }*/ + + /* @Test + void testMatchesFunctionSignature_withNonMatchingSignature() { + FEELFunction function = new FEELFunction() { + + @Override + public String getName() { + return ""; + } + + @Override + public Symbol getSymbol() { + return null; + } + + @Override + public List> getParameters() { + return List.of(); + } + + @Override + public FEELFnResult invokeReflectively(EvaluationContext ctx, Object[] params) { + return FEELFnResult.ofResult(new BigDecimal("1.0")); + } + }; + + assertThat(GenFnType.matchesFunctionSignature((FEELFunction) function)).isFalse(); + } + + @Test + void testMatchesFunctionSignature_withDifferentReturnType() { + FEELFunction function = new FEELFunction() { + + @Override + public String getName() { + return ""; + } + + @Override + public Symbol getSymbol() { + return null; + } + + @Override + public List> getParameters() { + return List.of(); + } + + @Override + public Object invokeReflectively(EvaluationContext ctx, Object[] params) { + return FEELFnResult.ofResult(1); + } + }; + + assertThat(GenFnType.matchesFunctionSignature(function)).isFalse(); + }*/ + static class SomeType implements Type { @Override public String getName() { From 61699e3b2bcfa6135784886dafa6327b5584a4e3 Mon Sep 17 00:00:00 2001 From: Gabriele-Cardosi Date: Wed, 26 Feb 2025 15:25:45 +0100 Subject: [PATCH 07/20] [incubator-kie-issues#1752] WIP --- .../kie/dmn/feel/lang/types/GenFnType.java | 10 ++----- .../kie/dmn/feel/runtime/FEELFunction.java | 4 +++ .../runtime/functions/BaseFEELFunction.java | 29 ++++++++++++------- 3 files changed, 25 insertions(+), 18 deletions(-) diff --git a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/types/GenFnType.java b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/types/GenFnType.java index 1eb0091321b..be7995d0544 100644 --- a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/types/GenFnType.java +++ b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/types/GenFnType.java @@ -43,18 +43,12 @@ public GenFnType(List evaluatedTypeArgs, Type functionReturnType) { @Override public boolean isInstanceOf(Object o) { if (o instanceof FEELFunction oFn) { - BaseFEELFunction baseFEELFunction=new BaseFEELFunction("Base Feel Function") { - @Override - public CandidateMethod getCandidateMethod(EvaluationContext ctx, Type[] types, boolean isNamedParams) { - return super.getCandidateMethod(ctx, types, isNamedParams); - } - }; List> currentGenFnTypeParams = oFn.getParameters(); if (currentGenFnTypeParams.isEmpty()) { //this is used to consider function as parameter - return true; + return oFn.isCompatible(evaluatedTypeArgs.toArray(new Type[0]), functionReturnType); } - return checkSignatures(currentGenFnTypeParams, evaluatedTypeArgs) && baseFEELFunction.getCandidateMethod(oFn, evaluatedTypeArgs, currentGenFnTypeParams); + return checkSignatures(currentGenFnTypeParams, evaluatedTypeArgs); } return false; } diff --git a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/FEELFunction.java b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/FEELFunction.java index f2883b23ec2..a43fffc87ec 100644 --- a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/FEELFunction.java +++ b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/FEELFunction.java @@ -88,6 +88,10 @@ default List feelDialectAdaptedInputList(List toAdapt) { return toAdapt; } + default boolean isCompatible(Type[] inputTypes, Type outputType) { + return true; + } + class Param { public final String name; diff --git a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/functions/BaseFEELFunction.java b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/functions/BaseFEELFunction.java index aaca91227c1..35aeb3b3771 100644 --- a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/functions/BaseFEELFunction.java +++ b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/functions/BaseFEELFunction.java @@ -160,6 +160,11 @@ public Object invoke(EvaluationContext ctx, Object[] params) { throw new RuntimeException("This method should be overriden by classes that implement custom feel functions"); } + @Override + public boolean isCompatible(Type[] inputTypes, Type outputType) { + return getCandidateMethod(inputTypes, outputType) != null; + } + /** * @param ctx * @param originalInput @@ -187,20 +192,23 @@ protected CandidateMethod getCandidateMethod(EvaluationContext ctx, Object[] ori return toReturn; } - protected CandidateMethod getCandidateMethod(EvaluationContext ctx, Type[] types, boolean isNamedParams) { - CandidateMethod toReturn = null; + private Method getCandidateMethod(Type[] inputTypes, Type outputType) { + Method toReturn = null; for (Method method : getClass().getDeclaredMethods()) { if (Modifier.isPublic(method.getModifiers()) && method.getName().equals("invoke")) { - CandidateMethod candidateMethod = getCandidateMethod(ctx, types, isNamedParams, method); - if (candidateMethod == null) { + if (method.getParameterCount() != inputTypes.length) { continue; } - if (toReturn == null) { - toReturn = candidateMethod; - } else if (candidateMethod.score > toReturn.score) { - toReturn = candidateMethod; - } else if (candidateMethod.score == toReturn.score) { - toReturn = getBestScoredCandidateMethod(types, candidateMethod, toReturn); + Class[] methodParameterTypes = method.getParameterTypes(); + for (int i = 0; i < inputTypes.length; i++) { + if (!methodParameterTypes[i].equals(inputTypes[i])) { + continue; + } + } + java.lang.reflect.Type methodReturnType= method.getGenericReturnType(); + if (methodReturnType.equals(outputType)) { + toReturn = method; + break; } } } @@ -225,6 +233,7 @@ private CandidateMethod getCandidateMethod(EvaluationContext ctx, Object[] origi return new CandidateMethod(m, ScoreHelper.grossScore(compares), adaptedInput); } + // TODO wrong private CandidateMethod getCandidateMethod(EvaluationContext ctx, Type[] types, boolean isNamedParams, Method m) { Object[] adaptedType = BaseFEELFunctionHelper.getAdjustedParametersForMethod(ctx, types, From 17a8abb7e9e9666dee5a213210a81be3d9c7aea3 Mon Sep 17 00:00:00 2001 From: bncriju Date: Thu, 27 Feb 2025 20:49:49 +0530 Subject: [PATCH 08/20] isCompatible method test and candidate method modification --- .../kie/dmn/feel/lang/types/GenFnType.java | 2 -- .../runtime/functions/BaseFEELFunction.java | 35 +++++++------------ .../functions/BaseFEELFunctionTest.java | 34 ++++++++++++++++++ 3 files changed, 46 insertions(+), 25 deletions(-) diff --git a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/types/GenFnType.java b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/types/GenFnType.java index be7995d0544..a7db54cc37a 100644 --- a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/types/GenFnType.java +++ b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/types/GenFnType.java @@ -22,12 +22,10 @@ import java.util.List; import java.util.stream.IntStream; -import org.kie.dmn.feel.lang.EvaluationContext; import org.kie.dmn.feel.lang.SimpleType; import org.kie.dmn.feel.lang.Type; import org.kie.dmn.feel.runtime.FEELFunction; import org.kie.dmn.feel.runtime.FEELFunction.Param; -import org.kie.dmn.feel.runtime.functions.BaseFEELFunction; public class GenFnType implements SimpleType { diff --git a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/functions/BaseFEELFunction.java b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/functions/BaseFEELFunction.java index 35aeb3b3771..c5d9c3e3e9d 100644 --- a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/functions/BaseFEELFunction.java +++ b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/functions/BaseFEELFunction.java @@ -192,26 +192,34 @@ protected CandidateMethod getCandidateMethod(EvaluationContext ctx, Object[] ori return toReturn; } - private Method getCandidateMethod(Type[] inputTypes, Type outputType) { + protected Method getCandidateMethod(Type[] inputTypes, Type outputType) { Method toReturn = null; + for (Method method : getClass().getDeclaredMethods()) { if (Modifier.isPublic(method.getModifiers()) && method.getName().equals("invoke")) { if (method.getParameterCount() != inputTypes.length) { continue; } + + org.kie.dmn.feel.lang.Type[] feelTypes = Arrays.stream(inputTypes) + .map(type -> (org.kie.dmn.feel.lang.Type) type) + .toArray(org.kie.dmn.feel.lang.Type[]::new); + Class[] methodParameterTypes = method.getParameterTypes(); - for (int i = 0; i < inputTypes.length; i++) { - if (!methodParameterTypes[i].equals(inputTypes[i])) { + for (int i = 0; i < feelTypes.length; i++) { + if (!methodParameterTypes[i].equals(feelTypes[i].getClass())) { continue; } } - java.lang.reflect.Type methodReturnType= method.getGenericReturnType(); + + java.lang.reflect.Type methodReturnType = method.getGenericReturnType(); if (methodReturnType.equals(outputType)) { toReturn = method; break; } } } + return toReturn; } @@ -233,25 +241,6 @@ private CandidateMethod getCandidateMethod(EvaluationContext ctx, Object[] origi return new CandidateMethod(m, ScoreHelper.grossScore(compares), adaptedInput); } - // TODO wrong - private CandidateMethod getCandidateMethod(EvaluationContext ctx, Type[] types, - boolean isNamedParams, Method m) { - Object[] adaptedType = BaseFEELFunctionHelper.getAdjustedParametersForMethod(ctx, types, - isNamedParams, m); - if (adaptedType == null) { - // incompatible method - return null; - } - - Class[] parameterTypes = m.getParameterTypes(); - if (parameterTypes.length != adaptedType.length) { - return null; - } - - ScoreHelper.Compares compares = new ScoreHelper.Compares(types, adaptedType, parameterTypes); - return new CandidateMethod(m, ScoreHelper.grossScore(compares), adaptedType); - } - /** * Returns the left CandidateMethod if its fineScore is greater than the right one, * otherwise returns the right CandidateMethod diff --git a/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/runtime/functions/BaseFEELFunctionTest.java b/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/runtime/functions/BaseFEELFunctionTest.java index af32bcc9c6a..36ad3953f5c 100644 --- a/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/runtime/functions/BaseFEELFunctionTest.java +++ b/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/runtime/functions/BaseFEELFunctionTest.java @@ -318,4 +318,38 @@ void getStddevFunctionCandidateMethod() { assertThat(parametersRetrieved).extracting("type").containsExactly(List.class); } + @Test + void testIsCompatible() { + BaseFEELFunction toTest = AllFunction.INSTANCE; + + org.kie.dmn.feel.lang.Type stringType = BuiltInType.STRING; + org.kie.dmn.feel.lang.Type integerType = BuiltInType.NUMBER; + + org.kie.dmn.feel.lang.Type[] inputTypes; + org.kie.dmn.feel.lang.Type outputType = stringType; + boolean result; + + inputTypes = new org.kie.dmn.feel.lang.Type[]{stringType}; + result = toTest.isCompatible(inputTypes, outputType); + assertThat(result).isTrue(); + + inputTypes = new org.kie.dmn.feel.lang.Type[]{integerType}; + outputType = integerType; + result = toTest.isCompatible(inputTypes, outputType); + assertThat(result).isTrue(); + + inputTypes = new org.kie.dmn.feel.lang.Type[]{stringType}; + outputType = stringType; + result = toTest.isCompatible(inputTypes, outputType); + assertThat(result).isTrue(); + + inputTypes = new org.kie.dmn.feel.lang.Type[]{integerType}; + result = toTest.isCompatible(inputTypes, outputType); + assertThat(result).isFalse(); + + outputType = integerType; + result = toTest.isCompatible(inputTypes, outputType); + assertThat(result).isFalse(); + } + } \ No newline at end of file From 6f56cfc8dc91f563c91b7a81545acee66c69cdc5 Mon Sep 17 00:00:00 2001 From: bncriju Date: Mon, 3 Mar 2025 18:51:11 +0530 Subject: [PATCH 09/20] Util class added for BuiltInType. Used util method --- kie-dmn/kie-dmn-core/pom.xml | 10 +- .../alphanetbased/TableCellParser.java | 25 +- .../java/org/kie/dmn/core/DMNRuntimeTest.java | 1311 +++++++++-------- .../org/kie/dmn/feel/lang/ast/RangeNode.java | 55 +- .../org/kie/dmn/feel/lang/ast/TypeNode.java | 11 +- .../kie/dmn/feel/lang/types/BuiltInType.java | 107 +- .../runtime/functions/BaseFEELFunction.java | 65 +- .../runtime/functions/ContextPutFunction.java | 17 +- .../runtime/functions/GetValueFunction.java | 9 +- .../feel/runtime/functions/IsFunction.java | 11 +- .../kie/dmn/feel/util/BooleanEvalHelper.java | 64 +- .../kie/dmn/feel/util/BuiltInTypeUtils.java | 153 ++ .../dmn/feel/lang/types/GenFnTypeTest.java | 61 - .../tests/core/v1_1/DMNRuntimeTest.java | 1185 +++++++-------- 14 files changed, 1557 insertions(+), 1527 deletions(-) create mode 100644 kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/util/BuiltInTypeUtils.java diff --git a/kie-dmn/kie-dmn-core/pom.xml b/kie-dmn/kie-dmn-core/pom.xml index 977df690c4c..d7bf1df6200 100644 --- a/kie-dmn/kie-dmn-core/pom.xml +++ b/kie-dmn/kie-dmn-core/pom.xml @@ -276,9 +276,13 @@ src/test/filtered-resources true + + ${project.build.directory}/generated-resources + false + - + org.apache.maven.plugins maven-dependency-plugin @@ -299,8 +303,8 @@ tests jar true - ${project.build.directory}/test-classes - **/*.dmn + ${project.build.directory}/generated-resources + valid_models/**/*.dmn diff --git a/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/compiler/alphanetbased/TableCellParser.java b/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/compiler/alphanetbased/TableCellParser.java index c63100a6956..a930e365def 100644 --- a/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/compiler/alphanetbased/TableCellParser.java +++ b/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/compiler/alphanetbased/TableCellParser.java @@ -6,9 +6,9 @@ * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

* Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY @@ -24,13 +24,12 @@ import org.kie.dmn.api.core.DMNType; import org.kie.dmn.core.impl.DMNModelImpl; import org.kie.dmn.feel.lang.Type; +import org.kie.dmn.feel.util.BuiltInTypeUtils; import org.kie.dmn.model.api.DecisionRule; import org.kie.dmn.model.api.DecisionTable; import org.kie.dmn.model.api.InputClause; import org.kie.dmn.model.api.LiteralExpression; -import static org.kie.dmn.feel.lang.types.BuiltInType.determineTypeFromName; - public class TableCellParser { TableCell.TableCellFactory tableCellFactory; @@ -55,9 +54,9 @@ public TableCells parseCells(DecisionTable decisionTable, DTQNameToTypeResolver final String columnName = column.getInputExpression().getText(); final Type columnType = resolver.resolve(column.getInputExpression().getTypeRef()); TableCell cell = tableCellFactory.createInputCell(tableIndex, - input, - columnName, - columnType); + input, + columnName, + columnType); tableCells.add(cell); @@ -87,13 +86,13 @@ private void parseColumnDefinition(String decisionTableName, List c for (int columnIndex = 0, columnsSize = columns.size(); columnIndex < columnsSize; columnIndex++) { InputClause column = columns.get(columnIndex); - Type type = determineTypeFromName(column.getInputExpression().getTypeRef() != null ? column.getInputExpression().getTypeRef().getLocalPart() : null); + Type type = BuiltInTypeUtils.determineTypeFromName(column.getInputExpression().getTypeRef() != null ? column.getInputExpression().getTypeRef().getLocalPart() : null); tableCells.addColumnCell(columnIndex, tableCellFactory.createColumnDefinition(columnIndex, - decisionTableName, - column.getInputExpression().getText(), - column.getInputValues(), - type)); + decisionTableName, + column.getInputExpression().getText(), + column.getInputValues(), + type)); } } diff --git a/kie-dmn/kie-dmn-core/src/test/java/org/kie/dmn/core/DMNRuntimeTest.java b/kie-dmn/kie-dmn-core/src/test/java/org/kie/dmn/core/DMNRuntimeTest.java index 13a044a6576..9692ac5321d 100644 --- a/kie-dmn/kie-dmn-core/src/test/java/org/kie/dmn/core/DMNRuntimeTest.java +++ b/kie-dmn/kie-dmn-core/src/test/java/org/kie/dmn/core/DMNRuntimeTest.java @@ -6,9 +6,9 @@ * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

* Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY @@ -76,6 +76,7 @@ import org.kie.dmn.feel.lang.types.BuiltInType; import org.kie.dmn.feel.lang.types.impl.ComparablePeriod; import org.kie.dmn.feel.marshaller.FEELStringMarshaller; +import org.kie.dmn.feel.util.BuiltInTypeUtils; import org.kie.dmn.feel.util.NumberEvalHelper; import org.kie.dmn.model.api.Decision; import org.kie.dmn.model.api.Definitions; @@ -107,155 +108,155 @@ public class DMNRuntimeTest extends BaseInterpretedVsCompiledTest { @MethodSource("params") void simpleItemDefinition(boolean useExecModelCompiler) { init(useExecModelCompiler); - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("simple-item-def.dmn", this.getClass() ); - final DMNModel dmnModel = runtime.getModel("https://github.com/kiegroup/kie-dmn/itemdef", "simple-item-def" ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("simple-item-def.dmn", this.getClass()); + final DMNModel dmnModel = runtime.getModel("https://github.com/kiegroup/kie-dmn/itemdef", "simple-item-def"); assertThat(dmnModel).isNotNull(); assertThat(dmnModel.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).isFalse(); final DMNContext context = DMNFactory.newContext(); - context.set( "Monthly Salary", 1000 ); + context.set("Monthly Salary", 1000); - final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context ); + final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context); assertThat(dmnResult.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnResult.getMessages())).isFalse(); final DMNContext result = dmnResult.getContext(); - assertThat( result.get( "Yearly Salary" )).isEqualTo(new BigDecimal( "12000" ) ); + assertThat(result.get("Yearly Salary")).isEqualTo(new BigDecimal("12000")); } @ParameterizedTest @MethodSource("params") void compositeItemDefinition(boolean useExecModelCompiler) { init(useExecModelCompiler); - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("0008-LX-arithmetic.dmn", this.getClass() ); - final DMNModel dmnModel = runtime.getModel("https://github.com/kiegroup/kie-dmn", "0008-LX-arithmetic" ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("0008-LX-arithmetic.dmn", this.getClass()); + final DMNModel dmnModel = runtime.getModel("https://github.com/kiegroup/kie-dmn", "0008-LX-arithmetic"); assertThat(dmnModel).isNotNull(); final DMNContext context = DMNFactory.newContext(); final Map loan = new HashMap<>(); - loan.put( "principal", 600000 ); - loan.put( "rate", 0.0375 ); - loan.put( "termMonths", 360 ); - context.set( "loan", loan ); + loan.put("principal", 600000); + loan.put("rate", 0.0375); + loan.put("termMonths", 360); + context.set("loan", loan); - final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context ); + final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context); final DMNContext result = dmnResult.getContext(); - assertThat( result.get( "payment" )).isEqualTo(new BigDecimal( "2778.693549432766768088520383236299" ) ); + assertThat(result.get("payment")).isEqualTo(new BigDecimal("2778.693549432766768088520383236299")); } @ParameterizedTest @MethodSource("params") void trisotechNamespace(boolean useExecModelCompiler) { init(useExecModelCompiler); - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("trisotech_namespace.dmn", this.getClass() ); - final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/dmn/definitions/_b8feec86-dadf-4051-9feb-8e6093bbb530", "Solution 3" ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("trisotech_namespace.dmn", this.getClass()); + final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/dmn/definitions/_b8feec86-dadf-4051-9feb-8e6093bbb530", "Solution 3"); assertThat(dmnModel).isNotNull(); assertThat(dmnModel.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).isFalse(); - + final DMNContext context = DMNFactory.newContext(); - context.set( "IsDoubleHulled", Boolean.TRUE ); - context.set( "Residual Cargo Size", BigDecimal.valueOf(0.1) ); - context.set( "Ship Size", new BigDecimal( 50 ) ); - - final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context ); + context.set("IsDoubleHulled", Boolean.TRUE); + context.set("Residual Cargo Size", BigDecimal.valueOf(0.1)); + context.set("Ship Size", new BigDecimal(50)); + + final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context); assertThat(dmnResult.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnResult.getMessages())).isFalse(); - + final DMNContext result = dmnResult.getContext(); - assertThat( result.get( "Ship can enter a Dutch port" )).isEqualTo(Boolean.TRUE); + assertThat(result.get("Ship can enter a Dutch port")).isEqualTo(Boolean.TRUE); } @ParameterizedTest @MethodSource("params") void emptyDecision1(boolean useExecModelCompiler) { init(useExecModelCompiler); - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("empty_decision.dmn", this.getClass() ); - final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/dmn/definitions/_ba9fc4b1-5ced-4d00-9b61-290de4bf3213", "Solution 3" ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("empty_decision.dmn", this.getClass()); + final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/dmn/definitions/_ba9fc4b1-5ced-4d00-9b61-290de4bf3213", "Solution 3"); assertThat(dmnModel).isNotNull(); final DMNContext context = DMNFactory.newContext(); final Map shipInfo = new HashMap<>(); - shipInfo.put( "Size", BigDecimal.valueOf( 70 ) ); - shipInfo.put( "Is Double Hulled", Boolean.FALSE ); - shipInfo.put( "Residual Cargo Size", BigDecimal.valueOf( 0.1 ) ); - context.set( "Ship Info", shipInfo ); + shipInfo.put("Size", BigDecimal.valueOf(70)); + shipInfo.put("Is Double Hulled", Boolean.FALSE); + shipInfo.put("Residual Cargo Size", BigDecimal.valueOf(0.1)); + context.set("Ship Info", shipInfo); // Test that even if one decision is empty or missing input data, // the other decisions in the model are still evaluated - final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context ); + final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context); final DMNContext result = dmnResult.getContext(); - assertThat( dmnResult.hasErrors()).isTrue(); - assertThat( result.get( "Ship Can Enter v2" )).isEqualTo(Boolean.TRUE); + assertThat(dmnResult.hasErrors()).isTrue(); + assertThat(result.get("Ship Can Enter v2")).isEqualTo(Boolean.TRUE); } @ParameterizedTest @MethodSource("params") void emptyDecision2(boolean useExecModelCompiler) { init(useExecModelCompiler); - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("empty_decision.dmn", this.getClass() ); - final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/dmn/definitions/_ba9fc4b1-5ced-4d00-9b61-290de4bf3213", "Solution 3" ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("empty_decision.dmn", this.getClass()); + final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/dmn/definitions/_ba9fc4b1-5ced-4d00-9b61-290de4bf3213", "Solution 3"); assertThat(dmnModel).isNotNull(); final DMNContext context = DMNFactory.newContext(); final Map shipInfo = new HashMap<>(); - shipInfo.put( "Size", BigDecimal.valueOf( 70 ) ); - shipInfo.put( "Is Double Hulled", Boolean.FALSE ); - shipInfo.put( "Residual Cargo Size", BigDecimal.valueOf( 0.1 ) ); - context.set( "Ship Info", shipInfo ); - context.set( "Ship Size", BigDecimal.valueOf( 70 ) ); - context.set( "IsDoubleHulled", Boolean.FALSE ); - context.set( "Residual Cargo Size", BigDecimal.valueOf( 0.1 ) ); + shipInfo.put("Size", BigDecimal.valueOf(70)); + shipInfo.put("Is Double Hulled", Boolean.FALSE); + shipInfo.put("Residual Cargo Size", BigDecimal.valueOf(0.1)); + context.set("Ship Info", shipInfo); + context.set("Ship Size", BigDecimal.valueOf(70)); + context.set("IsDoubleHulled", Boolean.FALSE); + context.set("Residual Cargo Size", BigDecimal.valueOf(0.1)); // check that if all the input data is available, but the // decision expression is empty, the model returns a warning - final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context ); + final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context); - final List messages = dmnResult.getMessages(DMNMessage.Severity.WARN ); + final List messages = dmnResult.getMessages(DMNMessage.Severity.WARN); assertThat(messages).hasSize(1); - assertThat( messages.get( 0 ).getSeverity()).isEqualTo(DMNMessage.Severity.WARN); - assertThat( messages.get( 0 ).getSourceId()).isEqualTo("_42806504-8ed5-488f-b274-de98c1bc67b9" ); + assertThat(messages.get(0).getSeverity()).isEqualTo(DMNMessage.Severity.WARN); + assertThat(messages.get(0).getSourceId()).isEqualTo("_42806504-8ed5-488f-b274-de98c1bc67b9"); final DMNContext result = dmnResult.getContext(); - assertThat( result.get( "Ship Can Enter v2" )).isEqualTo(Boolean.TRUE); + assertThat(result.get("Ship Can Enter v2")).isEqualTo(Boolean.TRUE); } @ParameterizedTest @MethodSource("params") void eventListeners(boolean useExecModelCompiler) { init(useExecModelCompiler); - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("car_damage_responsibility.dmn", this.getClass() ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("car_damage_responsibility.dmn", this.getClass()); - final DMNRuntimeEventListener listener = mock(DMNRuntimeEventListener.class ); - runtime.addListener( listener ); - runtime.addListener( DMNRuntimeUtil.createListener() ); + final DMNRuntimeEventListener listener = mock(DMNRuntimeEventListener.class); + runtime.addListener(listener); + runtime.addListener(DMNRuntimeUtil.createListener()); - final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/definitions/_820611e9-c21c-47cd-8e52-5cba2be9f9cc", "Car Damage Responsibility" ); + final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/definitions/_820611e9-c21c-47cd-8e52-5cba2be9f9cc", "Car Damage Responsibility"); assertThat(dmnModel).isNotNull(); final DMNContext context = DMNFactory.newContext(); - context.set( "Membership Level", "Silver" ); - context.set( "Damage Types", "Body" ); - context.set( "Responsible", "Driver" ); - - final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context ); + context.set("Membership Level", "Silver"); + context.set("Damage Types", "Body"); + context.set("Responsible", "Driver"); - final ArgumentCaptor argument = ArgumentCaptor.forClass(AfterEvaluateDecisionTableEvent.class ); - verify( listener, times( 2 ) ) - .beforeEvaluateDecision( any( BeforeEvaluateDecisionEvent.class ) ); - verify( listener, times( 2 ) ) - .afterEvaluateDecision( any( AfterEvaluateDecisionEvent.class ) ); - verify( listener, times( 2 ) ) - .beforeEvaluateDecisionTable( any( BeforeEvaluateDecisionTableEvent.class ) ); - verify( listener, times( 2 ) ) - .afterEvaluateDecisionTable( argument.capture() ); + final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context); - AfterEvaluateDecisionTableEvent dte = argument.getAllValues().get( 0 ); - assertThat(dte.getDecisionTableName()).isEqualTo("Car Damage Responsibility" ); + final ArgumentCaptor argument = ArgumentCaptor.forClass(AfterEvaluateDecisionTableEvent.class); + verify(listener, times(2)) + .beforeEvaluateDecision(any(BeforeEvaluateDecisionEvent.class)); + verify(listener, times(2)) + .afterEvaluateDecision(any(AfterEvaluateDecisionEvent.class)); + verify(listener, times(2)) + .beforeEvaluateDecisionTable(any(BeforeEvaluateDecisionTableEvent.class)); + verify(listener, times(2)) + .afterEvaluateDecisionTable(argument.capture()); + + AfterEvaluateDecisionTableEvent dte = argument.getAllValues().get(0); + assertThat(dte.getDecisionTableName()).isEqualTo("Car Damage Responsibility"); assertThat(dte.getMatches()).containsExactly(5); // rows are 1-based - dte = argument.getAllValues().get( 1 ); - assertThat(dte.getDecisionTableName()).isEqualTo("Payment method" ); + dte = argument.getAllValues().get(1); + assertThat(dte.getDecisionTableName()).isEqualTo("Payment method"); assertThat(dte.getMatches()).containsExactly(3); // rows are 1-based assertThat(dmnResult.hasErrors()).isFalse(); @@ -263,76 +264,76 @@ void eventListeners(boolean useExecModelCompiler) { final DMNContext result = dmnResult.getContext(); assertThat((Map) result.get("Car Damage Responsibility")).containsEntry("EU Rent", BigDecimal.valueOf(40)); assertThat((Map) result.get("Car Damage Responsibility")).containsEntry("Renter", BigDecimal.valueOf(60)); - assertThat(result.get( "Payment method")).isEqualTo("Check"); + assertThat(result.get("Payment method")).isEqualTo("Check"); } @ParameterizedTest @MethodSource("params") void contextEventListeners(boolean useExecModelCompiler) { init(useExecModelCompiler); - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("context_listener.dmn", this.getClass() ); - - final DMNRuntimeEventListener listener = mock(DMNRuntimeEventListener.class ); - runtime.addListener( listener ); - runtime.addListener( DMNRuntimeUtil.createListener() ); - - final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/dmn/definitions/_73481d02-76fb-4927-ac11-5d936882e16c", "context listener" ); - assertThat(dmnModel).isNotNull(); - - final DMNContext context = DMNFactory.newContext(); - - final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context ); - - final ArgumentCaptor argument = ArgumentCaptor.forClass(AfterEvaluateContextEntryEvent.class ); - verify( listener, times( 1 ) ) - .beforeEvaluateDecision( any( BeforeEvaluateDecisionEvent.class ) ); - verify( listener, times( 1 ) ) - .afterEvaluateDecision( any( AfterEvaluateDecisionEvent.class ) ); - verify( listener, times( 5 ) ) - .beforeEvaluateContextEntry( any( BeforeEvaluateContextEntryEvent.class ) ); - verify( listener, times( 5 ) ) - .afterEvaluateContextEntry( argument.capture() ); - - AfterEvaluateContextEntryEvent aece = argument.getAllValues().get( 0 ); - assertThat( aece.getNodeName()).isEqualTo("d1"); - assertThat( aece.getVariableName()).isEqualTo("a1"); - assertThat( aece.getVariableId()).isEqualTo("_b199c7b1-cb87-4a92-b045-a2954ccc9d01" ); - assertThat( aece.getExpressionId()).isEqualTo("_898c24f8-93da-4fe2-827c-924c30956833" ); - assertThat( aece.getExpressionResult()).isEqualTo(BigDecimal.valueOf( 10 ) ); - - aece = argument.getAllValues().get( 1 ); - assertThat( aece.getNodeName()).isEqualTo("d1"); - assertThat( aece.getVariableName()).isEqualTo("c1"); - assertThat( aece.getVariableId()).isEqualTo("_38a88aef-8b3c-424d-b60c-a139ffb610e1" ); - assertThat( aece.getExpressionId()).isEqualTo("_879c4ac6-8b25-4cd1-9b8e-c18d0b0b281c" ); - assertThat( aece.getExpressionResult()).isEqualTo("a"); - - aece = argument.getAllValues().get( 2 ); - assertThat( aece.getNodeName()).isEqualTo("d1"); - assertThat( aece.getVariableName()).isEqualTo("c2"); - assertThat( aece.getVariableId()).isEqualTo("_3aad82f0-74b9-4921-8b2f-d6c277c840db" ); - assertThat( aece.getExpressionId()).isEqualTo("_9acf4baf-6c49-4d47-88ab-2e511e598e04" ); - assertThat( aece.getExpressionResult()).isEqualTo("b"); - - aece = argument.getAllValues().get( 3 ); - assertThat( aece.getNodeName()).isEqualTo("d1"); - assertThat( aece.getVariableName()).isEqualTo("b1"); - assertThat( aece.getVariableId()).isEqualTo("_f4a6c2ba-e6e9-4dbd-b776-edef2c1a1343" ); - assertThat( aece.getExpressionId()).isEqualTo("_c450d947-1874-41fe-9c0a-da5f1cca7fde" ); - assertThat( (Map) aece.getExpressionResult()).containsEntry("c1", "a"); - assertThat( (Map) aece.getExpressionResult()).containsEntry("c2", "b"); - - aece = argument.getAllValues().get( 4 ); - assertThat( aece.getNodeName()).isEqualTo("d1"); - assertThat( aece.getVariableName()).isEqualTo(DMNContextEvaluator.RESULT_ENTRY); - assertThat( aece.getVariableId()).isNull(); - assertThat( aece.getExpressionId()).isEqualTo("_4264b25c-d676-4516-ab8a-a4ff34e7a95c" ); - assertThat( aece.getExpressionResult()).isEqualTo("a"); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("context_listener.dmn", this.getClass()); + + final DMNRuntimeEventListener listener = mock(DMNRuntimeEventListener.class); + runtime.addListener(listener); + runtime.addListener(DMNRuntimeUtil.createListener()); + + final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/dmn/definitions/_73481d02-76fb-4927-ac11-5d936882e16c", "context listener"); + assertThat(dmnModel).isNotNull(); + + final DMNContext context = DMNFactory.newContext(); + + final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context); + + final ArgumentCaptor argument = ArgumentCaptor.forClass(AfterEvaluateContextEntryEvent.class); + verify(listener, times(1)) + .beforeEvaluateDecision(any(BeforeEvaluateDecisionEvent.class)); + verify(listener, times(1)) + .afterEvaluateDecision(any(AfterEvaluateDecisionEvent.class)); + verify(listener, times(5)) + .beforeEvaluateContextEntry(any(BeforeEvaluateContextEntryEvent.class)); + verify(listener, times(5)) + .afterEvaluateContextEntry(argument.capture()); + + AfterEvaluateContextEntryEvent aece = argument.getAllValues().get(0); + assertThat(aece.getNodeName()).isEqualTo("d1"); + assertThat(aece.getVariableName()).isEqualTo("a1"); + assertThat(aece.getVariableId()).isEqualTo("_b199c7b1-cb87-4a92-b045-a2954ccc9d01"); + assertThat(aece.getExpressionId()).isEqualTo("_898c24f8-93da-4fe2-827c-924c30956833"); + assertThat(aece.getExpressionResult()).isEqualTo(BigDecimal.valueOf(10)); + + aece = argument.getAllValues().get(1); + assertThat(aece.getNodeName()).isEqualTo("d1"); + assertThat(aece.getVariableName()).isEqualTo("c1"); + assertThat(aece.getVariableId()).isEqualTo("_38a88aef-8b3c-424d-b60c-a139ffb610e1"); + assertThat(aece.getExpressionId()).isEqualTo("_879c4ac6-8b25-4cd1-9b8e-c18d0b0b281c"); + assertThat(aece.getExpressionResult()).isEqualTo("a"); + + aece = argument.getAllValues().get(2); + assertThat(aece.getNodeName()).isEqualTo("d1"); + assertThat(aece.getVariableName()).isEqualTo("c2"); + assertThat(aece.getVariableId()).isEqualTo("_3aad82f0-74b9-4921-8b2f-d6c277c840db"); + assertThat(aece.getExpressionId()).isEqualTo("_9acf4baf-6c49-4d47-88ab-2e511e598e04"); + assertThat(aece.getExpressionResult()).isEqualTo("b"); + + aece = argument.getAllValues().get(3); + assertThat(aece.getNodeName()).isEqualTo("d1"); + assertThat(aece.getVariableName()).isEqualTo("b1"); + assertThat(aece.getVariableId()).isEqualTo("_f4a6c2ba-e6e9-4dbd-b776-edef2c1a1343"); + assertThat(aece.getExpressionId()).isEqualTo("_c450d947-1874-41fe-9c0a-da5f1cca7fde"); + assertThat((Map) aece.getExpressionResult()).containsEntry("c1", "a"); + assertThat((Map) aece.getExpressionResult()).containsEntry("c2", "b"); + + aece = argument.getAllValues().get(4); + assertThat(aece.getNodeName()).isEqualTo("d1"); + assertThat(aece.getVariableName()).isEqualTo(DMNContextEvaluator.RESULT_ENTRY); + assertThat(aece.getVariableId()).isNull(); + assertThat(aece.getExpressionId()).isEqualTo("_4264b25c-d676-4516-ab8a-a4ff34e7a95c"); + assertThat(aece.getExpressionResult()).isEqualTo("a"); assertThat(dmnResult.hasErrors()).isFalse(); final DMNContext result = dmnResult.getContext(); - assertThat( result.get( "d1" )).isEqualTo("a"); + assertThat(result.get("d1")).isEqualTo("a"); } @ParameterizedTest @@ -347,132 +348,132 @@ void errorMessages(boolean useExecModelCompiler) { @MethodSource("params") void outputReuse(boolean useExecModelCompiler) { init(useExecModelCompiler); - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("Input_reuse_in_output.dmn", this.getClass() ); - final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/dmn/definitions/_098bb607-eff7-4772-83ac-6ded8b371fa7", "Input reuse in output" ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("Input_reuse_in_output.dmn", this.getClass()); + final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/dmn/definitions/_098bb607-eff7-4772-83ac-6ded8b371fa7", "Input reuse in output"); assertThat(dmnModel).isNotNull(); final DMNContext context = DMNFactory.newContext(); - context.set( "Age", 40 ); - context.set( "Requested Product", "Fixed30" ); + context.set("Age", 40); + context.set("Requested Product", "Fixed30"); - final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context ); + final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context); assertThat(dmnResult.hasErrors()).isFalse(); final DMNContext result = dmnResult.getContext(); - assertThat( result.get( "My Decision" )).isEqualTo("Fixed30"); + assertThat(result.get("My Decision")).isEqualTo("Fixed30"); } @ParameterizedTest @MethodSource("params") void simpleNot(boolean useExecModelCompiler) { init(useExecModelCompiler); - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("Simple_Not.dmn", this.getClass() ); - final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/definitions/_98436ebb-7c42-48c0-8d11-d693e2a817c9", "Simple Not" ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("Simple_Not.dmn", this.getClass()); + final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/definitions/_98436ebb-7c42-48c0-8d11-d693e2a817c9", "Simple Not"); assertThat(dmnModel).isNotNull(); final DMNContext context = DMNFactory.newContext(); - context.set( "Occupation", "Student" ); + context.set("Occupation", "Student"); - final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context ); + final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context); assertThat(dmnResult.hasErrors()).isFalse(); final DMNContext result = dmnResult.getContext(); - assertThat( result.get( "a" )).isEqualTo("Is Student" ); + assertThat(result.get("a")).isEqualTo("Is Student"); } @ParameterizedTest @MethodSource("params") void simpleNot2(boolean useExecModelCompiler) { init(useExecModelCompiler); - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("Simple_Not.dmn", this.getClass() ); - final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/definitions/_98436ebb-7c42-48c0-8d11-d693e2a817c9", "Simple Not" ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("Simple_Not.dmn", this.getClass()); + final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/definitions/_98436ebb-7c42-48c0-8d11-d693e2a817c9", "Simple Not"); assertThat(dmnModel).isNotNull(); final DMNContext context = DMNFactory.newContext(); - context.set( "Occupation", "Engineer" ); + context.set("Occupation", "Engineer"); - final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context ); + final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context); assertThat(dmnResult.hasErrors()).isFalse(); final DMNContext result = dmnResult.getContext(); - assertThat( result.get( "a" )).isEqualTo("Is not a Student" ); + assertThat(result.get("a")).isEqualTo("Is not a Student"); } @ParameterizedTest @MethodSource("params") void dinner(boolean useExecModelCompiler) { init(useExecModelCompiler); - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("Dinner.dmn", this.getClass() ); - final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/definitions/_0c45df24-0d57-4acc-b296-b4cba8b71a36", "Dinner" ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("Dinner.dmn", this.getClass()); + final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/definitions/_0c45df24-0d57-4acc-b296-b4cba8b71a36", "Dinner"); assertThat(dmnModel).isNotNull(); - assertThat( dmnModel.hasErrors()).isFalse(); + assertThat(dmnModel.hasErrors()).isFalse(); final DMNContext context = DMNFactory.newContext(); - context.set( "Guests with children", Boolean.TRUE ); - context.set( "Season", "Fall" ); - context.set( "Number of guests", 4 ); - context.set( "Temp", 25 ); - context.set( "Rain Probability", 30 ); + context.set("Guests with children", Boolean.TRUE); + context.set("Season", "Fall"); + context.set("Number of guests", 4); + context.set("Temp", 25); + context.set("Rain Probability", 30); - final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context ); + final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context); assertThat(dmnResult.hasErrors()).isFalse(); assertThat(dmnResult.getContext().get("Where to eat")).isEqualTo("Outside"); assertThat(dmnResult.getContext().get("Dish")).isEqualTo("Spareribs"); - assertThat( dmnResult.getContext().get("Drinks")).asList().containsExactly("Apero", "Ale", "Juice Boxes"); + assertThat(dmnResult.getContext().get("Drinks")).asList().containsExactly("Apero", "Ale", "Juice Boxes"); } @ParameterizedTest @MethodSource("params") void notificationsApproved2(boolean useExecModelCompiler) { init(useExecModelCompiler); - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("NotificationsTest2.dmn", this.getClass() ); - final DMNModel dmnModel = runtime.getModel("https://github.com/kiegroup/kie-dmn", "building-structure-rules" ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("NotificationsTest2.dmn", this.getClass()); + final DMNModel dmnModel = runtime.getModel("https://github.com/kiegroup/kie-dmn", "building-structure-rules"); assertThat(dmnModel).isNotNull(); final DMNContext context = DMNFactory.newContext(); - context.set( "existingActivityApplicability", Boolean.TRUE ); - context.set( "Distance", new BigDecimal( 9999 ) ); - context.set( "willIncreaseTraffic", Boolean.TRUE ); + context.set("existingActivityApplicability", Boolean.TRUE); + context.set("Distance", new BigDecimal(9999)); + context.set("willIncreaseTraffic", Boolean.TRUE); - final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context ); + final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context); final DMNContext result = dmnResult.getContext(); - assertThat( result.get( "Notification Status" )).isEqualTo("Notification to Province Approved" ); - assertThat( result.get( "Permit Status" )).isEqualTo("Building Activity Province Permit Required" ); + assertThat(result.get("Notification Status")).isEqualTo("Notification to Province Approved"); + assertThat(result.get("Permit Status")).isEqualTo("Building Activity Province Permit Required"); } @ParameterizedTest @MethodSource("params") void boxedContext(boolean useExecModelCompiler) { init(useExecModelCompiler); - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("BoxedContext.dmn", this.getClass() ); - final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/dmn/definitions/_0de36357-fec0-4b4e-b7f1-382d381e06e9", "Dessin 1" ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("BoxedContext.dmn", this.getClass()); + final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/dmn/definitions/_0de36357-fec0-4b4e-b7f1-382d381e06e9", "Dessin 1"); assertThat(dmnModel).isNotNull(); assertThat(dmnModel.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).isFalse(); final DMNContext context = DMNFactory.newContext(); - context.set( "a", 10 ); - context.set( "b", 5 ); + context.set("a", 10); + context.set("b", 5); - final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context ); + final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context); assertThat(dmnResult.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnResult.getMessages())).isFalse(); - assertThat( (Map) dmnResult.getContext().get( "Math" )).containsEntry( "Sum", BigDecimal.valueOf( 15 )); - assertThat( (Map) dmnResult.getContext().get( "Math" )).containsEntry( "Product", BigDecimal.valueOf( 50 )); + assertThat((Map) dmnResult.getContext().get("Math")).containsEntry("Sum", BigDecimal.valueOf(15)); + assertThat((Map) dmnResult.getContext().get("Math")).containsEntry("Product", BigDecimal.valueOf(50)); } @ParameterizedTest @MethodSource("params") void functionDefAndInvocation(boolean useExecModelCompiler) { init(useExecModelCompiler); - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("FunctionDefinition.dmn", this.getClass() ); - final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/dmn/definitions/_0de36357-fec0-4b4e-b7f1-382d381e06e9", "Dessin 1" ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("FunctionDefinition.dmn", this.getClass()); + final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/dmn/definitions/_0de36357-fec0-4b4e-b7f1-382d381e06e9", "Dessin 1"); assertThat(dmnModel).isNotNull(); assertThat(dmnModel.hasErrors()).as(dmnModel.getMessages().toString()).isFalse(); final DMNContext context = DMNFactory.newContext(); - context.set( "a", 10 ); - context.set( "b", 5 ); + context.set("a", 10); + context.set("b", 5); - final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context ); + final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context); assertThat(dmnResult.hasErrors()).isFalse(); assertThat((Map) dmnResult.getContext().get("Math")).containsEntry("Sum", BigDecimal.valueOf(15)); } @@ -481,46 +482,46 @@ void functionDefAndInvocation(boolean useExecModelCompiler) { @MethodSource("params") void builtInFunctionInvocation(boolean useExecModelCompiler) { init(useExecModelCompiler); - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("BuiltInFunctionInvocation.dmn", this.getClass() ); - final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/definitions/_b77219ee-ec28-48e3-b240-8e0dbbabefeb", "built in function invocation" ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("BuiltInFunctionInvocation.dmn", this.getClass()); + final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/definitions/_b77219ee-ec28-48e3-b240-8e0dbbabefeb", "built in function invocation"); assertThat(dmnModel).isNotNull(); assertThat(dmnModel.hasErrors()).as(dmnModel.getMessages().toString()).isFalse(); final DMNContext context = DMNFactory.newContext(); - context.set( "a", 10 ); - context.set( "b", 5 ); - context.set( "x", "Hello, World!" ); + context.set("a", 10); + context.set("b", 5); + context.set("x", "Hello, World!"); - final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context ); + final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context); assertThat(dmnResult.hasErrors()).isFalse(); - assertThat( dmnResult.getContext().get( "calc min" )).isEqualTo(BigDecimal.valueOf( 5 ) ); - assertThat( dmnResult.getContext().get( "fixed params" )).isEqualTo("World!"); - assertThat( dmnResult.getContext().get( "out of order" )).isEqualTo(BigDecimal.valueOf( 5 ) ); + assertThat(dmnResult.getContext().get("calc min")).isEqualTo(BigDecimal.valueOf(5)); + assertThat(dmnResult.getContext().get("fixed params")).isEqualTo("World!"); + assertThat(dmnResult.getContext().get("out of order")).isEqualTo(BigDecimal.valueOf(5)); } @ParameterizedTest @MethodSource("params") void bkmNode(boolean useExecModelCompiler) { init(useExecModelCompiler); - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("0009-invocation-arithmetic.dmn", getClass() ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("0009-invocation-arithmetic.dmn", getClass()); // runtime.addListener( DMNRuntimeUtil.createListener() ); - final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/definitions/_cb28c255-91cd-4c01-ac7b-1a9cb1ecdb11", "literal invocation1" ); + final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/definitions/_cb28c255-91cd-4c01-ac7b-1a9cb1ecdb11", "literal invocation1"); assertThat(dmnModel).isNotNull(); assertThat(dmnModel.hasErrors()).as(dmnModel.getMessages().toString()).isFalse(); final Map loan = new HashMap<>(); - loan.put( "amount", BigDecimal.valueOf( 600000 ) ); - loan.put( "rate", new BigDecimal( "0.0375" ) ); - loan.put( "term", BigDecimal.valueOf( 360 ) ); + loan.put("amount", BigDecimal.valueOf(600000)); + loan.put("rate", new BigDecimal("0.0375")); + loan.put("term", BigDecimal.valueOf(360)); final DMNContext context = DMNFactory.newContext(); - context.set( "fee", 100 ); - context.set( "Loan", loan ); + context.set("fee", 100); + context.set("Loan", loan); - final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context ); + final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context); assertThat(dmnResult.hasErrors()).isFalse(); assertThat( - ((BigDecimal) dmnResult.getContext().get( "MonthlyPayment" )).setScale( 8, BigDecimal.ROUND_DOWN )). + ((BigDecimal) dmnResult.getContext().get("MonthlyPayment")).setScale(8, BigDecimal.ROUND_DOWN)). isEqualTo(new BigDecimal("2878.69354943277").setScale(8, BigDecimal.ROUND_DOWN)); } @@ -528,10 +529,10 @@ void bkmNode(boolean useExecModelCompiler) { @MethodSource("params") void itemDefCollection(boolean useExecModelCompiler) { init(useExecModelCompiler); - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("0001-filter.dmn", getClass() ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("0001-filter.dmn", getClass()); // runtime.addListener( DMNRuntimeUtil.createListener() ); - final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/definitions/_f52ca843-504b-4c3b-a6bc-4d377bffef7a", "filter01" ); + final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/definitions/_f52ca843-504b-4c3b-a6bc-4d377bffef7a", "filter01"); assertThat(dmnModel).isNotNull(); assertThat(dmnModel.hasErrors()).as(dmnModel.getMessages().toString()).isFalse(); @@ -549,162 +550,162 @@ void itemDefCollection(boolean useExecModelCompiler) { employees.add(e); } final DMNContext context = DMNFactory.newContext(); - context.set( "Employee", employees ); + context.set("Employee", employees); - final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context ); + final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context); assertThat(dmnResult.hasErrors()).isFalse(); - assertThat( dmnResult.getContext().get( "filter01" )).asList().containsExactly("Mary"); + assertThat(dmnResult.getContext().get("filter01")).asList().containsExactly("Mary"); } @ParameterizedTest @MethodSource("params") void list(boolean useExecModelCompiler) { init(useExecModelCompiler); - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("list-expression.dmn", getClass() ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("list-expression.dmn", getClass()); // runtime.addListener( DMNRuntimeUtil.createListener() ); - final DMNModel dmnModel = runtime.getModel("https://github.com/kiegroup/kie-dmn", "list-expression" ); + final DMNModel dmnModel = runtime.getModel("https://github.com/kiegroup/kie-dmn", "list-expression"); assertThat(dmnModel).isNotNull(); assertThat(dmnModel.hasErrors()).as(dmnModel.getMessages().toString()).isFalse(); final DMNContext context = DMNFactory.newContext(); - final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context ); + final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context); assertThat(dmnResult.hasErrors()).isFalse(); - assertThat( dmnResult.getContext().get( "Name list" )).asList().containsExactly("John", "Mary"); + assertThat(dmnResult.getContext().get("Name list")).asList().containsExactly("John", "Mary"); } @ParameterizedTest @MethodSource("params") void relation(boolean useExecModelCompiler) { init(useExecModelCompiler); - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("relation-expression.dmn", getClass() ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("relation-expression.dmn", getClass()); // runtime.addListener( DMNRuntimeUtil.createListener() ); - final DMNModel dmnModel = runtime.getModel("https://github.com/kiegroup/kie-dmn", "relation-expression" ); + final DMNModel dmnModel = runtime.getModel("https://github.com/kiegroup/kie-dmn", "relation-expression"); assertThat(dmnModel).isNotNull(); assertThat(dmnModel.hasErrors()).as(dmnModel.getMessages().toString()).isFalse(); final DMNContext context = DMNFactory.newContext(); - final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context ); + final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context); assertThat(dmnResult.hasErrors()).isFalse(); - assertThat( dmnResult.getContext().get( "Employee Relation" )).isInstanceOf( List.class); + assertThat(dmnResult.getContext().get("Employee Relation")).isInstanceOf(List.class); - final List> employees = (List>) dmnResult.getContext().get("Employee Relation" ); - Map e = employees.get( 0 ); - assertThat( e.get( "Name" )).isEqualTo("John"); - assertThat( e.get( "Dept" )).isEqualTo("Sales"); - assertThat( e.get( "Salary" )).isEqualTo(BigDecimal.valueOf( 100000 ) ); + final List> employees = (List>) dmnResult.getContext().get("Employee Relation"); + Map e = employees.get(0); + assertThat(e.get("Name")).isEqualTo("John"); + assertThat(e.get("Dept")).isEqualTo("Sales"); + assertThat(e.get("Salary")).isEqualTo(BigDecimal.valueOf(100000)); - e = employees.get( 1 ); - assertThat( e.get( "Name" )).isEqualTo("Mary"); - assertThat( e.get( "Dept" )).isEqualTo("Finances"); - assertThat( e.get( "Salary" )).isEqualTo(BigDecimal.valueOf( 120000 ) ); + e = employees.get(1); + assertThat(e.get("Name")).isEqualTo("Mary"); + assertThat(e.get("Dept")).isEqualTo("Finances"); + assertThat(e.get("Salary")).isEqualTo(BigDecimal.valueOf(120000)); } @ParameterizedTest @MethodSource("params") void lendingExample(boolean useExecModelCompiler) { init(useExecModelCompiler); - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("0004-lending.dmn", getClass() ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("0004-lending.dmn", getClass()); // runtime.addListener( DMNRuntimeUtil.createListener() ); - final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/definitions/_4e0f0b70-d31c-471c-bd52-5ca709ed362b", "Lending1" ); + final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/definitions/_4e0f0b70-d31c-471c-bd52-5ca709ed362b", "Lending1"); assertThat(dmnModel).isNotNull(); assertThat(dmnModel.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).isFalse(); final DMNContext context = DMNFactory.newContext(); final Map applicant = new HashMap<>(); final Map monthly = new HashMap<>(); - monthly.put( "Income", 6000 ); - monthly.put( "Expenses", 2000 ); - monthly.put( "Repayments", 0 ); - applicant.put( "Monthly", monthly ); - applicant.put( "Age", 35 ); - applicant.put( "ExistingCustomer", Boolean.TRUE ); - applicant.put( "MaritalStatus", "M" ); - applicant.put( "EmploymentStatus", "EMPLOYED" ); + monthly.put("Income", 6000); + monthly.put("Expenses", 2000); + monthly.put("Repayments", 0); + applicant.put("Monthly", monthly); + applicant.put("Age", 35); + applicant.put("ExistingCustomer", Boolean.TRUE); + applicant.put("MaritalStatus", "M"); + applicant.put("EmploymentStatus", "EMPLOYED"); final Map product = new HashMap<>(); - product.put( "ProductType", "STANDARD LOAN" ); - product.put( "Amount", 350000 ); - product.put( "Rate", new BigDecimal( "0.0395" ) ); - product.put( "Term", 360 ); + product.put("ProductType", "STANDARD LOAN"); + product.put("Amount", 350000); + product.put("Rate", new BigDecimal("0.0395")); + product.put("Term", 360); final Map bureau = new HashMap<>(); - bureau.put( "CreditScore", 649 ); - bureau.put( "Bankrupt", Boolean.FALSE ); - - context.set( "ApplicantData", applicant ); - context.set( "RequestedProduct", product ); - context.set( "BureauData", bureau ); - context.set( "SupportingDocuments", "yes" ); - final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context ); + bureau.put("CreditScore", 649); + bureau.put("Bankrupt", Boolean.FALSE); + + context.set("ApplicantData", applicant); + context.set("RequestedProduct", product); + context.set("BureauData", bureau); + context.set("SupportingDocuments", "yes"); + final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context); LOG.debug("{}", dmnResult); final DMNContext ctx = dmnResult.getContext(); - assertThat(ctx.get("ApplicationRiskScore" )).isEqualTo(BigDecimal.valueOf( 130 ) ); - assertThat(ctx.get("Pre-bureauRiskCategory" )).isEqualTo("LOW"); - assertThat(ctx.get("BureauCallType" )).isEqualTo("MINI"); - assertThat(ctx.get("Post-bureauRiskCategory" )).isEqualTo("LOW"); - assertThat(((BigDecimal)ctx.get( "RequiredMonthlyInstallment")).setScale(5, BigDecimal.ROUND_DOWN)).isEqualTo(new BigDecimal("1680.880325608555").setScale(5, BigDecimal.ROUND_DOWN)); + assertThat(ctx.get("ApplicationRiskScore")).isEqualTo(BigDecimal.valueOf(130)); + assertThat(ctx.get("Pre-bureauRiskCategory")).isEqualTo("LOW"); + assertThat(ctx.get("BureauCallType")).isEqualTo("MINI"); + assertThat(ctx.get("Post-bureauRiskCategory")).isEqualTo("LOW"); + assertThat(((BigDecimal) ctx.get("RequiredMonthlyInstallment")).setScale(5, BigDecimal.ROUND_DOWN)).isEqualTo(new BigDecimal("1680.880325608555").setScale(5, BigDecimal.ROUND_DOWN)); assertThat(ctx.get("Pre-bureauAffordability")).isEqualTo(Boolean.TRUE); - assertThat(ctx.get("Eligibility" )).isEqualTo("ELIGIBLE"); - assertThat(ctx.get("Strategy" )).isEqualTo("BUREAU"); - assertThat(ctx.get("Post-bureauAffordability" )).isEqualTo(Boolean.TRUE); - assertThat(ctx.get("Routing" )).isEqualTo("ACCEPT"); + assertThat(ctx.get("Eligibility")).isEqualTo("ELIGIBLE"); + assertThat(ctx.get("Strategy")).isEqualTo("BUREAU"); + assertThat(ctx.get("Post-bureauAffordability")).isEqualTo(Boolean.TRUE); + assertThat(ctx.get("Routing")).isEqualTo("ACCEPT"); } @ParameterizedTest @MethodSource("params") void dateAndTime(boolean useExecModelCompiler) { init(useExecModelCompiler); - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("0007-date-time.dmn", getClass() ); - runtime.addListener( DMNRuntimeUtil.createListener() ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("0007-date-time.dmn", getClass()); + runtime.addListener(DMNRuntimeUtil.createListener()); - final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/definitions/_69430b3e-17b8-430d-b760-c505bf6469f9", "dateTime Table 58" ); + final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/definitions/_69430b3e-17b8-430d-b760-c505bf6469f9", "dateTime Table 58"); assertThat(dmnModel).isNotNull(); assertThat(dmnModel.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).isFalse(); final DMNContext context = DMNFactory.newContext(); - context.set( "dateString", "2015-12-24" ); - context.set( "timeString", "00:00:01-01:00" ); - context.set( "dateTimeString", "2016-12-24T23:59:00-05:00" ); - context.set( "Hours", 12 ); - context.set( "Minutes", 59 ); - context.set( "Seconds", new BigDecimal( "1.3" ) ); - context.set( "Timezone", "PT-1H" ); - context.set( "Year", 1999 ); - context.set( "Month", 11 ); - context.set( "Day", 22 ); - context.set( "oneHour", Duration.parse( "PT1H" ) ); // - context.set( "durationString", "P13DT2H14S" ); // - final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context ); + context.set("dateString", "2015-12-24"); + context.set("timeString", "00:00:01-01:00"); + context.set("dateTimeString", "2016-12-24T23:59:00-05:00"); + context.set("Hours", 12); + context.set("Minutes", 59); + context.set("Seconds", new BigDecimal("1.3")); + context.set("Timezone", "PT-1H"); + context.set("Year", 1999); + context.set("Month", 11); + context.set("Day", 22); + context.set("oneHour", Duration.parse("PT1H")); // + context.set("durationString", "P13DT2H14S"); // + final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context); final DMNContext ctx = dmnResult.getContext(); assertThat(dmnResult.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnResult.getMessages())).isFalse(); - assertThat(ctx.get("Date-Time")).isEqualTo( ZonedDateTime.of( 2016, 12, 24, 23, 59, 0, 0, ZoneOffset.ofHours( -5 ))); - assertThat(ctx.get("Date")).isEqualTo( new HashMap( ) {{ - put( "fromString", LocalDate.of( 2015, 12, 24 ) ); - put( "fromStringToDateTime", ZonedDateTime.of( 2015, 12, 24, 0, 0, 0, 0, ZoneOffset.UTC) ); - put( "fromDateTime", LocalDate.of( 2016, 12, 24 ) ); - put( "fromYearMonthDay", LocalDate.of( 1999, 11, 22 ) ); + assertThat(ctx.get("Date-Time")).isEqualTo(ZonedDateTime.of(2016, 12, 24, 23, 59, 0, 0, ZoneOffset.ofHours(-5))); + assertThat(ctx.get("Date")).isEqualTo(new HashMap() {{ + put("fromString", LocalDate.of(2015, 12, 24)); + put("fromStringToDateTime", ZonedDateTime.of(2015, 12, 24, 0, 0, 0, 0, ZoneOffset.UTC)); + put("fromDateTime", LocalDate.of(2016, 12, 24)); + put("fromYearMonthDay", LocalDate.of(1999, 11, 22)); }}); - assertThat( ctx.get("Time")).isEqualTo( OffsetTime.of(0, 0, 1, 0, ZoneOffset.ofHours(-1))); - assertThat( ctx.get("Date-Time2")).isEqualTo( ZonedDateTime.of(2015, 12, 24, 0, 0, 1, 0, ZoneOffset.ofHours(-1))); - assertThat( ctx.get("Time2")).isEqualTo( OffsetTime.of(0, 0, 1, 0, ZoneOffset.ofHours(-1))); - assertThat( ctx.get("Time3")).isEqualTo( OffsetTime.of( 12, 59, 1, 300000000, ZoneOffset.ofHours( -1))); - assertThat( ctx.get("dtDuration1")).isEqualTo(Duration.parse( "P13DT2H14S" ) ); - assertThat( ctx.get("dtDuration2")).isEqualTo(Duration.parse( "P367DT3H58M59S" ) ); - assertThat( ctx.get("hoursInDuration")).isEqualTo(new BigDecimal( "3" ) ); - assertThat( ctx.get("sumDurations")).isEqualTo(Duration.parse( "PT9125H59M13S" ) ); - assertThat( ctx.get("ymDuration2")).isEqualTo(ComparablePeriod.parse( "P1Y" ) ); - assertThat( ctx.get("cDay")).isEqualTo(BigDecimal.valueOf( 24 ) ); - assertThat( ctx.get("cYear")).isEqualTo(BigDecimal.valueOf( 2015 ) ); - assertThat( ctx.get("cMonth")).isEqualTo(BigDecimal.valueOf( 12 ) ); - assertThat( ctx.get("cHour")).isEqualTo(BigDecimal.valueOf( 0 ) ); - assertThat( ctx.get("cMinute")).isEqualTo(BigDecimal.valueOf( 0 ) ); - assertThat( ctx.get("cSecond")).isEqualTo(BigDecimal.valueOf( 1 ) ); - assertThat( ctx.get("cTimezone")).isEqualTo("GMT-01:00" ); - assertThat( ctx.get("years")).isEqualTo(BigDecimal.valueOf( 1 ) ); - assertThat( ctx.get("d1seconds")).isEqualTo(BigDecimal.valueOf( 14 ) ); + assertThat(ctx.get("Time")).isEqualTo(OffsetTime.of(0, 0, 1, 0, ZoneOffset.ofHours(-1))); + assertThat(ctx.get("Date-Time2")).isEqualTo(ZonedDateTime.of(2015, 12, 24, 0, 0, 1, 0, ZoneOffset.ofHours(-1))); + assertThat(ctx.get("Time2")).isEqualTo(OffsetTime.of(0, 0, 1, 0, ZoneOffset.ofHours(-1))); + assertThat(ctx.get("Time3")).isEqualTo(OffsetTime.of(12, 59, 1, 300000000, ZoneOffset.ofHours(-1))); + assertThat(ctx.get("dtDuration1")).isEqualTo(Duration.parse("P13DT2H14S")); + assertThat(ctx.get("dtDuration2")).isEqualTo(Duration.parse("P367DT3H58M59S")); + assertThat(ctx.get("hoursInDuration")).isEqualTo(new BigDecimal("3")); + assertThat(ctx.get("sumDurations")).isEqualTo(Duration.parse("PT9125H59M13S")); + assertThat(ctx.get("ymDuration2")).isEqualTo(ComparablePeriod.parse("P1Y")); + assertThat(ctx.get("cDay")).isEqualTo(BigDecimal.valueOf(24)); + assertThat(ctx.get("cYear")).isEqualTo(BigDecimal.valueOf(2015)); + assertThat(ctx.get("cMonth")).isEqualTo(BigDecimal.valueOf(12)); + assertThat(ctx.get("cHour")).isEqualTo(BigDecimal.valueOf(0)); + assertThat(ctx.get("cMinute")).isEqualTo(BigDecimal.valueOf(0)); + assertThat(ctx.get("cSecond")).isEqualTo(BigDecimal.valueOf(1)); + assertThat(ctx.get("cTimezone")).isEqualTo("GMT-01:00"); + assertThat(ctx.get("years")).isEqualTo(BigDecimal.valueOf(1)); + assertThat(ctx.get("d1seconds")).isEqualTo(BigDecimal.valueOf(14)); } @@ -714,7 +715,7 @@ void dateToDateTimeFunction(boolean useExecModelCompiler) { init(useExecModelCompiler); final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("valid_models/DMNv1_5/DateToDateTimeFunction.dmn", this.getClass()); final DMNModel dmnModel = runtime.getModel("https://kiegroup.org/dmn/_A7F17D7B-F0AB-4C0B-B521-02EA26C2FBEE", - "new-file"); + "new-file"); assertThat(dmnModel).isNotNull(); assertThat(dmnModel.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).isFalse(); @@ -732,50 +733,50 @@ void dateToDateTimeFunction(boolean useExecModelCompiler) { @MethodSource("params") void filtering(boolean useExecModelCompiler) { init(useExecModelCompiler); - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("Person_filtering_by_age.dmn", getClass() ); - runtime.addListener( DMNRuntimeUtil.createListener() ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("Person_filtering_by_age.dmn", getClass()); + runtime.addListener(DMNRuntimeUtil.createListener()); - final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/definitions/_e215ed7a-701b-4c53-b8df-4b4d23d5fe32", "Person filtering by age" ); + final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/definitions/_e215ed7a-701b-4c53-b8df-4b4d23d5fe32", "Person filtering by age"); assertThat(dmnModel).isNotNull(); assertThat(dmnModel.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).isFalse(); final DMNContext context = DMNFactory.newContext(); - context.set( "Min Age", 50 ); - final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context ); - assertThat(((List)dmnResult.getContext().get("Filtering"))).as(DMNRuntimeUtil.formatMessages(dmnResult.getMessages())).hasSize(2); + context.set("Min Age", 50); + final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context); + assertThat(((List) dmnResult.getContext().get("Filtering"))).as(DMNRuntimeUtil.formatMessages(dmnResult.getMessages())).hasSize(2); } @ParameterizedTest @MethodSource("params") void nowFunction(boolean useExecModelCompiler) { init(useExecModelCompiler); - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("today_function_test.dmn", getClass() ); - runtime.addListener( DMNRuntimeUtil.createListener() ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("today_function_test.dmn", getClass()); + runtime.addListener(DMNRuntimeUtil.createListener()); - final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/dmn/definitions/_4ad80959-5fd8-46b7-8c9a-ab2fa58cb5b4", "When is it" ); + final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/dmn/definitions/_4ad80959-5fd8-46b7-8c9a-ab2fa58cb5b4", "When is it"); assertThat(dmnModel).isNotNull(); assertThat(dmnModel.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).isFalse(); final DMNContext context = DMNFactory.newContext(); - context.set( "The date", LocalDate.of(2017, 1, 12 ) ); - final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context ); - assertThat(dmnResult.getContext().get("When is it")).as(DMNRuntimeUtil.formatMessages( dmnResult.getMessages())).isEqualTo("It is in the past"); + context.set("The date", LocalDate.of(2017, 1, 12)); + final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context); + assertThat(dmnResult.getContext().get("When is it")).as(DMNRuntimeUtil.formatMessages(dmnResult.getMessages())).isEqualTo("It is in the past"); } @ParameterizedTest @MethodSource("params") void timeFunction(boolean useExecModelCompiler) { init(useExecModelCompiler); - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("TimeFromDate.dmn", getClass() ); - runtime.addListener( DMNRuntimeUtil.createListener() ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("TimeFromDate.dmn", getClass()); + runtime.addListener(DMNRuntimeUtil.createListener()); - final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/dmn/definitions/_ecf4ea54-2abc-4e2f-a101-4fe14e356a46", "Dessin 1" ); + final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/dmn/definitions/_ecf4ea54-2abc-4e2f-a101-4fe14e356a46", "Dessin 1"); assertThat(dmnModel).isNotNull(); assertThat(dmnModel.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).isFalse(); final DMNContext context = DMNFactory.newContext(); - context.set( "datetimestring", "2016-07-29T05:48:23" ); - final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context ); + context.set("datetimestring", "2016-07-29T05:48:23"); + final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context); assertThat(dmnResult.getContext().get("time")).as(DMNRuntimeUtil.formatMessages(dmnResult.getMessages())).isEqualTo(LocalTime.of(5, 48, 23)); } @@ -783,36 +784,36 @@ void timeFunction(boolean useExecModelCompiler) { @MethodSource("params") void alternativeNSDecl(boolean useExecModelCompiler) { init(useExecModelCompiler); - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("alternative_feel_ns_declaration.dmn", this.getClass() ); - final DMNModel dmnModel = runtime.getModel("https://github.com/kiegroup/kie-dmn", "0001-input-data-string" ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("alternative_feel_ns_declaration.dmn", this.getClass()); + final DMNModel dmnModel = runtime.getModel("https://github.com/kiegroup/kie-dmn", "0001-input-data-string"); assertThat(dmnModel).isNotNull(); final DMNContext context = DMNFactory.newContext(); - context.set( "Full Name", "John Doe" ); + context.set("Full Name", "John Doe"); - final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context ); + final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context); - assertThat( dmnResult.getDecisionResults()).hasSize(1); - assertThat( dmnResult.getDecisionResultByName( "Greeting Message" ).getResult()).isEqualTo("Hello John Doe" ); + assertThat(dmnResult.getDecisionResults()).hasSize(1); + assertThat(dmnResult.getDecisionResultByName("Greeting Message").getResult()).isEqualTo("Hello John Doe"); final DMNContext result = dmnResult.getContext(); - assertThat( result.get( "Greeting Message" )).isEqualTo("Hello John Doe" ); + assertThat(result.get("Greeting Message")).isEqualTo("Hello John Doe"); } @ParameterizedTest @MethodSource("params") void loanComparison(boolean useExecModelCompiler) { init(useExecModelCompiler); - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("loanComparison.dmn", this.getClass() ); - final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/definitions/_3a1fd8f4-ea04-4453-aa30-ff14140e3441", "loanComparison" ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("loanComparison.dmn", this.getClass()); + final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/definitions/_3a1fd8f4-ea04-4453-aa30-ff14140e3441", "loanComparison"); assertThat(dmnModel).isNotNull(); assertThat(dmnModel.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).isFalse(); final DMNContext context = DMNFactory.newContext(); - context.set( "RequestedAmt", 500000 ); + context.set("RequestedAmt", 500000); - final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context ); + final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context); assertThat(dmnResult.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnResult.getMessages())).isFalse(); } @@ -820,48 +821,48 @@ void loanComparison(boolean useExecModelCompiler) { @MethodSource("params") void getViableLoanProducts(boolean useExecModelCompiler) { init(useExecModelCompiler); - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("Get_Viable_Loan_Products.dmn", this.getClass() ); - final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/definitions/_3e1a628d-36bc-45f1-8464-b201735e5ce0", "Get Viable Loan Products" ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("Get_Viable_Loan_Products.dmn", this.getClass()); + final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/definitions/_3e1a628d-36bc-45f1-8464-b201735e5ce0", "Get Viable Loan Products"); assertThat(dmnModel).isNotNull(); assertThat(dmnModel.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).isFalse(); - final Map requested = new HashMap<>( ); - requested.put( "PropertyZIP", "91001" ); - requested.put( "LoanAmt", 300000 ); - requested.put( "Objective", "Payment" ); - requested.put( "DownPct", new BigDecimal( "0.4" ) ); - requested.put( "MortgageType", "Fixed 20" ); + final Map requested = new HashMap<>(); + requested.put("PropertyZIP", "91001"); + requested.put("LoanAmt", 300000); + requested.put("Objective", "Payment"); + requested.put("DownPct", new BigDecimal("0.4")); + requested.put("MortgageType", "Fixed 20"); final DMNContext context = DMNFactory.newContext(); - context.set( "Requested", requested ); + context.set("Requested", requested); - final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context ); + final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context); assertThat(dmnResult.hasErrors()).isFalse(); final DMNContext result = dmnResult.getContext(); - assertThat( result.get( "isConforming" )).isEqualTo(Boolean.TRUE); - assertThat( (Collection) result.get( "LoanTypes" )).hasSize(3); + assertThat(result.get("isConforming")).isEqualTo(Boolean.TRUE); + assertThat((Collection) result.get("LoanTypes")).hasSize(3); } @ParameterizedTest @MethodSource("params") void yearsAndMonthsDuration(boolean useExecModelCompiler) { init(useExecModelCompiler); - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("yearMonthDuration.dmn", this.getClass() ); - final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/dmn/definitions/_6eda1490-21ca-441e-8a26-ab3ca800e43c", "Drawing 1" ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("yearMonthDuration.dmn", this.getClass()); + final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/dmn/definitions/_6eda1490-21ca-441e-8a26-ab3ca800e43c", "Drawing 1"); assertThat(dmnModel).isNotNull(); assertThat(dmnModel.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).isFalse(); - final BuiltInType feelType = (BuiltInType) BuiltInType.determineTypeFromName("yearMonthDuration" ); + final BuiltInType feelType = (BuiltInType) BuiltInTypeUtils.determineTypeFromName("yearMonthDuration"); final ChronoPeriod period = (ChronoPeriod) feelType.fromString("P2Y1M"); final DMNContext context = runtime.newContext(); - context.set( "iDuration", period ); + context.set("iDuration", period); - final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context ); + final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context); assertThat(dmnResult.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnResult.getMessages())).isFalse(); final DMNContext result = dmnResult.getContext(); - assertThat( result.get( "How long" )).isEqualTo("Longer than a year" ); + assertThat(result.get("How long")).isEqualTo("Longer than a year"); } @ParameterizedTest @@ -876,26 +877,26 @@ void invalidVariableNames(boolean useExecModelCompiler) { @MethodSource("params") void testNull(boolean useExecModelCompiler) { init(useExecModelCompiler); - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("null_values.dmn", this.getClass() ); - final DMNModel dmnModel = runtime.getModel("https://github.com/kiegroup/kie-dmn", "Null values model" ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("null_values.dmn", this.getClass()); + final DMNModel dmnModel = runtime.getModel("https://github.com/kiegroup/kie-dmn", "Null values model"); assertThat(dmnModel).isNotNull(); assertThat(dmnModel.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).isFalse(); DMNContext context = runtime.newContext(); - context.set( "Null Input", null ); + context.set("Null Input", null); - DMNResult dmnResult = runtime.evaluateAll( dmnModel, context ); + DMNResult dmnResult = runtime.evaluateAll(dmnModel, context); assertThat(dmnResult.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnResult.getMessages())).isFalse(); DMNContext result = dmnResult.getContext(); - assertThat( result.get( "Null value" )).isEqualTo("Input is null" ); + assertThat(result.get("Null value")).isEqualTo("Input is null"); context = runtime.newContext(); - context.set( "Null Input", "foo" ); + context.set("Null Input", "foo"); - dmnResult = runtime.evaluateAll( dmnModel, context ); + dmnResult = runtime.evaluateAll(dmnModel, context); assertThat(dmnResult.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnResult.getMessages())).isFalse(); result = dmnResult.getContext(); - assertThat( result.get( "Null value" )).isEqualTo("Input is not null" ); + assertThat(result.get("Null value")).isEqualTo("Input is not null"); } @@ -903,19 +904,19 @@ void testNull(boolean useExecModelCompiler) { @MethodSource("params") void invalidUHitPolicy(boolean useExecModelCompiler) { init(useExecModelCompiler); - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("Invalid_U_hit_policy.dmn", this.getClass() ); - final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/definitions/_7cf49108-9b55-4f35-b5ef-f83448061757", "Greater than 5 - Invalid U hit policy" ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("Invalid_U_hit_policy.dmn", this.getClass()); + final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/definitions/_7cf49108-9b55-4f35-b5ef-f83448061757", "Greater than 5 - Invalid U hit policy"); assertThat(dmnModel).isNotNull(); assertThat(dmnModel.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).isFalse(); final DMNContext context = runtime.newContext(); - context.set( "Number", 5 ); + context.set("Number", 5); - final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context ); + final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context); assertThat(dmnResult.hasErrors()).as(dmnResult.getMessages().toString()).isTrue(); - assertThat( dmnResult.getMessages()).hasSize(2); - assertThat( dmnResult.getMessages().get( 0 ).getSourceId()).isEqualTo("_c5eda7c3-7f22-43c2-8c1e-a3cc79bb7a74" ); - assertThat( dmnResult.getMessages().get( 1 ).getSourceId()).isEqualTo("_5bac3e4c-b59a-4f14-b5cf-d4d88c60877f" ); + assertThat(dmnResult.getMessages()).hasSize(2); + assertThat(dmnResult.getMessages().get(0).getSourceId()).isEqualTo("_c5eda7c3-7f22-43c2-8c1e-a3cc79bb7a74"); + assertThat(dmnResult.getMessages().get(1).getSourceId()).isEqualTo("_5bac3e4c-b59a-4f14-b5cf-d4d88c60877f"); } @ParameterizedTest @@ -932,102 +933,102 @@ void invalidModel(boolean useExecModelCompiler) { @MethodSource("params") void nullOnNumber(boolean useExecModelCompiler) { init(useExecModelCompiler); - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("Number_and_null_entry.dmn", this.getClass() ); - final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/definitions/_a293b9f9-c912-41ee-8147-eae59ba86ac5", "Number and null entry" ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("Number_and_null_entry.dmn", this.getClass()); + final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/definitions/_a293b9f9-c912-41ee-8147-eae59ba86ac5", "Number and null entry"); assertThat(dmnModel).isNotNull(); assertThat(dmnModel.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).isFalse(); DMNContext context = runtime.newContext(); - context.set( "num", null ); + context.set("num", null); - DMNResult dmnResult = runtime.evaluateAll( dmnModel, context ); + DMNResult dmnResult = runtime.evaluateAll(dmnModel, context); assertThat(dmnResult.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnResult.getMessages())).isFalse(); DMNContext result = dmnResult.getContext(); - assertThat( result.get( "Decision Logic 1" )).isEqualTo("Null"); + assertThat(result.get("Decision Logic 1")).isEqualTo("Null"); context = runtime.newContext(); - context.set( "num", 4 ); + context.set("num", 4); - dmnResult = runtime.evaluateAll( dmnModel, context ); + dmnResult = runtime.evaluateAll(dmnModel, context); assertThat(dmnResult.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnResult.getMessages())).isFalse(); result = dmnResult.getContext(); - assertThat( result.get( "Decision Logic 1" )).isEqualTo("Positive number" ); + assertThat(result.get("Decision Logic 1")).isEqualTo("Positive number"); } @ParameterizedTest @MethodSource("params") void loanRecommendation2(boolean useExecModelCompiler) { init(useExecModelCompiler); - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("Loan_Recommendation2.dmn", this.getClass() ); - final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/definitions/_35c7339b-b868-43da-8f06-eb481708c73c", "Loan Recommendation2" ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("Loan_Recommendation2.dmn", this.getClass()); + final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/definitions/_35c7339b-b868-43da-8f06-eb481708c73c", "Loan Recommendation2"); assertThat(dmnModel).isNotNull(); assertThat(dmnModel.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).isFalse(); - final Map loan = new HashMap<>( ); - loan.put( "Amount", 100000); - loan.put( "Rate", 2.39); - loan.put( "Term", 60); - - final Map borrower = new HashMap<>( ); - borrower.put( "Age", 39); - borrower.put( "EmploymentStatus", "Employed"); - borrower.put( "YearsAtCurrentEmployer", 10); - borrower.put( "TotalAnnualIncome", 150000); - borrower.put( "NonSalaryIncome", 0); - borrower.put( "MonthlyDebtPmtAmt", 2000); - borrower.put( "LiquidAssetsAmt", 50000); + final Map loan = new HashMap<>(); + loan.put("Amount", 100000); + loan.put("Rate", 2.39); + loan.put("Term", 60); + + final Map borrower = new HashMap<>(); + borrower.put("Age", 39); + borrower.put("EmploymentStatus", "Employed"); + borrower.put("YearsAtCurrentEmployer", 10); + borrower.put("TotalAnnualIncome", 150000); + borrower.put("NonSalaryIncome", 0); + borrower.put("MonthlyDebtPmtAmt", 2000); + borrower.put("LiquidAssetsAmt", 50000); final DMNContext context = runtime.newContext(); - context.set( "Credit Score", null ); - context.set( "Appraised Value", 200000 ); - context.set( "Loan", loan ); - context.set( "Borrower", borrower ); + context.set("Credit Score", null); + context.set("Appraised Value", 200000); + context.set("Loan", loan); + context.set("Borrower", borrower); - final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context ); + final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context); assertThat(dmnResult.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnResult.getMessages())).isFalse(); final DMNContext result = dmnResult.getContext(); - assertThat( result.get( "Loan Recommendation" )).isEqualTo("Decline"); + assertThat(result.get("Loan Recommendation")).isEqualTo("Decline"); } @ParameterizedTest @MethodSource("params") void priorityTable(boolean useExecModelCompiler) { init(useExecModelCompiler); - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("priority_table.dmn", this.getClass() ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("priority_table.dmn", this.getClass()); final DMNModel dmnModel = runtime.getModel( "http://www.trisotech.com/definitions/_ff54a44d-b8f5-48fc-b2b7-43db767e8a1c", - "not quite all or nothing P" ); + "not quite all or nothing P"); assertThat(dmnModel).isNotNull(); assertThat(dmnModel.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).isFalse(); - + final DMNContext context = runtime.newContext(); context.set("isAffordable", Boolean.FALSE); context.set("RiskCategory", "Medium"); - - final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context ); + + final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context); final DMNContext result = dmnResult.getContext(); - assertThat( result.get( "Approval Status" )).isEqualTo("Declined"); + assertThat(result.get("Approval Status")).isEqualTo("Declined"); } @ParameterizedTest @MethodSource("params") void priorityTableContextRecursion(boolean useExecModelCompiler) { init(useExecModelCompiler); - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("priority_table_context_recursion.dmn", this.getClass() ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("priority_table_context_recursion.dmn", this.getClass()); final DMNModel dmnModel = runtime.getModel( "http://www.trisotech.com/definitions/_ff54a44d-b8f5-48fc-b2b7-43db767e8a1c", - "not quite all or nothing P" ); + "not quite all or nothing P"); assertThat(dmnModel).isNotNull(); assertThat(dmnModel.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).isFalse(); - + final DMNContext context = runtime.newContext(); context.set("isAffordable", Boolean.FALSE); context.set("RiskCategory", "Medium"); - - final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context ); + + final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context); final DMNContext result = dmnResult.getContext(); - assertThat( result.get( "Approval Status" )).isEqualTo("Declined"); + assertThat(result.get("Approval Status")).isEqualTo("Declined"); } @ParameterizedTest @@ -1042,10 +1043,10 @@ void priorityTableMissingOutputValues(boolean useExecModelCompiler) { @MethodSource("params") void non_priority_table_missing_output_values(boolean useExecModelCompiler) { init(useExecModelCompiler); - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("DTABLE_NON_PRIORITY_MISSING_OUTVALS.dmn", this.getClass() ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("DTABLE_NON_PRIORITY_MISSING_OUTVALS.dmn", this.getClass()); final DMNModel dmnModel = runtime.getModel( - "https://github.com/kiegroup/kie-dmn", - "DTABLE_NON_PRIORITY_MISSING_OUTVALS" ); + "https://github.com/kiegroup/kie-dmn", + "DTABLE_NON_PRIORITY_MISSING_OUTVALS"); assertThat(dmnModel).isNotNull(); assertThat(dmnModel.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).isFalse(); } @@ -1054,10 +1055,10 @@ void non_priority_table_missing_output_values(boolean useExecModelCompiler) { @MethodSource("params") void priorityTableOneOutputValue(boolean useExecModelCompiler) { init(useExecModelCompiler); - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("DTABLE_PRIORITY_ONE_OUTVAL.dmn", this.getClass() ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("DTABLE_PRIORITY_ONE_OUTVAL.dmn", this.getClass()); final DMNModel dmnModel = runtime.getModel( - "https://github.com/kiegroup/kie-dmn", - "DTABLE_PRIORITY_ONE_OUTVAL" ); + "https://github.com/kiegroup/kie-dmn", + "DTABLE_PRIORITY_ONE_OUTVAL"); assertThat(dmnModel).isNotNull(); assertThat(dmnModel.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).isFalse(); } @@ -1066,21 +1067,21 @@ void priorityTableOneOutputValue(boolean useExecModelCompiler) { @MethodSource("params") void noPrefix(boolean useExecModelCompiler) { init(useExecModelCompiler); - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("drools1502-noprefix.dmn", this.getClass() ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("drools1502-noprefix.dmn", this.getClass()); final DMNModel dmnModel = runtime.getModel( "https://www.drools.org/kie-dmn/definitions", - "definitions" ); + "definitions"); assertThat(dmnModel).isNotNull(); assertThat(dmnModel.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).isFalse(); - + final DMNContext context = runtime.newContext(); context.set("MyInput", "a"); - final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context ); - + final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context); + assertThat(dmnResult.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnResult.getMessages())).isFalse(); final DMNContext result = dmnResult.getContext(); - assertThat( result.get( "MyDecision" )).isEqualTo("Decision taken" ); + assertThat(result.get("MyDecision")).isEqualTo("Decision taken"); } @ParameterizedTest @@ -1094,7 +1095,7 @@ void wrongConstraintsInItemDefinition(boolean useExecModelCompiler) { assertThat(messages.get(0).getMessageType()).isEqualTo(DMNMessageType.ERR_COMPILING_FEEL); assertThat(messages.get(1).getSourceId()).isEqualTo("_e794c655-4fdf-45d1-b7b7-d990df513f92"); assertThat(messages.get(1).getMessageType()).isEqualTo(DMNMessageType.ERR_COMPILING_FEEL); - + // The DecisionTable does not define typeRef for the single OutputClause, but neither the enclosing Decision define typeRef for its variable assertThat(messages.get(2).getSourceId()).isEqualTo("_31911de7-e184-411c-99d1-f33977971270"); assertThat(messages.get(2).getMessageType()).isEqualTo(DMNMessageType.MISSING_TYPE_REF); @@ -1105,37 +1106,37 @@ void wrongConstraintsInItemDefinition(boolean useExecModelCompiler) { void resolutionOfVariableWithLeadingOrTrailingSpaces(boolean useExecModelCompiler) { init(useExecModelCompiler); // DROOLS-1504 - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("variableLeadingTrailingSpaces.dmn", this.getClass() ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("variableLeadingTrailingSpaces.dmn", this.getClass()); final DMNModel dmnModel = runtime.getModel( "https://www.drools.org/kie-dmn/definitions", - "definitions" ); + "definitions"); assertThat(dmnModel).isNotNull(); assertThat(dmnModel.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).isFalse(); - + final DMNContext context = runtime.newContext(); final Map person = new HashMap<>(); person.put("Name", "John"); person.put("Surname", "Doe"); context.set("Input Person", person); - final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context ); - + final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context); + assertThat(dmnResult.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnResult.getMessages())).isFalse(); final DMNContext result = dmnResult.getContext(); - assertThat( result.get( "Further Decision" )).isEqualTo( "The person was greeted with: 'Ciao John Doe'"); + assertThat(result.get("Further Decision")).isEqualTo("The person was greeted with: 'Ciao John Doe'"); } @ParameterizedTest @MethodSource("params") void outOfOrderItemsNPE(boolean useExecModelCompiler) { init(useExecModelCompiler); - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("out-of-order-items.dmn", this.getClass() ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("out-of-order-items.dmn", this.getClass()); final DMNModel dmnModel = runtime.getModel( "https://github.com/kiegroup/kie-dmn", - "out-of-order" ); + "out-of-order"); assertThat(dmnModel).isNotNull(); - assertThat(dmnModel.getMessages().stream().anyMatch( m -> m.getMessageType().equals( DMNMessageType.FAILED_VALIDATOR))) - .as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).isFalse(); + assertThat(dmnModel.getMessages().stream().anyMatch(m -> m.getMessageType().equals(DMNMessageType.FAILED_VALIDATOR))) + .as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).isFalse(); } @ParameterizedTest @@ -1143,24 +1144,24 @@ void outOfOrderItemsNPE(boolean useExecModelCompiler) { void itemDefDependencies(boolean useExecModelCompiler) { init(useExecModelCompiler); // DROOLS-1505 - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("itemDef-dependency.dmn", this.getClass() ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("itemDef-dependency.dmn", this.getClass()); final DMNModel dmnModel = runtime.getModel( "http://www.trisotech.com/definitions/_2374ee6d-75ed-4e9d-95d3-a88c135e1c43", - "Drawing 1a" ); + "Drawing 1a"); assertThat(dmnModel).isNotNull(); assertThat(dmnModel.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).isFalse(); final DMNContext context = runtime.newContext(); final Map person = new HashMap<>(); - person.put( "Full Name", "John Doe" ); - person.put( "Address", "100 East Davie Street" ); - context.set( "Input Person", person ); + person.put("Full Name", "John Doe"); + person.put("Address", "100 East Davie Street"); + context.set("Input Person", person); - final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context ); + final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context); assertThat(dmnResult.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnResult.getMessages())).isFalse(); final DMNContext result = dmnResult.getContext(); - assertThat( result.get( "My Decision" )).isEqualTo("The person John Doe is located at 100 East Davie Street" ); + assertThat(result.get("My Decision")).isEqualTo("The person John Doe is located at 100 East Davie Street"); } @ParameterizedTest @@ -1168,14 +1169,14 @@ void itemDefDependencies(boolean useExecModelCompiler) { void decisionResultTypeCheck(boolean useExecModelCompiler) { init(useExecModelCompiler); // DROOLS-1513 - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("LoanRecommendationWrongOutputType.dmn", this.getClass() ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("LoanRecommendationWrongOutputType.dmn", this.getClass()); final DMNModel dmnModel = runtime.getModel( "http://www.trisotech.com/dmn/definitions/_591d49d0-26e1-4a1c-9f72-b65bec09964a", - "Loan Recommendation Multi-step" ); + "Loan Recommendation Multi-step"); assertThat(dmnModel).isNotNull(); - System.out.println(DMNRuntimeUtil.formatMessages( dmnModel.getMessages() )); + System.out.println(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())); assertThat(dmnModel.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).isFalse(); - + final DMNContext context = runtime.newContext(); final Map loan = new HashMap<>(); loan.put("Amount", 100); @@ -1185,9 +1186,9 @@ void decisionResultTypeCheck(boolean useExecModelCompiler) { final DMNResult dmnResult = runtime.evaluateByName(dmnModel, context, "Loan Payment"); assertThat(dmnResult.hasErrors()).as(dmnResult.getMessages().toString()).isTrue(); - assertThat( dmnResult.getMessages()).hasSize(1); - assertThat( dmnResult.getMessages().get( 0 ).getSourceId()).isEqualTo("_93062144-ebc7-4ef7-a156-c342aeffac49"); - assertThat( dmnResult.getMessages().get( 0 ).getMessageType()).isEqualTo(DMNMessageType.ERROR_EVAL_NODE); + assertThat(dmnResult.getMessages()).hasSize(1); + assertThat(dmnResult.getMessages().get(0).getSourceId()).isEqualTo("_93062144-ebc7-4ef7-a156-c342aeffac49"); + assertThat(dmnResult.getMessages().get(0).getMessageType()).isEqualTo(DMNMessageType.ERROR_EVAL_NODE); } @ParameterizedTest @@ -1195,42 +1196,42 @@ void decisionResultTypeCheck(boolean useExecModelCompiler) { void npe(boolean useExecModelCompiler) { init(useExecModelCompiler); // DROOLS-1512 - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("NPE.dmn", this.getClass() ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("NPE.dmn", this.getClass()); final DMNModel dmnModel = runtime.getModel( "http://www.trisotech.com/dmn/definitions/_95b7ee22-1964-4be5-b7db-7db66692c707", - "Dessin 1" ); + "Dessin 1"); assertThat(dmnModel).isNotNull(); assertThat(dmnModel.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).isFalse(); final DMNContext context = runtime.newContext(); - final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context ); + final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context); assertThat(dmnResult.hasErrors()).as(dmnResult.getMessages().toString()).isTrue(); - assertThat(dmnResult.getMessages().stream().anyMatch( m -> m.getMessageType().equals( DMNMessageType.REQ_NOT_FOUND))).isTrue(); + assertThat(dmnResult.getMessages().stream().anyMatch(m -> m.getMessageType().equals(DMNMessageType.REQ_NOT_FOUND))).isTrue(); } @ParameterizedTest @MethodSource("params") void unionofLetters(boolean useExecModelCompiler) { init(useExecModelCompiler); - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("Union_of_letters.dmn", this.getClass() ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("Union_of_letters.dmn", this.getClass()); final DMNModel dmnModel = runtime.getModel( "http://www.trisotech.com/definitions/_76362694-41e8-400c-8dea-e5f033d4f405", - "Union of letters" ); + "Union of letters"); assertThat(dmnModel).isNotNull(); assertThat(dmnModel.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).isFalse(); final DMNContext ctx1 = runtime.newContext(); ctx1.set("A1", Arrays.asList("a", "b")); ctx1.set("A2", Arrays.asList("b", "c")); - final DMNResult dmnResult1 = runtime.evaluateAll(dmnModel, ctx1 ); + final DMNResult dmnResult1 = runtime.evaluateAll(dmnModel, ctx1); assertThat(dmnResult1.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnResult1.getMessages())).isFalse(); - assertThat( (List) dmnResult1.getContext().get( "D1" )).asList().contains( "a", "b", "c" ); - + assertThat((List) dmnResult1.getContext().get("D1")).asList().contains("a", "b", "c"); + final DMNContext ctx2 = runtime.newContext(); ctx2.set("A1", Arrays.asList("a", "b")); ctx2.set("A2", Arrays.asList("b", "x")); - final DMNResult dmnResult2 = runtime.evaluateAll(dmnModel, ctx2 ); + final DMNResult dmnResult2 = runtime.evaluateAll(dmnModel, ctx2); assertThat(dmnResult2.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnResult2.getMessages())).isTrue(); assertThat(dmnResult2.getMessages().stream().anyMatch(m -> m.getMessageType().equals(DMNMessageType.ERROR_EVAL_NODE))).isTrue(); } @@ -1258,32 +1259,32 @@ void unknownVariable2(boolean useExecModelCompiler) { @MethodSource("params") void singleDecisionWithContext(boolean useExecModelCompiler) { init(useExecModelCompiler); - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("SingleDecisionWithContext.dmn", this.getClass() ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("SingleDecisionWithContext.dmn", this.getClass()); final DMNModel dmnModel = runtime.getModel( "http://www.trisotech.com/definitions/_71af58db-e1df-4b0f-aee2-48e0e8d89672", - "SingleDecisionWithContext" ); + "SingleDecisionWithContext"); assertThat(dmnModel).isNotNull(); assertThat(dmnModel.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).isFalse(); - + final DMNContext emptyContext = runtime.newContext(); - final DMNResult dmnResult = runtime.evaluateAll(dmnModel, emptyContext ); - + final DMNResult dmnResult = runtime.evaluateAll(dmnModel, emptyContext); + assertThat(dmnResult.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnResult.getMessages())).isFalse(); final DMNContext result = dmnResult.getContext(); - assertThat( result.get( "MyDecision" )).isEqualTo("Hello John Doe" ); + assertThat(result.get("MyDecision")).isEqualTo("Hello John Doe"); } @ParameterizedTest @MethodSource("params") void ex61(boolean useExecModelCompiler) { init(useExecModelCompiler); - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("Ex_6_1.dmn", this.getClass() ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("Ex_6_1.dmn", this.getClass()); final DMNModel dmnModel = runtime.getModel( "http://www.trisotech.com/definitions/_5f1269c8-1e6f-4748-9eca-26aa1b1278ef", - "Ex 6-1" ); + "Ex 6-1"); assertThat(dmnModel).isNotNull(); assertThat(dmnModel.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).isFalse(); - + final DMNContext ctx = runtime.newContext(); final Map t1 = new HashMap<>(); t1.put("city", "Los Angeles"); @@ -1298,68 +1299,68 @@ void ex61(boolean useExecModelCompiler) { t2.put("losses", 0); t2.put("bonus points", 7); ctx.set("NBA Pacific", Arrays.asList(t1, t2)); - final DMNResult dmnResult = runtime.evaluateAll(dmnModel, ctx ); - + final DMNResult dmnResult = runtime.evaluateAll(dmnModel, ctx); + assertThat(dmnResult.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnResult.getMessages())).isFalse(); final DMNContext result = dmnResult.getContext(); - assertThat( result.get( "Number of distinct cities" )).isEqualTo(new BigDecimal(2) ); - assertThat( result.get( "Second place losses" )).isEqualTo(new BigDecimal(0) ); - assertThat( result.get( "Max wins" )).isEqualTo(new BigDecimal(1) ); - assertThat( result.get( "Mean wins" )).isEqualTo(new BigDecimal(0.5) ); - assertThat( (List) result.get( "Positions of Los Angeles teams" )).asList().contains(new BigDecimal(1)); - assertThat( result.get( "Number of teams" )).isEqualTo(new BigDecimal(2) ); - assertThat( result.get( "Sum of bonus points" )).isEqualTo(new BigDecimal(47) ); + assertThat(result.get("Number of distinct cities")).isEqualTo(new BigDecimal(2)); + assertThat(result.get("Second place losses")).isEqualTo(new BigDecimal(0)); + assertThat(result.get("Max wins")).isEqualTo(new BigDecimal(1)); + assertThat(result.get("Mean wins")).isEqualTo(new BigDecimal(0.5)); + assertThat((List) result.get("Positions of Los Angeles teams")).asList().contains(new BigDecimal(1)); + assertThat(result.get("Number of teams")).isEqualTo(new BigDecimal(2)); + assertThat(result.get("Sum of bonus points")).isEqualTo(new BigDecimal(47)); } @ParameterizedTest @MethodSource("params") void singletonlistFunctionCall(boolean useExecModelCompiler) { init(useExecModelCompiler); - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("singletonlist_fuction_call.dmn", this.getClass() ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("singletonlist_fuction_call.dmn", this.getClass()); final DMNModel dmnModel = runtime.getModel( "http://www.trisotech.com/definitions/_0768879b-5ee1-410f-92f0-7732573b069d", - "expression function subst [a] with a" ); + "expression function subst [a] with a"); assertThat(dmnModel).isNotNull(); assertThat(dmnModel.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).isFalse(); - + final DMNContext ctx = runtime.newContext(); ctx.set("InputLineItem", prototype(entry("Line", "0015"), entry("Description", "additional Battery"))); - final DMNResult dmnResult = runtime.evaluateAll(dmnModel, ctx ); - + final DMNResult dmnResult = runtime.evaluateAll(dmnModel, ctx); + assertThat(dmnResult.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnResult.getMessages())).isFalse(); final DMNContext result = dmnResult.getContext(); - assertThat(result.get("The Battery")).isEqualTo( prototype(entry("Line", "0010"), entry("Description", "Battery")) ) ; - assertThat((List)result.get("Remove Battery")).asList().contains( prototype(entry("Line", "0020"), entry("Description", "Case")), - prototype(entry("Line", "0030"), entry("Description", "Power Supply")) - ); - assertThat((List)result.get("Remove Battery")).asList().doesNotContain(prototype(entry("Line", "0010"), entry("Description", "Battery"))); - - assertThat((List)result.get("Insert before Line 0020")).asList().contains(prototype(entry("Line", "0010"), entry("Description", "Battery")), - prototype(entry("Line", "0015"), entry("Description", "additional Battery")), - prototype(entry("Line", "0020"), entry("Description", "Case")), - prototype(entry("Line", "0030"), entry("Description", "Power Supply")) - ); + assertThat(result.get("The Battery")).isEqualTo(prototype(entry("Line", "0010"), entry("Description", "Battery"))); + assertThat((List) result.get("Remove Battery")).asList().contains(prototype(entry("Line", "0020"), entry("Description", "Case")), + prototype(entry("Line", "0030"), entry("Description", "Power Supply")) + ); + assertThat((List) result.get("Remove Battery")).asList().doesNotContain(prototype(entry("Line", "0010"), entry("Description", "Battery"))); + + assertThat((List) result.get("Insert before Line 0020")).asList().contains(prototype(entry("Line", "0010"), entry("Description", "Battery")), + prototype(entry("Line", "0015"), entry("Description", "additional Battery")), + prototype(entry("Line", "0020"), entry("Description", "Case")), + prototype(entry("Line", "0030"), entry("Description", "Power Supply")) + ); } @ParameterizedTest @MethodSource("params") void javaFunctionContext(boolean useExecModelCompiler) { init(useExecModelCompiler); - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("java_function_context.dmn", this.getClass() ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("java_function_context.dmn", this.getClass()); final DMNModel dmnModel = runtime.getModel( "http://www.trisotech.com/dmn/definitions/_b42317c4-4f0c-474e-a0bf-2895b0b3c314", - "Dessin 1" ); + "Dessin 1"); assertThat(dmnModel).isNotNull(); assertThat(dmnModel.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).isFalse(); final DMNContext ctx = runtime.newContext(); - ctx.set( "Input", 3.14 ); - final DMNResult dmnResult = runtime.evaluateAll(dmnModel, ctx ); + ctx.set("Input", 3.14); + final DMNResult dmnResult = runtime.evaluateAll(dmnModel, ctx); assertThat(dmnResult.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnResult.getMessages())).isFalse(); final DMNContext result = dmnResult.getContext(); - assertThat( ((BigDecimal) result.get( "D1" )).setScale( 4, BigDecimal.ROUND_HALF_UP )).isEqualTo(new BigDecimal( "-1.0000" ) ); - assertThat( ((BigDecimal) result.get( "D2" )).setScale( 4, BigDecimal.ROUND_HALF_UP )).isEqualTo(new BigDecimal( "-1.0000" ) ); + assertThat(((BigDecimal) result.get("D1")).setScale(4, BigDecimal.ROUND_HALF_UP)).isEqualTo(new BigDecimal("-1.0000")); + assertThat(((BigDecimal) result.get("D2")).setScale(4, BigDecimal.ROUND_HALF_UP)).isEqualTo(new BigDecimal("-1.0000")); } @ParameterizedTest @@ -1395,7 +1396,7 @@ void nestingFnDef(boolean useExecModelCompiler) { init(useExecModelCompiler); final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("nestingFnDef.dmn", this.getClass()); final DMNModel dmnModel = runtime.getModel("https://kiegroup.org/dmn/_FC72DC4B-DC64-4E43-9685-945FC3B7E4BC", - "new-file"); + "new-file"); assertThat(dmnModel).isNotNull(); assertThat(dmnModel.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).isFalse(); @@ -1413,7 +1414,7 @@ void bkmCurried(boolean useExecModelCompiler) { init(useExecModelCompiler); final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("bkmCurried.dmn", this.getClass()); final DMNModel dmnModel = runtime.getModel("https://kiegroup.org/dmn/_A7F17D7B-F0AB-4C0B-B521-02EA26C2FB7D", - "new-file"); + "new-file"); assertThat(dmnModel).isNotNull(); assertThat(dmnModel.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).isFalse(); @@ -1432,7 +1433,7 @@ void bkmWithDotsInName(boolean useExecModelCompiler) { init(useExecModelCompiler); final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("bkmWithDotsInName.dmn", this.getClass()); final DMNModel dmnModel = runtime.getModel("https://kiegroup.org/dmn/_E035C5C5-3571-453D-BD8F-FFF30E74A7F8", - "bkmWithDotsInName"); + "bkmWithDotsInName"); assertThat(dmnModel).isNotNull(); assertThat(dmnModel.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).isFalse(); @@ -1451,15 +1452,15 @@ void bkmWithDotsInName(boolean useExecModelCompiler) { @MethodSource("params") void pmmlFunctionContext(boolean useExecModelCompiler) { init(useExecModelCompiler); - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("pmml_function_context.dmn", this.getClass() ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("pmml_function_context.dmn", this.getClass()); final DMNModel dmnModel = runtime.getModel( "http://www.trisotech.com/dmn/definitions/_b42317c4-4f0c-474e-a0bf-2895b0b3c314", - "Dessin 1" ); + "Dessin 1"); assertThat(dmnModel).isNotNull(); assertThat(dmnModel.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).isFalse(); - assertThat( dmnModel.getMessages()).hasSize(1); - assertThat( dmnModel.getMessages().get( 0 ).getMessageType()).isEqualTo(DMNMessageType.INVALID_ATTRIBUTE_VALUE); - assertThat( dmnModel.getMessages().get( 0 ).getSeverity()).isEqualTo(DMNMessage.Severity.WARN); + assertThat(dmnModel.getMessages()).hasSize(1); + assertThat(dmnModel.getMessages().get(0).getMessageType()).isEqualTo(DMNMessageType.INVALID_ATTRIBUTE_VALUE); + assertThat(dmnModel.getMessages().get(0).getSeverity()).isEqualTo(DMNMessage.Severity.WARN); } @ParameterizedTest @@ -1467,36 +1468,36 @@ void pmmlFunctionContext(boolean useExecModelCompiler) { void count_csatrade_ratings(boolean useExecModelCompiler) { init(useExecModelCompiler); // DROOLS-1563 - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("countCSATradeRatings.dmn", this.getClass() ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("countCSATradeRatings.dmn", this.getClass()); final DMNModel dmnModel = runtime.getModel( "http://www.trisotech.com/definitions/_1a7d184c-2e38-4462-ae28-15591ef6d534", - "countCSATradeRatings" ); + "countCSATradeRatings"); assertThat(dmnModel).isNotNull(); assertThat(dmnModel.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).isFalse(); - + final DMNContext ctx = runtime.newContext(); final List> ratings = new ArrayList<>(); - ratings.add( prototype(entry("Agency", "FITCH"), entry("Value", "val1")) ); - ratings.add( prototype(entry("Agency", "MOODY"), entry("Value", "val2")) ); + ratings.add(prototype(entry("Agency", "FITCH"), entry("Value", "val1"))); + ratings.add(prototype(entry("Agency", "MOODY"), entry("Value", "val2"))); ctx.set("CSA Trade Ratings", ratings); - final DMNResult dmnResult = runtime.evaluateAll(dmnModel, ctx ); - + final DMNResult dmnResult = runtime.evaluateAll(dmnModel, ctx); + assertThat(dmnResult.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnResult.getMessages())).isFalse(); final DMNContext result = dmnResult.getContext(); - assertThat( result.get("Trade Ratings")).isEqualTo(new BigDecimal(2) ); - - + assertThat(result.get("Trade Ratings")).isEqualTo(new BigDecimal(2)); + + final DMNContext ctx2 = runtime.newContext(); ctx2.set("CSA Trade Ratings", null); - final DMNResult dmnResult2 = runtime.evaluateAll(dmnModel, ctx2 ); + final DMNResult dmnResult2 = runtime.evaluateAll(dmnModel, ctx2); assertThat(dmnResult2.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnResult2.getMessages())).isTrue(); assertThat(dmnResult2.getMessages().stream().anyMatch(m -> m.getMessageType().equals(DMNMessageType.FEEL_EVALUATION_ERROR))).isTrue(); assertThat(dmnResult2.getDecisionResultByName("Trade Ratings").getEvaluationStatus()).isEqualTo(DecisionEvaluationStatus.FAILED); - - - final DMNResult dmnResult3 = runtime.evaluateAll(dmnModel, runtime.newContext() ); - assertThat(dmnResult3.hasErrors()).as(DMNRuntimeUtil.formatMessages( dmnResult3.getMessages())).isTrue(); - assertThat(dmnResult3.getMessages().stream().anyMatch( m -> m.getMessageType().equals( DMNMessageType.REQ_NOT_FOUND ) )).isTrue(); + + + final DMNResult dmnResult3 = runtime.evaluateAll(dmnModel, runtime.newContext()); + assertThat(dmnResult3.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnResult3.getMessages())).isTrue(); + assertThat(dmnResult3.getMessages().stream().anyMatch(m -> m.getMessageType().equals(DMNMessageType.REQ_NOT_FOUND))).isTrue(); } @ParameterizedTest @@ -1504,25 +1505,25 @@ void count_csatrade_ratings(boolean useExecModelCompiler) { void forLoopTypeCheck(boolean useExecModelCompiler) { init(useExecModelCompiler); // DROOLS-1580 - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("PersonListHelloBKM.dmn", this.getClass() ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("PersonListHelloBKM.dmn", this.getClass()); final DMNModel dmnModel = runtime.getModel( "http://www.trisotech.com/definitions/_ec5a78c7-a317-4c39-8310-db59be60f1c8", - "PersonListHelloBKM" ); + "PersonListHelloBKM"); assertThat(dmnModel).isNotNull(); assertThat(dmnModel.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).isFalse(); - + final DMNContext context = runtime.newContext(); - - final Map p1 = prototype(entry("Full Name", "John Doe"), entry("Age", 33) ); - final Map p2 = prototype(entry("Full Name", "47"), entry("Age", 47) ); - + + final Map p1 = prototype(entry("Full Name", "John Doe"), entry("Age", 33)); + final Map p2 = prototype(entry("Full Name", "47"), entry("Age", 47)); + context.set("My Input Data", Arrays.asList(p1, p2)); - final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context ); + final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context); final DMNContext result = dmnResult.getContext(); assertThat(dmnResult.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnResult.getMessages())).isFalse(); - assertThat( (List)result.get("My Decision")).asList().contains( "The person named John Doe is 33 years old.", - "The person named 47 is 47 years old."); + assertThat((List) result.get("My Decision")).asList().contains("The person named John Doe is 33 years old.", + "The person named 47 is 47 years old."); } @ParameterizedTest @@ -1530,25 +1531,25 @@ void forLoopTypeCheck(boolean useExecModelCompiler) { void typeInferenceForNestedContextAnonymousEntry(boolean useExecModelCompiler) { init(useExecModelCompiler); // DROOLS-1585 - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("PersonListHelloBKM2.dmn", this.getClass() ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("PersonListHelloBKM2.dmn", this.getClass()); final DMNModel dmnModel = runtime.getModel( "http://www.trisotech.com/definitions/_7e41a76e-2df6-4899-bf81-ae098757a3b6", - "PersonListHelloBKM2" ); + "PersonListHelloBKM2"); assertThat(dmnModel).isNotNull(); assertThat(dmnModel.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).isFalse(); - + final DMNContext context = runtime.newContext(); - - final Map p1 = prototype(entry("Full Name", "John Doe"), entry("Age", 33) ); - final Map p2 = prototype(entry("Full Name", "47"), entry("Age", 47) ); - + + final Map p1 = prototype(entry("Full Name", "John Doe"), entry("Age", 33)); + final Map p2 = prototype(entry("Full Name", "47"), entry("Age", 47)); + context.set("My Input Data", Arrays.asList(p1, p2)); - final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context ); + final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context); final DMNContext result = dmnResult.getContext(); assertThat(dmnResult.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnResult.getMessages())).isFalse(); - assertThat( (List)result.get("My Decision")).asList().containsExactly( prototype( entry("Full Name", "Prof. John Doe"), entry("Age", NumberEvalHelper.coerceNumber(33)) ), - prototype( entry("Full Name", "Prof. 47"), entry("Age", NumberEvalHelper.coerceNumber(47)))); + assertThat((List) result.get("My Decision")).asList().containsExactly(prototype(entry("Full Name", "Prof. John Doe"), entry("Age", NumberEvalHelper.coerceNumber(33))), + prototype(entry("Full Name", "Prof. 47"), entry("Age", NumberEvalHelper.coerceNumber(47)))); } @ParameterizedTest @@ -1556,133 +1557,133 @@ void typeInferenceForNestedContextAnonymousEntry(boolean useExecModelCompiler) { void sameEveryTypeCheck(boolean useExecModelCompiler) { init(useExecModelCompiler); // DROOLS-1587 - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("same_every_type_check.dmn", this.getClass() ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("same_every_type_check.dmn", this.getClass()); final DMNModel dmnModel = runtime.getModel( "http://www.trisotech.com/definitions/_09a13244-114d-43fb-9e00-cda89a2000dd", - "same every type check" ); + "same every type check"); assertThat(dmnModel).isNotNull(); assertThat(dmnModel.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).isFalse(); - + final DMNContext emptyContext = runtime.newContext(); - final DMNResult dmnResult = runtime.evaluateAll(dmnModel, emptyContext ); + final DMNResult dmnResult = runtime.evaluateAll(dmnModel, emptyContext); final DMNContext result = dmnResult.getContext(); - + assertThat(dmnResult.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnResult.getMessages())).isFalse(); - assertThat( result.get("Some are even")).isEqualTo(Boolean.TRUE); - assertThat( result.get("Every are even")).isEqualTo(Boolean.FALSE); - assertThat( result.get("Some are positive")).isEqualTo(Boolean.TRUE); - assertThat( result.get("Every are positive")).isEqualTo(Boolean.TRUE); - assertThat( result.get("Some are negative")).isEqualTo(Boolean.FALSE); - assertThat( result.get("Every are negative")).isEqualTo(Boolean.FALSE); + assertThat(result.get("Some are even")).isEqualTo(Boolean.TRUE); + assertThat(result.get("Every are even")).isEqualTo(Boolean.FALSE); + assertThat(result.get("Some are positive")).isEqualTo(Boolean.TRUE); + assertThat(result.get("Every are positive")).isEqualTo(Boolean.TRUE); + assertThat(result.get("Some are negative")).isEqualTo(Boolean.FALSE); + assertThat(result.get("Every are negative")).isEqualTo(Boolean.FALSE); } @ParameterizedTest @MethodSource("params") void dateAllowedValues(boolean useExecModelCompiler) { init(useExecModelCompiler); - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("date_allowed_values.dmn", this.getClass() ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("date_allowed_values.dmn", this.getClass()); final DMNModel dmnModel = runtime.getModel( "http://www.trisotech.com/definitions/_fbf002a3-615b-4f02-98e4-c28d4676225a", - "Error with constraints verification" ); + "Error with constraints verification"); assertThat(dmnModel).isNotNull(); assertThat(dmnModel.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).isFalse(); final DMNContext ctx = runtime.newContext(); - final Object duration = BuiltInType.DURATION.fromString("P20Y" ); - ctx.set( "yearsMonth", duration ); - final Object dateTime = BuiltInType.DATE_TIME.fromString("2017-05-16T17:58:00.000" ); - ctx.set( "dateTime", dateTime ); - final DMNResult dmnResult = runtime.evaluateAll(dmnModel, ctx ); + final Object duration = BuiltInType.DURATION.fromString("P20Y"); + ctx.set("yearsMonth", duration); + final Object dateTime = BuiltInType.DATE_TIME.fromString("2017-05-16T17:58:00.000"); + ctx.set("dateTime", dateTime); + final DMNResult dmnResult = runtime.evaluateAll(dmnModel, ctx); final DMNContext result = dmnResult.getContext(); assertThat(dmnResult.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnResult.getMessages())).isFalse(); - assertThat((Map) result.get( "Decision Logic 1")).containsEntry("years and months", duration); - assertThat((Map) result.get( "Decision Logic 1")).containsEntry("Date Time", dateTime); + assertThat((Map) result.get("Decision Logic 1")).containsEntry("years and months", duration); + assertThat((Map) result.get("Decision Logic 1")).containsEntry("Date Time", dateTime); } @ParameterizedTest @MethodSource("params") void artificialAttributes(boolean useExecModelCompiler) { init(useExecModelCompiler); - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("0001-input-data-string-artificial-attributes.dmn", this.getClass() ); - final DMNModel dmnModel = runtime.getModel("https://github.com/kiegroup/drools", "0001-input-data-string" ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("0001-input-data-string-artificial-attributes.dmn", this.getClass()); + final DMNModel dmnModel = runtime.getModel("https://github.com/kiegroup/drools", "0001-input-data-string"); assertThat(dmnModel).isNotNull(); final DMNContext context = DMNFactory.newContext(); - context.set( "Full Name", "John Doe" ); + context.set("Full Name", "John Doe"); - final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context ); + final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context); - assertThat( dmnResult.getDecisionResults()).hasSize(1); - assertThat( dmnResult.getDecisionResultByName( "Greeting Message" ).getResult()).isEqualTo("Hello John Doe" ); + assertThat(dmnResult.getDecisionResults()).hasSize(1); + assertThat(dmnResult.getDecisionResultByName("Greeting Message").getResult()).isEqualTo("Hello John Doe"); final DMNContext result = dmnResult.getContext(); - assertThat( result.get( "Greeting Message" )).isEqualTo("Hello John Doe" ); + assertThat(result.get("Greeting Message")).isEqualTo("Hello John Doe"); } @ParameterizedTest @MethodSource("params") void invokeFunctionSuccess(boolean useExecModelCompiler) { init(useExecModelCompiler); - final DMNRuntime runtime = DMNRuntimeUtil.createRuntimeWithAdditionalResources("Caller.dmn", this.getClass(), "Calling.dmn" ); - final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/definitions/_b0a696d6-3d57-4e97-b5d4-b44a63909d67", "Caller" ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntimeWithAdditionalResources("Caller.dmn", this.getClass(), "Calling.dmn"); + final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/definitions/_b0a696d6-3d57-4e97-b5d4-b44a63909d67", "Caller"); assertThat(dmnModel).isNotNull(); final DMNContext context = DMNFactory.newContext(); - context.set( "My Name", "John Doe" ); - context.set( "My Number", 3 ); - context.set( "Call ns", "http://www.trisotech.com/definitions/_88156d21-3acc-43b6-8b81-385caf0bb6ca" ); - context.set( "Call name", "Calling" ); - context.set( "Invoke decision", "Final Result" ); + context.set("My Name", "John Doe"); + context.set("My Number", 3); + context.set("Call ns", "http://www.trisotech.com/definitions/_88156d21-3acc-43b6-8b81-385caf0bb6ca"); + context.set("Call name", "Calling"); + context.set("Invoke decision", "Final Result"); - final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context ); + final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context); assertThat(dmnResult.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnResult.getMessages())).isFalse(); - + final DMNContext result = dmnResult.getContext(); - assertThat( result.get( "Final decision" )).isEqualTo( "The final decision is: Hello, John Doe your number once double is equal to: 6"); + assertThat(result.get("Final decision")).isEqualTo("The final decision is: Hello, John Doe your number once double is equal to: 6"); } @ParameterizedTest @MethodSource("params") void invokeFunctionWrongNamespace(boolean useExecModelCompiler) { init(useExecModelCompiler); - final DMNRuntime runtime = DMNRuntimeUtil.createRuntimeWithAdditionalResources("Caller.dmn", this.getClass(), "Calling.dmn" ); - final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/definitions/_b0a696d6-3d57-4e97-b5d4-b44a63909d67", "Caller" ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntimeWithAdditionalResources("Caller.dmn", this.getClass(), "Calling.dmn"); + final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/definitions/_b0a696d6-3d57-4e97-b5d4-b44a63909d67", "Caller"); assertThat(dmnModel).isNotNull(); final DMNContext wrongContext = DMNFactory.newContext(); - wrongContext.set( "My Name", "John Doe" ); - wrongContext.set( "My Number", 3 ); + wrongContext.set("My Name", "John Doe"); + wrongContext.set("My Number", 3); wrongContext.set("Call ns", "http://www.acme.com/a-wrong-namespace"); - wrongContext.set( "Call name", "Calling" ); - wrongContext.set( "Invoke decision", "Final Result" ); + wrongContext.set("Call name", "Calling"); + wrongContext.set("Invoke decision", "Final Result"); - final DMNResult dmnResult = runtime.evaluateAll(dmnModel, wrongContext ); + final DMNResult dmnResult = runtime.evaluateAll(dmnModel, wrongContext); assertThat(dmnResult.hasErrors()).as(dmnResult.getMessages().toString()).isTrue(); // total of: 2. x1 error in calling external decision, and x1 error in making final decision as it depends on the former. - assertThat(dmnResult.getMessages()).as(DMNRuntimeUtil.formatMessages( dmnResult.getMessages())).hasSize(2); + assertThat(dmnResult.getMessages()).as(DMNRuntimeUtil.formatMessages(dmnResult.getMessages())).hasSize(2); } @ParameterizedTest @MethodSource("params") void invokeFunctionWrongDecisionName(boolean useExecModelCompiler) { init(useExecModelCompiler); - final DMNRuntime runtime = DMNRuntimeUtil.createRuntimeWithAdditionalResources("Caller.dmn", this.getClass(), "Calling.dmn" ); - final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/definitions/_b0a696d6-3d57-4e97-b5d4-b44a63909d67", "Caller" ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntimeWithAdditionalResources("Caller.dmn", this.getClass(), "Calling.dmn"); + final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/definitions/_b0a696d6-3d57-4e97-b5d4-b44a63909d67", "Caller"); assertThat(dmnModel).isNotNull(); final DMNContext wrongContext = DMNFactory.newContext(); - wrongContext.set( "My Name", "John Doe" ); - wrongContext.set( "My Number", 3 ); - wrongContext.set( "Call ns", "http://www.trisotech.com/definitions/_88156d21-3acc-43b6-8b81-385caf0bb6ca" ); - wrongContext.set( "Call name", "Calling" ); + wrongContext.set("My Name", "John Doe"); + wrongContext.set("My Number", 3); + wrongContext.set("Call ns", "http://www.trisotech.com/definitions/_88156d21-3acc-43b6-8b81-385caf0bb6ca"); + wrongContext.set("Call name", "Calling"); wrongContext.set("Invoke decision", ""); - final DMNResult dmnResult = runtime.evaluateAll(dmnModel, wrongContext ); + final DMNResult dmnResult = runtime.evaluateAll(dmnModel, wrongContext); assertThat(dmnResult.hasErrors()).as(dmnResult.getMessages().toString()).isTrue(); // total of: 2. x1 error in calling external decision, and x1 error in making final decision as it depends on the former. - assertThat(dmnResult.getMessages()).as(DMNRuntimeUtil.formatMessages( dmnResult.getMessages())).hasSize(2); + assertThat(dmnResult.getMessages()).as(DMNRuntimeUtil.formatMessages(dmnResult.getMessages())).hasSize(2); } @@ -1691,36 +1692,36 @@ void invokeFunctionWrongDecisionName(boolean useExecModelCompiler) { void invokeFunctionCallerError(boolean useExecModelCompiler) { init(useExecModelCompiler); - final DMNRuntime runtime = DMNRuntimeUtil.createRuntimeWithAdditionalResources("Caller.dmn", this.getClass(), "Calling.dmn" ); - final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/definitions/_b0a696d6-3d57-4e97-b5d4-b44a63909d67", "Caller" ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntimeWithAdditionalResources("Caller.dmn", this.getClass(), "Calling.dmn"); + final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/definitions/_b0a696d6-3d57-4e97-b5d4-b44a63909d67", "Caller"); assertThat(dmnModel).isNotNull(); final DMNContext wrongContext = DMNFactory.newContext(); - wrongContext.set( "My Name", "John Doe" ); + wrongContext.set("My Name", "John Doe"); wrongContext.set("My Number", ""); - wrongContext.set( "Call ns", "http://www.trisotech.com/definitions/_88156d21-3acc-43b6-8b81-385caf0bb6ca" ); - wrongContext.set( "Call name", "Calling" ); - wrongContext.set( "Invoke decision", "Final Result" ); + wrongContext.set("Call ns", "http://www.trisotech.com/definitions/_88156d21-3acc-43b6-8b81-385caf0bb6ca"); + wrongContext.set("Call name", "Calling"); + wrongContext.set("Invoke decision", "Final Result"); - final DMNResult dmnResult = runtime.evaluateAll(dmnModel, wrongContext ); + final DMNResult dmnResult = runtime.evaluateAll(dmnModel, wrongContext); assertThat(dmnResult.hasErrors()).as(dmnResult.getMessages().toString()).isTrue(); // total of: 2. x1 error in calling external decision, and x1 error in making final decision as it depends on the former. // please notice it will print 4 lines in the log, 2x are the "external invocation" and then 2x are the one by the caller, checked herebelow: - assertThat(dmnResult.getMessages()).as(DMNRuntimeUtil.formatMessages( dmnResult.getMessages())).hasSize(2); + assertThat(dmnResult.getMessages()).as(DMNRuntimeUtil.formatMessages(dmnResult.getMessages())).hasSize(2); } @ParameterizedTest @MethodSource("params") void invalidFunction(boolean useExecModelCompiler) { init(useExecModelCompiler); - final DMNRuntime runtime = DMNRuntimeUtil.createRuntimeWithAdditionalResources( "InvalidFunction.dmn", this.getClass() ); - final DMNModel model = runtime.getModel( "http://www.trisotech.com/definitions/_84453b71-5d23-479f-9481-5196d92bacae", "0003-iteration-augmented" ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntimeWithAdditionalResources("InvalidFunction.dmn", this.getClass()); + final DMNModel model = runtime.getModel("http://www.trisotech.com/definitions/_84453b71-5d23-479f-9481-5196d92bacae", "0003-iteration-augmented"); assertThat(model).isNotNull(); final DMNContext context = DMNFactory.newContext(); - context.set( "Loans", new HashMap<>() ); + context.set("Loans", new HashMap<>()); final DMNResult result = runtime.evaluateAll(model, context); final List decisionResults = result.getDecisionResults(); - FEELStringMarshaller.INSTANCE.marshall( Arrays.asList(decisionResults.get(0).getResult(), decisionResults.get(1).getResult()) ); + FEELStringMarshaller.INSTANCE.marshall(Arrays.asList(decisionResults.get(0).getResult(), decisionResults.get(1).getResult())); } private Definitions buildSimplifiedDefinitions(final String namespace, final String... decisions) { @@ -1741,8 +1742,8 @@ private Definitions buildSimplifiedDefinitions(final String namespace, final Str private DecisionNodeImpl buildSimplifiedDecisionNode(final Definitions def, final String name) { DecisionNodeImpl toReturn = new DecisionNodeImpl(def.getDrgElement().stream().filter(drg -> drg.getName().equals(name)).filter(Decision.class::isInstance) - .map(Decision.class::cast) - .findFirst().get()); + .map(Decision.class::cast) + .findFirst().get()); toReturn.setEvaluator((eventManager, result) -> new EvaluatorResultImpl(name, EvaluatorResult.ResultType.SUCCESS)); toReturn.setResultType(SimpleTypeImpl.UNKNOWN_DMNTYPE("")); return toReturn; @@ -1993,7 +1994,7 @@ void drools2201(boolean useExecModelCompiler) { // do NOT use the DMNRuntimeUtil as that enables typeSafe check override for runtime. final KieServices ks = KieServices.Factory.get(); final KieContainer kieContainer = KieHelper.getKieContainer(ks.newReleaseId("org.kie", "dmn-test-" + UUID.randomUUID(), "1.0"), - ks.getResources().newClassPathResource("typecheck_in_context_result.dmn", this.getClass())); + ks.getResources().newClassPathResource("typecheck_in_context_result.dmn", this.getClass())); final DMNRuntime runtime = kieContainer.newKieSession().getKieRuntime(DMNRuntime.class); final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/definitions/_42bf043d-df86-48bd-9045-dfc08aa8ba0d", "typecheck in context result"); @@ -2018,7 +2019,7 @@ void drools2201b(boolean useExecModelCompiler) { // do NOT use the DMNRuntimeUtil as that enables typeSafe check override for runtime. final KieServices ks = KieServices.Factory.get(); final KieContainer kieContainer = KieHelper.getKieContainer(ks.newReleaseId("org.kie", "dmn-test-" + UUID.randomUUID(), "1.0"), - ks.getResources().newClassPathResource("typecheck_in_DT.dmn", this.getClass())); + ks.getResources().newClassPathResource("typecheck_in_DT.dmn", this.getClass())); final DMNRuntime runtime = kieContainer.newKieSession().getKieRuntime(DMNRuntime.class); final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/definitions/_99ccd4df-41ac-43c3-a563-d58f43149829", "typecheck in DT"); @@ -2039,7 +2040,7 @@ public static class DROOLS2286 { private String name; private String surname; - DROOLS2286(final String name, final String surname){ + DROOLS2286(final String name, final String surname) { this.name = name; this.surname = surname; } @@ -2127,12 +2128,12 @@ void nowBetweenTwoDates(boolean useExecModelCompiler) { // DROOLS-3670 DMN `between` FEEL operator alignments final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("is office open.dmn", this.getClass()); final DMNModel dmnModel = runtime.getModel("https://github.com/kiegroup/drools/kie-dmn/_19170B18-B561-4EB2-9D38-714E2442710E", - "is office open"); + "is office open"); assertThat(dmnModel.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).isFalse(); final DMNContext context = DMNFactory.newContext(); context.set("an office", prototype(entry("opened from", LocalDateTime.of(2018, 12, 31, 8, 0)), - entry("opened till", LocalDateTime.of(2018, 12, 31, 16, 0)))); + entry("opened till", LocalDateTime.of(2018, 12, 31, 16, 0)))); final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context); assertThat(dmnResult.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnResult.getMessages())).isFalse(); @@ -2193,9 +2194,9 @@ void listOfVowels(boolean useExecModelCompiler) { final DMNResult dmnResult = runtime.evaluateAll(dmnModel, emptyContext); assertThat(dmnResult.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnResult.getMessages())).isTrue(); assertThat(dmnResult.getMessages().stream() - .filter(m -> m.getMessageType() == DMNMessageType.ERROR_EVAL_NODE) - .anyMatch(m -> m.getSourceId().equals("_b2205027-d06c-41b5-8419-e14b501e14a6"))) - .isTrue(); + .filter(m -> m.getMessageType() == DMNMessageType.ERROR_EVAL_NODE) + .anyMatch(m -> m.getSourceId().equals("_b2205027-d06c-41b5-8419-e14b501e14a6"))) + .isTrue(); final DMNContext result = dmnResult.getContext(); assertThat(result.get("Decide Vowel a")).isEqualTo("a"); @@ -2273,7 +2274,7 @@ void structureContainment(boolean useExecModelCompiler) { init(useExecModelCompiler); final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("structure-containtment.dmn", this.getClass()); final DMNModel dmnModel = runtime.getModel("https://github.com/kiegroup/drools/kie-dmn/_7FB5C3E4-4DF8-42A6-A7FA-28315DECCDD0", - "structure-containtment"); + "structure-containtment"); assertThat(dmnModel).isNotNull(); assertThat(dmnModel.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).isFalse(); @@ -2305,9 +2306,9 @@ void relationwithemptycell(boolean useExecModelCompiler) { final DMNContext result = dmnResult.getContext(); assertThat(result.get("Decision A")).asList().containsExactly(prototype(entry("name", null), entry("age", null)), - prototype(entry("name", "John"), entry("age", new BigDecimal(1))), - prototype(entry("name", null), entry("age", null)), - prototype(entry("name", "Matteo"), entry("age", null))); + prototype(entry("name", "John"), entry("age", new BigDecimal(1))), + prototype(entry("name", null), entry("age", null)), + prototype(entry("name", "Matteo"), entry("age", null))); } @ParameterizedTest @@ -2344,12 +2345,12 @@ void usingReusableKeywordAsPartOfBKMName(boolean useExecModelCompiler) { @MethodSource("params") void productFunction(boolean useExecModelCompiler) { init(useExecModelCompiler); - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("product.dmn", this.getClass() ); - final DMNModel model = runtime.getModel("http://www.trisotech.com/dmn/definitions/_40fdbc2c-a631-4ba4-8435-17571b5d1942", "Drawing 1" ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("product.dmn", this.getClass()); + final DMNModel model = runtime.getModel("http://www.trisotech.com/dmn/definitions/_40fdbc2c-a631-4ba4-8435-17571b5d1942", "Drawing 1"); assertThat(model).isNotNull(); assertThat(model.hasErrors()).as(DMNRuntimeUtil.formatMessages(model.getMessages())).isFalse(); final DMNContext context = DMNFactory.newContext(); - context.set("product", new HashMap(){{ + context.set("product", new HashMap() {{ put("name", "Product1"); put("type", 1); }}); @@ -2395,10 +2396,10 @@ void notWithPredicates20180601b(boolean useExecModelCompiler) { final DMNContext context = DMNFactory.newContext(); context.set("TheBook", Arrays.asList(prototype(entry("Title", "55"), entry("Price", new BigDecimal(5)), entry("Quantity", new BigDecimal(5))), - prototype(entry("Title", "510"), entry("Price", new BigDecimal(5)), entry("Quantity", new BigDecimal(10))), - prototype(entry("Title", "810"), entry("Price", new BigDecimal(8)), entry("Quantity", new BigDecimal(10))), - prototype(entry("Title", "85"), entry("Price", new BigDecimal(8)), entry("Quantity", new BigDecimal(5))), - prototype(entry("Title", "66"), entry("Price", new BigDecimal(6)), entry("Quantity", new BigDecimal(6))))); + prototype(entry("Title", "510"), entry("Price", new BigDecimal(5)), entry("Quantity", new BigDecimal(10))), + prototype(entry("Title", "810"), entry("Price", new BigDecimal(8)), entry("Quantity", new BigDecimal(10))), + prototype(entry("Title", "85"), entry("Price", new BigDecimal(8)), entry("Quantity", new BigDecimal(5))), + prototype(entry("Title", "66"), entry("Price", new BigDecimal(6)), entry("Quantity", new BigDecimal(6))))); final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context); assertThat(dmnResult.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnResult.getMessages())).isFalse(); @@ -2436,8 +2437,8 @@ void notWithPredicates20180601b(boolean useExecModelCompiler) { @MethodSource("params") void modelById(boolean useExecModelCompiler) { init(useExecModelCompiler); - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("simple-item-def.dmn", this.getClass() ); - final DMNModel dmnModel = runtime.getModelById("https://github.com/kiegroup/kie-dmn/itemdef", "_simple-item-def" ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("simple-item-def.dmn", this.getClass()); + final DMNModel dmnModel = runtime.getModelById("https://github.com/kiegroup/kie-dmn/itemdef", "_simple-item-def"); assertThat(dmnModel).isNotNull(); assertThat(dmnModel.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).isFalse(); @@ -2554,18 +2555,18 @@ void dMNv12Ch11Modified(boolean useExecModelCompiler) { final DMNContext context = DMNFactory.newContext(); context.set("Applicant data", mapOf(entry("Age", new BigDecimal(51)), - entry("MaritalStatus", "M"), - entry("EmploymentStatus", "EMPLOYED"), - entry("ExistingCustomer", Boolean.FALSE), - entry("Monthly", mapOf(entry("Income", new BigDecimal(100_000)), - entry("Repayments", new BigDecimal(2_500)), - entry("Expenses", new BigDecimal(10_000)))))); // DMN v1.2 spec page 181, first image: errata corrige values for Income and Expenses are likely inverted, corrected here. + entry("MaritalStatus", "M"), + entry("EmploymentStatus", "EMPLOYED"), + entry("ExistingCustomer", Boolean.FALSE), + entry("Monthly", mapOf(entry("Income", new BigDecimal(100_000)), + entry("Repayments", new BigDecimal(2_500)), + entry("Expenses", new BigDecimal(10_000)))))); // DMN v1.2 spec page 181, first image: errata corrige values for Income and Expenses are likely inverted, corrected here. context.set("Bureau data", mapOf(entry("Bankrupt", Boolean.FALSE), - entry("CreditScore", new BigDecimal(600)))); + entry("CreditScore", new BigDecimal(600)))); context.set("Requested product", mapOf(entry("ProductType", "STANDARD LOAN"), - entry("Rate", new BigDecimal(0.08)), - entry("Term", new BigDecimal(36)), - entry("Amount", new BigDecimal(100_000)))); + entry("Rate", new BigDecimal(0.08)), + entry("Term", new BigDecimal(36)), + entry("Amount", new BigDecimal(100_000)))); context.set("Supporting documents", null); final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context); LOG.debug("{}", dmnResult); @@ -2618,15 +2619,15 @@ void decisionTableInputClauseImportingItemDefinition(boolean useExecModelCompile init(useExecModelCompiler); // DROOLS-2927 DMN DecisionTable inputClause importing ItemDefinition throws NPE at compilation final DMNRuntime runtime = DMNRuntimeUtil.createRuntimeWithAdditionalResources("imports/Imported_Model.dmn", - this.getClass(), - "imports/Importing_Person_DT_with_Person.dmn"); + this.getClass(), + "imports/Importing_Person_DT_with_Person.dmn"); final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/dmn/definitions/_3d586cb1-3ed0-4bc4-a1a7-070b70ece398", "Importing Person DT with Person"); assertThat(dmnModel).isNotNull(); assertThat(dmnModel.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).isFalse(); final DMNContext context = DMNFactory.newContext(); context.set("A Person here", mapOf(entry("age", new BigDecimal(17)), - entry("name", "John"))); + entry("name", "John"))); final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context); LOG.debug("{}", dmnResult); @@ -2837,7 +2838,7 @@ void table61ForAliasFeelType(boolean useExecModelCompiler) { final DMNContext context = DMNFactory.newContext(); context.set("my input", mapOf(entry("Date", LocalDate.of(2019, 5, 10)), - entry("Text", "John"))); + entry("Text", "John"))); final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context); LOG.debug("{}", dmnResult); @@ -2966,10 +2967,10 @@ void so58507157(boolean useExecModelCompiler) { assertThat(dmnResult.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnResult.getMessages())).isFalse(); final DMNContext result = dmnResult.getContext(); - assertThat((Map) result.get("DecisionNumberInList")).containsEntry("Result_1_OK",Boolean.TRUE); - assertThat((Map) result.get("DecisionNumberInList")).containsEntry("Result_2_OK",Boolean.TRUE); - assertThat((Map) result.get("DecisionNumberInList")).containsEntry("Result_3",Boolean.TRUE); - assertThat((Map) result.get("DecisionNumberInList")).containsEntry("Result_4",Boolean.TRUE); + assertThat((Map) result.get("DecisionNumberInList")).containsEntry("Result_1_OK", Boolean.TRUE); + assertThat((Map) result.get("DecisionNumberInList")).containsEntry("Result_2_OK", Boolean.TRUE); + assertThat((Map) result.get("DecisionNumberInList")).containsEntry("Result_3", Boolean.TRUE); + assertThat((Map) result.get("DecisionNumberInList")).containsEntry("Result_4", Boolean.TRUE); } @ParameterizedTest @@ -2990,9 +2991,9 @@ void noExpr(boolean useExecModelCompiler) { assertThat(dmnResult.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnResult.getMessages())).isFalse(); assertThat(dmnModel.getMessages(DMNMessage.Severity.WARN)).as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).hasSize(1); assertThat(dmnModel.getMessages(DMNMessage.Severity.WARN) - .stream() - .filter(m -> m.getSourceId().equals("_cdd03786-d1ab-47b5-ba05-df830458dc62")) - .count()).as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).isEqualTo(1L); + .stream() + .filter(m -> m.getSourceId().equals("_cdd03786-d1ab-47b5-ba05-df830458dc62")) + .count()).as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).isEqualTo(1L); assertThat(dmnResult.getDecisionResultByName("is it raining?").getEvaluationStatus()).isEqualTo(DecisionEvaluationStatus.SUCCEEDED); assertThat(dmnResult.getDecisionResultByName("what to do today?").getEvaluationStatus()).isEqualTo(DecisionEvaluationStatus.SKIPPED); } @@ -3079,9 +3080,9 @@ void bindingContextTypeCheck(boolean useExecModelCompiler) { LOG.debug("{}", dmnResult); assertThat(dmnResult.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnResult.getMessages())).isTrue(); assertThat(dmnResult.getMessages(DMNMessage.Severity.ERROR) - .stream() - .filter(m -> m.getSourceId().equals("_decision_003")) - .count()).as(DMNRuntimeUtil.formatMessages(dmnResult.getMessages())).isEqualTo(1L); + .stream() + .filter(m -> m.getSourceId().equals("_decision_003")) + .count()).as(DMNRuntimeUtil.formatMessages(dmnResult.getMessages())).isEqualTo(1L); assertThat(dmnResult.getDecisionResultByName("decision_003").getEvaluationStatus()).isEqualTo(DecisionEvaluationStatus.FAILED); assertThat(dmnResult.getDecisionResultByName("decision_003").getResult()).isNull(); } @@ -3259,7 +3260,8 @@ private void checkUniqueMissingMatchDefaultEmpty(final DMNRuntime runtime, final void errorWhileLiteral(boolean useExecModelCompiler) { init(useExecModelCompiler); final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("errorWhileLiteral.dmn", this.getClass()); - runtime.addListener(new DMNRuntimeEventListener() {}); + runtime.addListener(new DMNRuntimeEventListener() { + }); final DMNModel dmnModel = runtime.getModel("https://kiegroup.org/dmn/_8DF63435-B34B-4C19-A06B-C6A3416194A9", "testBasic"); assertThat(dmnModel).isNotNull(); assertThat(dmnModel.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).isFalse(); @@ -3319,10 +3321,10 @@ void personInReq1(boolean useExecModelCompiler) { final DMNContext context = DMNFactory.newContext(); context.set("a person", mapOf(entry("age", new BigDecimal(47)), - entry("name", "John Doe"))); + entry("name", "John Doe"))); context.set("reqs", List.of(mapOf(entry("description", "req1"), - entry("bounds", mapOf(entry("LB", new BigDecimal(18)), - entry("UB", new BigDecimal(99))))))); + entry("bounds", mapOf(entry("LB", new BigDecimal(18)), + entry("UB", new BigDecimal(99))))))); final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context); LOG.debug("{}", dmnResult); assertThat(dmnResult.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnResult.getMessages())).isFalse(); @@ -3387,7 +3389,8 @@ void invokeJavaReturnArray(boolean useExecModelCompiler) { void notInvocable(boolean useExecModelCompiler) { init(useExecModelCompiler); final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("notInvocable.dmn", this.getClass()); - runtime.addListener(new DMNRuntimeEventListener() {}); + runtime.addListener(new DMNRuntimeEventListener() { + }); final DMNModel dmnModel = runtime.getModel("https://kiegroup.org/dmn/_4B70E98C-E74E-48A1-88C6-F3FB1F0C026B", "notInvocable"); assertThat(dmnModel).isNotNull(); assertThat(dmnModel.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).isFalse(); @@ -3407,7 +3410,8 @@ void notInvocable(boolean useExecModelCompiler) { void decisionTableWithNow(boolean useExecModelCompiler) { init(useExecModelCompiler); final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("decisiontable-with-now.dmn", this.getClass()); - runtime.addListener(new DMNRuntimeEventListener() {}); + runtime.addListener(new DMNRuntimeEventListener() { + }); final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/definitions/_fce3104a-30df-41f4-8c8f-0b67d4d996d4", "Drawing 1"); assertThat(dmnModel).isNotNull(); assertThat(dmnModel.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).isFalse(); @@ -3425,7 +3429,8 @@ void decisionTableWithNow(boolean useExecModelCompiler) { void dupContextEntryKey(boolean useExecModelCompiler) { init(useExecModelCompiler); final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("dupContextEntryKey.dmn", this.getClass()); - runtime.addListener(new DMNRuntimeEventListener() {}); + runtime.addListener(new DMNRuntimeEventListener() { + }); final DMNModel dmnModel = runtime.getModel("https://kiegroup.org/dmn/_730A7A75-F473-4083-93B9-85E0DAF7F4BD", "dupContextEntryKey"); assertThat(dmnModel).isNotNull(); assertThat(dmnModel.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).isFalse(); @@ -3443,14 +3448,15 @@ void dupContextEntryKey(boolean useExecModelCompiler) { void hyphenInPropertyOfCollectionForAccessor(boolean useExecModelCompiler) { init(useExecModelCompiler); final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("testHyphenInPropertyOfCollectionForAccessor.dmn", this.getClass()); - runtime.addListener(new DMNRuntimeEventListener() {}); + runtime.addListener(new DMNRuntimeEventListener() { + }); final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/definitions/_b5362305-17be-42d8-acec-f2621e3cc0e0", "Drawing 1"); assertThat(dmnModel).isNotNull(); assertThat(dmnModel.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).isFalse(); final DMNContext context = DMNFactory.newContext(); context.set("input", List.of(prototype(entry("Primary-Key", "k987"), entry("Value", "v47")))); - + final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context); LOG.debug("{}", dmnResult); assertThat(dmnResult.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnResult.getMessages())).isFalse(); @@ -3466,14 +3472,15 @@ void hyphenInPropertyOfCollectionForAccessor(boolean useExecModelCompiler) { void hyphenInPropertyOfCollectionForAccessorMultiple(boolean useExecModelCompiler) { init(useExecModelCompiler); final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("testHyphenInPropertyOfCollectionForAccessorMultiple.dmn", this.getClass()); - runtime.addListener(new DMNRuntimeEventListener() {}); + runtime.addListener(new DMNRuntimeEventListener() { + }); final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/definitions/_b5362305-17be-42d8-acec-f2621e3cc0e0", "Drawing 1"); assertThat(dmnModel).isNotNull(); assertThat(dmnModel.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).isFalse(); final DMNContext context = DMNFactory.newContext(); context.set("input", Arrays.asList(prototype(entry("Primary-Key", "k1"), entry("Value", 47)), prototype(entry("Primary-Key", "k2"), entry("Value", -9)), prototype(entry("Primary-Key", "k3"), entry("Value", 1)))); - + final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context); LOG.debug("{}", dmnResult); assertThat(dmnResult.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnResult.getMessages())).isFalse(); @@ -3481,7 +3488,7 @@ void hyphenInPropertyOfCollectionForAccessorMultiple(boolean useExecModelCompile * input.Primary-Key is a list projection: take all elements, and Stream+map using the accessor * input[Value>0].Primary-Key is filtering, then projecting */ - assertThat((Map)dmnResult.getDecisionResultByName("decision").getResult()).containsExactly(entry("correct", Arrays.asList("k1", "k2", "k3")),entry("incorrect", Arrays.asList("k1", "k3"))); + assertThat((Map) dmnResult.getDecisionResultByName("decision").getResult()).containsExactly(entry("correct", Arrays.asList("k1", "k2", "k3")), entry("incorrect", Arrays.asList("k1", "k3"))); } @ParameterizedTest @@ -3495,7 +3502,7 @@ void soundLevelAllowNull(boolean useExecModelCompiler) { final DMNContext contextWithNullValueForKey = DMNFactory.newContext(); contextWithNullValueForKey.set("Level", null); - + final DMNResult dmnResult = runtime.evaluateAll(dmnModel, contextWithNullValueForKey); LOG.debug("{}", dmnResult); assertThat(dmnResult.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnResult.getMessages())).isFalse(); @@ -3513,7 +3520,7 @@ void soundLevelAllowNullItemDef(boolean useExecModelCompiler) { final DMNContext contextWithNullValueForKey = DMNFactory.newContext(); contextWithNullValueForKey.set("Level", null); - + final DMNResult dmnResult = runtime.evaluateAll(dmnModel, contextWithNullValueForKey); LOG.debug("{}", dmnResult); assertThat(dmnResult.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnResult.getMessages())).isFalse(); @@ -3524,13 +3531,13 @@ void soundLevelAllowNullItemDef(boolean useExecModelCompiler) { @MethodSource("params") void kieIssue270(boolean useExecModelCompiler) { init(useExecModelCompiler); - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("habitability.dmn", this.getClass() ); - final DMNModel dmnModel = runtime.getModel("https://kiegroup.org/dmn/_93836704-04E9-45B6-8D10-51409FEBDF25", "habitability" ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("habitability.dmn", this.getClass()); + final DMNModel dmnModel = runtime.getModel("https://kiegroup.org/dmn/_93836704-04E9-45B6-8D10-51409FEBDF25", "habitability"); assertThat(dmnModel).isNotNull(); assertThat(dmnModel.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).isFalse(); final DMNContext context = DMNFactory.newContext(); - + final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context); assertThat(dmnResult.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnResult.getMessages())).isTrue(); assertThat(dmnResult.getMessages()).hasSize(2); diff --git a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/RangeNode.java b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/RangeNode.java index 5ef569e051e..c80cf0faf94 100644 --- a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/RangeNode.java +++ b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/RangeNode.java @@ -6,9 +6,9 @@ * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

* Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY @@ -29,6 +29,7 @@ import org.kie.dmn.feel.runtime.Range; import org.kie.dmn.feel.runtime.impl.RangeImpl; import org.kie.dmn.feel.runtime.impl.UndefinedValueComparable; +import org.kie.dmn.feel.util.BuiltInTypeUtils; import org.kie.dmn.feel.util.Msg; public class RangeNode @@ -36,17 +37,21 @@ public class RangeNode public enum IntervalBoundary { OPEN, CLOSED; + public static IntervalBoundary low(String input) { switch (input) { - case "[": return CLOSED; + case "[": + return CLOSED; case "]": default: - return OPEN; + return OPEN; } } + public static IntervalBoundary high(String input) { switch (input) { - case "]": return CLOSED; + case "]": + return CLOSED; case "[": default: return OPEN; @@ -56,11 +61,11 @@ public static IntervalBoundary high(String input) { private IntervalBoundary lowerBound; private IntervalBoundary upperBound; - private BaseNode start; - private BaseNode end; + private BaseNode start; + private BaseNode end; public RangeNode(ParserRuleContext ctx, IntervalBoundary lowerBound, BaseNode start, BaseNode end, IntervalBoundary upperBound) { - super( ctx ); + super(ctx); this.lowerBound = lowerBound; this.upperBound = upperBound; this.start = start; @@ -109,30 +114,30 @@ public void setEnd(BaseNode end) { @Override public Range evaluate(EvaluationContext ctx) { - Object s = start.evaluate( ctx ); - Object e = end.evaluate( ctx ); + Object s = start.evaluate(ctx); + Object e = end.evaluate(ctx); if (s == null && e == null) { return null; } - - Type sType = BuiltInType.determineTypeFromInstance(s); - Type eType = BuiltInType.determineTypeFromInstance(e); + + Type sType = BuiltInTypeUtils.determineTypeFromInstance(s); + Type eType = BuiltInTypeUtils.determineTypeFromInstance(e); boolean withUndefined = s instanceof UndefinedValueComparable || e instanceof UndefinedValueComparable; if (s != null && e != null && !withUndefined && sType != eType && !s.getClass().isAssignableFrom(e.getClass())) { - ctx.notifyEvt( astEvent(Severity.ERROR, Msg.createMessage(Msg.X_TYPE_INCOMPATIBLE_WITH_Y_TYPE, "Start", "End"))); + ctx.notifyEvt(astEvent(Severity.ERROR, Msg.createMessage(Msg.X_TYPE_INCOMPATIBLE_WITH_Y_TYPE, "Start", "End"))); return null; } - Comparable start = s instanceof UndefinedValueComparable ? (Comparable) s : convertToComparable(ctx, s ); - Comparable end = e instanceof UndefinedValueComparable ? (Comparable) e : convertToComparable( ctx, e ); + Comparable start = s instanceof UndefinedValueComparable ? (Comparable) s : convertToComparable(ctx, s); + Comparable end = e instanceof UndefinedValueComparable ? (Comparable) e : convertToComparable(ctx, e); return isDescendingRange(start, end) ? null : - new RangeImpl( lowerBound==IntervalBoundary.OPEN ? Range.RangeBoundary.OPEN : Range.RangeBoundary.CLOSED, - start, - end, - upperBound==IntervalBoundary.OPEN ? Range.RangeBoundary.OPEN : Range.RangeBoundary.CLOSED ); + new RangeImpl(lowerBound == IntervalBoundary.OPEN ? Range.RangeBoundary.OPEN : Range.RangeBoundary.CLOSED, + start, + end, + upperBound == IntervalBoundary.OPEN ? Range.RangeBoundary.OPEN : Range.RangeBoundary.CLOSED); } static boolean isDescendingRange(Comparable start, Comparable end) { @@ -145,11 +150,11 @@ private Comparable convertToComparable(EvaluationContext ctx, Object s) { start = null; } else if (s instanceof Comparable) { start = (Comparable) s; - } else if( s instanceof Period ) { + } else if (s instanceof Period) { // period has special semantics - start = new ComparablePeriod( (Period) s ); + start = new ComparablePeriod((Period) s); } else { - ctx.notifyEvt( astEvent(Severity.ERROR, Msg.createMessage(Msg.INCOMPATIBLE_TYPE_FOR_RANGE, s.getClass().getSimpleName() ))); + ctx.notifyEvt(astEvent(Severity.ERROR, Msg.createMessage(Msg.INCOMPATIBLE_TYPE_FOR_RANGE, s.getClass().getSimpleName()))); start = null; } return start; @@ -162,7 +167,7 @@ public Type getResultType() { @Override public ASTNode[] getChildrenNode() { - return new ASTNode[] { start, end }; + return new ASTNode[]{start, end}; } @Override diff --git a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/TypeNode.java b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/TypeNode.java index aa1bb125905..2cd4611062d 100644 --- a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/TypeNode.java +++ b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/TypeNode.java @@ -6,9 +6,9 @@ * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

* Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY @@ -22,6 +22,7 @@ import org.kie.dmn.feel.lang.EvaluationContext; import org.kie.dmn.feel.lang.Type; import org.kie.dmn.feel.lang.types.BuiltInType; +import org.kie.dmn.feel.util.BuiltInTypeUtils; public abstract class TypeNode extends BaseNode { @@ -31,12 +32,12 @@ public TypeNode() { } public TypeNode(ParserRuleContext ctx) { - super( ctx ); + super(ctx); } @Override public Type evaluate(EvaluationContext ctx) { - return BuiltInType.determineTypeFromName( getText() ); + return BuiltInTypeUtils.determineTypeFromName(getText()); } @Override diff --git a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/types/BuiltInType.java b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/types/BuiltInType.java index fc28acc0011..5a226dc21e3 100644 --- a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/types/BuiltInType.java +++ b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/types/BuiltInType.java @@ -1,4 +1,4 @@ -/** +/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information @@ -18,22 +18,9 @@ */ package org.kie.dmn.feel.lang.types; -import java.time.Duration; -import java.time.LocalDate; -import java.time.LocalDateTime; -import java.time.LocalTime; -import java.time.OffsetDateTime; -import java.time.OffsetTime; -import java.time.ZonedDateTime; -import java.time.chrono.ChronoPeriod; -import java.time.temporal.ChronoField; -import java.time.temporal.Temporal; -import java.time.temporal.TemporalAccessor; -import java.time.temporal.TemporalQueries; import java.util.Arrays; import java.util.Collection; -import java.util.List; -import java.util.Map; + import java.util.function.Function; import java.util.stream.Collectors; @@ -41,10 +28,7 @@ import org.kie.dmn.feel.lang.SimpleType; import org.kie.dmn.feel.lang.Type; import org.kie.dmn.feel.marshaller.FEELStringMarshaller; -import org.kie.dmn.feel.runtime.FEELFunction; -import org.kie.dmn.feel.runtime.Range; -import org.kie.dmn.feel.runtime.UnaryTest; -import org.kie.dmn.feel.runtime.custom.ZoneTime; +import org.kie.dmn.feel.util.BuiltInTypeUtils; public enum BuiltInType implements SimpleType { @@ -67,7 +51,7 @@ public enum BuiltInType implements SimpleType { BuiltInType(String... names) { this.names = names; - this.symbols = Arrays.asList(names).stream().map(n -> new BuiltInTypeSymbol(n, this)).collect(Collectors.toList()); + this.symbols = Arrays.stream(names).map(n -> new BuiltInTypeSymbol(n, this)).collect(Collectors.toList()); } public String getName() { @@ -79,13 +63,13 @@ public String[] getNames() { } public Object fromString(String value) { - return FEELStringMarshaller.INSTANCE.unmarshall( this, value ); + return FEELStringMarshaller.INSTANCE.unmarshall(this, value); } public String toString(Object value) { - return FEELStringMarshaller.INSTANCE.marshall( value ); + return FEELStringMarshaller.INSTANCE.marshall(value); } - + public static Function justNull() { // TODO we should add the EventListener here somehow? return t -> null; @@ -98,88 +82,21 @@ public Collection getSymbols() { @Override public String toString() { return "Type{ " + - names[0] + - " }"; - } - - public static Type determineTypeFromName( String name ) { - if( name == null ) { - return UNKNOWN; - } - for( BuiltInType t : BuiltInType.values() ) { - for( String n : t.getNames() ) { - if( n.equals( name ) ) { - return t; - } - } - } - return UNKNOWN; - } - - public static Type determineTypeFromInstance( Object o ) { - if( o == null ) { - return UNKNOWN; - } else if( o instanceof Number ) { - return NUMBER; - } else if( o instanceof String ) { - return STRING; - } else if( o instanceof LocalDate ) { - return DATE; - } else if( o instanceof LocalTime || o instanceof OffsetTime || o instanceof ZoneTime) { - return TIME; - } else if( o instanceof ZonedDateTime || o instanceof OffsetDateTime || o instanceof LocalDateTime ) { - return DATE_TIME; - } else if (o instanceof Duration || o instanceof ChronoPeriod) { - return DURATION; - } else if( o instanceof Boolean ) { - return BOOLEAN; - } else if( o instanceof UnaryTest ) { - return UNARY_TEST; - } else if( o instanceof Range ) { - return RANGE; - } else if( o instanceof FEELFunction ) { - return FUNCTION; - } else if( o instanceof List ) { - return LIST; - } else if( o instanceof Map ) { - return CONTEXT; - } else if (o instanceof TemporalAccessor) { - // last, determine if it's a FEEL time with TZ - TemporalAccessor ta = (TemporalAccessor) o; - if (!(ta instanceof Temporal) && ta.isSupported(ChronoField.HOUR_OF_DAY) - && ta.isSupported(ChronoField.MINUTE_OF_HOUR) && ta.isSupported(ChronoField.SECOND_OF_MINUTE) - && ta.query(TemporalQueries.zone()) != null) { - return TIME; - } - } - return UNKNOWN; - } - - public static boolean isInstanceOf( Object o, Type t ) { - if ( o == null ) { - return false; // See FEEL specifications Table 49. - } - if ( t == UNKNOWN ) { - return true; - } - return determineTypeFromInstance( o ) == t; - } - - public static boolean isInstanceOf( Object o, String name ) { - return determineTypeFromInstance( o ) == determineTypeFromName( name ); + names[0] + + " }"; } @Override public boolean isInstanceOf(Object o) { - return isInstanceOf(o, this); + return BuiltInTypeUtils.isInstanceOf(o, this); } @Override public boolean isAssignableValue(Object value) { - if ( value == null ) { + if (value == null) { return true; // a null-value can be assigned to any type. } - return isInstanceOf(value, this); + return BuiltInTypeUtils.isInstanceOf(value, this); } @Override diff --git a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/functions/BaseFEELFunction.java b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/functions/BaseFEELFunction.java index c5d9c3e3e9d..cf3b6305b05 100644 --- a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/functions/BaseFEELFunction.java +++ b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/functions/BaseFEELFunction.java @@ -1,4 +1,4 @@ -/** +/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information @@ -40,6 +40,7 @@ import org.kie.dmn.feel.runtime.FEELFunction; import org.kie.dmn.feel.runtime.events.FEELEventBase; import org.kie.dmn.feel.runtime.events.InvalidParametersEvent; +import org.kie.dmn.feel.util.BuiltInTypeUtils; import org.kie.dmn.feel.util.Either; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -85,7 +86,7 @@ public Object invokeReflectively(EvaluationContext ctx, Object[] params) { if (cm.actualParams != null) { for (int i = 0; i < cm.actualParams.length; i++) { if (cm.actualParams[i] instanceof List list) { - cm.actualParams[i] = getFEELDialectAdaptedList(ctx, list); + cm.actualParams[i] = getFEELDialectAdaptedList(ctx, list); } } } @@ -96,9 +97,9 @@ public Object invokeReflectively(EvaluationContext ctx, Object[] params) { @SuppressWarnings("unchecked") Either either = (Either) result; return getEitherResult(ctx, - either, - () -> Stream.of(cm.actualMethod.getParameters()).map(p -> p.getAnnotation(ParameterName.class).value()).collect(Collectors.toList()), - () -> Arrays.asList(cm.actualParams)); + either, + () -> Stream.of(cm.actualMethod.getParameters()).map(p -> p.getAnnotation(ParameterName.class).value()).collect(Collectors.toList()), + () -> Arrays.asList(cm.actualParams)); } return result; @@ -107,7 +108,7 @@ public Object invokeReflectively(EvaluationContext ctx, Object[] params) { // getClass().getDeclaredMethods() String ps = getClass().toString(); logger.error("Unable to find function '" + getName() + "( " + ps.substring(1, ps.length() - 1) + - " )'"); + " )'"); ctx.notifyEvt(() -> new FEELEventBase(Severity.ERROR, "Unable to find function '" + getName() + "( " + ps.substring(1, ps.length() - 1) + " )'", null)); } @@ -118,7 +119,7 @@ public Object invokeReflectively(EvaluationContext ctx, Object[] params) { NamedParameter[] namedParams = Arrays.stream(params).map(NamedParameter.class::cast).toArray(NamedParameter[]::new); params = BaseFEELFunctionHelper.rearrangeParameters(namedParams, - this.getParameters().get(0).stream().map(Param::getName).collect(Collectors.toList())); + this.getParameters().get(0).stream().map(Param::getName).collect(Collectors.toList())); } Object result = invoke(ctx, params); if (result instanceof Either) { @@ -127,10 +128,10 @@ public Object invokeReflectively(EvaluationContext ctx, Object[] params) { final Object[] usedParams = params; Object eitherResult = getEitherResult(ctx, - either, - () -> IntStream.of(0, usedParams.length).mapToObj(i -> "arg" - + i).collect(Collectors.toList()), - () -> Arrays.asList(usedParams)); + either, + () -> IntStream.of(0, usedParams.length).mapToObj(i -> "arg" + + i).collect(Collectors.toList()), + () -> Arrays.asList(usedParams)); return BaseFEELFunctionHelper.normalizeResult(eitherResult); } return BaseFEELFunctionHelper.normalizeResult(result); @@ -138,7 +139,7 @@ public Object invokeReflectively(EvaluationContext ctx, Object[] params) { } catch (Exception e) { logger.error("Error trying to call function " + getName() + ".", e); ctx.notifyEvt(() -> new FEELEventBase(Severity.ERROR, "Error trying to call function " + getName() + ".", - e)); + e)); } return getFEELDialectAdaptedObject(ctx, null); } @@ -169,7 +170,7 @@ public boolean isCompatible(Type[] inputTypes, Type outputType) { * @param ctx * @param originalInput * @param isNamedParams true if the parameter refers to value to be retrieved inside - * ctx; false if the parameter is the actual value + * ctx; false if the parameter is the actual value * @return */ protected CandidateMethod getCandidateMethod(EvaluationContext ctx, Object[] originalInput, boolean isNamedParams) { @@ -201,19 +202,14 @@ protected Method getCandidateMethod(Type[] inputTypes, Type outputType) { continue; } - org.kie.dmn.feel.lang.Type[] feelTypes = Arrays.stream(inputTypes) - .map(type -> (org.kie.dmn.feel.lang.Type) type) - .toArray(org.kie.dmn.feel.lang.Type[]::new); - Class[] methodParameterTypes = method.getParameterTypes(); - for (int i = 0; i < feelTypes.length; i++) { - if (!methodParameterTypes[i].equals(feelTypes[i].getClass())) { - continue; + for (Class methodParameterType : methodParameterTypes) { + if (!BuiltInTypeUtils.determineTypeFromClass(methodParameterType).getClass().equals(methodParameterType)) { + break; } } - java.lang.reflect.Type methodReturnType = method.getGenericReturnType(); - if (methodReturnType.equals(outputType)) { + if (method.getGenericReturnType().equals(outputType)) { toReturn = method; break; } @@ -226,7 +222,7 @@ protected Method getCandidateMethod(Type[] inputTypes, Type outputType) { private CandidateMethod getCandidateMethod(EvaluationContext ctx, Object[] originalInput, boolean isNamedParams, Method m) { Object[] adaptedInput = BaseFEELFunctionHelper.getAdjustedParametersForMethod(ctx, originalInput, - isNamedParams, m); + isNamedParams, m); if (adaptedInput == null) { // incompatible method return null; @@ -244,6 +240,7 @@ private CandidateMethod getCandidateMethod(EvaluationContext ctx, Object[] origi /** * Returns the left CandidateMethod if its fineScore is greater than the right one, * otherwise returns the right CandidateMethod + * * @param originalInput * @param left * @param right @@ -253,7 +250,7 @@ private CandidateMethod getBestScoredCandidateMethod(Object[] originalInput, Can CandidateMethod right) { ScoreHelper.Compares compares = new ScoreHelper.Compares(originalInput, left.getActualParams(), - left.getParameterTypes()); + left.getParameterTypes()); int leftScore = ScoreHelper.fineScore(compares); compares = new ScoreHelper.Compares(originalInput, right.getActualParams(), right.getParameterTypes()); int rightScore = ScoreHelper.fineScore(compares); @@ -266,13 +263,13 @@ private Object getEitherResult(EvaluationContext ctx, Either source = getFEELDialectAdaptedEither(ctx, source); return source.cata((left) -> { ctx.notifyEvt(() -> { - if (left instanceof InvalidParametersEvent invalidParametersEvent) { - invalidParametersEvent.setNodeName(getName()); - invalidParametersEvent.setActualParameters(parameterNamesSupplier.get(), - parameterValuesSupplier.get()); - } - return left; - } + if (left instanceof InvalidParametersEvent invalidParametersEvent) { + invalidParametersEvent.setNodeName(getName()); + invalidParametersEvent.setActualParameters(parameterNamesSupplier.get(), + parameterValuesSupplier.get()); + } + return left; + } ); return null; }, Function.identity()); @@ -281,10 +278,10 @@ private Object getEitherResult(EvaluationContext ctx, Either /** * Adapt the given Either<FEELEvent, Object> to contain FEEL-Dialect-specific value, if needed * - * @see FEELFunction#defaultValue() * @param ctx * @param source * @return + * @see FEELFunction#defaultValue() */ private Either getFEELDialectAdaptedEither(EvaluationContext ctx, Either source) { if (ctx.getFEELDialect().equals(FEELDialect.BFEEL) @@ -298,10 +295,10 @@ private Either getFEELDialectAdaptedEither(EvaluationContext /** * Adapt the given Object to FEEL-Dialect-specific value, if needed * - * @see FEELFunction#defaultValue() * @param ctx * @param source * @return + * @see FEELFunction#defaultValue() */ private Object getFEELDialectAdaptedObject(EvaluationContext ctx, Object source) { if (ctx.getFEELDialect().equals(FEELDialect.BFEEL) @@ -315,10 +312,10 @@ private Object getFEELDialectAdaptedObject(EvaluationContext ctx, Object source) /** * Adapt the given List to FEEL-Dialect-specific values, if needed * - * @see FEELFunction#feelDialectAdaptedInputList(List) * @param ctx * @param source * @return + * @see FEELFunction#feelDialectAdaptedInputList(List) */ private List getFEELDialectAdaptedList(EvaluationContext ctx, List source) { if (ctx.getFEELDialect().equals(FEELDialect.BFEEL) diff --git a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/functions/ContextPutFunction.java b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/functions/ContextPutFunction.java index 57d8173b325..9a30bc0a454 100644 --- a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/functions/ContextPutFunction.java +++ b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/functions/ContextPutFunction.java @@ -6,9 +6,9 @@ * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

* Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY @@ -27,6 +27,7 @@ import org.kie.dmn.feel.lang.types.BuiltInType; import org.kie.dmn.feel.lang.types.impl.ImmutableFPAWrappingPOJO; import org.kie.dmn.feel.runtime.events.InvalidParametersEvent; +import org.kie.dmn.feel.util.BuiltInTypeUtils; public class ContextPutFunction extends BaseFEELFunction { @@ -48,7 +49,7 @@ public FEELFnResult> invoke(@ParameterName("context") Object return result; } - + public FEELFnResult> invoke(@ParameterName("context") Object context, @ParameterName("keys") List keys, @ParameterName("value") Object value) { if (context == null) { return FEELFnResult.ofError(new InvalidParametersEvent(FEELEvent.Severity.ERROR, "context", "cannot be null")); @@ -60,7 +61,7 @@ public FEELFnResult> invoke(@ParameterName("context") Object } Object head = keys.get(0); if (!(head instanceof String)) { - return FEELFnResult.ofError(new InvalidParametersEvent(FEELEvent.Severity.ERROR, "keys", "an element is not a key: "+head)); + return FEELFnResult.ofError(new InvalidParametersEvent(FEELEvent.Severity.ERROR, "keys", "an element is not a key: " + head)); } final String key0 = (String) head; if (keys.size() == 1) { @@ -68,10 +69,10 @@ public FEELFnResult> invoke(@ParameterName("context") Object } final List keysTail = keys.subList(1, keys.size()); final FEELFnResult> result = toMap(context).flatMap(r -> invoke(r.get(key0), keysTail, value).map(rv -> put(r, key0, rv))); - + return result; } - + private static Map put(Map map, K key, V value) { map.put(key, value); return map; @@ -89,7 +90,7 @@ public static FEELFnResult> toMap(Object context) { FEELFnResult.ofError(new InvalidParametersEvent(FEELEvent.Severity.ERROR, "found a key which is not a string: " + kv.getKey())); } } - } else if (BuiltInType.determineTypeFromInstance(context) == BuiltInType.UNKNOWN) { + } else if (BuiltInTypeUtils.determineTypeFromInstance(context) == BuiltInType.UNKNOWN) { result = new ImmutableFPAWrappingPOJO(context).allFEELProperties(); } else { return FEELFnResult.ofError(new InvalidParametersEvent(FEELEvent.Severity.ERROR, "context", "is not a context")); diff --git a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/functions/GetValueFunction.java b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/functions/GetValueFunction.java index 89fc3a3e09c..dc760c1b44d 100644 --- a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/functions/GetValueFunction.java +++ b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/functions/GetValueFunction.java @@ -6,9 +6,9 @@ * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

* Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY @@ -24,6 +24,7 @@ import org.kie.dmn.feel.lang.types.BuiltInType; import org.kie.dmn.feel.lang.types.impl.ImmutableFPAWrappingPOJO; import org.kie.dmn.feel.runtime.events.InvalidParametersEvent; +import org.kie.dmn.feel.util.BuiltInTypeUtils; public class GetValueFunction extends BaseFEELFunction { @@ -38,7 +39,7 @@ public FEELFnResult invoke(@ParameterName("m") Object m, @ParameterName( return FEELFnResult.ofError(new InvalidParametersEvent(Severity.ERROR, "m", "cannot be null")); } else if (m instanceof Map) { return FEELFnResult.ofResult(((Map) m).get(key)); - } else if (BuiltInType.determineTypeFromInstance(m) == BuiltInType.UNKNOWN) { + } else if (BuiltInTypeUtils.determineTypeFromInstance(m) == BuiltInType.UNKNOWN) { return FEELFnResult.ofResult(new ImmutableFPAWrappingPOJO(m).getFEELProperty(key).toOptional().orElse(null)); } else { return FEELFnResult.ofError(new InvalidParametersEvent(Severity.ERROR, "m", "is not a context")); diff --git a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/functions/IsFunction.java b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/functions/IsFunction.java index 2ecbc4a7e01..21b31ff2c76 100644 --- a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/functions/IsFunction.java +++ b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/functions/IsFunction.java @@ -6,9 +6,9 @@ * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

* Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY @@ -25,6 +25,7 @@ import org.kie.dmn.feel.lang.types.BuiltInType; import org.kie.dmn.feel.runtime.FEELBooleanFunction; import org.kie.dmn.feel.util.BooleanEvalHelper; +import org.kie.dmn.feel.util.BuiltInTypeUtils; public class IsFunction extends BaseFEELFunction implements FEELBooleanFunction { public static final IsFunction INSTANCE = new IsFunction(); @@ -41,9 +42,9 @@ public FEELFnResult invoke(@ParameterName("value1") Object value1, @Par // Handle specific cases when both time / datetime TemporalAccessor left = (TemporalAccessor) value1; TemporalAccessor right = (TemporalAccessor) value2; - if (BuiltInType.determineTypeFromInstance(left) == BuiltInType.TIME && BuiltInType.determineTypeFromInstance(right) == BuiltInType.TIME) { + if (BuiltInTypeUtils.determineTypeFromInstance(left) == BuiltInType.TIME && BuiltInTypeUtils.determineTypeFromInstance(right) == BuiltInType.TIME) { return FEELFnResult.ofResult(BooleanEvalHelper.isEqualTimeInSemanticD(left, right)); - } else if (BuiltInType.determineTypeFromInstance(left) == BuiltInType.DATE_TIME && BuiltInType.determineTypeFromInstance(right) == BuiltInType.DATE_TIME) { + } else if (BuiltInTypeUtils.determineTypeFromInstance(left) == BuiltInType.DATE_TIME && BuiltInTypeUtils.determineTypeFromInstance(right) == BuiltInType.DATE_TIME) { return FEELFnResult.ofResult(BooleanEvalHelper.isEqualDateTimeInSemanticD(left, right)); } // fallback; continue: } diff --git a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/util/BooleanEvalHelper.java b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/util/BooleanEvalHelper.java index 104002e898d..27977101169 100644 --- a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/util/BooleanEvalHelper.java +++ b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/util/BooleanEvalHelper.java @@ -42,7 +42,7 @@ import static org.kie.dmn.feel.util.NumberEvalHelper.getBigDecimalOrNull; public class BooleanEvalHelper { - public static final Logger LOG = LoggerFactory.getLogger( BooleanEvalHelper.class ); + public static final Logger LOG = LoggerFactory.getLogger(BooleanEvalHelper.class); public static Boolean getBooleanOrNull(Object value) { if (!(value instanceof Boolean)) { @@ -60,22 +60,22 @@ public static Boolean getBooleanOrNull(Object value) { * @return */ public static Boolean compare(Object left, Object right, FEELDialect feelDialect, BiPredicate op) { - if ( left == null || right == null ) { + if (left == null || right == null) { return getBooleanOrDialectDefault(null, feelDialect); } if (left instanceof ChronoPeriod && right instanceof ChronoPeriod) { // periods have special compare semantics in FEEL as it ignores "days". Only months and years are compared Long l = ComparablePeriod.toTotalMonths((ChronoPeriod) left); Long r = ComparablePeriod.toTotalMonths((ChronoPeriod) right); - return op.test( l, r ); + return op.test(l, r); } if (left instanceof TemporalAccessor && right instanceof TemporalAccessor) { // Handle specific cases when both time / datetime TemporalAccessor l = (TemporalAccessor) left; TemporalAccessor r = (TemporalAccessor) right; - if (BuiltInType.determineTypeFromInstance(left) == BuiltInType.TIME && BuiltInType.determineTypeFromInstance(right) == BuiltInType.TIME) { + if (BuiltInTypeUtils.determineTypeFromInstance(left) == BuiltInType.TIME && BuiltInTypeUtils.determineTypeFromInstance(right) == BuiltInType.TIME) { return op.test(valuet(l), valuet(r)); - } else if (BuiltInType.determineTypeFromInstance(left) == BuiltInType.DATE_TIME && BuiltInType.determineTypeFromInstance(right) == BuiltInType.DATE_TIME) { + } else if (BuiltInTypeUtils.determineTypeFromInstance(left) == BuiltInType.DATE_TIME && BuiltInTypeUtils.determineTypeFromInstance(right) == BuiltInType.DATE_TIME) { return op.test(valuedt(l, r.query(TemporalQueries.zone())), valuedt(r, l.query(TemporalQueries.zone()))); } } @@ -104,24 +104,24 @@ public static Boolean compare(Object left, Object right, FEELDialect feelDialect * @return */ public static Boolean isEqual(Object left, Object right, FEELDialect feelDialect) { - if ( left == null || right == null ) { + if (left == null || right == null) { return left == right; } // spec defines that "a=[a]", i.e., singleton collections should be treated as the single element // and vice-versa - if( left instanceof Collection && !(right instanceof Collection) && ((Collection)left).size() == 1 ) { - left = ((Collection)left).toArray()[0]; - } else if( right instanceof Collection && !(left instanceof Collection) && ((Collection)right).size()==1 ) { + if (left instanceof Collection && !(right instanceof Collection) && ((Collection) left).size() == 1) { + left = ((Collection) left).toArray()[0]; + } else if (right instanceof Collection && !(left instanceof Collection) && ((Collection) right).size() == 1) { right = ((Collection) right).toArray()[0]; } - if( left instanceof Range && right instanceof Range ) { - return isEqual( (Range)left, (Range) right ); - } else if( left instanceof Iterable && right instanceof Iterable ) { - return isEqual( (Iterable)left, (Iterable) right ); - } else if( left instanceof Map && right instanceof Map ) { - return isEqual( (Map)left, (Map) right ); + if (left instanceof Range && right instanceof Range) { + return isEqual((Range) left, (Range) right); + } else if (left instanceof Iterable && right instanceof Iterable) { + return isEqual((Iterable) left, (Iterable) right); + } else if (left instanceof Map && right instanceof Map) { + return isEqual((Map) left, (Map) right); } else if (left instanceof ChronoPeriod && right instanceof ChronoPeriod) { // periods have special compare semantics in FEEL as it ignores "days". Only months and years are compared Long l = ComparablePeriod.toTotalMonths((ChronoPeriod) left); @@ -131,13 +131,13 @@ public static Boolean isEqual(Object left, Object right, FEELDialect feelDialect // Handle specific cases when both time / datetime TemporalAccessor l = (TemporalAccessor) left; TemporalAccessor r = (TemporalAccessor) right; - if (BuiltInType.determineTypeFromInstance(left) == BuiltInType.TIME && BuiltInType.determineTypeFromInstance(right) == BuiltInType.TIME) { + if (BuiltInTypeUtils.determineTypeFromInstance(left) == BuiltInType.TIME && BuiltInTypeUtils.determineTypeFromInstance(right) == BuiltInType.TIME) { return isEqual(DateTimeEvalHelper.valuet(l), DateTimeEvalHelper.valuet(r), feelDialect); - } else if (BuiltInType.determineTypeFromInstance(left) == BuiltInType.DATE_TIME && BuiltInType.determineTypeFromInstance(right) == BuiltInType.DATE_TIME) { + } else if (BuiltInTypeUtils.determineTypeFromInstance(left) == BuiltInType.DATE_TIME && BuiltInTypeUtils.determineTypeFromInstance(right) == BuiltInType.DATE_TIME) { return isEqual(DateTimeEvalHelper.valuedt(l, r.query(TemporalQueries.zone())), DateTimeEvalHelper.valuedt(r, l.query(TemporalQueries.zone())), feelDialect); } // fallback; continue: } - return compare( left, right, feelDialect, (l, r) -> l.compareTo( r ) == 0 ); + return compare(left, right, feelDialect, (l, r) -> l.compareTo(r) == 0); } /** @@ -184,6 +184,7 @@ public static Boolean isEqualTimeInSemanticD(TemporalAccessor left, TemporalAcce * This method consider if the value object is a String * In that case, return the {@link String#equals(Object)} result * Otherwise, default to the {@link #isEqual(Object, Object, FEELDialect)} + * * @param value * @param itemFromList * @return @@ -200,6 +201,7 @@ public static boolean isEqualsStringCompare(Object value, Object itemFromList) { /** * Return the original object or, depending on the FEELDialect, a default value + * * @param rawReturn * @param feelDialect * @return @@ -216,6 +218,7 @@ public static Boolean getBooleanOrDialectDefault(Object rawReturn, FEELDialect f /** * Return TRUE if it is the original object or, depending on the FEELDialect, a default value + * * @param rawReturn * @param feelDialect * @return @@ -230,6 +233,7 @@ public static Boolean getTrueOrDialectDefault(Object rawReturn, FEELDialect feel /** * Return TRUE if it is the original object or, depending on the FEELDialect, a default value + * * @param rawReturn * @param feelDialect * @return @@ -243,40 +247,40 @@ public static Boolean getFalseOrDialectDefault(Object rawReturn, FEELDialect fee } static Boolean isEqual(Range left, Range right) { - return left.equals( right ); + return left.equals(right); } static Boolean isEqual(Iterable left, Iterable right) { Iterator li = left.iterator(); Iterator ri = right.iterator(); - while( li.hasNext() && ri.hasNext() ) { + while (li.hasNext() && ri.hasNext()) { Object l = li.next(); Object r = ri.next(); - if ( !isEqualObject(l, r ) ) return false; + if (!isEqualObject(l, r)) return false; } return li.hasNext() == ri.hasNext(); } - static Boolean isEqual(Map left, Map right) { - if( left.size() != right.size() ) { + static Boolean isEqual(Map left, Map right) { + if (left.size() != right.size()) { return false; } - for( Map.Entry le : left.entrySet() ) { + for (Map.Entry le : left.entrySet()) { Object l = le.getValue(); - Object r = right.get( le.getKey() ); - if ( !isEqualObject( l, r ) ) return false; + Object r = right.get(le.getKey()); + if (!isEqualObject(l, r)) return false; } return true; } static Boolean isEqualObject(Object l, Object r) { - if( l instanceof Iterable && r instanceof Iterable && !isEqual( (Iterable) l, (Iterable) r ) ) { + if (l instanceof Iterable && r instanceof Iterable && !isEqual((Iterable) l, (Iterable) r)) { return false; - } else if( l instanceof Map && r instanceof Map && !isEqual( (Map) l, (Map) r ) ) { + } else if (l instanceof Map && r instanceof Map && !isEqual((Map) l, (Map) r)) { return false; - } else if( l != null && r != null && !l.equals( r ) ) { + } else if (l != null && r != null && !l.equals(r)) { return false; - } else if( ( l == null || r == null ) && l != r ) { + } else if ((l == null || r == null) && l != r) { return false; } return true; diff --git a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/util/BuiltInTypeUtils.java b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/util/BuiltInTypeUtils.java new file mode 100644 index 00000000000..bfb9911ce60 --- /dev/null +++ b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/util/BuiltInTypeUtils.java @@ -0,0 +1,153 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.dmn.feel.util; + +import java.time.Duration; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.OffsetDateTime; +import java.time.OffsetTime; +import java.time.ZonedDateTime; +import java.time.chrono.ChronoPeriod; +import java.time.temporal.ChronoField; +import java.time.temporal.Temporal; +import java.time.temporal.TemporalAccessor; +import java.time.temporal.TemporalQueries; +import java.util.List; +import java.util.Map; + +import org.kie.dmn.feel.lang.Type; +import org.kie.dmn.feel.lang.types.BuiltInType; +import org.kie.dmn.feel.runtime.FEELFunction; +import org.kie.dmn.feel.runtime.Range; +import org.kie.dmn.feel.runtime.UnaryTest; +import org.kie.dmn.feel.runtime.custom.ZoneTime; + +public class BuiltInTypeUtils { + + private BuiltInTypeUtils() { + // Utility class, no instantiation allowed + } + + public static Type determineTypeFromName(String name) { + if (name == null) { + return BuiltInType.UNKNOWN; + } + for (BuiltInType t : BuiltInType.values()) { + for (String n : t.getNames()) { + if (n.equals(name)) { + return t; + } + } + } + return BuiltInType.UNKNOWN; + } + + public static Type determineTypeFromInstance(Object o) { + if (o == null) { + return BuiltInType.UNKNOWN; + } else if (o instanceof Number) { + return BuiltInType.NUMBER; + } else if (o instanceof String) { + return BuiltInType.STRING; + } else if (o instanceof LocalDate) { + return BuiltInType.DATE; + } else if (o instanceof LocalTime || o instanceof OffsetTime || o instanceof ZoneTime) { + return BuiltInType.TIME; + } else if (o instanceof ZonedDateTime || o instanceof OffsetDateTime || o instanceof LocalDateTime) { + return BuiltInType.DATE_TIME; + } else if (o instanceof Duration || o instanceof ChronoPeriod) { + return BuiltInType.DURATION; + } else if (o instanceof Boolean) { + return BuiltInType.BOOLEAN; + } else if (o instanceof UnaryTest) { + return BuiltInType.UNARY_TEST; + } else if (o instanceof Range) { + return BuiltInType.RANGE; + } else if (o instanceof FEELFunction) { + return BuiltInType.FUNCTION; + } else if (o instanceof List) { + return BuiltInType.LIST; + } else if (o instanceof Map) { + return BuiltInType.CONTEXT; + } else if (o instanceof TemporalAccessor) { + TemporalAccessor ta = (TemporalAccessor) o; + if (!(ta instanceof Temporal) && ta.isSupported(ChronoField.HOUR_OF_DAY) + && ta.isSupported(ChronoField.MINUTE_OF_HOUR) && ta.isSupported(ChronoField.SECOND_OF_MINUTE) + && ta.query(TemporalQueries.zone()) != null) { + return BuiltInType.TIME; + } + } + return BuiltInType.UNKNOWN; + } + + public static Type determineTypeFromClass(Class clazz) { + if (clazz == null) { + return BuiltInType.UNKNOWN; + } else if (Number.class.isAssignableFrom(clazz)) { + return BuiltInType.NUMBER; + } else if (String.class.isAssignableFrom(clazz)) { + return BuiltInType.STRING; + } else if (LocalDate.class.isAssignableFrom(clazz)) { + return BuiltInType.DATE; + } else if (LocalTime.class.isAssignableFrom(clazz) || OffsetTime.class.isAssignableFrom(clazz) || ZoneTime.class.isAssignableFrom(clazz)) { + return BuiltInType.TIME; + } else if (ZonedDateTime.class.isAssignableFrom(clazz) || OffsetDateTime.class.isAssignableFrom(clazz) || LocalDateTime.class.isAssignableFrom(clazz)) { + return BuiltInType.DATE_TIME; + } else if (Duration.class.isAssignableFrom(clazz) || ChronoPeriod.class.isAssignableFrom(clazz)) { + return BuiltInType.DURATION; + } else if (Boolean.class.isAssignableFrom(clazz)) { + return BuiltInType.BOOLEAN; + } else if (UnaryTest.class.isAssignableFrom(clazz)) { + return BuiltInType.UNARY_TEST; + } else if (Range.class.isAssignableFrom(clazz)) { + return BuiltInType.RANGE; + } else if (FEELFunction.class.isAssignableFrom(clazz)) { + return BuiltInType.FUNCTION; + } else if (List.class.isAssignableFrom(clazz)) { + return BuiltInType.LIST; + } else if (Map.class.isAssignableFrom(clazz)) { + return BuiltInType.CONTEXT; + } else if (TemporalAccessor.class.isAssignableFrom(clazz)) { + TemporalAccessor ta = TemporalAccessor.class.cast(clazz); + if (!(ta instanceof Temporal) && ta.isSupported(ChronoField.HOUR_OF_DAY) + && ta.isSupported(ChronoField.MINUTE_OF_HOUR) && ta.isSupported(ChronoField.SECOND_OF_MINUTE) + && ta.query(TemporalQueries.zone()) != null) { + return BuiltInType.TIME; + } + } + return BuiltInType.UNKNOWN; + } + + public static boolean isInstanceOf(Object o, Type t) { + if (o == null) { + return false; // See FEEL specifications Table 49. + } + if (t == BuiltInType.UNKNOWN) { + return true; + } + return determineTypeFromInstance(o) == t; + } + + public static boolean isInstanceOf(Object o, String name) { + return determineTypeFromInstance(o) == determineTypeFromName(name); + } + +} diff --git a/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/lang/types/GenFnTypeTest.java b/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/lang/types/GenFnTypeTest.java index 8a18c729c9d..e25b2cae5be 100644 --- a/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/lang/types/GenFnTypeTest.java +++ b/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/lang/types/GenFnTypeTest.java @@ -147,67 +147,6 @@ void testCheckSignatures_withMatchingEmptySignature() { assertThat(GenFnType.checkSignatures(params, argsGen)).isFalse(); } - /* @Test - void testMatchesFunctionSignature_withMatchingSignature() { - assertThat(GenFnType.matchesFunctionSignature(absFunctionInstance)).isTrue(); - }*/ - - /* @Test - void testMatchesFunctionSignature_withNonMatchingSignature() { - FEELFunction function = new FEELFunction() { - - @Override - public String getName() { - return ""; - } - - @Override - public Symbol getSymbol() { - return null; - } - - @Override - public List> getParameters() { - return List.of(); - } - - @Override - public FEELFnResult invokeReflectively(EvaluationContext ctx, Object[] params) { - return FEELFnResult.ofResult(new BigDecimal("1.0")); - } - }; - - assertThat(GenFnType.matchesFunctionSignature((FEELFunction) function)).isFalse(); - } - - @Test - void testMatchesFunctionSignature_withDifferentReturnType() { - FEELFunction function = new FEELFunction() { - - @Override - public String getName() { - return ""; - } - - @Override - public Symbol getSymbol() { - return null; - } - - @Override - public List> getParameters() { - return List.of(); - } - - @Override - public Object invokeReflectively(EvaluationContext ctx, Object[] params) { - return FEELFnResult.ofResult(1); - } - }; - - assertThat(GenFnType.matchesFunctionSignature(function)).isFalse(); - }*/ - static class SomeType implements Type { @Override public String getName() { diff --git a/kie-dmn/kie-dmn-legacy-tests/src/test/java/org/kie/dmn/legacy/tests/core/v1_1/DMNRuntimeTest.java b/kie-dmn/kie-dmn-legacy-tests/src/test/java/org/kie/dmn/legacy/tests/core/v1_1/DMNRuntimeTest.java index e562d67e1aa..6adcfc33dab 100644 --- a/kie-dmn/kie-dmn-legacy-tests/src/test/java/org/kie/dmn/legacy/tests/core/v1_1/DMNRuntimeTest.java +++ b/kie-dmn/kie-dmn-legacy-tests/src/test/java/org/kie/dmn/legacy/tests/core/v1_1/DMNRuntimeTest.java @@ -6,9 +6,9 @@ * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

* Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY @@ -70,6 +70,7 @@ import org.kie.dmn.feel.lang.types.BuiltInType; import org.kie.dmn.feel.lang.types.impl.ComparablePeriod; import org.kie.dmn.feel.marshaller.FEELStringMarshaller; +import org.kie.dmn.feel.util.BuiltInTypeUtils; import org.kie.dmn.feel.util.NumberEvalHelper; import org.kie.dmn.model.api.Decision; import org.kie.dmn.model.api.Definitions; @@ -101,232 +102,232 @@ public class DMNRuntimeTest extends BaseDMN1_1VariantTest { @MethodSource("params") void simpleItemDefinition(VariantTestConf conf) { testConfig = conf; - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("simple-item-def.dmn", this.getClass() ); - final DMNModel dmnModel = runtime.getModel("https://github.com/kiegroup/kie-dmn/itemdef", "simple-item-def" ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("simple-item-def.dmn", this.getClass()); + final DMNModel dmnModel = runtime.getModel("https://github.com/kiegroup/kie-dmn/itemdef", "simple-item-def"); assertThat(dmnModel).isNotNull(); assertThat(dmnModel.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).isFalse(); final DMNContext context = DMNFactory.newContext(); - context.set( "Monthly Salary", 1000 ); + context.set("Monthly Salary", 1000); - final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context ); + final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context); assertThat(dmnResult.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnResult.getMessages())).isFalse(); final DMNContext result = dmnResult.getContext(); - assertThat( result.get( "Yearly Salary" )).isEqualTo(new BigDecimal( "12000" ) ); + assertThat(result.get("Yearly Salary")).isEqualTo(new BigDecimal("12000")); } @ParameterizedTest(name = "{0}") @MethodSource("params") void compositeItemDefinition(VariantTestConf conf) { testConfig = conf; - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("0008-LX-arithmetic.dmn", this.getClass() ); - final DMNModel dmnModel = runtime.getModel("https://github.com/kiegroup/kie-dmn", "0008-LX-arithmetic" ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("0008-LX-arithmetic.dmn", this.getClass()); + final DMNModel dmnModel = runtime.getModel("https://github.com/kiegroup/kie-dmn", "0008-LX-arithmetic"); assertThat(dmnModel).isNotNull(); final DMNContext context = DMNFactory.newContext(); final Map loan = new HashMap<>(); - loan.put( "principal", 600000 ); - loan.put( "rate", 0.0375 ); - loan.put( "termMonths", 360 ); - context.set( "loan", loan ); + loan.put("principal", 600000); + loan.put("rate", 0.0375); + loan.put("termMonths", 360); + context.set("loan", loan); - final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context ); + final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context); final DMNContext result = dmnResult.getContext(); - assertThat( result.get( "payment" )).isEqualTo(new BigDecimal( "2778.693549432766768088520383236299" ) ); + assertThat(result.get("payment")).isEqualTo(new BigDecimal("2778.693549432766768088520383236299")); } @ParameterizedTest(name = "{0}") @MethodSource("params") void trisotechNamespace(VariantTestConf conf) { testConfig = conf; - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("trisotech_namespace.dmn", this.getClass() ); - final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/dmn/definitions/_b8feec86-dadf-4051-9feb-8e6093bbb530", "Solution 3" ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("trisotech_namespace.dmn", this.getClass()); + final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/dmn/definitions/_b8feec86-dadf-4051-9feb-8e6093bbb530", "Solution 3"); assertThat(dmnModel).isNotNull(); assertThat(dmnModel.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).isFalse(); - + final DMNContext context = DMNFactory.newContext(); - context.set( "IsDoubleHulled", true ); - context.set( "Residual Cargo Size", BigDecimal.valueOf(0.1) ); - context.set( "Ship Size", new BigDecimal( 50 ) ); - - final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context ); + context.set("IsDoubleHulled", true); + context.set("Residual Cargo Size", BigDecimal.valueOf(0.1)); + context.set("Ship Size", new BigDecimal(50)); + + final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context); assertThat(dmnResult.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnResult.getMessages())).isFalse(); - + final DMNContext result = dmnResult.getContext(); - assertThat( result.get( "Ship can enter a Dutch port" )).isEqualTo(Boolean.TRUE); + assertThat(result.get("Ship can enter a Dutch port")).isEqualTo(Boolean.TRUE); } @ParameterizedTest(name = "{0}") @MethodSource("params") void emptyDecision1(VariantTestConf conf) { testConfig = conf; - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("empty_decision.dmn", this.getClass() ); - final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/dmn/definitions/_ba9fc4b1-5ced-4d00-9b61-290de4bf3213", "Solution 3" ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("empty_decision.dmn", this.getClass()); + final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/dmn/definitions/_ba9fc4b1-5ced-4d00-9b61-290de4bf3213", "Solution 3"); assertThat(dmnModel).isNotNull(); final DMNContext context = DMNFactory.newContext(); final Map shipInfo = new HashMap<>(); - shipInfo.put( "Size", BigDecimal.valueOf( 70 ) ); - shipInfo.put( "Is Double Hulled", Boolean.FALSE ); - shipInfo.put( "Residual Cargo Size", BigDecimal.valueOf( 0.1 ) ); - context.set( "Ship Info", shipInfo ); + shipInfo.put("Size", BigDecimal.valueOf(70)); + shipInfo.put("Is Double Hulled", Boolean.FALSE); + shipInfo.put("Residual Cargo Size", BigDecimal.valueOf(0.1)); + context.set("Ship Info", shipInfo); // Test that even if one decision is empty or missing input data, // the other decisions in the model are still evaluated - final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context ); + final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context); final DMNContext result = dmnResult.getContext(); - assertThat( dmnResult.hasErrors()).isTrue(); - assertThat( result.get( "Ship Can Enter v2" )).isEqualTo(Boolean.TRUE); + assertThat(dmnResult.hasErrors()).isTrue(); + assertThat(result.get("Ship Can Enter v2")).isEqualTo(Boolean.TRUE); } @ParameterizedTest(name = "{0}") @MethodSource("params") void emptyDecision2(VariantTestConf conf) { testConfig = conf; - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("empty_decision.dmn", this.getClass() ); - final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/dmn/definitions/_ba9fc4b1-5ced-4d00-9b61-290de4bf3213", "Solution 3" ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("empty_decision.dmn", this.getClass()); + final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/dmn/definitions/_ba9fc4b1-5ced-4d00-9b61-290de4bf3213", "Solution 3"); assertThat(dmnModel).isNotNull(); final DMNContext context = DMNFactory.newContext(); final Map shipInfo = new HashMap<>(); - shipInfo.put( "Size", BigDecimal.valueOf( 70 ) ); - shipInfo.put( "Is Double Hulled", Boolean.FALSE ); - shipInfo.put( "Residual Cargo Size", BigDecimal.valueOf( 0.1 ) ); - context.set( "Ship Info", shipInfo ); - context.set( "Ship Size", BigDecimal.valueOf( 70 ) ); - context.set( "IsDoubleHulled", Boolean.FALSE ); - context.set( "Residual Cargo Size", BigDecimal.valueOf( 0.1 ) ); + shipInfo.put("Size", BigDecimal.valueOf(70)); + shipInfo.put("Is Double Hulled", Boolean.FALSE); + shipInfo.put("Residual Cargo Size", BigDecimal.valueOf(0.1)); + context.set("Ship Info", shipInfo); + context.set("Ship Size", BigDecimal.valueOf(70)); + context.set("IsDoubleHulled", Boolean.FALSE); + context.set("Residual Cargo Size", BigDecimal.valueOf(0.1)); // check that if all the input data is available, but the // decision expression is empty, the model returns a warning - final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context ); + final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context); - final List messages = dmnResult.getMessages(DMNMessage.Severity.WARN ); - assertThat( messages).hasSize(1); - assertThat( messages.get( 0 ).getSeverity()).isEqualTo(DMNMessage.Severity.WARN ); - assertThat( messages.get( 0 ).getSourceId()).isEqualTo("_42806504-8ed5-488f-b274-de98c1bc67b9" ); + final List messages = dmnResult.getMessages(DMNMessage.Severity.WARN); + assertThat(messages).hasSize(1); + assertThat(messages.get(0).getSeverity()).isEqualTo(DMNMessage.Severity.WARN); + assertThat(messages.get(0).getSourceId()).isEqualTo("_42806504-8ed5-488f-b274-de98c1bc67b9"); final DMNContext result = dmnResult.getContext(); - assertThat( result.get( "Ship Can Enter v2" )).isEqualTo(Boolean.TRUE); + assertThat(result.get("Ship Can Enter v2")).isEqualTo(Boolean.TRUE); } @ParameterizedTest(name = "{0}") @MethodSource("params") void eventListeners(VariantTestConf conf) { testConfig = conf; - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("car_damage_responsibility.dmn", this.getClass() ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("car_damage_responsibility.dmn", this.getClass()); - final DMNRuntimeEventListener listener = mock(DMNRuntimeEventListener.class ); - runtime.addListener( listener ); - runtime.addListener( DMNRuntimeUtil.createListener() ); + final DMNRuntimeEventListener listener = mock(DMNRuntimeEventListener.class); + runtime.addListener(listener); + runtime.addListener(DMNRuntimeUtil.createListener()); - final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/definitions/_820611e9-c21c-47cd-8e52-5cba2be9f9cc", "Car Damage Responsibility" ); + final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/definitions/_820611e9-c21c-47cd-8e52-5cba2be9f9cc", "Car Damage Responsibility"); assertThat(dmnModel).isNotNull(); final DMNContext context = DMNFactory.newContext(); - context.set( "Membership Level", "Silver" ); - context.set( "Damage Types", "Body" ); - context.set( "Responsible", "Driver" ); - - final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context ); - - final ArgumentCaptor argument = ArgumentCaptor.forClass(AfterEvaluateDecisionTableEvent.class ); - verify( listener, times( 2 ) ) - .beforeEvaluateDecision( any( BeforeEvaluateDecisionEvent.class ) ); - verify( listener, times( 2 ) ) - .afterEvaluateDecision( any( AfterEvaluateDecisionEvent.class ) ); - verify( listener, times( 2 ) ) - .beforeEvaluateDecisionTable( any( BeforeEvaluateDecisionTableEvent.class ) ); - verify( listener, times( 2 ) ) - .afterEvaluateDecisionTable( argument.capture() ); - - AfterEvaluateDecisionTableEvent dte = argument.getAllValues().get( 0 ); - assertThat( dte.getDecisionTableName()).isEqualTo("Car Damage Responsibility" ); - assertThat( dte.getMatches()).containsExactly(5); // rows are 1-based - - dte = argument.getAllValues().get( 1 ); - assertThat( dte.getDecisionTableName()).isEqualTo("Payment method" ); - assertThat( dte.getMatches()).containsExactly(3); // rows are 1-based + context.set("Membership Level", "Silver"); + context.set("Damage Types", "Body"); + context.set("Responsible", "Driver"); + + final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context); + + final ArgumentCaptor argument = ArgumentCaptor.forClass(AfterEvaluateDecisionTableEvent.class); + verify(listener, times(2)) + .beforeEvaluateDecision(any(BeforeEvaluateDecisionEvent.class)); + verify(listener, times(2)) + .afterEvaluateDecision(any(AfterEvaluateDecisionEvent.class)); + verify(listener, times(2)) + .beforeEvaluateDecisionTable(any(BeforeEvaluateDecisionTableEvent.class)); + verify(listener, times(2)) + .afterEvaluateDecisionTable(argument.capture()); + + AfterEvaluateDecisionTableEvent dte = argument.getAllValues().get(0); + assertThat(dte.getDecisionTableName()).isEqualTo("Car Damage Responsibility"); + assertThat(dte.getMatches()).containsExactly(5); // rows are 1-based + + dte = argument.getAllValues().get(1); + assertThat(dte.getDecisionTableName()).isEqualTo("Payment method"); + assertThat(dte.getMatches()).containsExactly(3); // rows are 1-based assertThat(dmnResult.hasErrors()).isFalse(); final DMNContext result = dmnResult.getContext(); - assertThat( (Map) result.get( "Car Damage Responsibility" )).containsEntry("EU Rent", BigDecimal.valueOf(40)); - assertThat( (Map) result.get( "Car Damage Responsibility" )).containsEntry("Renter", BigDecimal.valueOf(60)); - assertThat( result.get( "Payment method" )).isEqualTo("Check" ); + assertThat((Map) result.get("Car Damage Responsibility")).containsEntry("EU Rent", BigDecimal.valueOf(40)); + assertThat((Map) result.get("Car Damage Responsibility")).containsEntry("Renter", BigDecimal.valueOf(60)); + assertThat(result.get("Payment method")).isEqualTo("Check"); } @ParameterizedTest(name = "{0}") @MethodSource("params") void contextEventListeners(VariantTestConf conf) { testConfig = conf; - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("context_listener.dmn", this.getClass() ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("context_listener.dmn", this.getClass()); - final DMNRuntimeEventListener listener = mock(DMNRuntimeEventListener.class ); - runtime.addListener( listener ); - runtime.addListener( DMNRuntimeUtil.createListener() ); + final DMNRuntimeEventListener listener = mock(DMNRuntimeEventListener.class); + runtime.addListener(listener); + runtime.addListener(DMNRuntimeUtil.createListener()); - final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/dmn/definitions/_73481d02-76fb-4927-ac11-5d936882e16c", "context listener" ); + final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/dmn/definitions/_73481d02-76fb-4927-ac11-5d936882e16c", "context listener"); assertThat(dmnModel).isNotNull(); final DMNContext context = DMNFactory.newContext(); - final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context ); - - final ArgumentCaptor argument = ArgumentCaptor.forClass(AfterEvaluateContextEntryEvent.class ); - verify( listener, times( 1 ) ) - .beforeEvaluateDecision( any( BeforeEvaluateDecisionEvent.class ) ); - verify( listener, times( 1 ) ) - .afterEvaluateDecision( any( AfterEvaluateDecisionEvent.class ) ); - verify( listener, times( 5 ) ) - .beforeEvaluateContextEntry( any( BeforeEvaluateContextEntryEvent.class ) ); - verify( listener, times( 5 ) ) - .afterEvaluateContextEntry( argument.capture() ); - - AfterEvaluateContextEntryEvent aece = argument.getAllValues().get( 0 ); - assertThat( aece.getNodeName()).isEqualTo("d1" ); - assertThat( aece.getVariableName()).isEqualTo("a1" ); - assertThat( aece.getVariableId()).isEqualTo("_b199c7b1-cb87-4a92-b045-a2954ccc9d01" ); - assertThat( aece.getExpressionId()).isEqualTo("_898c24f8-93da-4fe2-827c-924c30956833" ); - assertThat( aece.getExpressionResult()).isEqualTo(BigDecimal.valueOf( 10 ) ); - - aece = argument.getAllValues().get( 1 ); - assertThat( aece.getNodeName()).isEqualTo("d1" ); - assertThat( aece.getVariableName()).isEqualTo("c1" ); - assertThat( aece.getVariableId()).isEqualTo("_38a88aef-8b3c-424d-b60c-a139ffb610e1" ); - assertThat( aece.getExpressionId()).isEqualTo("_879c4ac6-8b25-4cd1-9b8e-c18d0b0b281c" ); - assertThat( aece.getExpressionResult()).isEqualTo("a" ); - - aece = argument.getAllValues().get( 2 ); - assertThat( aece.getNodeName()).isEqualTo("d1" ); - assertThat( aece.getVariableName()).isEqualTo("c2" ); - assertThat( aece.getVariableId()).isEqualTo("_3aad82f0-74b9-4921-8b2f-d6c277c840db" ); - assertThat( aece.getExpressionId()).isEqualTo("_9acf4baf-6c49-4d47-88ab-2e511e598e04" ); - assertThat( aece.getExpressionResult()).isEqualTo("b" ); - - aece = argument.getAllValues().get( 3 ); - assertThat( aece.getNodeName()).isEqualTo("d1" ); - assertThat( aece.getVariableName()).isEqualTo("b1" ); - assertThat( aece.getVariableId()).isEqualTo("_f4a6c2ba-e6e9-4dbd-b776-edef2c1a1343" ); - assertThat( aece.getExpressionId()).isEqualTo("_c450d947-1874-41fe-9c0a-da5f1cca7fde" ); - assertThat( (Map) aece.getExpressionResult()).containsEntry("c1", "a"); - assertThat( (Map) aece.getExpressionResult()).containsEntry("c2", "b"); - - aece = argument.getAllValues().get( 4 ); - assertThat( aece.getNodeName()).isEqualTo("d1" ); - assertThat( aece.getVariableName()).isEqualTo(DMNContextEvaluator.RESULT_ENTRY ); + final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context); + + final ArgumentCaptor argument = ArgumentCaptor.forClass(AfterEvaluateContextEntryEvent.class); + verify(listener, times(1)) + .beforeEvaluateDecision(any(BeforeEvaluateDecisionEvent.class)); + verify(listener, times(1)) + .afterEvaluateDecision(any(AfterEvaluateDecisionEvent.class)); + verify(listener, times(5)) + .beforeEvaluateContextEntry(any(BeforeEvaluateContextEntryEvent.class)); + verify(listener, times(5)) + .afterEvaluateContextEntry(argument.capture()); + + AfterEvaluateContextEntryEvent aece = argument.getAllValues().get(0); + assertThat(aece.getNodeName()).isEqualTo("d1"); + assertThat(aece.getVariableName()).isEqualTo("a1"); + assertThat(aece.getVariableId()).isEqualTo("_b199c7b1-cb87-4a92-b045-a2954ccc9d01"); + assertThat(aece.getExpressionId()).isEqualTo("_898c24f8-93da-4fe2-827c-924c30956833"); + assertThat(aece.getExpressionResult()).isEqualTo(BigDecimal.valueOf(10)); + + aece = argument.getAllValues().get(1); + assertThat(aece.getNodeName()).isEqualTo("d1"); + assertThat(aece.getVariableName()).isEqualTo("c1"); + assertThat(aece.getVariableId()).isEqualTo("_38a88aef-8b3c-424d-b60c-a139ffb610e1"); + assertThat(aece.getExpressionId()).isEqualTo("_879c4ac6-8b25-4cd1-9b8e-c18d0b0b281c"); + assertThat(aece.getExpressionResult()).isEqualTo("a"); + + aece = argument.getAllValues().get(2); + assertThat(aece.getNodeName()).isEqualTo("d1"); + assertThat(aece.getVariableName()).isEqualTo("c2"); + assertThat(aece.getVariableId()).isEqualTo("_3aad82f0-74b9-4921-8b2f-d6c277c840db"); + assertThat(aece.getExpressionId()).isEqualTo("_9acf4baf-6c49-4d47-88ab-2e511e598e04"); + assertThat(aece.getExpressionResult()).isEqualTo("b"); + + aece = argument.getAllValues().get(3); + assertThat(aece.getNodeName()).isEqualTo("d1"); + assertThat(aece.getVariableName()).isEqualTo("b1"); + assertThat(aece.getVariableId()).isEqualTo("_f4a6c2ba-e6e9-4dbd-b776-edef2c1a1343"); + assertThat(aece.getExpressionId()).isEqualTo("_c450d947-1874-41fe-9c0a-da5f1cca7fde"); + assertThat((Map) aece.getExpressionResult()).containsEntry("c1", "a"); + assertThat((Map) aece.getExpressionResult()).containsEntry("c2", "b"); + + aece = argument.getAllValues().get(4); + assertThat(aece.getNodeName()).isEqualTo("d1"); + assertThat(aece.getVariableName()).isEqualTo(DMNContextEvaluator.RESULT_ENTRY); assertThat(aece.getVariableId()).isNull(); - assertThat( aece.getExpressionId()).isEqualTo("_4264b25c-d676-4516-ab8a-a4ff34e7a95c" ); - assertThat( aece.getExpressionResult()).isEqualTo("a" ); + assertThat(aece.getExpressionId()).isEqualTo("_4264b25c-d676-4516-ab8a-a4ff34e7a95c"); + assertThat(aece.getExpressionResult()).isEqualTo("a"); assertThat(dmnResult.hasErrors()).isFalse(); final DMNContext result = dmnResult.getContext(); - assertThat( result.get( "d1" )).isEqualTo("a" ); + assertThat(result.get("d1")).isEqualTo("a"); } @ParameterizedTest(name = "{0}") @@ -341,132 +342,132 @@ void errorMessages(VariantTestConf conf) { @MethodSource("params") void outputReuse(VariantTestConf conf) { testConfig = conf; - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("Input_reuse_in_output.dmn", this.getClass() ); - final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/dmn/definitions/_098bb607-eff7-4772-83ac-6ded8b371fa7", "Input reuse in output" ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("Input_reuse_in_output.dmn", this.getClass()); + final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/dmn/definitions/_098bb607-eff7-4772-83ac-6ded8b371fa7", "Input reuse in output"); assertThat(dmnModel).isNotNull(); final DMNContext context = DMNFactory.newContext(); - context.set( "Age", 40 ); - context.set( "Requested Product", "Fixed30" ); + context.set("Age", 40); + context.set("Requested Product", "Fixed30"); - final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context ); + final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context); assertThat(dmnResult.hasErrors()).isFalse(); final DMNContext result = dmnResult.getContext(); - assertThat( result.get( "My Decision" )).isEqualTo("Fixed30" ); + assertThat(result.get("My Decision")).isEqualTo("Fixed30"); } @ParameterizedTest(name = "{0}") @MethodSource("params") void simpleNot(VariantTestConf conf) { testConfig = conf; - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("Simple_Not.dmn", this.getClass() ); - final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/definitions/_98436ebb-7c42-48c0-8d11-d693e2a817c9", "Simple Not" ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("Simple_Not.dmn", this.getClass()); + final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/definitions/_98436ebb-7c42-48c0-8d11-d693e2a817c9", "Simple Not"); assertThat(dmnModel).isNotNull(); final DMNContext context = DMNFactory.newContext(); - context.set( "Occupation", "Student" ); + context.set("Occupation", "Student"); - final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context ); + final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context); assertThat(dmnResult.hasErrors()).isFalse(); final DMNContext result = dmnResult.getContext(); - assertThat( result.get( "a" )).isEqualTo("Is Student" ); + assertThat(result.get("a")).isEqualTo("Is Student"); } @ParameterizedTest(name = "{0}") @MethodSource("params") void simpleNot2(VariantTestConf conf) { testConfig = conf; - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("Simple_Not.dmn", this.getClass() ); - final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/definitions/_98436ebb-7c42-48c0-8d11-d693e2a817c9", "Simple Not" ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("Simple_Not.dmn", this.getClass()); + final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/definitions/_98436ebb-7c42-48c0-8d11-d693e2a817c9", "Simple Not"); assertThat(dmnModel).isNotNull(); final DMNContext context = DMNFactory.newContext(); - context.set( "Occupation", "Engineer" ); + context.set("Occupation", "Engineer"); - final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context ); + final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context); assertThat(dmnResult.hasErrors()).isFalse(); final DMNContext result = dmnResult.getContext(); - assertThat( result.get( "a" )).isEqualTo("Is not a Student" ); + assertThat(result.get("a")).isEqualTo("Is not a Student"); } @ParameterizedTest(name = "{0}") @MethodSource("params") void dinner(VariantTestConf conf) { testConfig = conf; - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("Dinner.dmn", this.getClass() ); - final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/definitions/_0c45df24-0d57-4acc-b296-b4cba8b71a36", "Dinner" ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("Dinner.dmn", this.getClass()); + final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/definitions/_0c45df24-0d57-4acc-b296-b4cba8b71a36", "Dinner"); assertThat(dmnModel).isNotNull(); - assertThat( dmnModel.hasErrors()).isFalse(); + assertThat(dmnModel.hasErrors()).isFalse(); final DMNContext context = DMNFactory.newContext(); - context.set( "Guests with children", true ); - context.set( "Season", "Fall" ); - context.set( "Number of guests", 4 ); - context.set( "Temp", 25 ); - context.set( "Rain Probability", 30 ); + context.set("Guests with children", true); + context.set("Season", "Fall"); + context.set("Number of guests", 4); + context.set("Temp", 25); + context.set("Rain Probability", 30); - final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context ); + final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context); assertThat(dmnResult.hasErrors()).isFalse(); - assertThat( dmnResult.getContext().get( "Where to eat" )).isEqualTo("Outside" ); - assertThat( dmnResult.getContext().get( "Dish" )).isEqualTo("Spareribs" ); - assertThat( dmnResult.getContext().get( "Drinks" )).asList().containsExactly( "Apero", "Ale", "Juice Boxes"); + assertThat(dmnResult.getContext().get("Where to eat")).isEqualTo("Outside"); + assertThat(dmnResult.getContext().get("Dish")).isEqualTo("Spareribs"); + assertThat(dmnResult.getContext().get("Drinks")).asList().containsExactly("Apero", "Ale", "Juice Boxes"); } @ParameterizedTest(name = "{0}") @MethodSource("params") void notificationsApproved2(VariantTestConf conf) { testConfig = conf; - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("NotificationsTest2.dmn", this.getClass() ); - final DMNModel dmnModel = runtime.getModel("https://github.com/kiegroup/kie-dmn", "building-structure-rules" ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("NotificationsTest2.dmn", this.getClass()); + final DMNModel dmnModel = runtime.getModel("https://github.com/kiegroup/kie-dmn", "building-structure-rules"); assertThat(dmnModel).isNotNull(); final DMNContext context = DMNFactory.newContext(); - context.set( "existingActivityApplicability", true ); - context.set( "Distance", new BigDecimal( 9999 ) ); - context.set( "willIncreaseTraffic", true ); + context.set("existingActivityApplicability", true); + context.set("Distance", new BigDecimal(9999)); + context.set("willIncreaseTraffic", true); - final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context ); + final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context); final DMNContext result = dmnResult.getContext(); - assertThat( result.get( "Notification Status" )).isEqualTo("Notification to Province Approved" ); - assertThat( result.get( "Permit Status" )).isEqualTo("Building Activity Province Permit Required" ); + assertThat(result.get("Notification Status")).isEqualTo("Notification to Province Approved"); + assertThat(result.get("Permit Status")).isEqualTo("Building Activity Province Permit Required"); } @ParameterizedTest(name = "{0}") @MethodSource("params") void boxedContext(VariantTestConf conf) { testConfig = conf; - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("BoxedContext.dmn", this.getClass() ); - final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/dmn/definitions/_0de36357-fec0-4b4e-b7f1-382d381e06e9", "Dessin 1" ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("BoxedContext.dmn", this.getClass()); + final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/dmn/definitions/_0de36357-fec0-4b4e-b7f1-382d381e06e9", "Dessin 1"); assertThat(dmnModel).isNotNull(); assertThat(dmnModel.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).isFalse(); final DMNContext context = DMNFactory.newContext(); - context.set( "a", 10 ); - context.set( "b", 5 ); + context.set("a", 10); + context.set("b", 5); - final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context ); + final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context); assertThat(dmnResult.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnResult.getMessages())).isFalse(); - assertThat( (Map) dmnResult.getContext().get( "Math" )).containsEntry("Sum", BigDecimal.valueOf(15)); - assertThat( (Map) dmnResult.getContext().get( "Math" )).containsEntry("Product", BigDecimal.valueOf(50)); + assertThat((Map) dmnResult.getContext().get("Math")).containsEntry("Sum", BigDecimal.valueOf(15)); + assertThat((Map) dmnResult.getContext().get("Math")).containsEntry("Product", BigDecimal.valueOf(50)); } @ParameterizedTest(name = "{0}") @MethodSource("params") void functionDefAndInvocation(VariantTestConf conf) { testConfig = conf; - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("FunctionDefinition.dmn", this.getClass() ); - final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/dmn/definitions/_0de36357-fec0-4b4e-b7f1-382d381e06e9", "Dessin 1" ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("FunctionDefinition.dmn", this.getClass()); + final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/dmn/definitions/_0de36357-fec0-4b4e-b7f1-382d381e06e9", "Dessin 1"); assertThat(dmnModel).isNotNull(); assertThat(dmnModel.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).isFalse(); final DMNContext context = DMNFactory.newContext(); - context.set( "a", 10 ); - context.set( "b", 5 ); + context.set("a", 10); + context.set("b", 5); - final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context ); + final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context); assertThat(dmnResult.hasErrors()).isFalse(); assertThat((Map) dmnResult.getContext().get("Math")).containsEntry("Sum", BigDecimal.valueOf(15)); } @@ -475,43 +476,43 @@ void functionDefAndInvocation(VariantTestConf conf) { @MethodSource("params") void builtInFunctionInvocation(VariantTestConf conf) { testConfig = conf; - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("BuiltInFunctionInvocation.dmn", this.getClass() ); - final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/definitions/_b77219ee-ec28-48e3-b240-8e0dbbabefeb", "built in function invocation" ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("BuiltInFunctionInvocation.dmn", this.getClass()); + final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/definitions/_b77219ee-ec28-48e3-b240-8e0dbbabefeb", "built in function invocation"); assertThat(dmnModel).isNotNull(); assertThat(dmnModel.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).isFalse(); final DMNContext context = DMNFactory.newContext(); - context.set( "a", 10 ); - context.set( "b", 5 ); - context.set( "x", "Hello, World!" ); + context.set("a", 10); + context.set("b", 5); + context.set("x", "Hello, World!"); - final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context ); + final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context); assertThat(dmnResult.hasErrors()).isFalse(); - assertThat( dmnResult.getContext().get( "calc min" )).isEqualTo(BigDecimal.valueOf( 5 ) ); - assertThat( dmnResult.getContext().get( "fixed params" )).isEqualTo("World!"); - assertThat( dmnResult.getContext().get( "out of order" )).isEqualTo(BigDecimal.valueOf( 5 ) ); + assertThat(dmnResult.getContext().get("calc min")).isEqualTo(BigDecimal.valueOf(5)); + assertThat(dmnResult.getContext().get("fixed params")).isEqualTo("World!"); + assertThat(dmnResult.getContext().get("out of order")).isEqualTo(BigDecimal.valueOf(5)); } @ParameterizedTest(name = "{0}") @MethodSource("params") void bkmNode(VariantTestConf conf) { testConfig = conf; - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("0009-invocation-arithmetic.dmn", getClass() ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("0009-invocation-arithmetic.dmn", getClass()); // runtime.addListener( DMNRuntimeUtil.createListener() ); - final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/definitions/_cb28c255-91cd-4c01-ac7b-1a9cb1ecdb11", "literal invocation1" ); + final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/definitions/_cb28c255-91cd-4c01-ac7b-1a9cb1ecdb11", "literal invocation1"); assertThat(dmnModel).isNotNull(); assertThat(dmnModel.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).isFalse(); final Map loan = new HashMap<>(); - loan.put( "amount", BigDecimal.valueOf( 600000 ) ); - loan.put( "rate", new BigDecimal( "0.0375" ) ); - loan.put( "term", BigDecimal.valueOf( 360 ) ); + loan.put("amount", BigDecimal.valueOf(600000)); + loan.put("rate", new BigDecimal("0.0375")); + loan.put("term", BigDecimal.valueOf(360)); final DMNContext context = DMNFactory.newContext(); - context.set( "fee", 100 ); - context.set( "Loan", loan ); + context.set("fee", 100); + context.set("Loan", loan); - final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context ); + final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context); assertThat(dmnResult.hasErrors()).isFalse(); assertThat( ((BigDecimal) dmnResult.getContext().get("MonthlyPayment")).setScale(8, BigDecimal.ROUND_DOWN)). @@ -522,10 +523,10 @@ void bkmNode(VariantTestConf conf) { @MethodSource("params") void itemDefCollection(VariantTestConf conf) { testConfig = conf; - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("0001-filter.dmn", getClass() ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("0001-filter.dmn", getClass()); // runtime.addListener( DMNRuntimeUtil.createListener() ); - final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/definitions/_f52ca843-504b-4c3b-a6bc-4d377bffef7a", "filter01" ); + final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/definitions/_f52ca843-504b-4c3b-a6bc-4d377bffef7a", "filter01"); assertThat(dmnModel).isNotNull(); assertThat(dmnModel.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).isFalse(); @@ -543,26 +544,26 @@ void itemDefCollection(VariantTestConf conf) { employees.add(e); } final DMNContext context = DMNFactory.newContext(); - context.set( "Employee", employees ); + context.set("Employee", employees); - final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context ); + final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context); assertThat(dmnResult.hasErrors()).isFalse(); - assertThat( dmnResult.getContext().get("filter01")).asList().containsExactly("Mary"); + assertThat(dmnResult.getContext().get("filter01")).asList().containsExactly("Mary"); } @ParameterizedTest(name = "{0}") @MethodSource("params") void list(VariantTestConf conf) { testConfig = conf; - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("list-expression.dmn", getClass() ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("list-expression.dmn", getClass()); // runtime.addListener( DMNRuntimeUtil.createListener() ); - final DMNModel dmnModel = runtime.getModel("https://github.com/kiegroup/kie-dmn", "list-expression" ); + final DMNModel dmnModel = runtime.getModel("https://github.com/kiegroup/kie-dmn", "list-expression"); assertThat(dmnModel).isNotNull(); assertThat(dmnModel.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).isFalse(); final DMNContext context = DMNFactory.newContext(); - final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context ); + final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context); assertThat(dmnResult.hasErrors()).isFalse(); assertThat(dmnResult.getContext().get("Name list")).asList().containsExactly("John", "Mary"); } @@ -571,134 +572,134 @@ void list(VariantTestConf conf) { @MethodSource("params") void relation(VariantTestConf conf) { testConfig = conf; - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("relation-expression.dmn", getClass() ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("relation-expression.dmn", getClass()); // runtime.addListener( DMNRuntimeUtil.createListener() ); - final DMNModel dmnModel = runtime.getModel("https://github.com/kiegroup/kie-dmn", "relation-expression" ); + final DMNModel dmnModel = runtime.getModel("https://github.com/kiegroup/kie-dmn", "relation-expression"); assertThat(dmnModel).isNotNull(); assertThat(dmnModel.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).isFalse(); final DMNContext context = DMNFactory.newContext(); - final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context ); + final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context); assertThat(dmnResult.hasErrors()).isFalse(); - assertThat(dmnResult.getContext().get( "Employee Relation")).isInstanceOf(List.class); + assertThat(dmnResult.getContext().get("Employee Relation")).isInstanceOf(List.class); - final List> employees = (List>) dmnResult.getContext().get("Employee Relation" ); - Map e = employees.get( 0 ); - assertThat( e.get( "Name" )).isEqualTo("John" ); - assertThat( e.get( "Dept" )).isEqualTo("Sales" ); - assertThat( e.get( "Salary" )).isEqualTo(BigDecimal.valueOf( 100000 ) ); + final List> employees = (List>) dmnResult.getContext().get("Employee Relation"); + Map e = employees.get(0); + assertThat(e.get("Name")).isEqualTo("John"); + assertThat(e.get("Dept")).isEqualTo("Sales"); + assertThat(e.get("Salary")).isEqualTo(BigDecimal.valueOf(100000)); - e = employees.get( 1 ); - assertThat( e.get( "Name" )).isEqualTo("Mary" ); - assertThat( e.get( "Dept" )).isEqualTo("Finances" ); - assertThat( e.get( "Salary" )).isEqualTo(BigDecimal.valueOf( 120000 ) ); + e = employees.get(1); + assertThat(e.get("Name")).isEqualTo("Mary"); + assertThat(e.get("Dept")).isEqualTo("Finances"); + assertThat(e.get("Salary")).isEqualTo(BigDecimal.valueOf(120000)); } @ParameterizedTest(name = "{0}") @MethodSource("params") void lendingExample(VariantTestConf conf) { testConfig = conf; - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("0004-lending.dmn", getClass() ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("0004-lending.dmn", getClass()); // runtime.addListener( DMNRuntimeUtil.createListener() ); - final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/definitions/_4e0f0b70-d31c-471c-bd52-5ca709ed362b", "Lending1" ); + final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/definitions/_4e0f0b70-d31c-471c-bd52-5ca709ed362b", "Lending1"); assertThat(dmnModel).isNotNull(); assertThat(dmnModel.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).isFalse(); final DMNContext context = DMNFactory.newContext(); final Map applicant = new HashMap<>(); final Map monthly = new HashMap<>(); - monthly.put( "Income", 6000 ); - monthly.put( "Expenses", 2000 ); - monthly.put( "Repayments", 0 ); - applicant.put( "Monthly", monthly ); - applicant.put( "Age", 35 ); - applicant.put( "ExistingCustomer", true ); - applicant.put( "MaritalStatus", "M" ); - applicant.put( "EmploymentStatus", "EMPLOYED" ); + monthly.put("Income", 6000); + monthly.put("Expenses", 2000); + monthly.put("Repayments", 0); + applicant.put("Monthly", monthly); + applicant.put("Age", 35); + applicant.put("ExistingCustomer", true); + applicant.put("MaritalStatus", "M"); + applicant.put("EmploymentStatus", "EMPLOYED"); final Map product = new HashMap<>(); - product.put( "ProductType", "STANDARD LOAN" ); - product.put( "Amount", 350000 ); - product.put( "Rate", new BigDecimal( "0.0395" ) ); - product.put( "Term", 360 ); + product.put("ProductType", "STANDARD LOAN"); + product.put("Amount", 350000); + product.put("Rate", new BigDecimal("0.0395")); + product.put("Term", 360); final Map bureau = new HashMap<>(); - bureau.put( "CreditScore", 649 ); - bureau.put( "Bankrupt", false ); - - context.set( "ApplicantData", applicant ); - context.set( "RequestedProduct", product ); - context.set( "BureauData", bureau ); - context.set( "SupportingDocuments", "yes" ); - final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context ); + bureau.put("CreditScore", 649); + bureau.put("Bankrupt", false); + + context.set("ApplicantData", applicant); + context.set("RequestedProduct", product); + context.set("BureauData", bureau); + context.set("SupportingDocuments", "yes"); + final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context); LOG.debug("{}", dmnResult); final DMNContext ctx = dmnResult.getContext(); - assertThat( ctx.get( "ApplicationRiskScore" )).isEqualTo(BigDecimal.valueOf( 130 ) ); - assertThat( ctx.get( "Pre-bureauRiskCategory" )).isEqualTo("LOW" ); - assertThat( ctx.get( "BureauCallType" )).isEqualTo("MINI" ); - assertThat( ctx.get( "Post-bureauRiskCategory" )).isEqualTo("LOW" ); - assertThat( ((BigDecimal)ctx.get( "RequiredMonthlyInstallment" )).setScale(5, BigDecimal.ROUND_DOWN )). - isEqualTo(new BigDecimal("1680.880325608555").setScale( 5, BigDecimal.ROUND_DOWN)); - assertThat( ctx.get( "Pre-bureauAffordability" )).isEqualTo(Boolean.TRUE); - assertThat( ctx.get( "Eligibility" )).isEqualTo("ELIGIBLE" ); - assertThat( ctx.get( "Strategy" )).isEqualTo("BUREAU" ); - assertThat( ctx.get( "Post-bureauAffordability" )).isEqualTo(Boolean.TRUE); - assertThat( ctx.get( "Routing" )).isEqualTo("ACCEPT" ); + assertThat(ctx.get("ApplicationRiskScore")).isEqualTo(BigDecimal.valueOf(130)); + assertThat(ctx.get("Pre-bureauRiskCategory")).isEqualTo("LOW"); + assertThat(ctx.get("BureauCallType")).isEqualTo("MINI"); + assertThat(ctx.get("Post-bureauRiskCategory")).isEqualTo("LOW"); + assertThat(((BigDecimal) ctx.get("RequiredMonthlyInstallment")).setScale(5, BigDecimal.ROUND_DOWN)). + isEqualTo(new BigDecimal("1680.880325608555").setScale(5, BigDecimal.ROUND_DOWN)); + assertThat(ctx.get("Pre-bureauAffordability")).isEqualTo(Boolean.TRUE); + assertThat(ctx.get("Eligibility")).isEqualTo("ELIGIBLE"); + assertThat(ctx.get("Strategy")).isEqualTo("BUREAU"); + assertThat(ctx.get("Post-bureauAffordability")).isEqualTo(Boolean.TRUE); + assertThat(ctx.get("Routing")).isEqualTo("ACCEPT"); } @ParameterizedTest(name = "{0}") @MethodSource("params") void dateAndTime(VariantTestConf conf) { testConfig = conf; - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("0007-date-time.dmn", getClass() ); - runtime.addListener( DMNRuntimeUtil.createListener() ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("0007-date-time.dmn", getClass()); + runtime.addListener(DMNRuntimeUtil.createListener()); - final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/definitions/_69430b3e-17b8-430d-b760-c505bf6469f9", "dateTime Table 58" ); + final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/definitions/_69430b3e-17b8-430d-b760-c505bf6469f9", "dateTime Table 58"); assertThat(dmnModel).isNotNull(); assertThat(dmnModel.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).isFalse(); final DMNContext context = DMNFactory.newContext(); - context.set( "dateString", "2015-12-24" ); - context.set( "timeString", "00:00:01-01:00" ); - context.set( "dateTimeString", "2016-12-24T23:59:00-05:00" ); - context.set( "Hours", 12 ); - context.set( "Minutes", 59 ); - context.set( "Seconds", new BigDecimal( "1.3" ) ); - context.set( "Timezone", "PT-1H" ); - context.set( "Year", 1999 ); - context.set( "Month", 11 ); - context.set( "Day", 22 ); - context.set( "oneHour", Duration.parse( "PT1H" ) ); // - context.set( "durationString", "P13DT2H14S" ); // - final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context ); + context.set("dateString", "2015-12-24"); + context.set("timeString", "00:00:01-01:00"); + context.set("dateTimeString", "2016-12-24T23:59:00-05:00"); + context.set("Hours", 12); + context.set("Minutes", 59); + context.set("Seconds", new BigDecimal("1.3")); + context.set("Timezone", "PT-1H"); + context.set("Year", 1999); + context.set("Month", 11); + context.set("Day", 22); + context.set("oneHour", Duration.parse("PT1H")); // + context.set("durationString", "P13DT2H14S"); // + final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context); final DMNContext ctx = dmnResult.getContext(); assertThat(dmnResult.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnResult.getMessages())).isFalse(); - assertThat( ctx.get("Date-Time")).isEqualTo(ZonedDateTime.of( 2016, 12, 24, 23, 59, 0, 0, ZoneOffset.ofHours( -5 ) ) ); - assertThat( ctx.get("Date")).isEqualTo( new HashMap( ) {{ - put( "fromString", LocalDate.of( 2015, 12, 24 ) ); - put( "fromDateTime", LocalDate.of( 2016, 12, 24 ) ); - put( "fromYearMonthDay", LocalDate.of( 1999, 11, 22 ) ); + assertThat(ctx.get("Date-Time")).isEqualTo(ZonedDateTime.of(2016, 12, 24, 23, 59, 0, 0, ZoneOffset.ofHours(-5))); + assertThat(ctx.get("Date")).isEqualTo(new HashMap() {{ + put("fromString", LocalDate.of(2015, 12, 24)); + put("fromDateTime", LocalDate.of(2016, 12, 24)); + put("fromYearMonthDay", LocalDate.of(1999, 11, 22)); }}); - assertThat( ctx.get("Time")).isEqualTo(OffsetTime.of(0, 0, 1, 0, ZoneOffset.ofHours(-1 ) ) ); - assertThat( ctx.get("Date-Time2")).isEqualTo(ZonedDateTime.of(2015, 12, 24, 0, 0, 1, 0, ZoneOffset.ofHours(-1 ) ) ); - assertThat( ctx.get("Time2")).isEqualTo(OffsetTime.of(0, 0, 1, 0, ZoneOffset.ofHours(-1 ) ) ); - assertThat( ctx.get("Time3")).isEqualTo(OffsetTime.of( 12, 59, 1, 300000000, ZoneOffset.ofHours( -1 ) )); - assertThat( ctx.get("dtDuration1")).isEqualTo(Duration.parse( "P13DT2H14S" ) ); - assertThat( ctx.get("dtDuration2")).isEqualTo(Duration.parse( "P367DT3H58M59S" ) ); - assertThat( ctx.get("hoursInDuration")).isEqualTo(new BigDecimal( "3" ) ); - assertThat( ctx.get("sumDurations")).isEqualTo(Duration.parse( "PT9125H59M13S" ) ); - assertThat( ctx.get("ymDuration2")).isEqualTo(ComparablePeriod.parse( "P1Y" ) ); - assertThat( ctx.get("cDay")).isEqualTo(BigDecimal.valueOf( 24 ) ); - assertThat( ctx.get("cYear")).isEqualTo(BigDecimal.valueOf( 2015 ) ); - assertThat( ctx.get("cMonth")).isEqualTo(BigDecimal.valueOf( 12 ) ); - assertThat( ctx.get("cHour")).isEqualTo(BigDecimal.valueOf( 0 ) ); - assertThat( ctx.get("cMinute")).isEqualTo(BigDecimal.valueOf( 0 ) ); - assertThat( ctx.get("cSecond")).isEqualTo(BigDecimal.valueOf( 1 ) ); - assertThat( ctx.get("cTimezone")).isEqualTo( "GMT-01:00"); - assertThat( ctx.get("years")).isEqualTo(BigDecimal.valueOf( 1 ) ); - assertThat( ctx.get("d1seconds")).isEqualTo(BigDecimal.valueOf( 14 ) ); + assertThat(ctx.get("Time")).isEqualTo(OffsetTime.of(0, 0, 1, 0, ZoneOffset.ofHours(-1))); + assertThat(ctx.get("Date-Time2")).isEqualTo(ZonedDateTime.of(2015, 12, 24, 0, 0, 1, 0, ZoneOffset.ofHours(-1))); + assertThat(ctx.get("Time2")).isEqualTo(OffsetTime.of(0, 0, 1, 0, ZoneOffset.ofHours(-1))); + assertThat(ctx.get("Time3")).isEqualTo(OffsetTime.of(12, 59, 1, 300000000, ZoneOffset.ofHours(-1))); + assertThat(ctx.get("dtDuration1")).isEqualTo(Duration.parse("P13DT2H14S")); + assertThat(ctx.get("dtDuration2")).isEqualTo(Duration.parse("P367DT3H58M59S")); + assertThat(ctx.get("hoursInDuration")).isEqualTo(new BigDecimal("3")); + assertThat(ctx.get("sumDurations")).isEqualTo(Duration.parse("PT9125H59M13S")); + assertThat(ctx.get("ymDuration2")).isEqualTo(ComparablePeriod.parse("P1Y")); + assertThat(ctx.get("cDay")).isEqualTo(BigDecimal.valueOf(24)); + assertThat(ctx.get("cYear")).isEqualTo(BigDecimal.valueOf(2015)); + assertThat(ctx.get("cMonth")).isEqualTo(BigDecimal.valueOf(12)); + assertThat(ctx.get("cHour")).isEqualTo(BigDecimal.valueOf(0)); + assertThat(ctx.get("cMinute")).isEqualTo(BigDecimal.valueOf(0)); + assertThat(ctx.get("cSecond")).isEqualTo(BigDecimal.valueOf(1)); + assertThat(ctx.get("cTimezone")).isEqualTo("GMT-01:00"); + assertThat(ctx.get("years")).isEqualTo(BigDecimal.valueOf(1)); + assertThat(ctx.get("d1seconds")).isEqualTo(BigDecimal.valueOf(14)); } @@ -706,87 +707,87 @@ void dateAndTime(VariantTestConf conf) { @MethodSource("params") void filtering(VariantTestConf conf) { testConfig = conf; - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("Person_filtering_by_age.dmn", getClass() ); - runtime.addListener( DMNRuntimeUtil.createListener() ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("Person_filtering_by_age.dmn", getClass()); + runtime.addListener(DMNRuntimeUtil.createListener()); - final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/definitions/_e215ed7a-701b-4c53-b8df-4b4d23d5fe32", "Person filtering by age" ); + final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/definitions/_e215ed7a-701b-4c53-b8df-4b4d23d5fe32", "Person filtering by age"); assertThat(dmnModel).isNotNull(); assertThat(dmnModel.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).isFalse(); final DMNContext context = DMNFactory.newContext(); - context.set( "Min Age", 50 ); - final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context ); - assertThat(((List)dmnResult.getContext().get("Filtering"))).as(DMNRuntimeUtil.formatMessages( dmnResult.getMessages())).hasSize(2); + context.set("Min Age", 50); + final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context); + assertThat(((List) dmnResult.getContext().get("Filtering"))).as(DMNRuntimeUtil.formatMessages(dmnResult.getMessages())).hasSize(2); } @ParameterizedTest(name = "{0}") @MethodSource("params") void nowFunction(VariantTestConf conf) { testConfig = conf; - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("today_function_test.dmn", getClass() ); - runtime.addListener( DMNRuntimeUtil.createListener() ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("today_function_test.dmn", getClass()); + runtime.addListener(DMNRuntimeUtil.createListener()); - final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/dmn/definitions/_4ad80959-5fd8-46b7-8c9a-ab2fa58cb5b4", "When is it" ); + final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/dmn/definitions/_4ad80959-5fd8-46b7-8c9a-ab2fa58cb5b4", "When is it"); assertThat(dmnModel).isNotNull(); assertThat(dmnModel.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).isFalse(); final DMNContext context = DMNFactory.newContext(); - context.set( "The date", LocalDate.of(2017, 1, 12 ) ); - final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context ); - assertThat(dmnResult.getContext().get("When is it")).as(DMNRuntimeUtil.formatMessages( dmnResult.getMessages())).isEqualTo( "It is in the past" ); + context.set("The date", LocalDate.of(2017, 1, 12)); + final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context); + assertThat(dmnResult.getContext().get("When is it")).as(DMNRuntimeUtil.formatMessages(dmnResult.getMessages())).isEqualTo("It is in the past"); } @ParameterizedTest(name = "{0}") @MethodSource("params") void timeFunction(VariantTestConf conf) { testConfig = conf; - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("TimeFromDate.dmn", getClass() ); - runtime.addListener( DMNRuntimeUtil.createListener() ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("TimeFromDate.dmn", getClass()); + runtime.addListener(DMNRuntimeUtil.createListener()); - final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/dmn/definitions/_ecf4ea54-2abc-4e2f-a101-4fe14e356a46", "Dessin 1" ); + final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/dmn/definitions/_ecf4ea54-2abc-4e2f-a101-4fe14e356a46", "Dessin 1"); assertThat(dmnModel).isNotNull(); assertThat(dmnModel.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).isFalse(); final DMNContext context = DMNFactory.newContext(); - context.set( "datetimestring", "2016-07-29T05:48:23" ); - final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context ); - assertThat(dmnResult.getContext().get("time")).as(DMNRuntimeUtil.formatMessages( dmnResult.getMessages() )).isEqualTo(LocalTime.of(5, 48, 23)); + context.set("datetimestring", "2016-07-29T05:48:23"); + final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context); + assertThat(dmnResult.getContext().get("time")).as(DMNRuntimeUtil.formatMessages(dmnResult.getMessages())).isEqualTo(LocalTime.of(5, 48, 23)); } @ParameterizedTest(name = "{0}") @MethodSource("params") void alternativeNSDecl(VariantTestConf conf) { testConfig = conf; - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("alternative_feel_ns_declaration.dmn", this.getClass() ); - final DMNModel dmnModel = runtime.getModel("https://github.com/kiegroup/kie-dmn", "0001-input-data-string" ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("alternative_feel_ns_declaration.dmn", this.getClass()); + final DMNModel dmnModel = runtime.getModel("https://github.com/kiegroup/kie-dmn", "0001-input-data-string"); assertThat(dmnModel).isNotNull(); final DMNContext context = DMNFactory.newContext(); - context.set( "Full Name", "John Doe" ); + context.set("Full Name", "John Doe"); - final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context ); + final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context); - assertThat( dmnResult.getDecisionResults()).hasSize(1); - assertThat( dmnResult.getDecisionResultByName( "Greeting Message" ).getResult()).isEqualTo("Hello John Doe" ); + assertThat(dmnResult.getDecisionResults()).hasSize(1); + assertThat(dmnResult.getDecisionResultByName("Greeting Message").getResult()).isEqualTo("Hello John Doe"); final DMNContext result = dmnResult.getContext(); - assertThat( result.get( "Greeting Message" )).isEqualTo("Hello John Doe" ); + assertThat(result.get("Greeting Message")).isEqualTo("Hello John Doe"); } @ParameterizedTest(name = "{0}") @MethodSource("params") void loanComparison(VariantTestConf conf) { testConfig = conf; - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("loanComparison.dmn", this.getClass() ); - final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/definitions/_3a1fd8f4-ea04-4453-aa30-ff14140e3441", "loanComparison" ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("loanComparison.dmn", this.getClass()); + final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/definitions/_3a1fd8f4-ea04-4453-aa30-ff14140e3441", "loanComparison"); assertThat(dmnModel).isNotNull(); assertThat(dmnModel.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).isFalse(); final DMNContext context = DMNFactory.newContext(); - context.set( "RequestedAmt", 500000 ); + context.set("RequestedAmt", 500000); - final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context ); + final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context); assertThat(dmnResult.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnResult.getMessages())).isFalse(); } @@ -794,25 +795,25 @@ void loanComparison(VariantTestConf conf) { @MethodSource("params") void getViableLoanProducts(VariantTestConf conf) { testConfig = conf; - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("Get_Viable_Loan_Products.dmn", this.getClass() ); - final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/definitions/_3e1a628d-36bc-45f1-8464-b201735e5ce0", "Get Viable Loan Products" ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("Get_Viable_Loan_Products.dmn", this.getClass()); + final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/definitions/_3e1a628d-36bc-45f1-8464-b201735e5ce0", "Get Viable Loan Products"); assertThat(dmnModel).isNotNull(); assertThat(dmnModel.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).isFalse(); - final Map requested = new HashMap<>( ); - requested.put( "PropertyZIP", "91001" ); - requested.put( "LoanAmt", 300000 ); - requested.put( "Objective", "Payment" ); - requested.put( "DownPct", new BigDecimal( "0.4" ) ); - requested.put( "MortgageType", "Fixed 20" ); + final Map requested = new HashMap<>(); + requested.put("PropertyZIP", "91001"); + requested.put("LoanAmt", 300000); + requested.put("Objective", "Payment"); + requested.put("DownPct", new BigDecimal("0.4")); + requested.put("MortgageType", "Fixed 20"); final DMNContext context = DMNFactory.newContext(); - context.set( "Requested", requested ); + context.set("Requested", requested); - final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context ); + final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context); assertThat(dmnResult.hasErrors()).isFalse(); final DMNContext result = dmnResult.getContext(); - assertThat( result.get( "isConforming" )).isEqualTo(Boolean.TRUE); + assertThat(result.get("isConforming")).isEqualTo(Boolean.TRUE); assertThat((Collection) result.get("LoanTypes")).hasSize(3); } @@ -820,22 +821,22 @@ void getViableLoanProducts(VariantTestConf conf) { @MethodSource("params") void yearsAndMonthsDuration(VariantTestConf conf) { testConfig = conf; - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("yearMonthDuration.dmn", this.getClass() ); - final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/dmn/definitions/_6eda1490-21ca-441e-8a26-ab3ca800e43c", "Drawing 1" ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("yearMonthDuration.dmn", this.getClass()); + final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/dmn/definitions/_6eda1490-21ca-441e-8a26-ab3ca800e43c", "Drawing 1"); assertThat(dmnModel).isNotNull(); assertThat(dmnModel.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).isFalse(); - final BuiltInType feelType = (BuiltInType) BuiltInType.determineTypeFromName("yearMonthDuration" ); + final BuiltInType feelType = (BuiltInType) BuiltInTypeUtils.determineTypeFromName("yearMonthDuration"); final ChronoPeriod period = (ChronoPeriod) feelType.fromString("P2Y1M"); final DMNContext context = runtime.newContext(); - context.set( "iDuration", period ); + context.set("iDuration", period); - final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context ); + final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context); assertThat(dmnResult.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnResult.getMessages())).isFalse(); final DMNContext result = dmnResult.getContext(); - assertThat( result.get( "How long" )).isEqualTo("Longer than a year" ); + assertThat(result.get("How long")).isEqualTo("Longer than a year"); } @ParameterizedTest(name = "{0}") @@ -850,26 +851,26 @@ void invalidVariableNames(VariantTestConf conf) { @MethodSource("params") void testNull(VariantTestConf conf) { testConfig = conf; - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("null_values.dmn", this.getClass() ); - final DMNModel dmnModel = runtime.getModel("https://github.com/kiegroup/kie-dmn", "Null values model" ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("null_values.dmn", this.getClass()); + final DMNModel dmnModel = runtime.getModel("https://github.com/kiegroup/kie-dmn", "Null values model"); assertThat(dmnModel).isNotNull(); assertThat(dmnModel.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).isFalse(); DMNContext context = runtime.newContext(); - context.set( "Null Input", null ); + context.set("Null Input", null); - DMNResult dmnResult = runtime.evaluateAll( dmnModel, context ); + DMNResult dmnResult = runtime.evaluateAll(dmnModel, context); assertThat(dmnResult.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnResult.getMessages())).isFalse(); DMNContext result = dmnResult.getContext(); - assertThat( result.get( "Null value" )).isEqualTo("Input is null" ); + assertThat(result.get("Null value")).isEqualTo("Input is null"); context = runtime.newContext(); - context.set( "Null Input", "foo" ); + context.set("Null Input", "foo"); - dmnResult = runtime.evaluateAll( dmnModel, context ); + dmnResult = runtime.evaluateAll(dmnModel, context); assertThat(dmnResult.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnResult.getMessages())).isFalse(); result = dmnResult.getContext(); - assertThat( result.get( "Null value" )).isEqualTo("Input is not null" ); + assertThat(result.get("Null value")).isEqualTo("Input is not null"); } @@ -887,102 +888,102 @@ void invalidModel(VariantTestConf conf) { @MethodSource("params") void nullOnNumber(VariantTestConf conf) { testConfig = conf; - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("Number_and_null_entry.dmn", this.getClass() ); - final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/definitions/_a293b9f9-c912-41ee-8147-eae59ba86ac5", "Number and null entry" ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("Number_and_null_entry.dmn", this.getClass()); + final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/definitions/_a293b9f9-c912-41ee-8147-eae59ba86ac5", "Number and null entry"); assertThat(dmnModel).isNotNull(); assertThat(dmnModel.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).isFalse(); DMNContext context = runtime.newContext(); - context.set( "num", null ); + context.set("num", null); - DMNResult dmnResult = runtime.evaluateAll( dmnModel, context ); + DMNResult dmnResult = runtime.evaluateAll(dmnModel, context); assertThat(dmnResult.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnResult.getMessages())).isFalse(); DMNContext result = dmnResult.getContext(); - assertThat( result.get( "Decision Logic 1" )).isEqualTo("Null" ); + assertThat(result.get("Decision Logic 1")).isEqualTo("Null"); context = runtime.newContext(); - context.set( "num", 4 ); + context.set("num", 4); - dmnResult = runtime.evaluateAll( dmnModel, context ); + dmnResult = runtime.evaluateAll(dmnModel, context); assertThat(dmnResult.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnResult.getMessages())).isFalse(); result = dmnResult.getContext(); - assertThat( result.get( "Decision Logic 1" )).isEqualTo("Positive number" ); + assertThat(result.get("Decision Logic 1")).isEqualTo("Positive number"); } @ParameterizedTest(name = "{0}") @MethodSource("params") void loanRecommendation2(VariantTestConf conf) { testConfig = conf; - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("Loan_Recommendation2.dmn", this.getClass() ); - final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/definitions/_35c7339b-b868-43da-8f06-eb481708c73c", "Loan Recommendation2" ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("Loan_Recommendation2.dmn", this.getClass()); + final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/definitions/_35c7339b-b868-43da-8f06-eb481708c73c", "Loan Recommendation2"); assertThat(dmnModel).isNotNull(); assertThat(dmnModel.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).isFalse(); - final Map loan = new HashMap<>( ); - loan.put( "Amount", 100000); - loan.put( "Rate", 2.39); - loan.put( "Term", 60); - - final Map borrower = new HashMap<>( ); - borrower.put( "Age", 39); - borrower.put( "EmploymentStatus", "Employed"); - borrower.put( "YearsAtCurrentEmployer", 10); - borrower.put( "TotalAnnualIncome", 150000); - borrower.put( "NonSalaryIncome", 0); - borrower.put( "MonthlyDebtPmtAmt", 2000); - borrower.put( "LiquidAssetsAmt", 50000); + final Map loan = new HashMap<>(); + loan.put("Amount", 100000); + loan.put("Rate", 2.39); + loan.put("Term", 60); + + final Map borrower = new HashMap<>(); + borrower.put("Age", 39); + borrower.put("EmploymentStatus", "Employed"); + borrower.put("YearsAtCurrentEmployer", 10); + borrower.put("TotalAnnualIncome", 150000); + borrower.put("NonSalaryIncome", 0); + borrower.put("MonthlyDebtPmtAmt", 2000); + borrower.put("LiquidAssetsAmt", 50000); final DMNContext context = runtime.newContext(); - context.set( "Credit Score", null ); - context.set( "Appraised Value", 200000 ); - context.set( "Loan", loan ); - context.set( "Borrower", borrower ); + context.set("Credit Score", null); + context.set("Appraised Value", 200000); + context.set("Loan", loan); + context.set("Borrower", borrower); - final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context ); + final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context); assertThat(dmnResult.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnResult.getMessages())).isFalse(); final DMNContext result = dmnResult.getContext(); - assertThat( result.get( "Loan Recommendation" )).isEqualTo("Decline" ); + assertThat(result.get("Loan Recommendation")).isEqualTo("Decline"); } @ParameterizedTest(name = "{0}") @MethodSource("params") void priorityTable(VariantTestConf conf) { testConfig = conf; - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("priority_table.dmn", this.getClass() ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("priority_table.dmn", this.getClass()); final DMNModel dmnModel = runtime.getModel( "http://www.trisotech.com/definitions/_ff54a44d-b8f5-48fc-b2b7-43db767e8a1c", - "not quite all or nothing P" ); + "not quite all or nothing P"); assertThat(dmnModel).isNotNull(); assertThat(dmnModel.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).isFalse(); - + final DMNContext context = runtime.newContext(); context.set("isAffordable", false); context.set("RiskCategory", "Medium"); - - final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context ); + + final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context); final DMNContext result = dmnResult.getContext(); - assertThat( result.get( "Approval Status" )).isEqualTo("Declined" ); + assertThat(result.get("Approval Status")).isEqualTo("Declined"); } @ParameterizedTest(name = "{0}") @MethodSource("params") void priorityTableContextRecursion(VariantTestConf conf) { testConfig = conf; - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("priority_table_context_recursion.dmn", this.getClass() ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("priority_table_context_recursion.dmn", this.getClass()); final DMNModel dmnModel = runtime.getModel( "http://www.trisotech.com/definitions/_ff54a44d-b8f5-48fc-b2b7-43db767e8a1c", - "not quite all or nothing P" ); + "not quite all or nothing P"); assertThat(dmnModel).isNotNull(); assertThat(dmnModel.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).isFalse(); - + final DMNContext context = runtime.newContext(); context.set("isAffordable", false); context.set("RiskCategory", "Medium"); - - final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context ); + + final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context); final DMNContext result = dmnResult.getContext(); - assertThat( result.get( "Approval Status" )).isEqualTo("Declined" ); + assertThat(result.get("Approval Status")).isEqualTo("Declined"); } @ParameterizedTest(name = "{0}") @@ -997,10 +998,10 @@ void priorityTableMissingOutputValues(VariantTestConf conf) { @MethodSource("params") void non_priority_table_missing_output_values(VariantTestConf conf) { testConfig = conf; - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("DTABLE_NON_PRIORITY_MISSING_OUTVALS.dmn", this.getClass() ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("DTABLE_NON_PRIORITY_MISSING_OUTVALS.dmn", this.getClass()); final DMNModel dmnModel = runtime.getModel( - "https://github.com/kiegroup/kie-dmn", - "DTABLE_NON_PRIORITY_MISSING_OUTVALS" ); + "https://github.com/kiegroup/kie-dmn", + "DTABLE_NON_PRIORITY_MISSING_OUTVALS"); assertThat(dmnModel).isNotNull(); assertThat(dmnModel.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).isFalse(); } @@ -1009,10 +1010,10 @@ void non_priority_table_missing_output_values(VariantTestConf conf) { @MethodSource("params") void priorityTableOneOutputValue(VariantTestConf conf) { testConfig = conf; - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("DTABLE_PRIORITY_ONE_OUTVAL.dmn", this.getClass() ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("DTABLE_PRIORITY_ONE_OUTVAL.dmn", this.getClass()); final DMNModel dmnModel = runtime.getModel( - "https://github.com/kiegroup/kie-dmn", - "DTABLE_PRIORITY_ONE_OUTVAL" ); + "https://github.com/kiegroup/kie-dmn", + "DTABLE_PRIORITY_ONE_OUTVAL"); assertThat(dmnModel).isNotNull(); assertThat(dmnModel.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).isFalse(); } @@ -1021,21 +1022,21 @@ void priorityTableOneOutputValue(VariantTestConf conf) { @MethodSource("params") void noPrefix(VariantTestConf conf) { testConfig = conf; - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("drools1502-noprefix.dmn", this.getClass() ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("drools1502-noprefix.dmn", this.getClass()); final DMNModel dmnModel = runtime.getModel( "https://www.drools.org/kie-dmn/definitions", - "definitions" ); + "definitions"); assertThat(dmnModel).isNotNull(); assertThat(dmnModel.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).isFalse(); - + final DMNContext context = runtime.newContext(); context.set("MyInput", "a"); - final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context ); - + final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context); + assertThat(dmnResult.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnResult.getMessages())).isFalse(); final DMNContext result = dmnResult.getContext(); - assertThat( result.get( "MyDecision" )).isEqualTo("Decision taken" ); + assertThat(result.get("MyDecision")).isEqualTo("Decision taken"); } @ParameterizedTest(name = "{0}") @@ -1049,7 +1050,7 @@ void wrongConstraintsInItemDefinition(VariantTestConf conf) { assertThat(messages.get(0).getMessageType()).isEqualTo(DMNMessageType.ERR_COMPILING_FEEL); assertThat(messages.get(1).getSourceId()).isEqualTo("_e794c655-4fdf-45d1-b7b7-d990df513f92"); assertThat(messages.get(1).getMessageType()).isEqualTo(DMNMessageType.ERR_COMPILING_FEEL); - + // The DecisionTable does not define typeRef for the single OutputClause, but neither the enclosing Decision define typeRef for its variable assertThat(messages.get(2).getSourceId()).isEqualTo("_31911de7-e184-411c-99d1-f33977971270"); assertThat(messages.get(2).getMessageType()).isEqualTo(DMNMessageType.MISSING_TYPE_REF); @@ -1060,21 +1061,21 @@ void wrongConstraintsInItemDefinition(VariantTestConf conf) { void resolutionOfVariableWithLeadingOrTrailingSpaces(VariantTestConf conf) { testConfig = conf; // DROOLS-1504 - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("variableLeadingTrailingSpaces.dmn", this.getClass() ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("variableLeadingTrailingSpaces.dmn", this.getClass()); final DMNModel dmnModel = runtime.getModel( "https://www.drools.org/kie-dmn/definitions", - "definitions" ); + "definitions"); assertThat(dmnModel).isNotNull(); assertThat(dmnModel.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).isFalse(); - + final DMNContext context = runtime.newContext(); final Map person = new HashMap<>(); person.put("Name", "John"); person.put("Surname", "Doe"); context.set("Input Person", person); - final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context ); - + final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context); + assertThat(dmnResult.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnResult.getMessages())).isFalse(); final DMNContext result = dmnResult.getContext(); assertThat(result.get("Further Decision")).isEqualTo("The person was greeted with: 'Ciao John Doe'"); @@ -1084,13 +1085,13 @@ void resolutionOfVariableWithLeadingOrTrailingSpaces(VariantTestConf conf) { @MethodSource("params") void outOfOrderItemsNPE(VariantTestConf conf) { testConfig = conf; - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("out-of-order-items.dmn", this.getClass() ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("out-of-order-items.dmn", this.getClass()); final DMNModel dmnModel = runtime.getModel( "https://github.com/kiegroup/kie-dmn", - "out-of-order" ); + "out-of-order"); assertThat(dmnModel).isNotNull(); - assertThat(dmnModel.getMessages().stream().anyMatch( m -> m.getMessageType().equals( DMNMessageType.FAILED_VALIDATOR ) )) - .as(DMNRuntimeUtil.formatMessages( dmnModel.getMessages() )).isFalse(); + assertThat(dmnModel.getMessages().stream().anyMatch(m -> m.getMessageType().equals(DMNMessageType.FAILED_VALIDATOR))) + .as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).isFalse(); } @ParameterizedTest(name = "{0}") @@ -1098,24 +1099,24 @@ void outOfOrderItemsNPE(VariantTestConf conf) { void itemDefDependencies(VariantTestConf conf) { testConfig = conf; // DROOLS-1505 - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("itemDef-dependency.dmn", this.getClass() ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("itemDef-dependency.dmn", this.getClass()); final DMNModel dmnModel = runtime.getModel( "http://www.trisotech.com/definitions/_2374ee6d-75ed-4e9d-95d3-a88c135e1c43", - "Drawing 1a" ); + "Drawing 1a"); assertThat(dmnModel).isNotNull(); assertThat(dmnModel.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).isFalse(); final DMNContext context = runtime.newContext(); final Map person = new HashMap<>(); - person.put( "Full Name", "John Doe" ); - person.put( "Address", "100 East Davie Street" ); - context.set( "Input Person", person ); + person.put("Full Name", "John Doe"); + person.put("Address", "100 East Davie Street"); + context.set("Input Person", person); - final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context ); + final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context); assertThat(dmnResult.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnResult.getMessages())).isFalse(); final DMNContext result = dmnResult.getContext(); - assertThat( result.get( "My Decision" )).isEqualTo("The person John Doe is located at 100 East Davie Street" ); + assertThat(result.get("My Decision")).isEqualTo("The person John Doe is located at 100 East Davie Street"); } @ParameterizedTest(name = "{0}") @@ -1123,14 +1124,14 @@ void itemDefDependencies(VariantTestConf conf) { void decisionResultTypeCheck(VariantTestConf conf) { testConfig = conf; // DROOLS-1513 - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("LoanRecommendationWrongOutputType.dmn", this.getClass() ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("LoanRecommendationWrongOutputType.dmn", this.getClass()); final DMNModel dmnModel = runtime.getModel( "http://www.trisotech.com/dmn/definitions/_591d49d0-26e1-4a1c-9f72-b65bec09964a", - "Loan Recommendation Multi-step" ); + "Loan Recommendation Multi-step"); assertThat(dmnModel).isNotNull(); - System.out.println(DMNRuntimeUtil.formatMessages( dmnModel.getMessages() )); + System.out.println(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())); assertThat(dmnModel.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).isFalse(); - + final DMNContext context = runtime.newContext(); final Map loan = new HashMap<>(); loan.put("Amount", 100); @@ -1140,9 +1141,9 @@ void decisionResultTypeCheck(VariantTestConf conf) { final DMNResult dmnResult = runtime.evaluateByName(dmnModel, context, "Loan Payment"); assertThat(dmnResult.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnResult.getMessages())).isTrue(); - assertThat( dmnResult.getMessages()).hasSize(1); - assertThat( dmnResult.getMessages().get( 0 ).getSourceId()).isEqualTo("_93062144-ebc7-4ef7-a156-c342aeffac49"); - assertThat( dmnResult.getMessages().get( 0 ).getMessageType()).isEqualTo(DMNMessageType.ERROR_EVAL_NODE ); + assertThat(dmnResult.getMessages()).hasSize(1); + assertThat(dmnResult.getMessages().get(0).getSourceId()).isEqualTo("_93062144-ebc7-4ef7-a156-c342aeffac49"); + assertThat(dmnResult.getMessages().get(0).getMessageType()).isEqualTo(DMNMessageType.ERROR_EVAL_NODE); } @ParameterizedTest(name = "{0}") @@ -1150,44 +1151,44 @@ void decisionResultTypeCheck(VariantTestConf conf) { void npe(VariantTestConf conf) { testConfig = conf; // DROOLS-1512 - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("NPE.dmn", this.getClass() ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("NPE.dmn", this.getClass()); final DMNModel dmnModel = runtime.getModel( "http://www.trisotech.com/dmn/definitions/_95b7ee22-1964-4be5-b7db-7db66692c707", - "Dessin 1" ); + "Dessin 1"); assertThat(dmnModel).isNotNull(); assertThat(dmnModel.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).isFalse(); final DMNContext context = runtime.newContext(); - final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context ); + final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context); assertThat(dmnResult.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnResult.getMessages())).isTrue(); - assertThat( dmnResult.getMessages().stream().anyMatch( m -> m.getMessageType().equals( DMNMessageType.REQ_NOT_FOUND ) )).isEqualTo(Boolean.TRUE); + assertThat(dmnResult.getMessages().stream().anyMatch(m -> m.getMessageType().equals(DMNMessageType.REQ_NOT_FOUND))).isEqualTo(Boolean.TRUE); } @ParameterizedTest(name = "{0}") @MethodSource("params") void unionofLetters(VariantTestConf conf) { testConfig = conf; - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("Union_of_letters.dmn", this.getClass() ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("Union_of_letters.dmn", this.getClass()); final DMNModel dmnModel = runtime.getModel( "http://www.trisotech.com/definitions/_76362694-41e8-400c-8dea-e5f033d4f405", - "Union of letters" ); + "Union of letters"); assertThat(dmnModel).isNotNull(); assertThat(dmnModel.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).isFalse(); final DMNContext ctx1 = runtime.newContext(); ctx1.set("A1", Arrays.asList("a", "b")); ctx1.set("A2", Arrays.asList("b", "c")); - final DMNResult dmnResult1 = runtime.evaluateAll(dmnModel, ctx1 ); + final DMNResult dmnResult1 = runtime.evaluateAll(dmnModel, ctx1); assertThat(dmnResult1.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnResult1.getMessages())).isFalse(); assertThat((List) dmnResult1.getContext().get("D1")).asList().contains("a", "b", "c"); - + final DMNContext ctx2 = runtime.newContext(); ctx2.set("A1", Arrays.asList("a", "b")); ctx2.set("A2", Arrays.asList("b", "x")); - final DMNResult dmnResult2 = runtime.evaluateAll(dmnModel, ctx2 ); + final DMNResult dmnResult2 = runtime.evaluateAll(dmnModel, ctx2); assertThat(dmnResult2.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnResult2.getMessages())).isTrue(); - assertThat( dmnResult2.getMessages().stream().anyMatch( m -> m.getMessageType().equals( DMNMessageType.ERROR_EVAL_NODE ) )).isTrue(); + assertThat(dmnResult2.getMessages().stream().anyMatch(m -> m.getMessageType().equals(DMNMessageType.ERROR_EVAL_NODE))).isTrue(); } @ParameterizedTest(name = "{0}") @@ -1213,32 +1214,32 @@ void unknownVariable2(VariantTestConf conf) { @MethodSource("params") void singleDecisionWithContext(VariantTestConf conf) { testConfig = conf; - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("SingleDecisionWithContext.dmn", this.getClass() ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("SingleDecisionWithContext.dmn", this.getClass()); final DMNModel dmnModel = runtime.getModel( "http://www.trisotech.com/definitions/_71af58db-e1df-4b0f-aee2-48e0e8d89672", - "SingleDecisionWithContext" ); + "SingleDecisionWithContext"); assertThat(dmnModel).isNotNull(); assertThat(dmnModel.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).isFalse(); - + final DMNContext emptyContext = runtime.newContext(); - final DMNResult dmnResult = runtime.evaluateAll(dmnModel, emptyContext ); - + final DMNResult dmnResult = runtime.evaluateAll(dmnModel, emptyContext); + assertThat(dmnResult.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnResult.getMessages())).isFalse(); final DMNContext result = dmnResult.getContext(); - assertThat( result.get( "MyDecision" )).isEqualTo("Hello John Doe" ); + assertThat(result.get("MyDecision")).isEqualTo("Hello John Doe"); } @ParameterizedTest(name = "{0}") @MethodSource("params") void ex61(VariantTestConf conf) { testConfig = conf; - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("Ex_6_1.dmn", this.getClass() ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("Ex_6_1.dmn", this.getClass()); final DMNModel dmnModel = runtime.getModel( "http://www.trisotech.com/definitions/_5f1269c8-1e6f-4748-9eca-26aa1b1278ef", - "Ex 6-1" ); + "Ex 6-1"); assertThat(dmnModel).isNotNull(); assertThat(dmnModel.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).isFalse(); - + final DMNContext ctx = runtime.newContext(); final Map t1 = new HashMap<>(); t1.put("city", "Los Angeles"); @@ -1253,68 +1254,68 @@ void ex61(VariantTestConf conf) { t2.put("losses", 0); t2.put("bonus points", 7); ctx.set("NBA Pacific", Arrays.asList(t1, t2)); - final DMNResult dmnResult = runtime.evaluateAll(dmnModel, ctx ); - + final DMNResult dmnResult = runtime.evaluateAll(dmnModel, ctx); + assertThat(dmnResult.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnResult.getMessages())).isFalse(); final DMNContext result = dmnResult.getContext(); - assertThat( result.get( "Number of distinct cities" )).isEqualTo(new BigDecimal(2) ); - assertThat( result.get( "Second place losses" )).isEqualTo(new BigDecimal(0) ); - assertThat( result.get( "Max wins" )).isEqualTo(new BigDecimal(1) ); - assertThat( result.get( "Mean wins" )).isEqualTo(new BigDecimal(0.5) ); - assertThat( (List) result.get( "Positions of Los Angeles teams" )).asList().contains(new BigDecimal(1)); - assertThat( result.get( "Number of teams" )).isEqualTo(new BigDecimal(2) ); - assertThat( result.get( "Sum of bonus points" )).isEqualTo(new BigDecimal(47) ); + assertThat(result.get("Number of distinct cities")).isEqualTo(new BigDecimal(2)); + assertThat(result.get("Second place losses")).isEqualTo(new BigDecimal(0)); + assertThat(result.get("Max wins")).isEqualTo(new BigDecimal(1)); + assertThat(result.get("Mean wins")).isEqualTo(new BigDecimal(0.5)); + assertThat((List) result.get("Positions of Los Angeles teams")).asList().contains(new BigDecimal(1)); + assertThat(result.get("Number of teams")).isEqualTo(new BigDecimal(2)); + assertThat(result.get("Sum of bonus points")).isEqualTo(new BigDecimal(47)); } @ParameterizedTest(name = "{0}") @MethodSource("params") void singletonlistFunctionCall(VariantTestConf conf) { testConfig = conf; - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("singletonlist_fuction_call.dmn", this.getClass() ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("singletonlist_fuction_call.dmn", this.getClass()); final DMNModel dmnModel = runtime.getModel( "http://www.trisotech.com/definitions/_0768879b-5ee1-410f-92f0-7732573b069d", - "expression function subst [a] with a" ); + "expression function subst [a] with a"); assertThat(dmnModel).isNotNull(); assertThat(dmnModel.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).isFalse(); - + final DMNContext ctx = runtime.newContext(); ctx.set("InputLineItem", prototype(entry("Line", "0015"), entry("Description", "additional Battery"))); - final DMNResult dmnResult = runtime.evaluateAll(dmnModel, ctx ); - + final DMNResult dmnResult = runtime.evaluateAll(dmnModel, ctx); + assertThat(dmnResult.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnResult.getMessages())).isFalse(); final DMNContext result = dmnResult.getContext(); - assertThat( result.get("The Battery")).isEqualTo( prototype(entry("Line", "0010"), entry("Description", "Battery"))); - assertThat( (List)result.get("Remove Battery")).asList().contains( prototype(entry("Line", "0020"), entry("Description", "Case")), - prototype(entry("Line", "0030"), entry("Description", "Power Supply")) - ); - assertThat( (List)result.get("Remove Battery")).asList().doesNotContain(prototype(entry("Line", "0010"), entry("Description", "Battery"))); - - assertThat( (List)result.get("Insert before Line 0020")).asList().contains(prototype(entry("Line", "0010"), entry("Description", "Battery")), - prototype(entry("Line", "0015"), entry("Description", "additional Battery")), - prototype(entry("Line", "0020"), entry("Description", "Case")), - prototype(entry("Line", "0030"), entry("Description", "Power Supply")) - ); + assertThat(result.get("The Battery")).isEqualTo(prototype(entry("Line", "0010"), entry("Description", "Battery"))); + assertThat((List) result.get("Remove Battery")).asList().contains(prototype(entry("Line", "0020"), entry("Description", "Case")), + prototype(entry("Line", "0030"), entry("Description", "Power Supply")) + ); + assertThat((List) result.get("Remove Battery")).asList().doesNotContain(prototype(entry("Line", "0010"), entry("Description", "Battery"))); + + assertThat((List) result.get("Insert before Line 0020")).asList().contains(prototype(entry("Line", "0010"), entry("Description", "Battery")), + prototype(entry("Line", "0015"), entry("Description", "additional Battery")), + prototype(entry("Line", "0020"), entry("Description", "Case")), + prototype(entry("Line", "0030"), entry("Description", "Power Supply")) + ); } @ParameterizedTest(name = "{0}") @MethodSource("params") void javaFunctionContext(VariantTestConf conf) { testConfig = conf; - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("java_function_context.dmn", this.getClass() ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("java_function_context.dmn", this.getClass()); final DMNModel dmnModel = runtime.getModel( "http://www.trisotech.com/dmn/definitions/_b42317c4-4f0c-474e-a0bf-2895b0b3c314", - "Dessin 1" ); + "Dessin 1"); assertThat(dmnModel).isNotNull(); assertThat(dmnModel.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).isFalse(); final DMNContext ctx = runtime.newContext(); - ctx.set( "Input", 3.14 ); - final DMNResult dmnResult = runtime.evaluateAll(dmnModel, ctx ); + ctx.set("Input", 3.14); + final DMNResult dmnResult = runtime.evaluateAll(dmnModel, ctx); assertThat(dmnResult.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnResult.getMessages())).isFalse(); final DMNContext result = dmnResult.getContext(); - assertThat( ((BigDecimal) result.get( "D1" )).setScale( 4, BigDecimal.ROUND_HALF_UP )).isEqualTo(new BigDecimal( "-1.0000" ) ); - assertThat( ((BigDecimal) result.get( "D2" )).setScale( 4, BigDecimal.ROUND_HALF_UP )).isEqualTo(new BigDecimal( "-1.0000" ) ); + assertThat(((BigDecimal) result.get("D1")).setScale(4, BigDecimal.ROUND_HALF_UP)).isEqualTo(new BigDecimal("-1.0000")); + assertThat(((BigDecimal) result.get("D2")).setScale(4, BigDecimal.ROUND_HALF_UP)).isEqualTo(new BigDecimal("-1.0000")); } @ParameterizedTest(name = "{0}") @@ -1335,36 +1336,36 @@ void javaFunctionContextWithErrors(VariantTestConf conf) { void count_csatrade_ratings(VariantTestConf conf) { testConfig = conf; // DROOLS-1563 - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("countCSATradeRatings.dmn", this.getClass() ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("countCSATradeRatings.dmn", this.getClass()); final DMNModel dmnModel = runtime.getModel( "http://www.trisotech.com/definitions/_1a7d184c-2e38-4462-ae28-15591ef6d534", - "countCSATradeRatings" ); + "countCSATradeRatings"); assertThat(dmnModel).isNotNull(); assertThat(dmnModel.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).isFalse(); - + final DMNContext ctx = runtime.newContext(); final List> ratings = new ArrayList<>(); - ratings.add( prototype(entry("Agency", "FITCH"), entry("Value", "val1")) ); - ratings.add( prototype(entry("Agency", "MOODY"), entry("Value", "val2")) ); + ratings.add(prototype(entry("Agency", "FITCH"), entry("Value", "val1"))); + ratings.add(prototype(entry("Agency", "MOODY"), entry("Value", "val2"))); ctx.set("CSA Trade Ratings", ratings); - final DMNResult dmnResult = runtime.evaluateAll(dmnModel, ctx ); - + final DMNResult dmnResult = runtime.evaluateAll(dmnModel, ctx); + assertThat(dmnResult.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnResult.getMessages())).isFalse(); final DMNContext result = dmnResult.getContext(); - assertThat( result.get("Trade Ratings")).isEqualTo(new BigDecimal(2) ); - - + assertThat(result.get("Trade Ratings")).isEqualTo(new BigDecimal(2)); + + final DMNContext ctx2 = runtime.newContext(); ctx2.set("CSA Trade Ratings", null); - final DMNResult dmnResult2 = runtime.evaluateAll(dmnModel, ctx2 ); + final DMNResult dmnResult2 = runtime.evaluateAll(dmnModel, ctx2); assertThat(dmnResult2.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnResult2.getMessages())).isTrue(); assertThat(dmnResult2.getMessages().stream().anyMatch(m -> m.getMessageType().equals(DMNMessageType.FEEL_EVALUATION_ERROR))).isTrue(); assertThat(dmnResult2.getDecisionResultByName("Trade Ratings").getEvaluationStatus()).isEqualTo(DecisionEvaluationStatus.FAILED); - - - final DMNResult dmnResult3 = runtime.evaluateAll(dmnModel, runtime.newContext() ); + + + final DMNResult dmnResult3 = runtime.evaluateAll(dmnModel, runtime.newContext()); assertThat(dmnResult3.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnResult3.getMessages())).isTrue(); - assertThat(dmnResult3.getMessages().stream().anyMatch( m -> m.getMessageType().equals( DMNMessageType.REQ_NOT_FOUND ))).isTrue(); + assertThat(dmnResult3.getMessages().stream().anyMatch(m -> m.getMessageType().equals(DMNMessageType.REQ_NOT_FOUND))).isTrue(); } @ParameterizedTest(name = "{0}") @@ -1372,25 +1373,25 @@ void count_csatrade_ratings(VariantTestConf conf) { void forLoopTypeCheck(VariantTestConf conf) { testConfig = conf; // DROOLS-1580 - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("PersonListHelloBKM.dmn", this.getClass() ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("PersonListHelloBKM.dmn", this.getClass()); final DMNModel dmnModel = runtime.getModel( "http://www.trisotech.com/definitions/_ec5a78c7-a317-4c39-8310-db59be60f1c8", - "PersonListHelloBKM" ); + "PersonListHelloBKM"); assertThat(dmnModel).isNotNull(); assertThat(dmnModel.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).isFalse(); - + final DMNContext context = runtime.newContext(); - - final Map p1 = prototype(entry("Full Name", "John Doe"), entry("Age", 33) ); - final Map p2 = prototype(entry("Full Name", "47"), entry("Age", 47) ); - + + final Map p1 = prototype(entry("Full Name", "John Doe"), entry("Age", 33)); + final Map p2 = prototype(entry("Full Name", "47"), entry("Age", 47)); + context.set("My Input Data", Arrays.asList(p1, p2)); - final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context ); + final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context); final DMNContext result = dmnResult.getContext(); assertThat(dmnResult.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnResult.getMessages())).isFalse(); - assertThat( (List)result.get("My Decision")).asList().contains( "The person named John Doe is 33 years old.", - "The person named 47 is 47 years old."); + assertThat((List) result.get("My Decision")).asList().contains("The person named John Doe is 33 years old.", + "The person named 47 is 47 years old."); } @ParameterizedTest(name = "{0}") @@ -1398,26 +1399,26 @@ void forLoopTypeCheck(VariantTestConf conf) { void typeInferenceForNestedContextAnonymousEntry(VariantTestConf conf) { testConfig = conf; // DROOLS-1585 - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("PersonListHelloBKM2.dmn", this.getClass() ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("PersonListHelloBKM2.dmn", this.getClass()); final DMNModel dmnModel = runtime.getModel( "http://www.trisotech.com/definitions/_7e41a76e-2df6-4899-bf81-ae098757a3b6", - "PersonListHelloBKM2" ); + "PersonListHelloBKM2"); assertThat(dmnModel).isNotNull(); assertThat(dmnModel.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).isFalse(); - + final DMNContext context = runtime.newContext(); - - final Map p1 = prototype(entry("Full Name", "John Doe"), entry("Age", 33) ); - final Map p2 = prototype(entry("Full Name", "47"), entry("Age", 47) ); - + + final Map p1 = prototype(entry("Full Name", "John Doe"), entry("Age", 33)); + final Map p2 = prototype(entry("Full Name", "47"), entry("Age", 47)); + context.set("My Input Data", Arrays.asList(p1, p2)); - final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context ); + final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context); final DMNContext result = dmnResult.getContext(); assertThat(dmnResult.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnResult.getMessages())).isFalse(); - assertThat( (List)result.get("My Decision")).asList().contains( prototype( entry("Full Name", "Prof. John Doe"), entry("Age", NumberEvalHelper.coerceNumber(33)) ), - prototype( entry("Full Name", "Prof. 47"), entry("Age", NumberEvalHelper.coerceNumber(47)) ) - ); + assertThat((List) result.get("My Decision")).asList().contains(prototype(entry("Full Name", "Prof. John Doe"), entry("Age", NumberEvalHelper.coerceNumber(33))), + prototype(entry("Full Name", "Prof. 47"), entry("Age", NumberEvalHelper.coerceNumber(47))) + ); } @ParameterizedTest(name = "{0}") @@ -1425,109 +1426,109 @@ void typeInferenceForNestedContextAnonymousEntry(VariantTestConf conf) { void sameEveryTypeCheck(VariantTestConf conf) { testConfig = conf; // DROOLS-1587 - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("same_every_type_check.dmn", this.getClass() ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("same_every_type_check.dmn", this.getClass()); final DMNModel dmnModel = runtime.getModel( "http://www.trisotech.com/definitions/_09a13244-114d-43fb-9e00-cda89a2000dd", - "same every type check" ); + "same every type check"); assertThat(dmnModel).isNotNull(); assertThat(dmnModel.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).isFalse(); - + final DMNContext emptyContext = runtime.newContext(); - final DMNResult dmnResult = runtime.evaluateAll(dmnModel, emptyContext ); + final DMNResult dmnResult = runtime.evaluateAll(dmnModel, emptyContext); final DMNContext result = dmnResult.getContext(); - + assertThat(dmnResult.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnResult.getMessages())).isFalse(); - assertThat( result.get("Some are even")).isEqualTo(Boolean.TRUE); - assertThat( result.get("Every are even")).isEqualTo(Boolean.FALSE); - assertThat( result.get("Some are positive")).isEqualTo(Boolean.TRUE); - assertThat( result.get("Every are positive")).isEqualTo(Boolean.TRUE); - assertThat( result.get("Some are negative")).isEqualTo(Boolean.FALSE); - assertThat( result.get("Every are negative")).isEqualTo(Boolean.FALSE); + assertThat(result.get("Some are even")).isEqualTo(Boolean.TRUE); + assertThat(result.get("Every are even")).isEqualTo(Boolean.FALSE); + assertThat(result.get("Some are positive")).isEqualTo(Boolean.TRUE); + assertThat(result.get("Every are positive")).isEqualTo(Boolean.TRUE); + assertThat(result.get("Some are negative")).isEqualTo(Boolean.FALSE); + assertThat(result.get("Every are negative")).isEqualTo(Boolean.FALSE); } @ParameterizedTest(name = "{0}") @MethodSource("params") void dateAllowedValues(VariantTestConf conf) { testConfig = conf; - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("date_allowed_values.dmn", this.getClass() ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("date_allowed_values.dmn", this.getClass()); final DMNModel dmnModel = runtime.getModel( "http://www.trisotech.com/definitions/_fbf002a3-615b-4f02-98e4-c28d4676225a", - "Error with constraints verification" ); + "Error with constraints verification"); assertThat(dmnModel).isNotNull(); assertThat(dmnModel.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).isFalse(); final DMNContext ctx = runtime.newContext(); - final Object duration = BuiltInType.DURATION.fromString("P20Y" ); - ctx.set( "yearsMonth", duration ); - final Object dateTime = BuiltInType.DATE_TIME.fromString("2017-05-16T17:58:00.000" ); - ctx.set( "dateTime", dateTime ); - final DMNResult dmnResult = runtime.evaluateAll(dmnModel, ctx ); + final Object duration = BuiltInType.DURATION.fromString("P20Y"); + ctx.set("yearsMonth", duration); + final Object dateTime = BuiltInType.DATE_TIME.fromString("2017-05-16T17:58:00.000"); + ctx.set("dateTime", dateTime); + final DMNResult dmnResult = runtime.evaluateAll(dmnModel, ctx); final DMNContext result = dmnResult.getContext(); assertThat(dmnResult.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnResult.getMessages())).isFalse(); - assertThat( (Map) result.get( "Decision Logic 1" )).containsEntry("years and months", duration); - assertThat( (Map) result.get( "Decision Logic 1" )).containsEntry("Date Time", dateTime); + assertThat((Map) result.get("Decision Logic 1")).containsEntry("years and months", duration); + assertThat((Map) result.get("Decision Logic 1")).containsEntry("Date Time", dateTime); } @ParameterizedTest(name = "{0}") @MethodSource("params") void artificialAttributes(VariantTestConf conf) { testConfig = conf; - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("0001-input-data-string-artificial-attributes.dmn", this.getClass() ); - final DMNModel dmnModel = runtime.getModel("https://github.com/kiegroup/drools", "0001-input-data-string" ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("0001-input-data-string-artificial-attributes.dmn", this.getClass()); + final DMNModel dmnModel = runtime.getModel("https://github.com/kiegroup/drools", "0001-input-data-string"); assertThat(dmnModel).isNotNull(); final DMNContext context = DMNFactory.newContext(); - context.set( "Full Name", "John Doe" ); + context.set("Full Name", "John Doe"); - final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context ); + final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context); - assertThat( dmnResult.getDecisionResults()).hasSize(1); - assertThat( dmnResult.getDecisionResultByName( "Greeting Message" ).getResult()).isEqualTo("Hello John Doe" ); + assertThat(dmnResult.getDecisionResults()).hasSize(1); + assertThat(dmnResult.getDecisionResultByName("Greeting Message").getResult()).isEqualTo("Hello John Doe"); final DMNContext result = dmnResult.getContext(); - assertThat( result.get( "Greeting Message" )).isEqualTo("Hello John Doe" ); + assertThat(result.get("Greeting Message")).isEqualTo("Hello John Doe"); } @ParameterizedTest(name = "{0}") @MethodSource("params") void invokeFunctionSuccess(VariantTestConf conf) { testConfig = conf; - final DMNRuntime runtime = DMNRuntimeUtil.createRuntimeWithAdditionalResources("Caller.dmn", this.getClass(), "Calling.dmn" ); - final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/definitions/_b0a696d6-3d57-4e97-b5d4-b44a63909d67", "Caller" ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntimeWithAdditionalResources("Caller.dmn", this.getClass(), "Calling.dmn"); + final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/definitions/_b0a696d6-3d57-4e97-b5d4-b44a63909d67", "Caller"); assertThat(dmnModel).isNotNull(); final DMNContext context = DMNFactory.newContext(); - context.set( "My Name", "John Doe" ); - context.set( "My Number", 3 ); - context.set( "Call ns", "http://www.trisotech.com/definitions/_88156d21-3acc-43b6-8b81-385caf0bb6ca" ); - context.set( "Call name", "Calling" ); - context.set( "Invoke decision", "Final Result" ); + context.set("My Name", "John Doe"); + context.set("My Number", 3); + context.set("Call ns", "http://www.trisotech.com/definitions/_88156d21-3acc-43b6-8b81-385caf0bb6ca"); + context.set("Call name", "Calling"); + context.set("Invoke decision", "Final Result"); - final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context ); + final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context); assertThat(dmnResult.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnResult.getMessages())).isFalse(); - + final DMNContext result = dmnResult.getContext(); - assertThat( result.get("Final decision")).isEqualTo("The final decision is: Hello, John Doe your number once double is equal to: 6"); + assertThat(result.get("Final decision")).isEqualTo("The final decision is: Hello, John Doe your number once double is equal to: 6"); } @ParameterizedTest(name = "{0}") @MethodSource("params") void invokeFunctionWrongNamespace(VariantTestConf conf) { testConfig = conf; - final DMNRuntime runtime = DMNRuntimeUtil.createRuntimeWithAdditionalResources("Caller.dmn", this.getClass(), "Calling.dmn" ); - final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/definitions/_b0a696d6-3d57-4e97-b5d4-b44a63909d67", "Caller" ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntimeWithAdditionalResources("Caller.dmn", this.getClass(), "Calling.dmn"); + final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/definitions/_b0a696d6-3d57-4e97-b5d4-b44a63909d67", "Caller"); assertThat(dmnModel).isNotNull(); final DMNContext wrongContext = DMNFactory.newContext(); - wrongContext.set( "My Name", "John Doe" ); - wrongContext.set( "My Number", 3 ); + wrongContext.set("My Name", "John Doe"); + wrongContext.set("My Number", 3); wrongContext.set("Call ns", "http://www.acme.com/a-wrong-namespace"); - wrongContext.set( "Call name", "Calling" ); - wrongContext.set( "Invoke decision", "Final Result" ); + wrongContext.set("Call name", "Calling"); + wrongContext.set("Invoke decision", "Final Result"); - final DMNResult dmnResult = runtime.evaluateAll(dmnModel, wrongContext ); + final DMNResult dmnResult = runtime.evaluateAll(dmnModel, wrongContext); assertThat(dmnResult.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnResult.getMessages())).isTrue(); // total of: 2. x1 error in calling external decision, and x1 error in making final decision as it depends on the former. assertThat(dmnResult.getMessages()).as(DMNRuntimeUtil.formatMessages(dmnResult.getMessages())).hasSize(2); @@ -1537,18 +1538,18 @@ void invokeFunctionWrongNamespace(VariantTestConf conf) { @MethodSource("params") void invokeFunctionWrongDecisionName(VariantTestConf conf) { testConfig = conf; - final DMNRuntime runtime = DMNRuntimeUtil.createRuntimeWithAdditionalResources("Caller.dmn", this.getClass(), "Calling.dmn" ); - final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/definitions/_b0a696d6-3d57-4e97-b5d4-b44a63909d67", "Caller" ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntimeWithAdditionalResources("Caller.dmn", this.getClass(), "Calling.dmn"); + final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/definitions/_b0a696d6-3d57-4e97-b5d4-b44a63909d67", "Caller"); assertThat(dmnModel).isNotNull(); final DMNContext wrongContext = DMNFactory.newContext(); - wrongContext.set( "My Name", "John Doe" ); - wrongContext.set( "My Number", 3 ); - wrongContext.set( "Call ns", "http://www.trisotech.com/definitions/_88156d21-3acc-43b6-8b81-385caf0bb6ca" ); - wrongContext.set( "Call name", "Calling" ); + wrongContext.set("My Name", "John Doe"); + wrongContext.set("My Number", 3); + wrongContext.set("Call ns", "http://www.trisotech.com/definitions/_88156d21-3acc-43b6-8b81-385caf0bb6ca"); + wrongContext.set("Call name", "Calling"); wrongContext.set("Invoke decision", ""); - final DMNResult dmnResult = runtime.evaluateAll(dmnModel, wrongContext ); + final DMNResult dmnResult = runtime.evaluateAll(dmnModel, wrongContext); assertThat(dmnResult.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnResult.getMessages())).isTrue(); // total of: 2. x1 error in calling external decision, and x1 error in making final decision as it depends on the former. assertThat(dmnResult.getMessages()).as(DMNRuntimeUtil.formatMessages(dmnResult.getMessages())).hasSize(2); @@ -1559,18 +1560,18 @@ void invokeFunctionWrongDecisionName(VariantTestConf conf) { void invokeFunctionCallerError(VariantTestConf conf) { testConfig = conf; - final DMNRuntime runtime = DMNRuntimeUtil.createRuntimeWithAdditionalResources("Caller.dmn", this.getClass(), "Calling.dmn" ); - final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/definitions/_b0a696d6-3d57-4e97-b5d4-b44a63909d67", "Caller" ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntimeWithAdditionalResources("Caller.dmn", this.getClass(), "Calling.dmn"); + final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/definitions/_b0a696d6-3d57-4e97-b5d4-b44a63909d67", "Caller"); assertThat(dmnModel).isNotNull(); final DMNContext wrongContext = DMNFactory.newContext(); - wrongContext.set( "My Name", "John Doe" ); + wrongContext.set("My Name", "John Doe"); wrongContext.set("My Number", ""); - wrongContext.set( "Call ns", "http://www.trisotech.com/definitions/_88156d21-3acc-43b6-8b81-385caf0bb6ca" ); - wrongContext.set( "Call name", "Calling" ); - wrongContext.set( "Invoke decision", "Final Result" ); + wrongContext.set("Call ns", "http://www.trisotech.com/definitions/_88156d21-3acc-43b6-8b81-385caf0bb6ca"); + wrongContext.set("Call name", "Calling"); + wrongContext.set("Invoke decision", "Final Result"); - final DMNResult dmnResult = runtime.evaluateAll(dmnModel, wrongContext ); + final DMNResult dmnResult = runtime.evaluateAll(dmnModel, wrongContext); assertThat(dmnResult.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnResult.getMessages())).isTrue(); // total of: 2. x1 error in calling external decision, and x1 error in making final decision as it depends on the former. // please notice it will print 4 lines in the log, 2x are the "external invocation" and then 2x are the one by the caller, checked herebelow: @@ -1581,14 +1582,14 @@ void invokeFunctionCallerError(VariantTestConf conf) { @MethodSource("params") void invalidFunction(VariantTestConf conf) { testConfig = conf; - final DMNRuntime runtime = DMNRuntimeUtil.createRuntimeWithAdditionalResources( "InvalidFunction.dmn", this.getClass() ); - final DMNModel model = runtime.getModel( "http://www.trisotech.com/definitions/_84453b71-5d23-479f-9481-5196d92bacae", "0003-iteration-augmented" ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntimeWithAdditionalResources("InvalidFunction.dmn", this.getClass()); + final DMNModel model = runtime.getModel("http://www.trisotech.com/definitions/_84453b71-5d23-479f-9481-5196d92bacae", "0003-iteration-augmented"); assertThat(model).isNotNull(); final DMNContext context = DMNFactory.newContext(); - context.set( "Loans", new HashMap<>() ); + context.set("Loans", new HashMap<>()); final DMNResult result = runtime.evaluateAll(model, context); final List decisionResults = result.getDecisionResults(); - FEELStringMarshaller.INSTANCE.marshall( Arrays.asList(decisionResults.get(0).getResult(), decisionResults.get(1).getResult()) ); + FEELStringMarshaller.INSTANCE.marshall(Arrays.asList(decisionResults.get(0).getResult(), decisionResults.get(1).getResult())); } private Definitions buildSimplifiedDefinitions(final String namespace, final String... decisions) { @@ -1609,8 +1610,8 @@ private Definitions buildSimplifiedDefinitions(final String namespace, final Str private DecisionNodeImpl buildSimplifiedDecisionNode(final Definitions def, final String name) { DecisionNodeImpl toReturn = new DecisionNodeImpl(def.getDrgElement().stream().filter(drg -> drg.getName().equals(name)).filter(Decision.class::isInstance) - .map(Decision.class::cast) - .findFirst().get()); + .map(Decision.class::cast) + .findFirst().get()); toReturn.setEvaluator((eventManager, result) -> new EvaluatorResultImpl(name, EvaluatorResult.ResultType.SUCCESS)); toReturn.setResultType(SimpleTypeImpl.UNKNOWN_DMNTYPE("")); return toReturn; @@ -1861,7 +1862,7 @@ void drools2201(VariantTestConf conf) { // do NOT use the DMNRuntimeUtil as that enables typeSafe check override for runtime. final KieServices ks = KieServices.Factory.get(); final KieContainer kieContainer = KieHelper.getKieContainer(ks.newReleaseId("org.kie", "dmn-test-" + UUID.randomUUID(), "1.0"), - ks.getResources().newClassPathResource("typecheck_in_context_result.dmn", this.getClass())); + ks.getResources().newClassPathResource("typecheck_in_context_result.dmn", this.getClass())); final DMNRuntime runtime = kieContainer.newKieSession().getKieRuntime(DMNRuntime.class); final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/definitions/_42bf043d-df86-48bd-9045-dfc08aa8ba0d", "typecheck in context result"); @@ -1886,7 +1887,7 @@ void drools2201b(VariantTestConf conf) { // do NOT use the DMNRuntimeUtil as that enables typeSafe check override for runtime. final KieServices ks = KieServices.Factory.get(); final KieContainer kieContainer = KieHelper.getKieContainer(ks.newReleaseId("org.kie", "dmn-test-" + UUID.randomUUID(), "1.0"), - ks.getResources().newClassPathResource("typecheck_in_DT.dmn", this.getClass())); + ks.getResources().newClassPathResource("typecheck_in_DT.dmn", this.getClass())); final DMNRuntime runtime = kieContainer.newKieSession().getKieRuntime(DMNRuntime.class); final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/definitions/_99ccd4df-41ac-43c3-a563-d58f43149829", "typecheck in DT"); @@ -1907,7 +1908,7 @@ public static class DROOLS2286 { private String name; private String surname; - DROOLS2286(final String name, final String surname){ + DROOLS2286(final String name, final String surname) { this.name = name; this.surname = surname; } @@ -2040,8 +2041,8 @@ void listOfVowels(VariantTestConf conf) { final DMNResult dmnResult = runtime.evaluateAll(dmnModel, emptyContext); assertThat(dmnResult.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnResult.getMessages())).isTrue(); assertThat(dmnResult.getMessages().stream() - .filter(m -> m.getMessageType() == DMNMessageType.ERROR_EVAL_NODE) - .anyMatch(m -> m.getSourceId().equals("_b2205027-d06c-41b5-8419-e14b501e14a6"))).isTrue(); + .filter(m -> m.getMessageType() == DMNMessageType.ERROR_EVAL_NODE) + .anyMatch(m -> m.getSourceId().equals("_b2205027-d06c-41b5-8419-e14b501e14a6"))).isTrue(); final DMNContext result = dmnResult.getContext(); assertThat(result.get("Decide Vowel a")).isEqualTo("a"); @@ -2131,9 +2132,9 @@ void relationwithemptycell(VariantTestConf conf) { final DMNContext result = dmnResult.getContext(); assertThat(result.get("Decision A")).asList().containsExactly(prototype(entry("name", null), entry("age", null)), - prototype(entry("name", "John"), entry("age", new BigDecimal(1))), - prototype(entry("name", null), entry("age", null)), - prototype(entry("name", "Matteo"), entry("age", null))); + prototype(entry("name", "John"), entry("age", new BigDecimal(1))), + prototype(entry("name", null), entry("age", null)), + prototype(entry("name", "Matteo"), entry("age", null))); } @ParameterizedTest(name = "{0}") @@ -2170,12 +2171,12 @@ void usingReusableKeywordAsPartOfBKMName(VariantTestConf conf) { @MethodSource("params") void productFunction(VariantTestConf conf) { testConfig = conf; - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("product.dmn", this.getClass() ); - final DMNModel model = runtime.getModel("http://www.trisotech.com/dmn/definitions/_40fdbc2c-a631-4ba4-8435-17571b5d1942", "Drawing 1" ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("product.dmn", this.getClass()); + final DMNModel model = runtime.getModel("http://www.trisotech.com/dmn/definitions/_40fdbc2c-a631-4ba4-8435-17571b5d1942", "Drawing 1"); assertThat(model).isNotNull(); assertThat(model.hasErrors()).as(DMNRuntimeUtil.formatMessages(model.getMessages())).isFalse(); final DMNContext context = DMNFactory.newContext(); - context.set("product", new HashMap(){{ + context.set("product", new HashMap() {{ put("name", "Product1"); put("type", 1); }}); @@ -2221,10 +2222,10 @@ void notWithPredicates20180601b(VariantTestConf conf) { final DMNContext context = DMNFactory.newContext(); context.set("TheBook", Arrays.asList(prototype(entry("Title", "55"), entry("Price", new BigDecimal(5)), entry("Quantity", new BigDecimal(5))), - prototype(entry("Title", "510"), entry("Price", new BigDecimal(5)), entry("Quantity", new BigDecimal(10))), - prototype(entry("Title", "810"), entry("Price", new BigDecimal(8)), entry("Quantity", new BigDecimal(10))), - prototype(entry("Title", "85"), entry("Price", new BigDecimal(8)), entry("Quantity", new BigDecimal(5))), - prototype(entry("Title", "66"), entry("Price", new BigDecimal(6)), entry("Quantity", new BigDecimal(6))))); + prototype(entry("Title", "510"), entry("Price", new BigDecimal(5)), entry("Quantity", new BigDecimal(10))), + prototype(entry("Title", "810"), entry("Price", new BigDecimal(8)), entry("Quantity", new BigDecimal(10))), + prototype(entry("Title", "85"), entry("Price", new BigDecimal(8)), entry("Quantity", new BigDecimal(5))), + prototype(entry("Title", "66"), entry("Price", new BigDecimal(6)), entry("Quantity", new BigDecimal(6))))); final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context); assertThat(dmnResult.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnResult.getMessages())).isFalse(); @@ -2262,8 +2263,8 @@ void notWithPredicates20180601b(VariantTestConf conf) { @MethodSource("params") void modelById(VariantTestConf conf) { testConfig = conf; - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("simple-item-def.dmn", this.getClass() ); - final DMNModel dmnModel = runtime.getModelById("https://github.com/kiegroup/kie-dmn/itemdef", "_simple-item-def" ); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime("simple-item-def.dmn", this.getClass()); + final DMNModel dmnModel = runtime.getModelById("https://github.com/kiegroup/kie-dmn/itemdef", "_simple-item-def"); assertThat(dmnModel).isNotNull(); assertThat(dmnModel.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).isFalse(); @@ -2411,15 +2412,15 @@ void decisionTableInputClauseImportingItemDefinition(VariantTestConf conf) { testConfig = conf; // DROOLS-2927 DMN DecisionTable inputClause importing ItemDefinition throws NPE at compilation final DMNRuntime runtime = DMNRuntimeUtil.createRuntimeWithAdditionalResources("imports/Imported_Model.dmn", - this.getClass(), - "imports/Importing_Person_DT_with_Person.dmn"); + this.getClass(), + "imports/Importing_Person_DT_with_Person.dmn"); final DMNModel dmnModel = runtime.getModel("http://www.trisotech.com/dmn/definitions/_3d586cb1-3ed0-4bc4-a1a7-070b70ece398", "Importing Person DT with Person"); assertThat(dmnModel).isNotNull(); assertThat(dmnModel.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).isFalse(); final DMNContext context = DMNFactory.newContext(); context.set("A Person here", mapOf(entry("age", new BigDecimal(17)), - entry("name", "John"))); + entry("name", "John"))); final DMNResult dmnResult = runtime.evaluateAll(dmnModel, context); LOG.debug("{}", dmnResult); From fe19990fc05b24d12edf53428589e0b02b921b55 Mon Sep 17 00:00:00 2001 From: bncriju Date: Mon, 3 Mar 2025 18:55:06 +0530 Subject: [PATCH 10/20] resolved merge conflicts --- .../org/kie/dmn/feel/lang/ast/RangeNode.java | 49 ++++++++++--------- 1 file changed, 27 insertions(+), 22 deletions(-) diff --git a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/RangeNode.java b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/RangeNode.java index c0608ec1cbc..71ef7ca5223 100644 --- a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/RangeNode.java +++ b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/RangeNode.java @@ -29,6 +29,7 @@ import org.kie.dmn.feel.runtime.Range; import org.kie.dmn.feel.runtime.impl.RangeImpl; import org.kie.dmn.feel.runtime.impl.UndefinedValueComparable; +import org.kie.dmn.feel.util.BuiltInTypeUtils; import org.kie.dmn.feel.util.Msg; public class RangeNode @@ -36,17 +37,21 @@ public class RangeNode public enum IntervalBoundary { OPEN, CLOSED; + public static IntervalBoundary low(String input) { switch (input) { - case "[": return CLOSED; + case "[": + return CLOSED; case "]": default: - return OPEN; + return OPEN; } } + public static IntervalBoundary high(String input) { switch (input) { - case "]": return CLOSED; + case "]": + return CLOSED; case "[": default: return OPEN; @@ -56,11 +61,11 @@ public static IntervalBoundary high(String input) { private IntervalBoundary lowerBound; private IntervalBoundary upperBound; - private BaseNode start; - private BaseNode end; + private BaseNode start; + private BaseNode end; public RangeNode(ParserRuleContext ctx, IntervalBoundary lowerBound, BaseNode start, BaseNode end, IntervalBoundary upperBound) { - super( ctx ); + super(ctx); this.lowerBound = lowerBound; this.upperBound = upperBound; this.start = start; @@ -109,30 +114,30 @@ public void setEnd(BaseNode end) { @Override public Range evaluate(EvaluationContext ctx) { - Object s = start.evaluate( ctx ); - Object e = end.evaluate( ctx ); + Object s = start.evaluate(ctx); + Object e = end.evaluate(ctx); if (s == null || e == null) { return null; } - - Type sType = BuiltInType.determineTypeFromInstance(s); - Type eType = BuiltInType.determineTypeFromInstance(e); + + Type sType = BuiltInTypeUtils.determineTypeFromInstance(s); + Type eType = BuiltInTypeUtils.determineTypeFromInstance(e); boolean withUndefined = s instanceof UndefinedValueComparable || e instanceof UndefinedValueComparable; if (s != null && e != null && !withUndefined && sType != eType && !s.getClass().isAssignableFrom(e.getClass())) { - ctx.notifyEvt( astEvent(Severity.ERROR, Msg.createMessage(Msg.X_TYPE_INCOMPATIBLE_WITH_Y_TYPE, "Start", "End"))); + ctx.notifyEvt(astEvent(Severity.ERROR, Msg.createMessage(Msg.X_TYPE_INCOMPATIBLE_WITH_Y_TYPE, "Start", "End"))); return null; } - Comparable start = s instanceof UndefinedValueComparable ? (Comparable) s : convertToComparable(ctx, s ); - Comparable end = e instanceof UndefinedValueComparable ? (Comparable) e : convertToComparable( ctx, e ); + Comparable start = s instanceof UndefinedValueComparable ? (Comparable) s : convertToComparable(ctx, s); + Comparable end = e instanceof UndefinedValueComparable ? (Comparable) e : convertToComparable(ctx, e); return isDescendingRange(start, end) ? null : - new RangeImpl( lowerBound==IntervalBoundary.OPEN ? Range.RangeBoundary.OPEN : Range.RangeBoundary.CLOSED, - start, - end, - upperBound==IntervalBoundary.OPEN ? Range.RangeBoundary.OPEN : Range.RangeBoundary.CLOSED ); + new RangeImpl(lowerBound == IntervalBoundary.OPEN ? Range.RangeBoundary.OPEN : Range.RangeBoundary.CLOSED, + start, + end, + upperBound == IntervalBoundary.OPEN ? Range.RangeBoundary.OPEN : Range.RangeBoundary.CLOSED); } static boolean isDescendingRange(Comparable start, Comparable end) { @@ -145,11 +150,11 @@ private Comparable convertToComparable(EvaluationContext ctx, Object s) { start = null; } else if (s instanceof Comparable) { start = (Comparable) s; - } else if( s instanceof Period ) { + } else if (s instanceof Period) { // period has special semantics - start = new ComparablePeriod( (Period) s ); + start = new ComparablePeriod((Period) s); } else { - ctx.notifyEvt( astEvent(Severity.ERROR, Msg.createMessage(Msg.INCOMPATIBLE_TYPE_FOR_RANGE, s.getClass().getSimpleName() ))); + ctx.notifyEvt(astEvent(Severity.ERROR, Msg.createMessage(Msg.INCOMPATIBLE_TYPE_FOR_RANGE, s.getClass().getSimpleName()))); start = null; } return start; @@ -162,7 +167,7 @@ public Type getResultType() { @Override public ASTNode[] getChildrenNode() { - return new ASTNode[] { start, end }; + return new ASTNode[]{start, end}; } @Override From 93e22ab94629a3c14aa5a698bbde8347939868f7 Mon Sep 17 00:00:00 2001 From: bncriju Date: Mon, 3 Mar 2025 19:05:25 +0530 Subject: [PATCH 11/20] reverting pom changes --- kie-dmn/kie-dmn-core/pom.xml | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/kie-dmn/kie-dmn-core/pom.xml b/kie-dmn/kie-dmn-core/pom.xml index d7bf1df6200..977df690c4c 100644 --- a/kie-dmn/kie-dmn-core/pom.xml +++ b/kie-dmn/kie-dmn-core/pom.xml @@ -276,13 +276,9 @@ src/test/filtered-resources true - - ${project.build.directory}/generated-resources - false - - + org.apache.maven.plugins maven-dependency-plugin @@ -303,8 +299,8 @@ tests jar true - ${project.build.directory}/generated-resources - valid_models/**/*.dmn + ${project.build.directory}/test-classes + **/*.dmn From bc6e3749f09d8587188bd7beb38f5c404b1c0c29 Mon Sep 17 00:00:00 2001 From: Gabriele-Cardosi Date: Mon, 3 Mar 2025 17:53:27 +0100 Subject: [PATCH 12/20] [incubator-kie-issues#1752] Improve parameters check on BaseFEELFunction --- .../main/java/org/kie/dmn/feel/lang/Type.java | 2 +- .../kie/dmn/feel/lang/types/BuiltInType.java | 6 +- .../kie/dmn/feel/runtime/FEELFunction.java | 2 +- .../runtime/functions/BaseFEELFunction.java | 17 ++++-- .../functions/BaseFEELFunctionHelper.java | 26 +------- .../kie/dmn/feel/util/BuiltInTypeUtils.java | 40 +++++-------- .../dmn/feel/lang/types/GenFnTypeTest.java | 4 -- .../functions/BaseFEELFunctionTest.java | 60 +++++++++++-------- 8 files changed, 69 insertions(+), 88 deletions(-) diff --git a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/Type.java b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/Type.java index 3a8343e6442..a80b279f53e 100644 --- a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/Type.java +++ b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/Type.java @@ -1,4 +1,4 @@ -/** +/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information diff --git a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/types/BuiltInType.java b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/types/BuiltInType.java index 5a226dc21e3..00f6e476ed8 100644 --- a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/types/BuiltInType.java +++ b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/types/BuiltInType.java @@ -93,10 +93,8 @@ public boolean isInstanceOf(Object o) { @Override public boolean isAssignableValue(Object value) { - if (value == null) { - return true; // a null-value can be assigned to any type. - } - return BuiltInTypeUtils.isInstanceOf(value, this); + // a null-value can be assigned to any type. + return value == null || isInstanceOf(value); } @Override diff --git a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/FEELFunction.java b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/FEELFunction.java index a43fffc87ec..9cb174d2acf 100644 --- a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/FEELFunction.java +++ b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/FEELFunction.java @@ -1,4 +1,4 @@ -/** +/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information diff --git a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/functions/BaseFEELFunction.java b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/functions/BaseFEELFunction.java index cf3b6305b05..fc2e7017759 100644 --- a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/functions/BaseFEELFunction.java +++ b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/functions/BaseFEELFunction.java @@ -23,6 +23,7 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; +import java.util.Set; import java.util.function.Function; import java.util.function.Supplier; import java.util.stream.Collectors; @@ -201,15 +202,21 @@ protected Method getCandidateMethod(Type[] inputTypes, Type outputType) { if (method.getParameterCount() != inputTypes.length) { continue; } - + if (!BuiltInTypeUtils.determineTypeFromInstance(this.defaultValue()).equals(outputType)) { + continue; + } Class[] methodParameterTypes = method.getParameterTypes(); - for (Class methodParameterType : methodParameterTypes) { - if (!BuiltInTypeUtils.determineTypeFromClass(methodParameterType).getClass().equals(methodParameterType)) { + boolean found = true; + for (int i = 0; i < methodParameterTypes.length; i++) { + Class methodParameterType = methodParameterTypes[i]; + Type inputType = inputTypes[i]; + Set expectedTypes = BuiltInTypeUtils.determineTypesFromClass(methodParameterType); + if (!expectedTypes.contains(inputType)) { + found = false; break; } } - - if (method.getGenericReturnType().equals(outputType)) { + if (found) { toReturn = method; break; } diff --git a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/functions/BaseFEELFunctionHelper.java b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/functions/BaseFEELFunctionHelper.java index 4a0d5787e92..10cbdbaf61e 100644 --- a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/functions/BaseFEELFunctionHelper.java +++ b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/functions/BaseFEELFunctionHelper.java @@ -1,4 +1,4 @@ -/** +/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information @@ -27,7 +27,6 @@ import java.util.Optional; import org.kie.dmn.feel.lang.EvaluationContext; -import org.kie.dmn.feel.lang.Type; import org.kie.dmn.feel.lang.impl.NamedParameter; import org.kie.dmn.feel.util.NumberEvalHelper; import org.slf4j.Logger; @@ -63,29 +62,6 @@ static Object[] getAdjustedParametersForMethod(EvaluationContext ctx, Object[] p return toReturn; } - static Object[] getAdjustedParametersForMethod(EvaluationContext ctx, Type[] types, boolean isNamedParams, - Method m) { - logger.trace("getAdjustedParametersForMethod {} {} {} {}", ctx, types, isNamedParams, m); - Object[] toReturn = addCtxParamIfRequired(ctx, types, isNamedParams, m); - Class[] parameterTypes = m.getParameterTypes(); - if (isNamedParams) { - // This is inherently frail because it expects that, if, the first parameter is NamedParameter and the - // function is a CustomFunction, then all parameters are NamedParameter - NamedParameter[] namedParams = - Arrays.stream(toReturn).map(NamedParameter.class::cast).toArray(NamedParameter[]::new); - toReturn = BaseFEELFunctionHelper.calculateActualParams(m, namedParams); - if (toReturn == null) { - // incompatible method - return null; - } - } else if (toReturn.length > 0) { - // if named parameters, then it has been adjusted already in the calculateActualParams method, - // otherwise adjust here - toReturn = adjustForVariableParameters(toReturn, parameterTypes); - } - toReturn = adjustByCoercion(parameterTypes, toReturn); - return toReturn; - } /** * This method check if the input parameters, set inside the given CandidateMethod, * could match the given parameterTypes, eventually coerced. diff --git a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/util/BuiltInTypeUtils.java b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/util/BuiltInTypeUtils.java index bfb9911ce60..5c68584a87a 100644 --- a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/util/BuiltInTypeUtils.java +++ b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/util/BuiltInTypeUtils.java @@ -30,9 +30,12 @@ import java.time.temporal.Temporal; import java.time.temporal.TemporalAccessor; import java.time.temporal.TemporalQueries; +import java.util.Collections; +import java.util.Date; import java.util.List; import java.util.Map; +import java.util.Set; import org.kie.dmn.feel.lang.Type; import org.kie.dmn.feel.lang.types.BuiltInType; import org.kie.dmn.feel.runtime.FEELFunction; @@ -98,42 +101,31 @@ public static Type determineTypeFromInstance(Object o) { return BuiltInType.UNKNOWN; } - public static Type determineTypeFromClass(Class clazz) { + public static Set determineTypesFromClass(Class clazz) { if (clazz == null) { - return BuiltInType.UNKNOWN; + return Collections.singleton(BuiltInType.UNKNOWN); } else if (Number.class.isAssignableFrom(clazz)) { - return BuiltInType.NUMBER; + return Collections.singleton(BuiltInType.NUMBER); } else if (String.class.isAssignableFrom(clazz)) { - return BuiltInType.STRING; - } else if (LocalDate.class.isAssignableFrom(clazz)) { - return BuiltInType.DATE; - } else if (LocalTime.class.isAssignableFrom(clazz) || OffsetTime.class.isAssignableFrom(clazz) || ZoneTime.class.isAssignableFrom(clazz)) { - return BuiltInType.TIME; - } else if (ZonedDateTime.class.isAssignableFrom(clazz) || OffsetDateTime.class.isAssignableFrom(clazz) || LocalDateTime.class.isAssignableFrom(clazz)) { - return BuiltInType.DATE_TIME; + return Collections.singleton(BuiltInType.STRING); } else if (Duration.class.isAssignableFrom(clazz) || ChronoPeriod.class.isAssignableFrom(clazz)) { - return BuiltInType.DURATION; + return Collections.singleton(BuiltInType.DURATION); } else if (Boolean.class.isAssignableFrom(clazz)) { - return BuiltInType.BOOLEAN; + return Collections.singleton(BuiltInType.BOOLEAN); } else if (UnaryTest.class.isAssignableFrom(clazz)) { - return BuiltInType.UNARY_TEST; + return Collections.singleton(BuiltInType.UNARY_TEST); } else if (Range.class.isAssignableFrom(clazz)) { - return BuiltInType.RANGE; + return Collections.singleton(BuiltInType.RANGE); } else if (FEELFunction.class.isAssignableFrom(clazz)) { - return BuiltInType.FUNCTION; + return Collections.singleton(BuiltInType.FUNCTION); } else if (List.class.isAssignableFrom(clazz)) { - return BuiltInType.LIST; + return Collections.singleton(BuiltInType.LIST); } else if (Map.class.isAssignableFrom(clazz)) { - return BuiltInType.CONTEXT; + return Collections.singleton(BuiltInType.CONTEXT); } else if (TemporalAccessor.class.isAssignableFrom(clazz)) { - TemporalAccessor ta = TemporalAccessor.class.cast(clazz); - if (!(ta instanceof Temporal) && ta.isSupported(ChronoField.HOUR_OF_DAY) - && ta.isSupported(ChronoField.MINUTE_OF_HOUR) && ta.isSupported(ChronoField.SECOND_OF_MINUTE) - && ta.query(TemporalQueries.zone()) != null) { - return BuiltInType.TIME; - } + return Set.of(BuiltInType.DATE, BuiltInType.TIME, BuiltInType.DATE_TIME); } - return BuiltInType.UNKNOWN; + return Collections.singleton(BuiltInType.UNKNOWN); } public static boolean isInstanceOf(Object o, Type t) { diff --git a/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/lang/types/GenFnTypeTest.java b/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/lang/types/GenFnTypeTest.java index e25b2cae5be..6ace4a6e11d 100644 --- a/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/lang/types/GenFnTypeTest.java +++ b/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/lang/types/GenFnTypeTest.java @@ -22,16 +22,12 @@ import static org.assertj.core.api.Assertions.assertThat; import org.junit.jupiter.api.Test; -import org.kie.dmn.feel.lang.EvaluationContext; -import org.kie.dmn.feel.lang.Symbol; import org.kie.dmn.feel.lang.Type; -import org.kie.dmn.feel.runtime.FEELFunction; import org.kie.dmn.feel.runtime.functions.AbsFunction; import org.kie.dmn.feel.runtime.functions.AnyFunction; import org.kie.dmn.feel.runtime.functions.FEELFnResult; import org.kie.dmn.feel.runtime.FEELFunction.Param; -import java.math.BigDecimal; import java.util.Arrays; import java.util.Collections; import java.util.List; diff --git a/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/runtime/functions/BaseFEELFunctionTest.java b/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/runtime/functions/BaseFEELFunctionTest.java index 36ad3953f5c..d98db977f48 100644 --- a/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/runtime/functions/BaseFEELFunctionTest.java +++ b/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/runtime/functions/BaseFEELFunctionTest.java @@ -1,4 +1,4 @@ -/** +/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information @@ -31,6 +31,7 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.kie.dmn.feel.lang.Type; import org.kie.dmn.feel.util.EvaluationContextTestUtil; import org.kie.dmn.feel.lang.EvaluationContext; import org.kie.dmn.feel.lang.ast.BaseNode; @@ -319,37 +320,48 @@ void getStddevFunctionCandidateMethod() { } @Test - void testIsCompatible() { + void testIsCompatibleTrue() { BaseFEELFunction toTest = AllFunction.INSTANCE; + Type outputType = BuiltInType.BOOLEAN; + Type[] inputTypes = { BuiltInType.LIST }; + assertThat(toTest.isCompatible(inputTypes, outputType)).isTrue(); - org.kie.dmn.feel.lang.Type stringType = BuiltInType.STRING; - org.kie.dmn.feel.lang.Type integerType = BuiltInType.NUMBER; + toTest = DateFunction.INSTANCE; + outputType = BuiltInType.DATE; + inputTypes = new Type[]{BuiltInType.STRING}; + assertThat(toTest.isCompatible(inputTypes, outputType)).isTrue(); - org.kie.dmn.feel.lang.Type[] inputTypes; - org.kie.dmn.feel.lang.Type outputType = stringType; - boolean result; + inputTypes = new Type[]{ BuiltInType.NUMBER,BuiltInType.NUMBER,BuiltInType.NUMBER }; + assertThat(toTest.isCompatible(inputTypes, outputType)).isTrue(); - inputTypes = new org.kie.dmn.feel.lang.Type[]{stringType}; - result = toTest.isCompatible(inputTypes, outputType); - assertThat(result).isTrue(); + } + + @Test + void testIsCompatibleFalse() { + BaseFEELFunction toTest = AllFunction.INSTANCE; + Type outputType = BuiltInType.DATE; + Type[] inputTypes = { BuiltInType.LIST }; + assertThat(toTest.isCompatible(inputTypes, outputType)).isFalse(); + + outputType = BuiltInType.BOOLEAN; + inputTypes = new Type[]{BuiltInType.STRING}; + assertThat(toTest.isCompatible(inputTypes, outputType)).isFalse(); + + toTest = DateFunction.INSTANCE; - inputTypes = new org.kie.dmn.feel.lang.Type[]{integerType}; - outputType = integerType; - result = toTest.isCompatible(inputTypes, outputType); - assertThat(result).isTrue(); + outputType = BuiltInType.DATE; + inputTypes = new Type[]{BuiltInType.RANGE}; + assertThat(toTest.isCompatible(inputTypes, outputType)).isFalse(); - inputTypes = new org.kie.dmn.feel.lang.Type[]{stringType}; - outputType = stringType; - result = toTest.isCompatible(inputTypes, outputType); - assertThat(result).isTrue(); + inputTypes = new Type[]{ BuiltInType.NUMBER,BuiltInType.STRING,BuiltInType.NUMBER }; + assertThat(toTest.isCompatible(inputTypes, outputType)).isFalse(); - inputTypes = new org.kie.dmn.feel.lang.Type[]{integerType}; - result = toTest.isCompatible(inputTypes, outputType); - assertThat(result).isFalse(); + outputType = BuiltInType.STRING; + inputTypes = new Type[]{BuiltInType.STRING}; + assertThat(toTest.isCompatible(inputTypes, outputType)).isFalse(); - outputType = integerType; - result = toTest.isCompatible(inputTypes, outputType); - assertThat(result).isFalse(); + inputTypes = new Type[]{ BuiltInType.NUMBER,BuiltInType.NUMBER,BuiltInType.NUMBER }; + assertThat(toTest.isCompatible(inputTypes, outputType)).isFalse(); } } \ No newline at end of file From 0560f1fcbe488388957373f8496541e81874c90b Mon Sep 17 00:00:00 2001 From: Gabriele-Cardosi Date: Tue, 4 Mar 2025 14:26:45 +0100 Subject: [PATCH 13/20] [incubator-kie-issues#1752] Fix usage of BuiltInTypeUtils inside drl validation file --- .../validation/DMNv1_1/dmn-validation-rules-typeref.drl | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/kie-dmn/kie-dmn-validation/src/main/resources/org/kie/dmn/validation/DMNv1_1/dmn-validation-rules-typeref.drl b/kie-dmn/kie-dmn-validation/src/main/resources/org/kie/dmn/validation/DMNv1_1/dmn-validation-rules-typeref.drl index 95c180de858..1938fc429e5 100644 --- a/kie-dmn/kie-dmn-validation/src/main/resources/org/kie/dmn/validation/DMNv1_1/dmn-validation-rules-typeref.drl +++ b/kie-dmn/kie-dmn-validation/src/main/resources/org/kie/dmn/validation/DMNv1_1/dmn-validation-rules-typeref.drl @@ -26,6 +26,7 @@ import org.kie.dmn.core.util.MsgUtil; import org.kie.dmn.feel.lang.types.BuiltInType; import org.kie.dmn.feel.parser.feel11.FEELParser; import org.kie.dmn.feel.runtime.events.SyntaxErrorEvent; +import org.kie.dmn.feel.util.BuiltInTypeUtils; import org.kie.dmn.api.feel.runtime.events.FEELEvent; import org.kie.dmn.core.util.Msg; @@ -56,28 +57,28 @@ end rule TYPEREF_NO_FEEL_TYPE_p1 when - $o: Expression( !(this instanceof UnaryTests), typeRef!.prefix != null, getNamespaceURI( typeRef.prefix ) == getURIFEEL(), BuiltInType.determineTypeFromName( typeRef.localPart ) == BuiltInType.UNKNOWN ) + $o: Expression( !(this instanceof UnaryTests), typeRef!.prefix != null, getNamespaceURI( typeRef.prefix ) == getURIFEEL(), BuiltInTypeUtils.determineTypeFromName( typeRef.localPart ) == BuiltInType.UNKNOWN ) then reporter.report( DMNMessage.Severity.ERROR, $o , Msg.UNKNOWN_FEEL_TYPE_REF_ON_NODE, $o.getTypeRef(), $o.getParentDRDElement().getIdentifierString() ); end rule TYPEREF_NO_FEEL_TYPE_p2 when - $o: InformationItem( typeRef!.prefix != null, getNamespaceURI( typeRef.prefix ) == getURIFEEL(), BuiltInType.determineTypeFromName( typeRef.localPart ) == BuiltInType.UNKNOWN ) + $o: InformationItem( typeRef!.prefix != null, getNamespaceURI( typeRef.prefix ) == getURIFEEL(), BuiltInTypeUtils.determineTypeFromName( typeRef.localPart ) == BuiltInType.UNKNOWN ) then $o: reporter.report( DMNMessage.Severity.ERROR, $o , Msg.UNKNOWN_FEEL_TYPE_REF_ON_NODE, $o.getTypeRef(), $o.getParentDRDElement().getIdentifierString() ); end rule TYPEREF_NO_FEEL_TYPE_p3 when - $o: ItemDefinition( typeRef!.prefix != null, getNamespaceURI( typeRef.prefix ) == getURIFEEL(), BuiltInType.determineTypeFromName( typeRef.localPart ) == BuiltInType.UNKNOWN ) + $o: ItemDefinition( typeRef!.prefix != null, getNamespaceURI( typeRef.prefix ) == getURIFEEL(), BuiltInTypeUtils.determineTypeFromName( typeRef.localPart ) == BuiltInType.UNKNOWN ) then reporter.report( DMNMessage.Severity.ERROR, $o , Msg.UNKNOWN_FEEL_TYPE_REF_ON_NODE, $o.getTypeRef(), $o.getParentDRDElement().getIdentifierString() ); end rule TYPEREF_NO_FEEL_TYPE_p4 when - $o: OutputClause( typeRef!.prefix != null, getNamespaceURI( typeRef.prefix ) == getURIFEEL(), BuiltInType.determineTypeFromName( typeRef.localPart ) == BuiltInType.UNKNOWN ) + $o: OutputClause( typeRef!.prefix != null, getNamespaceURI( typeRef.prefix ) == getURIFEEL(), BuiltInTypeUtils.determineTypeFromName( typeRef.localPart ) == BuiltInType.UNKNOWN ) then reporter.report( DMNMessage.Severity.ERROR, $o , Msg.UNKNOWN_FEEL_TYPE_REF_ON_NODE, $o.getTypeRef(), $o.getParentDRDElement().getIdentifierString() ); end From 7013c13e9059fe853d88230286bf151260050696 Mon Sep 17 00:00:00 2001 From: bncriju Date: Wed, 5 Mar 2025 20:35:23 +0530 Subject: [PATCH 14/20] adding tests --- .../dmn/feel/lang/types/GenFnTypeTest.java | 57 ++++++++++++------- 1 file changed, 38 insertions(+), 19 deletions(-) diff --git a/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/lang/types/GenFnTypeTest.java b/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/lang/types/GenFnTypeTest.java index 6ace4a6e11d..bce68f549f5 100644 --- a/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/lang/types/GenFnTypeTest.java +++ b/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/lang/types/GenFnTypeTest.java @@ -21,12 +21,15 @@ import static org.assertj.core.api.Assertions.assertThat; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.kie.dmn.feel.lang.Type; +import org.kie.dmn.feel.runtime.FEELFunction; import org.kie.dmn.feel.runtime.functions.AbsFunction; import org.kie.dmn.feel.runtime.functions.AnyFunction; -import org.kie.dmn.feel.runtime.functions.FEELFnResult; import org.kie.dmn.feel.runtime.FEELFunction.Param; +import org.kie.dmn.feel.runtime.functions.FEELFnResult; +import org.mockito.Mockito; import java.util.Arrays; import java.util.Collections; @@ -35,17 +38,35 @@ class GenFnTypeTest { - private static final AbsFunction absFunctionInstance = AbsFunction.INSTANCE; - private static final AnyFunction anyFunctionInstance = AnyFunction.INSTANCE; + private GenFnType genFnType; + private FEELFunction mockFunction; + private AbsFunction absFunctionInstance; + private AnyFunction anyFunctionInstance; + + @BeforeEach + void setUp() { + absFunctionInstance = AbsFunction.INSTANCE; + anyFunctionInstance = AnyFunction.INSTANCE; + + genFnType = new GenFnType( + Arrays.asList(new SomeType(), new AnotherType()), + new SomeType() + ); + mockFunction = Mockito.mock(FEELFunction.class); + } + + @Test + public void testIsInstanceOfWithCompatibleFunction() { + List> params = new ArrayList<>(); + Mockito.when(mockFunction.getParameters()).thenReturn(params); + Mockito.when(mockFunction.isCompatible(Mockito.any(), Mockito.any())).thenReturn(true); - private final GenFnType genFnType = new GenFnType( - Arrays.asList(new SomeType(), new AnotherType()), - new SomeType() - ); + assertThat(genFnType.isInstanceOf(mockFunction)).isTrue(); + } @Test public void testIsInstanceOfWithNoParameters() { - assertThat(genFnType.isInstanceOf(absFunctionInstance)).isTrue(); + assertThat(genFnType.isInstanceOf(absFunctionInstance)).isFalse(); } @Test @@ -54,23 +75,21 @@ public void testIsInstanceOfWithNonMatchingParameters() { assertThat(genFnType.isInstanceOf(feelFn)).isFalse(); } - @Test - public void testIsInstanceOfWithMatchingFunctionSignature() { - GenFnType matchingGenFnType = new GenFnType( - Arrays.asList(new SomeType(), new AnotherType()), - new SomeType() - ); - assertThat(matchingGenFnType.isInstanceOf(absFunctionInstance)).isTrue(); - } - @Test public void testIsAssignableValueWithNullValue() { assertThat(genFnType.isAssignableValue(null)).isTrue(); } @Test - public void testIsAssignableValueWithFunction() { - assertThat(genFnType.isAssignableValue(absFunctionInstance)).isTrue(); + public void testIsAssignableValue_withNonNullValue() { + Type evaluatedTypeArg = BuiltInType.NUMBER; + Type functionReturnType = BuiltInType.NUMBER; + GenFnType genFnType = new GenFnType( + List.of(evaluatedTypeArg), functionReturnType + ); + Object value = "Hello"; + boolean result = genFnType.isAssignableValue(value); + assertThat(result).isFalse(); } @Test From 62ce7a19fa4e2c3e1a032b1121645404714a6444 Mon Sep 17 00:00:00 2001 From: Gabriele-Cardosi Date: Wed, 5 Mar 2025 17:40:03 +0100 Subject: [PATCH 15/20] [incubator-kie-issues#1752] WIP - Test suggestion --- .../kie/dmn/feel/lang/types/GenFnType.java | 4 ++ .../functions/interval/BeforeFunction.java | 2 +- .../kie/dmn/feel/util/BuiltInTypeUtils.java | 1 - .../dmn/feel/lang/types/GenFnTypeTest.java | 58 ++++++++++++++----- .../functions/BaseFEELFunctionTest.java | 13 +++++ 5 files changed, 62 insertions(+), 16 deletions(-) diff --git a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/types/GenFnType.java b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/types/GenFnType.java index a7db54cc37a..76ec3a4b464 100644 --- a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/types/GenFnType.java +++ b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/types/GenFnType.java @@ -76,6 +76,10 @@ public boolean conformsTo(Type t) { } static boolean checkSignatures(List> currentGenFnTypeParams, List evaluatedTypeArgs) { + // TODO + // This method, and the overall code, works by a side-effect, since there is only one calling code, isInstanceOf, + // that checks for empty parameters + // if this method relies on the assumption that currentGenFnTypeParams is not empty, then an exception should be thrown when an empty list is received List> signatures = currentGenFnTypeParams.stream().filter(signature -> signature.size() == evaluatedTypeArgs.size()).toList(); for (List signature : signatures) { if (signature.size() == evaluatedTypeArgs.size() && IntStream.range(0, evaluatedTypeArgs.size()).allMatch(i -> evaluatedTypeArgs.get(i).conformsTo(signature.get(i).type))) { diff --git a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/functions/interval/BeforeFunction.java b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/functions/interval/BeforeFunction.java index 2f65b7a6ec7..6effdbe8c3a 100644 --- a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/functions/interval/BeforeFunction.java +++ b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/functions/interval/BeforeFunction.java @@ -1,4 +1,4 @@ -/** +/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information diff --git a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/util/BuiltInTypeUtils.java b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/util/BuiltInTypeUtils.java index 5c68584a87a..a6dba3cc48a 100644 --- a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/util/BuiltInTypeUtils.java +++ b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/util/BuiltInTypeUtils.java @@ -31,7 +31,6 @@ import java.time.temporal.TemporalAccessor; import java.time.temporal.TemporalQueries; import java.util.Collections; -import java.util.Date; import java.util.List; import java.util.Map; diff --git a/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/lang/types/GenFnTypeTest.java b/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/lang/types/GenFnTypeTest.java index bce68f549f5..5b7f701660e 100644 --- a/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/lang/types/GenFnTypeTest.java +++ b/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/lang/types/GenFnTypeTest.java @@ -52,25 +52,37 @@ void setUp() { Arrays.asList(new SomeType(), new AnotherType()), new SomeType() ); + // TODO remove usage of mock mockFunction = Mockito.mock(FEELFunction.class); } @Test public void testIsInstanceOfWithCompatibleFunction() { + // TODO remove usage of mock + // Instead, use a properly instantiated GenFnType that match the Function used as argument List> params = new ArrayList<>(); Mockito.when(mockFunction.getParameters()).thenReturn(params); Mockito.when(mockFunction.isCompatible(Mockito.any(), Mockito.any())).thenReturn(true); - assertThat(genFnType.isInstanceOf(mockFunction)).isTrue(); } + @Test + public void testIsInstanceOfWithIncompatibleFunction() { + // TODO + // Use a properly instantiated GenFnType that does not match the Function used as argument + // copy copy testing values from testIsAssignableValuWithInvalidValue + } + @Test public void testIsInstanceOfWithNoParameters() { + // remove - to be replaced by testIsInstanceOfWithIncompatibleFunction assertThat(genFnType.isInstanceOf(absFunctionInstance)).isFalse(); } @Test public void testIsInstanceOfWithNonMatchingParameters() { + // remove the anyFunctionInstance.invoke invocation, it makes test unclear. + // any object that is not a FEELFunction should return false FEELFnResult feelFn = anyFunctionInstance.invoke(new Object[]{Boolean.TRUE, Boolean.TRUE}); assertThat(genFnType.isInstanceOf(feelFn)).isFalse(); } @@ -81,7 +93,13 @@ public void testIsAssignableValueWithNullValue() { } @Test - public void testIsAssignableValue_withNonNullValue() { + public void testIsAssignableValuWithValidValue() { + // TODO + // copy testing values from testIsInstanceOfWithCompatibleFunction + } + + @Test + public void testIsAssignableValuWithInvalidValue() { Type evaluatedTypeArg = BuiltInType.NUMBER; Type functionReturnType = BuiltInType.NUMBER; GenFnType genFnType = new GenFnType( @@ -93,7 +111,22 @@ public void testIsAssignableValue_withNonNullValue() { } @Test - public void testConformsToWithSignature() { + public void testConformsToWithValidBuiltinType() { + assertThat(genFnType.conformsTo(BuiltInType.FUNCTION)).isTrue(); + } + + @Test + public void testConformsToWithInvalidBuiltinType() { + // TODO + } + + @Test + public void testConformsToWithValidGenFnType() { + // TODO + } + + @Test + public void testConformsToWithInvalidGenFnType() { GenFnType matchingGenFnType = new GenFnType( Collections.singletonList(new SomeType()), new SomeType() @@ -102,12 +135,7 @@ public void testConformsToWithSignature() { } @Test - public void testConformsToWithFunctionType() { - assertThat(genFnType.conformsTo(BuiltInType.FUNCTION)).isTrue(); - } - - @Test - void testCheckSignatures_withMatchingSignatures() { + void testCheckSignaturesWithMatchingSignatures() { List argsGen = Arrays.asList(new SomeType(), new AnotherType()); List paramTypes = Arrays.asList(new SomeType(), new AnotherType()); List paramNames = Arrays.asList("param1", "param2"); @@ -117,7 +145,7 @@ void testCheckSignatures_withMatchingSignatures() { } @Test - void testCheckSignatures_withNonMatchingSignatures() { + void testCheckSignaturesWithNonMatchingSignatures() { List argsGen = Arrays.asList(new SomeType(), new AnotherType()); List paramTypes = Arrays.asList(new SomeType(), new YetAnotherType()); List paramNames = Arrays.asList("param1", "param2"); @@ -127,7 +155,7 @@ void testCheckSignatures_withNonMatchingSignatures() { } @Test - void testCheckSignatures_withSignatureSizeMismatch() { + void testCheckSignaturesWithSignatureSizeMismatch() { List argsGen = Arrays.asList(new SomeType(), new AnotherType()); List paramTypes = List.of(new SomeType()); List paramNames = List.of("param1"); @@ -137,7 +165,7 @@ void testCheckSignatures_withSignatureSizeMismatch() { } @Test - void testCheckSignatures_withEmptyParams() { + void testCheckSignaturesWithEmptyParams() { List argsGen = Arrays.asList(new SomeType(), new AnotherType()); List> params = List.of(); @@ -145,7 +173,7 @@ void testCheckSignatures_withEmptyParams() { } @Test - void testCheckSignatures_withEmptyArgsGen() { + void testCheckSignaturesWithEmptyArgsGen() { List argsGen = List.of(); List paramTypes = Arrays.asList(new SomeType(), new AnotherType()); List paramNames = Arrays.asList("param1", "param2"); @@ -155,7 +183,9 @@ void testCheckSignatures_withEmptyArgsGen() { } @Test - void testCheckSignatures_withMatchingEmptySignature() { + void testCheckSignaturesWithMatchingEmptySignature() { + // TODO + // This should throw an exception, because checkSignatures is implemented on the assumption that params is not empty List argsGen = List.of(); List> params = List.of(); diff --git a/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/runtime/functions/BaseFEELFunctionTest.java b/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/runtime/functions/BaseFEELFunctionTest.java index d98db977f48..bf5fcb029a4 100644 --- a/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/runtime/functions/BaseFEELFunctionTest.java +++ b/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/runtime/functions/BaseFEELFunctionTest.java @@ -334,6 +334,19 @@ void testIsCompatibleTrue() { inputTypes = new Type[]{ BuiltInType.NUMBER,BuiltInType.NUMBER,BuiltInType.NUMBER }; assertThat(toTest.isCompatible(inputTypes, outputType)).isTrue(); + + // TODO find correct mapping for Object[] and test + // AllFunction.invoke(Object[]) +// toTest = AllFunction.INSTANCE; +// outputType = BuiltInType.BOOLEAN; + + // TODO find correct mapping for FEELFunction and test + //SortFunction.invoke(EvaluationContext, List, FEELFunction) +// toTest = SortFunction.INSTANCE; +// outputType = BuiltInType.LIST; +// inputTypes = new Type[]{BuiltInType.CONTEXT, BuiltInType.LIST, BeforeFunction.INSTANCE }; +// assertThat(toTest.isCompatible(inputTypes, outputType)).isTrue(); + } @Test From 365eb155ad7fc1605dd470d785fd8e66129f8e94 Mon Sep 17 00:00:00 2001 From: bncriju Date: Thu, 6 Mar 2025 13:19:59 +0530 Subject: [PATCH 16/20] test suggestions incorporated --- .../kie/dmn/feel/lang/types/GenFnType.java | 15 ++- .../dmn/feel/lang/types/GenFnTypeTest.java | 124 +++++++++++------- .../functions/BaseFEELFunctionTest.java | 69 +++++----- 3 files changed, 119 insertions(+), 89 deletions(-) diff --git a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/types/GenFnType.java b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/types/GenFnType.java index 76ec3a4b464..63200fa54ac 100644 --- a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/types/GenFnType.java +++ b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/types/GenFnType.java @@ -18,6 +18,7 @@ */ package org.kie.dmn.feel.lang.types; + import java.util.ArrayList; import java.util.List; import java.util.stream.IntStream; @@ -76,13 +77,15 @@ public boolean conformsTo(Type t) { } static boolean checkSignatures(List> currentGenFnTypeParams, List evaluatedTypeArgs) { - // TODO - // This method, and the overall code, works by a side-effect, since there is only one calling code, isInstanceOf, - // that checks for empty parameters - // if this method relies on the assumption that currentGenFnTypeParams is not empty, then an exception should be thrown when an empty list is received - List> signatures = currentGenFnTypeParams.stream().filter(signature -> signature.size() == evaluatedTypeArgs.size()).toList(); + if (currentGenFnTypeParams.isEmpty()) { + throw new IllegalArgumentException("The list of function parameter signatures cannot be empty."); + } + List> signatures = currentGenFnTypeParams.stream() + .filter(signature -> signature.size() == evaluatedTypeArgs.size()) + .toList(); for (List signature : signatures) { - if (signature.size() == evaluatedTypeArgs.size() && IntStream.range(0, evaluatedTypeArgs.size()).allMatch(i -> evaluatedTypeArgs.get(i).conformsTo(signature.get(i).type))) { + if (IntStream.range(0, evaluatedTypeArgs.size()).allMatch(i -> + evaluatedTypeArgs.get(i).conformsTo(signature.get(i).type))) { return true; } } diff --git a/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/lang/types/GenFnTypeTest.java b/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/lang/types/GenFnTypeTest.java index 5b7f701660e..d00a17ffdbb 100644 --- a/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/lang/types/GenFnTypeTest.java +++ b/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/lang/types/GenFnTypeTest.java @@ -20,16 +20,17 @@ package org.kie.dmn.feel.lang.types; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.kie.dmn.feel.lang.EvaluationContext; +import org.kie.dmn.feel.lang.Symbol; import org.kie.dmn.feel.lang.Type; import org.kie.dmn.feel.runtime.FEELFunction; -import org.kie.dmn.feel.runtime.functions.AbsFunction; -import org.kie.dmn.feel.runtime.functions.AnyFunction; import org.kie.dmn.feel.runtime.FEELFunction.Param; -import org.kie.dmn.feel.runtime.functions.FEELFnResult; -import org.mockito.Mockito; +import org.kie.dmn.feel.runtime.functions.ContextPutFunction; +import org.kie.dmn.feel.runtime.functions.EvenFunction; import java.util.Arrays; import java.util.Collections; @@ -39,52 +40,53 @@ class GenFnTypeTest { private GenFnType genFnType; - private FEELFunction mockFunction; - private AbsFunction absFunctionInstance; - private AnyFunction anyFunctionInstance; @BeforeEach void setUp() { - absFunctionInstance = AbsFunction.INSTANCE; - anyFunctionInstance = AnyFunction.INSTANCE; - genFnType = new GenFnType( Arrays.asList(new SomeType(), new AnotherType()), new SomeType() ); - // TODO remove usage of mock - mockFunction = Mockito.mock(FEELFunction.class); } @Test public void testIsInstanceOfWithCompatibleFunction() { - // TODO remove usage of mock - // Instead, use a properly instantiated GenFnType that match the Function used as argument - List> params = new ArrayList<>(); - Mockito.when(mockFunction.getParameters()).thenReturn(params); - Mockito.when(mockFunction.isCompatible(Mockito.any(), Mockito.any())).thenReturn(true); - assertThat(genFnType.isInstanceOf(mockFunction)).isTrue(); + FEELFunction compatibleFunction = new FEELFunction() { + @Override + public String getName() { + return "SomeType"; + } + + @Override + public Symbol getSymbol() { + return null; + } + + @Override + public List> getParameters() { + List paramTypes = Arrays.asList(new SomeType(), new AnotherType()); + List paramNames = Arrays.asList("param1", "param2"); + return createParams(paramTypes, paramNames); + } + + @Override + public Object invokeReflectively(EvaluationContext ctx, Object[] params) { + return null; + } + }; + assertThat(genFnType.isInstanceOf(compatibleFunction)).isTrue(); } @Test public void testIsInstanceOfWithIncompatibleFunction() { - // TODO - // Use a properly instantiated GenFnType that does not match the Function used as argument - // copy copy testing values from testIsAssignableValuWithInvalidValue + FEELFunction incompatibleFunction = ContextPutFunction.INSTANCE; + assertThat(genFnType.isInstanceOf(incompatibleFunction)).isFalse(); } @Test - public void testIsInstanceOfWithNoParameters() { - // remove - to be replaced by testIsInstanceOfWithIncompatibleFunction - assertThat(genFnType.isInstanceOf(absFunctionInstance)).isFalse(); - } - - @Test - public void testIsInstanceOfWithNonMatchingParameters() { - // remove the anyFunctionInstance.invoke invocation, it makes test unclear. - // any object that is not a FEELFunction should return false - FEELFnResult feelFn = anyFunctionInstance.invoke(new Object[]{Boolean.TRUE, Boolean.TRUE}); - assertThat(genFnType.isInstanceOf(feelFn)).isFalse(); + public void testIsInstanceOfWithNonFeelFunction() { + FEELFunction notFeelFn = EvenFunction.INSTANCE; + assertThat(genFnType.isInstanceOf(notFeelFn)).isFalse(); } @Test @@ -93,13 +95,36 @@ public void testIsAssignableValueWithNullValue() { } @Test - public void testIsAssignableValuWithValidValue() { - // TODO - // copy testing values from testIsInstanceOfWithCompatibleFunction + public void testIsAssignableValueWithValidValue() { + FEELFunction compatibleFunction = new FEELFunction() { + @Override + public String getName() { + return "SomeType"; + } + + @Override + public Symbol getSymbol() { + return null; + } + + @Override + public List> getParameters() { + List paramTypes = Arrays.asList(new SomeType(), new AnotherType()); + List paramNames = Arrays.asList("param1", "param2"); + return createParams(paramTypes, paramNames); + } + + @Override + public Object invokeReflectively(EvaluationContext ctx, Object[] params) { + return null; + } + }; + boolean result = genFnType.isAssignableValue(compatibleFunction); + assertThat(result).isTrue(); } @Test - public void testIsAssignableValuWithInvalidValue() { + public void testIsAssignableValueWithInvalidValue() { Type evaluatedTypeArg = BuiltInType.NUMBER; Type functionReturnType = BuiltInType.NUMBER; GenFnType genFnType = new GenFnType( @@ -117,21 +142,27 @@ public void testConformsToWithValidBuiltinType() { @Test public void testConformsToWithInvalidBuiltinType() { - // TODO + assertThat(genFnType.conformsTo(BuiltInType.STRING)).isFalse(); } @Test public void testConformsToWithValidGenFnType() { - // TODO + GenFnType anotherGenFnType = new GenFnType( + Arrays.asList(new SomeType(), new AnotherType()), + new SomeType() + ); + + assertThat(genFnType.conformsTo(anotherGenFnType)).isTrue(); } @Test public void testConformsToWithInvalidGenFnType() { - GenFnType matchingGenFnType = new GenFnType( + GenFnType invalidGenFnType = new GenFnType( Collections.singletonList(new SomeType()), new SomeType() ); - assertThat(genFnType.conformsTo(matchingGenFnType)).isFalse(); + + assertThat(genFnType.conformsTo(invalidGenFnType)).isFalse(); } @Test @@ -169,7 +200,9 @@ void testCheckSignaturesWithEmptyParams() { List argsGen = Arrays.asList(new SomeType(), new AnotherType()); List> params = List.of(); - assertThat(GenFnType.checkSignatures(params, argsGen)).isFalse(); + assertThatThrownBy(() -> GenFnType.checkSignatures(params, argsGen)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("The list of function parameter signatures cannot be empty."); } @Test @@ -183,13 +216,12 @@ void testCheckSignaturesWithEmptyArgsGen() { } @Test - void testCheckSignaturesWithMatchingEmptySignature() { - // TODO - // This should throw an exception, because checkSignatures is implemented on the assumption that params is not empty + void testCheckSignaturesWithEmptySignature() { List argsGen = List.of(); List> params = List.of(); - - assertThat(GenFnType.checkSignatures(params, argsGen)).isFalse(); + assertThatThrownBy(() -> GenFnType.checkSignatures(params, argsGen)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("The list of function parameter signatures cannot be empty."); } static class SomeType implements Type { diff --git a/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/runtime/functions/BaseFEELFunctionTest.java b/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/runtime/functions/BaseFEELFunctionTest.java index bf5fcb029a4..3577de51fed 100644 --- a/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/runtime/functions/BaseFEELFunctionTest.java +++ b/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/runtime/functions/BaseFEELFunctionTest.java @@ -58,23 +58,23 @@ public void setUp() { @Test void invokeReflectiveCustomFunction() { List parameters = List.of(new FEELFunction.Param("foo", BuiltInType.UNKNOWN), - new FEELFunction.Param("person's age", BuiltInType.UNKNOWN)); + new FEELFunction.Param("person's age", BuiltInType.UNKNOWN)); BaseNode left = new InfixOpNode(InfixOperator.EQ, - new NameRefNode(BuiltInType.UNKNOWN, "foo"), - new NullNode(""), - "foo = null"); + new NameRefNode(BuiltInType.UNKNOWN, "foo"), + new NullNode(""), + "foo = null"); BaseNode right = new InfixOpNode(InfixOperator.LT, - new NameRefNode(BuiltInType.UNKNOWN, "person's age"), - new NumberNode(BigDecimal.valueOf(18), "18"), - "person's age < 18"); + new NameRefNode(BuiltInType.UNKNOWN, "person's age"), + new NumberNode(BigDecimal.valueOf(18), "18"), + "person's age < 18"); BaseNode body = new InfixOpNode(InfixOperator.AND, left, right, "foo = null and person's age < 18"); BaseFEELFunction toTest = new CustomFEELFunction("", - parameters, - body, - ctx); - Object[] params = {new NamedParameter("foo", null), - new NamedParameter("person's age", 16)}; + parameters, + body, + ctx); + Object[] params = {new NamedParameter("foo", null), + new NamedParameter("person's age", 16)}; Object retrieved = toTest.invokeReflectively(ctx, params); assertThat(retrieved).isNotNull(); assertThat(retrieved).isInstanceOf(Boolean.class); @@ -164,8 +164,8 @@ void getDateAndTimeFunctionCandidateMethod() { parametersRetrieved = retrieved.getParameters(); assertThat(parametersRetrieved).isNotNull(); assertThat(parametersRetrieved).hasSize(6); - assertThat(parametersRetrieved).extracting("type").containsExactly(Number.class, Number.class, Number.class, - Number.class, Number.class, Number.class); + assertThat(parametersRetrieved).extracting("type").containsExactly(Number.class, Number.class, Number.class, + Number.class, Number.class, Number.class); // invoke(@ParameterName( "year" ) Number year, @ParameterName( "month" ) Number month, @ParameterName( "day" // ) Number day, @@ -182,8 +182,8 @@ void getDateAndTimeFunctionCandidateMethod() { parametersRetrieved = retrieved.getParameters(); assertThat(parametersRetrieved).isNotNull(); assertThat(parametersRetrieved).hasSize(7); - assertThat(parametersRetrieved).extracting("type").containsExactly(Number.class, Number.class, Number.class, - Number.class, Number.class, Number.class, Number.class); + assertThat(parametersRetrieved).extracting("type").containsExactly(Number.class, Number.class, Number.class, + Number.class, Number.class, Number.class, Number.class); // invoke(@ParameterName( "year" ) Number year, @ParameterName( "month" ) Number month, @ParameterName( "day" // ) Number day, @@ -200,8 +200,8 @@ void getDateAndTimeFunctionCandidateMethod() { parametersRetrieved = retrieved.getParameters(); assertThat(parametersRetrieved).isNotNull(); assertThat(parametersRetrieved).hasSize(7); - assertThat(parametersRetrieved).extracting("type").containsExactly(Number.class, Number.class, Number.class, - Number.class, Number.class, Number.class, String.class); + assertThat(parametersRetrieved).extracting("type").containsExactly(Number.class, Number.class, Number.class, + Number.class, Number.class, Number.class, String.class); } @Test @@ -249,7 +249,7 @@ void getExtendedTimeFunctionCandidateMethod() { parametersRetrieved = retrieved.getParameters(); assertThat(parametersRetrieved).isNotNull(); assertThat(parametersRetrieved).hasSize(4); - + assertThat(parametersRetrieved).extracting("type").containsExactly(Number.class, Number.class, Number.class, Duration.class); @@ -323,7 +323,7 @@ void getStddevFunctionCandidateMethod() { void testIsCompatibleTrue() { BaseFEELFunction toTest = AllFunction.INSTANCE; Type outputType = BuiltInType.BOOLEAN; - Type[] inputTypes = { BuiltInType.LIST }; + Type[] inputTypes = {BuiltInType.LIST}; assertThat(toTest.isCompatible(inputTypes, outputType)).isTrue(); toTest = DateFunction.INSTANCE; @@ -331,29 +331,25 @@ void testIsCompatibleTrue() { inputTypes = new Type[]{BuiltInType.STRING}; assertThat(toTest.isCompatible(inputTypes, outputType)).isTrue(); - inputTypes = new Type[]{ BuiltInType.NUMBER,BuiltInType.NUMBER,BuiltInType.NUMBER }; + inputTypes = new Type[]{BuiltInType.NUMBER, BuiltInType.NUMBER, BuiltInType.NUMBER}; assertThat(toTest.isCompatible(inputTypes, outputType)).isTrue(); + toTest = AllFunction.INSTANCE; + outputType = BuiltInType.BOOLEAN; + inputTypes = new Type[]{BuiltInType.UNKNOWN}; + assertThat(toTest.isCompatible(inputTypes, outputType)).isTrue(); - // TODO find correct mapping for Object[] and test - // AllFunction.invoke(Object[]) -// toTest = AllFunction.INSTANCE; -// outputType = BuiltInType.BOOLEAN; - - // TODO find correct mapping for FEELFunction and test - //SortFunction.invoke(EvaluationContext, List, FEELFunction) -// toTest = SortFunction.INSTANCE; -// outputType = BuiltInType.LIST; -// inputTypes = new Type[]{BuiltInType.CONTEXT, BuiltInType.LIST, BeforeFunction.INSTANCE }; -// assertThat(toTest.isCompatible(inputTypes, outputType)).isTrue(); - + toTest = SortFunction.INSTANCE; + outputType = BuiltInType.LIST; + inputTypes = new Type[]{BuiltInType.LIST}; + assertThat(toTest.isCompatible(inputTypes, outputType)).isTrue(); } @Test void testIsCompatibleFalse() { BaseFEELFunction toTest = AllFunction.INSTANCE; Type outputType = BuiltInType.DATE; - Type[] inputTypes = { BuiltInType.LIST }; + Type[] inputTypes = {BuiltInType.LIST}; assertThat(toTest.isCompatible(inputTypes, outputType)).isFalse(); outputType = BuiltInType.BOOLEAN; @@ -361,19 +357,18 @@ void testIsCompatibleFalse() { assertThat(toTest.isCompatible(inputTypes, outputType)).isFalse(); toTest = DateFunction.INSTANCE; - outputType = BuiltInType.DATE; inputTypes = new Type[]{BuiltInType.RANGE}; assertThat(toTest.isCompatible(inputTypes, outputType)).isFalse(); - inputTypes = new Type[]{ BuiltInType.NUMBER,BuiltInType.STRING,BuiltInType.NUMBER }; + inputTypes = new Type[]{BuiltInType.NUMBER, BuiltInType.STRING, BuiltInType.NUMBER}; assertThat(toTest.isCompatible(inputTypes, outputType)).isFalse(); outputType = BuiltInType.STRING; inputTypes = new Type[]{BuiltInType.STRING}; assertThat(toTest.isCompatible(inputTypes, outputType)).isFalse(); - inputTypes = new Type[]{ BuiltInType.NUMBER,BuiltInType.NUMBER,BuiltInType.NUMBER }; + inputTypes = new Type[]{BuiltInType.NUMBER, BuiltInType.NUMBER, BuiltInType.NUMBER}; assertThat(toTest.isCompatible(inputTypes, outputType)).isFalse(); } From 4995fbdb18acea9e2677650da183046f3bcdf1a7 Mon Sep 17 00:00:00 2001 From: Gabriele-Cardosi Date: Thu, 6 Mar 2025 14:40:57 +0100 Subject: [PATCH 17/20] [incubator-kie-issues#1752] Managing arrays conversion. Begin BuiltInTypeUtilsTest --- .../kie/dmn/feel/util/BuiltInTypeUtils.java | 2 +- .../dmn/feel/util/BuiltInTypeUtilsTest.java | 44 +++++++++++++++++++ 2 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/util/BuiltInTypeUtilsTest.java diff --git a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/util/BuiltInTypeUtils.java b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/util/BuiltInTypeUtils.java index a6dba3cc48a..7be6f7f95a9 100644 --- a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/util/BuiltInTypeUtils.java +++ b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/util/BuiltInTypeUtils.java @@ -117,7 +117,7 @@ public static Set determineTypesFromClass(Class clazz) { return Collections.singleton(BuiltInType.RANGE); } else if (FEELFunction.class.isAssignableFrom(clazz)) { return Collections.singleton(BuiltInType.FUNCTION); - } else if (List.class.isAssignableFrom(clazz)) { + } else if (List.class.isAssignableFrom(clazz) || clazz.isArray()) { return Collections.singleton(BuiltInType.LIST); } else if (Map.class.isAssignableFrom(clazz)) { return Collections.singleton(BuiltInType.CONTEXT); diff --git a/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/util/BuiltInTypeUtilsTest.java b/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/util/BuiltInTypeUtilsTest.java new file mode 100644 index 00000000000..593e125433e --- /dev/null +++ b/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/util/BuiltInTypeUtilsTest.java @@ -0,0 +1,44 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.kie.dmn.feel.util; + +import org.junit.jupiter.api.Test; +import org.kie.dmn.feel.lang.types.BuiltInType; + +import static org.assertj.core.api.Assertions.assertThat; + +class BuiltInTypeUtilsTest { + + @Test + void determineTypesFromClass() { + Object toTest = new Object[4]; + assertThat(BuiltInTypeUtils.determineTypesFromClass(toTest.getClass())) + .isNotEmpty() + .hasSize(1) + .containsExactly(BuiltInType.LIST); + toTest = 4; + assertThat(BuiltInTypeUtils.determineTypesFromClass(toTest.getClass())) + .isNotEmpty() + .hasSize(1) + .containsExactly(BuiltInType.NUMBER); + + // TODO add missing cases + + } +} \ No newline at end of file From a69fbe75e2ff17c6071cc8bc75bdb04a0410800d Mon Sep 17 00:00:00 2001 From: bncriju Date: Thu, 6 Mar 2025 20:58:30 +0530 Subject: [PATCH 18/20] tests updated --- .../functions/BaseFEELFunctionTest.java | 2 +- .../dmn/feel/util/BuiltInTypeUtilsTest.java | 65 ++++++++++++++++++- 2 files changed, 65 insertions(+), 2 deletions(-) diff --git a/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/runtime/functions/BaseFEELFunctionTest.java b/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/runtime/functions/BaseFEELFunctionTest.java index 3577de51fed..21e88d68782 100644 --- a/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/runtime/functions/BaseFEELFunctionTest.java +++ b/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/runtime/functions/BaseFEELFunctionTest.java @@ -337,7 +337,7 @@ void testIsCompatibleTrue() { toTest = AllFunction.INSTANCE; outputType = BuiltInType.BOOLEAN; inputTypes = new Type[]{BuiltInType.UNKNOWN}; - assertThat(toTest.isCompatible(inputTypes, outputType)).isTrue(); + assertThat(toTest.isCompatible(inputTypes, outputType)).isFalse(); toTest = SortFunction.INSTANCE; outputType = BuiltInType.LIST; diff --git a/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/util/BuiltInTypeUtilsTest.java b/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/util/BuiltInTypeUtilsTest.java index 593e125433e..1bca7af86d8 100644 --- a/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/util/BuiltInTypeUtilsTest.java +++ b/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/util/BuiltInTypeUtilsTest.java @@ -21,6 +21,8 @@ import org.junit.jupiter.api.Test; import org.kie.dmn.feel.lang.types.BuiltInType; +import java.time.Duration; + import static org.assertj.core.api.Assertions.assertThat; class BuiltInTypeUtilsTest { @@ -38,7 +40,68 @@ void determineTypesFromClass() { .hasSize(1) .containsExactly(BuiltInType.NUMBER); - // TODO add missing cases + toTest = "Test string"; + assertThat(BuiltInTypeUtils.determineTypesFromClass(toTest.getClass())) + .isNotEmpty() + .hasSize(1) + .containsExactly(BuiltInType.STRING); + + toTest = true; + assertThat(BuiltInTypeUtils.determineTypesFromClass(toTest.getClass())) + .isNotEmpty() + .hasSize(1) + .containsExactly(BuiltInType.BOOLEAN); + + toTest = Duration.ofHours(1); + assertThat(BuiltInTypeUtils.determineTypesFromClass(toTest.getClass())) + .isNotEmpty() + .hasSize(1) + .containsExactly(BuiltInType.DURATION); + + toTest = java.util.Map.of("key", "value"); + assertThat(BuiltInTypeUtils.determineTypesFromClass(toTest.getClass())) + .isNotEmpty() + .hasSize(1) + .containsExactly(BuiltInType.CONTEXT); + + toTest = java.time.LocalDate.now(); + assertThat(BuiltInTypeUtils.determineTypesFromClass(toTest.getClass())) + .isNotEmpty() + .hasSize(3) + .containsExactlyInAnyOrder(BuiltInType.DATE, BuiltInType.DATE_TIME, BuiltInType.TIME) + .filteredOn(type -> type == BuiltInType.DATE) + .hasSize(1); + + toTest = java.time.ZonedDateTime.now(); + assertThat(BuiltInTypeUtils.determineTypesFromClass(toTest.getClass())) + .isNotEmpty() + .hasSize(3) + .containsExactlyInAnyOrder(BuiltInType.DATE, BuiltInType.DATE_TIME, BuiltInType.TIME) + .filteredOn(type -> type == BuiltInType.DATE_TIME) + .hasSize(1); + toTest = java.time.OffsetDateTime.now(); + assertThat(BuiltInTypeUtils.determineTypesFromClass(toTest.getClass())) + .isNotEmpty() + .hasSize(3) + .containsExactlyInAnyOrder(BuiltInType.DATE, BuiltInType.DATE_TIME, BuiltInType.TIME) + .filteredOn(type -> type == BuiltInType.DATE_TIME) + .hasSize(1); + + toTest = java.time.OffsetTime.now(); + assertThat(BuiltInTypeUtils.determineTypesFromClass(toTest.getClass())) + .isNotEmpty() + .hasSize(3) + .containsExactlyInAnyOrder(BuiltInType.DATE, BuiltInType.DATE_TIME, BuiltInType.TIME) + .filteredOn(type -> type == BuiltInType.TIME) + .hasSize(1); + + toTest = java.time.LocalTime.now(); + assertThat(BuiltInTypeUtils.determineTypesFromClass(toTest.getClass())) + .isNotEmpty() + .hasSize(3) + .containsExactlyInAnyOrder(BuiltInType.DATE, BuiltInType.DATE_TIME, BuiltInType.TIME) + .filteredOn(type -> type == BuiltInType.TIME) + .hasSize(1); } } \ No newline at end of file From 5c44070c634575c28d81598918bfcce2811e3ae0 Mon Sep 17 00:00:00 2001 From: bncriju Date: Fri, 7 Mar 2025 13:25:20 +0530 Subject: [PATCH 19/20] license header corrected and managed unused imports --- .../dmn/core/compiler/alphanetbased/TableCellParser.java | 6 +++--- .../src/main/java/org/kie/dmn/feel/lang/ast/TypeNode.java | 7 +++---- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/compiler/alphanetbased/TableCellParser.java b/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/compiler/alphanetbased/TableCellParser.java index a930e365def..d246868cb7f 100644 --- a/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/compiler/alphanetbased/TableCellParser.java +++ b/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/compiler/alphanetbased/TableCellParser.java @@ -1,4 +1,4 @@ -/** +/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information @@ -6,9 +6,9 @@ * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at - *

+ * * http://www.apache.org/licenses/LICENSE-2.0 - *

+ * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY diff --git a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/TypeNode.java b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/TypeNode.java index 2cd4611062d..fbe5b676572 100644 --- a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/TypeNode.java +++ b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/TypeNode.java @@ -1,4 +1,4 @@ -/** +/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information @@ -6,9 +6,9 @@ * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at - *

+ * * http://www.apache.org/licenses/LICENSE-2.0 - *

+ * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY @@ -21,7 +21,6 @@ import org.antlr.v4.runtime.ParserRuleContext; import org.kie.dmn.feel.lang.EvaluationContext; import org.kie.dmn.feel.lang.Type; -import org.kie.dmn.feel.lang.types.BuiltInType; import org.kie.dmn.feel.util.BuiltInTypeUtils; public abstract class TypeNode From 19fc323900d0030119ff87aa8090cc9cd403bcda Mon Sep 17 00:00:00 2001 From: bncriju Date: Fri, 7 Mar 2025 13:49:06 +0530 Subject: [PATCH 20/20] license header corrected --- .../src/test/java/org/kie/dmn/core/DMNRuntimeTest.java | 6 +++--- .../src/main/java/org/kie/dmn/feel/lang/ast/TypeNode.java | 2 +- .../kie/dmn/feel/runtime/functions/ContextPutFunction.java | 6 +++--- .../kie/dmn/feel/runtime/functions/GetValueFunction.java | 6 +++--- .../java/org/kie/dmn/feel/runtime/functions/IsFunction.java | 6 +++--- .../org/kie/dmn/legacy/tests/core/v1_1/DMNRuntimeTest.java | 6 +++--- 6 files changed, 16 insertions(+), 16 deletions(-) diff --git a/kie-dmn/kie-dmn-core/src/test/java/org/kie/dmn/core/DMNRuntimeTest.java b/kie-dmn/kie-dmn-core/src/test/java/org/kie/dmn/core/DMNRuntimeTest.java index 9692ac5321d..b84932427a9 100644 --- a/kie-dmn/kie-dmn-core/src/test/java/org/kie/dmn/core/DMNRuntimeTest.java +++ b/kie-dmn/kie-dmn-core/src/test/java/org/kie/dmn/core/DMNRuntimeTest.java @@ -1,4 +1,4 @@ -/** +/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information @@ -6,9 +6,9 @@ * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at - *

+ * * http://www.apache.org/licenses/LICENSE-2.0 - *

+ * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY diff --git a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/TypeNode.java b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/TypeNode.java index fbe5b676572..5737c71e75a 100644 --- a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/TypeNode.java +++ b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/TypeNode.java @@ -6,7 +6,7 @@ * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, diff --git a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/functions/ContextPutFunction.java b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/functions/ContextPutFunction.java index 9a30bc0a454..c57b903f107 100644 --- a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/functions/ContextPutFunction.java +++ b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/functions/ContextPutFunction.java @@ -1,4 +1,4 @@ -/** +/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information @@ -6,9 +6,9 @@ * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at - *

+ * * http://www.apache.org/licenses/LICENSE-2.0 - *

+ * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY diff --git a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/functions/GetValueFunction.java b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/functions/GetValueFunction.java index dc760c1b44d..a0825279e2c 100644 --- a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/functions/GetValueFunction.java +++ b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/functions/GetValueFunction.java @@ -1,4 +1,4 @@ -/** +/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information @@ -6,9 +6,9 @@ * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at - *

+ * * http://www.apache.org/licenses/LICENSE-2.0 - *

+ * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY diff --git a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/functions/IsFunction.java b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/functions/IsFunction.java index 21b31ff2c76..bf2acf7f1fe 100644 --- a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/functions/IsFunction.java +++ b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/functions/IsFunction.java @@ -1,4 +1,4 @@ -/** +/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information @@ -6,9 +6,9 @@ * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at - *

+ * * http://www.apache.org/licenses/LICENSE-2.0 - *

+ * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY diff --git a/kie-dmn/kie-dmn-legacy-tests/src/test/java/org/kie/dmn/legacy/tests/core/v1_1/DMNRuntimeTest.java b/kie-dmn/kie-dmn-legacy-tests/src/test/java/org/kie/dmn/legacy/tests/core/v1_1/DMNRuntimeTest.java index 6adcfc33dab..f9f5d69b5cb 100644 --- a/kie-dmn/kie-dmn-legacy-tests/src/test/java/org/kie/dmn/legacy/tests/core/v1_1/DMNRuntimeTest.java +++ b/kie-dmn/kie-dmn-legacy-tests/src/test/java/org/kie/dmn/legacy/tests/core/v1_1/DMNRuntimeTest.java @@ -1,4 +1,4 @@ -/** +/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information @@ -6,9 +6,9 @@ * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at - *

+ * * http://www.apache.org/licenses/LICENSE-2.0 - *

+ * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY