diff --git a/src/main/java/org/powerflows/dmn/engine/model/decision/Decision.java b/src/main/java/org/powerflows/dmn/engine/model/decision/Decision.java index cff09d8..80936da 100644 --- a/src/main/java/org/powerflows/dmn/engine/model/decision/Decision.java +++ b/src/main/java/org/powerflows/dmn/engine/model/decision/Decision.java @@ -43,11 +43,15 @@ public class Decision implements Serializable { private static final long serialVersionUID = 1; + public static final HitPolicy DEFAULT_HIT_POLICY = HitPolicy.UNIQUE; + public static final ExpressionType DEFAULT_EXPRESSION_TYPE = ExpressionType.LITERAL; + public static final EvaluationMode DEFAULT_EVALUATION_MODE = EvaluationMode.BOOLEAN; + private String id; private String name; - private HitPolicy hitPolicy = HitPolicy.UNIQUE; - private ExpressionType expressionType = ExpressionType.LITERAL; - private EvaluationMode evaluationMode = EvaluationMode.BOOLEAN; + private HitPolicy hitPolicy = DEFAULT_HIT_POLICY; + private ExpressionType expressionType = DEFAULT_EXPRESSION_TYPE; + private EvaluationMode evaluationMode = DEFAULT_EVALUATION_MODE; private List inputs = new ArrayList<>(); private List outputs = new ArrayList<>(); private List rules = new ArrayList<>(); diff --git a/src/main/java/org/powerflows/dmn/engine/model/decision/DecisionUtil.java b/src/main/java/org/powerflows/dmn/engine/model/decision/DecisionUtil.java index 31d471e..38d60fc 100644 --- a/src/main/java/org/powerflows/dmn/engine/model/decision/DecisionUtil.java +++ b/src/main/java/org/powerflows/dmn/engine/model/decision/DecisionUtil.java @@ -86,7 +86,7 @@ private static void assignEntriesDefaults(final List inputs, if (inputEntry.getExpression().getType() == null) { setValue(expressionTypeField, inputEntry.getExpression(), - inputsMap.get(inputEntry.getName()).getExpression().getType()); + decisionExpressionType); } if (inputEntry.getEvaluationMode() == null) { diff --git a/src/main/java/org/powerflows/dmn/engine/model/decision/expression/Expression.java b/src/main/java/org/powerflows/dmn/engine/model/decision/expression/Expression.java index ed649ad..f4e86de 100644 --- a/src/main/java/org/powerflows/dmn/engine/model/decision/expression/Expression.java +++ b/src/main/java/org/powerflows/dmn/engine/model/decision/expression/Expression.java @@ -69,15 +69,6 @@ public B type(ExpressionType type) { return (B) this; } - - @Override - protected Expression assembleProduct() { - if (product.type == null) { - product.type = ExpressionType.LITERAL; - } - - return product; - } } public static class Builder extends ExpressionBuilder { diff --git a/src/main/java/org/powerflows/dmn/io/yaml/CustomRepresenter.java b/src/main/java/org/powerflows/dmn/io/yaml/CustomRepresenter.java index 713942d..54a8836 100644 --- a/src/main/java/org/powerflows/dmn/io/yaml/CustomRepresenter.java +++ b/src/main/java/org/powerflows/dmn/io/yaml/CustomRepresenter.java @@ -15,8 +15,6 @@ */ package org.powerflows.dmn.io.yaml; -import org.powerflows.dmn.engine.model.decision.EvaluationMode; -import org.powerflows.dmn.engine.model.decision.expression.ExpressionType; import org.powerflows.dmn.io.yaml.model.YamlDecision; import org.powerflows.dmn.io.yaml.model.rule.entry.YamlInputEntry; import org.powerflows.dmn.io.yaml.model.rule.entry.YamlOutputEntry; @@ -42,8 +40,12 @@ class RepresentYamlInputEntry implements Represent { @Override public Node representData(Object data) { - if (data instanceof YamlInputEntry && ((YamlInputEntry) data).getExpressionType() == ExpressionType.LITERAL && ((YamlInputEntry) data).getEvaluationMode() == EvaluationMode.BOOLEAN) { - return represent(((YamlInputEntry) data).getExpression()); + if (data instanceof YamlInputEntry) { + final YamlInputEntry yie = (YamlInputEntry) data; + + if (yie.getEvaluationMode() == null && yie.getExpressionType() == null && yie.getNameAlias() == null) { + return represent(yie.getExpression()); + } } return representJavaBean(getProperties(data.getClass()), data); @@ -51,11 +53,14 @@ public Node representData(Object data) { } class RepresentYamlOutputEntry implements Represent { - @Override public Node representData(Object data) { - if (data instanceof YamlOutputEntry && ((YamlOutputEntry) data).getExpressionType() == ExpressionType.LITERAL) { - return represent(((YamlOutputEntry) data).getExpression()); + if (data instanceof YamlOutputEntry) { + final YamlOutputEntry yoe = (YamlOutputEntry) data; + + if (yoe.getExpressionType() == null) { + return represent(yoe.getExpression()); + } } return representJavaBean(getProperties(data.getClass()), data); @@ -81,7 +86,7 @@ private boolean isEmpty(final Object propertyValue) { } else if (propertyValue instanceof String) { empty = ((String) propertyValue).isEmpty(); } else { - empty = propertyValue == ExpressionType.LITERAL || propertyValue == EvaluationMode.BOOLEAN; + empty = false; } return empty; diff --git a/src/main/java/org/powerflows/dmn/io/yaml/YamlDecisionConverter.java b/src/main/java/org/powerflows/dmn/io/yaml/YamlDecisionConverter.java index ab4a0c8..fec044f 100644 --- a/src/main/java/org/powerflows/dmn/io/yaml/YamlDecisionConverter.java +++ b/src/main/java/org/powerflows/dmn/io/yaml/YamlDecisionConverter.java @@ -17,10 +17,14 @@ package org.powerflows.dmn.io.yaml; import org.powerflows.dmn.engine.model.decision.Decision; +import org.powerflows.dmn.engine.model.decision.EvaluationMode; +import org.powerflows.dmn.engine.model.decision.HitPolicy; import org.powerflows.dmn.engine.model.decision.expression.ExpressionType; import org.powerflows.dmn.engine.model.decision.field.Input; import org.powerflows.dmn.engine.model.decision.field.Output; import org.powerflows.dmn.engine.model.decision.rule.Rule; +import org.powerflows.dmn.engine.model.decision.rule.entry.InputEntry; +import org.powerflows.dmn.engine.model.decision.rule.entry.OutputEntry; import org.powerflows.dmn.io.DecisionToExternalModelConverter; import org.powerflows.dmn.io.yaml.model.YamlDecision; import org.powerflows.dmn.io.yaml.model.field.YamlFields; @@ -38,15 +42,20 @@ import java.util.stream.Collectors; public class YamlDecisionConverter implements DecisionToExternalModelConverter { + @Override public YamlDecision to(final Decision decision) { + final ExpressionType decisionExpressionType = findDecisionExpressionType(decision); + final EvaluationMode decisionEvaluationMode = Decision.DEFAULT_EVALUATION_MODE.equals(decision.getEvaluationMode()) ? null : decision.getEvaluationMode(); + final HitPolicy decisionHitPolicy = Decision.DEFAULT_HIT_POLICY.equals(decision.getHitPolicy()) ? null : decision.getHitPolicy(); + final YamlDecision yamlDecision = new YamlDecision(); yamlDecision.setId(decision.getId()); yamlDecision.setName(decision.getName()); - yamlDecision.setExpressionType(decision.getExpressionType()); - yamlDecision.setEvaluationMode(decision.getEvaluationMode()); - yamlDecision.setHitPolicy(decision.getHitPolicy()); - yamlDecision.setFields(createFields(decision.getInputs(), decision.getOutputs())); + yamlDecision.setExpressionType(Decision.DEFAULT_EXPRESSION_TYPE.equals(decisionExpressionType) ? null : decisionExpressionType); + yamlDecision.setEvaluationMode(decisionEvaluationMode); + yamlDecision.setHitPolicy(decisionHitPolicy); + yamlDecision.setFields(createFields(decision.getInputs(), decision.getOutputs(), decisionEvaluationMode, decisionExpressionType)); final Map inputsMap = decision.getInputs() .stream() @@ -54,13 +63,35 @@ public YamlDecision to(final Decision decision) { yamlDecision.setRules(decision.getRules() .stream() - .map(rule -> ruleToYamlRule(rule, inputsMap)) + .map(rule -> ruleToYamlRule(rule, inputsMap, decisionExpressionType)) .collect(Collectors.toList())); return yamlDecision; } - private YamlFields createFields(final List inputs, final List outputs) { + private ExpressionType findDecisionExpressionType(final Decision decision) { + final ExpressionType expressionType = decision.getRules().get(0).getInputEntries().get(0).getExpression().getType(); + + for (Rule rule : decision.getRules()) { + for (InputEntry inputEntry : rule.getInputEntries()) { + if (!expressionType.equals(inputEntry.getExpression().getType())) { + return decision.getExpressionType(); + } + } + for (OutputEntry outputEntry : rule.getOutputEntries()) { + if (!expressionType.equals(outputEntry.getExpression().getType())) { + return decision.getExpressionType(); + } + } + } + + return expressionType; + } + + private YamlFields createFields(final List inputs, + final List outputs, + final EvaluationMode decisionEvaluationMode, + final ExpressionType decisionExpressionType) { final YamlFields yamlFields = new YamlFields(); final LinkedHashMap in = new LinkedHashMap<>(); yamlFields.setIn(in); @@ -71,19 +102,18 @@ private YamlFields createFields(final List inputs, final List out final YamlInput yamlInput = new YamlInput(); yamlInput.setDescription(input.getDescription()); yamlInput.setType(input.getType()); - yamlInput.setEvaluationMode(input.getEvaluationMode()); + + if (decisionEvaluationMode != null && !decisionEvaluationMode.equals(input.getEvaluationMode())) { + yamlInput.setEvaluationMode(input.getEvaluationMode()); + } if (!Input.DEFAULT_NAME_ALIAS.equals(input.getNameAlias())) { yamlInput.setNameAlias(input.getNameAlias()); } - if (input.getExpression() != null && input.getExpression().getValue() != null) { - yamlInput.setExpression(input.getExpression().getValue()); - yamlInput.setExpressionType( - input.getExpression().getType() == ExpressionType.LITERAL ? null : input - .getExpression() - .getType()); - + yamlInput.setExpression(input.getExpression().getValue()); + if (!decisionExpressionType.equals(input.getExpression().getType())) { + yamlInput.setExpressionType(input.getExpression().getType()); } in.put(input.getName(), yamlInput); @@ -100,7 +130,7 @@ private YamlFields createFields(final List inputs, final List out return yamlFields; } - private YamlRule ruleToYamlRule(final Rule rule, final Map inputsMap) { + private YamlRule ruleToYamlRule(final Rule rule, final Map inputsMap, final ExpressionType decisionExpressionType) { final YamlRule yamlRule = new YamlRule(); yamlRule.setDescription(rule.getDescription()); final LinkedHashMap in = new LinkedHashMap<>(); @@ -109,14 +139,20 @@ private YamlRule ruleToYamlRule(final Rule rule, final Map inputs yamlRule.setOut(out); rule.getInputEntries().forEach(inputEntry -> { + final Input input = inputsMap.get(inputEntry.getName()); final YamlInputEntry yamlInputEntry = new YamlInputEntry(); - yamlInputEntry.setExpressionType(inputEntry.getExpression().getType()); + yamlInputEntry.setExpression(inputEntry.getExpression().getValue()); - yamlInputEntry.setEvaluationMode(inputEntry.getEvaluationMode()); - final Input input = inputsMap.get(inputEntry.getName()); + if (!inputEntry.getExpression().getType().equals(decisionExpressionType)) { + yamlInputEntry.setExpressionType(inputEntry.getExpression().getType()); + } - if (inputEntry.getNameAlias() != null && !inputEntry.getNameAlias().equals(input.getNameAlias())) { + if (!input.getEvaluationMode().equals(inputEntry.getEvaluationMode())) { + yamlInputEntry.setEvaluationMode(inputEntry.getEvaluationMode()); + } + + if (!inputEntry.getNameAlias().equals(input.getNameAlias())) { yamlInputEntry.setNameAlias(inputEntry.getNameAlias()); } @@ -125,7 +161,10 @@ private YamlRule ruleToYamlRule(final Rule rule, final Map inputs rule.getOutputEntries().forEach(outputEntry -> { final YamlOutputEntry yamlOutputEntry = new YamlOutputEntry(); - yamlOutputEntry.setExpressionType(outputEntry.getExpression().getType()); + if (!outputEntry.getExpression().getType().equals(decisionExpressionType)) { + yamlOutputEntry.setExpressionType(outputEntry.getExpression().getType()); + } + yamlOutputEntry.setExpression(outputEntry.getExpression().getValue()); out.put(outputEntry.getName(), yamlOutputEntry); @@ -138,14 +177,22 @@ private YamlRule ruleToYamlRule(final Rule rule, final Map inputs public Decision from(final YamlDecision model) { final Decision.Builder builder = Decision.builder(); builder.id(model.getId()) - .name(model.getName()) - .expressionType(model.getExpressionType()) - .evaluationMode(model.getEvaluationMode()) - .hitPolicy(model.getHitPolicy()); + .name(model.getName()); + + if (model.getExpressionType() != null) { + builder.expressionType(model.getExpressionType()); + } + + if (model.getEvaluationMode() != null) { + builder.evaluationMode(model.getEvaluationMode()); + } + + if (model.getHitPolicy() != null) { + builder.hitPolicy(model.getHitPolicy()); + } model.getFields().getIn().forEach((name, input) -> builder .withInput(inputBuilder -> { - if (input.getNameAlias() != null) { inputBuilder.nameAlias(input.getNameAlias()); } diff --git a/src/main/java/org/powerflows/dmn/io/yaml/model/YamlDecision.java b/src/main/java/org/powerflows/dmn/io/yaml/model/YamlDecision.java index f6d66a9..472eb42 100644 --- a/src/main/java/org/powerflows/dmn/io/yaml/model/YamlDecision.java +++ b/src/main/java/org/powerflows/dmn/io/yaml/model/YamlDecision.java @@ -29,9 +29,9 @@ public final class YamlDecision { private String id; private String name; - private HitPolicy hitPolicy = HitPolicy.UNIQUE; - private ExpressionType expressionType = ExpressionType.LITERAL; - private EvaluationMode evaluationMode = EvaluationMode.BOOLEAN; + private HitPolicy hitPolicy; + private ExpressionType expressionType; + private EvaluationMode evaluationMode; private YamlFields fields; private List rules; } diff --git a/src/main/java/org/powerflows/dmn/io/yaml/model/field/YamlInput.java b/src/main/java/org/powerflows/dmn/io/yaml/model/field/YamlInput.java index 4844cca..507cdc5 100644 --- a/src/main/java/org/powerflows/dmn/io/yaml/model/field/YamlInput.java +++ b/src/main/java/org/powerflows/dmn/io/yaml/model/field/YamlInput.java @@ -26,7 +26,7 @@ public final class YamlInput { private String description; private String nameAlias; private ValueType type; - private ExpressionType expressionType = ExpressionType.LITERAL; + private ExpressionType expressionType; private Object expression; private EvaluationMode evaluationMode; diff --git a/src/main/java/org/powerflows/dmn/io/yaml/model/rule/entry/YamlInputEntry.java b/src/main/java/org/powerflows/dmn/io/yaml/model/rule/entry/YamlInputEntry.java index a6473b0..00908bb 100644 --- a/src/main/java/org/powerflows/dmn/io/yaml/model/rule/entry/YamlInputEntry.java +++ b/src/main/java/org/powerflows/dmn/io/yaml/model/rule/entry/YamlInputEntry.java @@ -30,7 +30,7 @@ public YamlInputEntry() { } private String nameAlias; - private ExpressionType expressionType = ExpressionType.LITERAL; + private ExpressionType expressionType; private Object expression; private EvaluationMode evaluationMode; } diff --git a/src/main/java/org/powerflows/dmn/io/yaml/model/rule/entry/YamlOutputEntry.java b/src/main/java/org/powerflows/dmn/io/yaml/model/rule/entry/YamlOutputEntry.java index 4a86647..fd826c3 100644 --- a/src/main/java/org/powerflows/dmn/io/yaml/model/rule/entry/YamlOutputEntry.java +++ b/src/main/java/org/powerflows/dmn/io/yaml/model/rule/entry/YamlOutputEntry.java @@ -28,6 +28,6 @@ public YamlOutputEntry(final Object value) { public YamlOutputEntry() { } - private ExpressionType expressionType = ExpressionType.LITERAL; + private ExpressionType expressionType; private Object expression; } diff --git a/src/test/groovy/org/powerflows/dmn/engine/model/decision/DecisionSpec.groovy b/src/test/groovy/org/powerflows/dmn/engine/model/decision/DecisionSpec.groovy index 9954da4..8a22dae 100644 --- a/src/test/groovy/org/powerflows/dmn/engine/model/decision/DecisionSpec.groovy +++ b/src/test/groovy/org/powerflows/dmn/engine/model/decision/DecisionSpec.groovy @@ -180,7 +180,7 @@ class DecisionSpec extends Specification { final Expression input1Expression2 = input2.getExpression() with(input1Expression2) { - getType() == ExpressionType.LITERAL + getType() == someExpressionType getValue() == null } @@ -494,7 +494,7 @@ class DecisionSpec extends Specification { final Expression rule2OutputEntry2Expression = rule2OutputEntry2.getExpression() with(rule2OutputEntry2Expression) { - getType() == ExpressionType.LITERAL + getType() == someExpressionType getValue() == someRule2OutputEntry2ExpressionValue } } diff --git a/src/test/groovy/org/powerflows/dmn/engine/model/decision/DecisionUtilSpec.groovy b/src/test/groovy/org/powerflows/dmn/engine/model/decision/DecisionUtilSpec.groovy index 495988c..60c7a7e 100644 --- a/src/test/groovy/org/powerflows/dmn/engine/model/decision/DecisionUtilSpec.groovy +++ b/src/test/groovy/org/powerflows/dmn/engine/model/decision/DecisionUtilSpec.groovy @@ -75,7 +75,7 @@ class DecisionUtilSpec extends Specification { input2.expression.type == ExpressionType.GROOVY input2.evaluationMode == EvaluationMode.INPUT_COMPARISON - inputEntry1.expression.type == ExpressionType.FEEL + inputEntry1.expression.type == ExpressionType.GROOVY inputEntry1.evaluationMode == EvaluationMode.BOOLEAN inputEntry1.nameAlias == input1NameAlias inputEntry2.expression.type == ExpressionType.LITERAL diff --git a/src/test/groovy/org/powerflows/dmn/io/yaml/YamlDecisionConverterSpec.groovy b/src/test/groovy/org/powerflows/dmn/io/yaml/YamlDecisionConverterSpec.groovy new file mode 100644 index 0000000..2dbcfeb --- /dev/null +++ b/src/test/groovy/org/powerflows/dmn/io/yaml/YamlDecisionConverterSpec.groovy @@ -0,0 +1,230 @@ +/* + * Copyright (c) 2018-present PowerFlows.org - all rights reserved. + * + * Licensed 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.powerflows.dmn.io.yaml + +import org.powerflows.dmn.engine.model.decision.Decision +import org.powerflows.dmn.engine.model.decision.EvaluationMode +import org.powerflows.dmn.engine.model.decision.HitPolicy +import org.powerflows.dmn.engine.model.decision.expression.ExpressionType +import org.powerflows.dmn.engine.model.decision.field.ValueType +import org.powerflows.dmn.io.yaml.model.YamlDecision +import spock.lang.Specification + +class YamlDecisionConverterSpec extends Specification { + + private final YamlDecisionConverter converter = new YamlDecisionConverter(); + + void 'should convert simple decision to yaml '() { + given: + final InputStream inputStream = this.class.getResourceAsStream('converter-simple.yml') + final Decision decision = new YamlDecisionReader().read(inputStream).get() + + when: + final YamlDecision yamlDecision = converter.to(decision) + + then: + yamlDecision != null + + with(yamlDecision) { + getId() == 'some_table_id' + getName() == 'Some Table Name' + getHitPolicy() == null + getExpressionType() == null + getEvaluationMode() == null + getFields().getIn().size() == 2 + getFields().getOut().size() == 1 + getRules().size() == 1 + } + + with(yamlDecision.getFields().getIn().get('inputOne')) { + getType() == ValueType.INTEGER + getEvaluationMode() == null + getExpressionType() == null + getExpression() == null + getNameAlias() == null + getDescription() == null + } + + with(yamlDecision.getFields().getIn().get('inputTwo')) { + getType() == ValueType.STRING + getEvaluationMode() == null + getExpressionType() == null + getExpression() == null + getNameAlias() == null + getDescription() == null + } + + with(yamlDecision.getFields().getOut().get('outputOne')) { + getType() == ValueType.BOOLEAN + getDescription() == null + } + + yamlDecision.getRules().get(0).getDescription() == null + + with(yamlDecision.getRules().get(0).getIn().get('inputOne')) { + getEvaluationMode() == null + getExpressionType() == null + getExpression() == '> 20' + getNameAlias() == null + } + + with(yamlDecision.getRules().get(0).getIn().get('inputTwo')) { + getEvaluationMode() == null + getExpressionType() == null + getExpression() == 3 + getNameAlias() == null + } + + with(yamlDecision.getRules().get(0).getOut().get('outputOne')) { + getExpressionType() == null + getExpression() == 'someVariable1 || someVariable2' + } + } + + void 'should convert simple with expression type decision to yaml '() { + given: + final InputStream inputStream = this.class.getResourceAsStream('converter-simple-with-expression-type.yml') + final Decision decision = new YamlDecisionReader().read(inputStream).get() + + when: + final YamlDecision yamlDecision = converter.to(decision) + + then: + yamlDecision != null + + with(yamlDecision) { + getId() == 'some_table_id' + getName() == 'Some Table Name' + getHitPolicy() == null + getExpressionType() == null + getEvaluationMode() == null + getFields().getIn().size() == 2 + getFields().getOut().size() == 1 + getRules().size() == 1 + } + + with(yamlDecision.getFields().getIn().get('inputOne')) { + getType() == ValueType.INTEGER + getEvaluationMode() == null + getExpressionType() == null + getExpression() == null + getNameAlias() == null + getDescription() == null + } + + with(yamlDecision.getFields().getIn().get('inputTwo')) { + getType() == ValueType.STRING + getEvaluationMode() == null + getExpressionType() == null + getExpression() == null + getNameAlias() == null + getDescription() == null + } + + with(yamlDecision.getFields().getOut().get('outputOne')) { + getType() == ValueType.BOOLEAN + getDescription() == null + } + + yamlDecision.getRules().get(0).getDescription() == null + + with(yamlDecision.getRules().get(0).getIn().get('inputOne')) { + getEvaluationMode() == null + getExpressionType() == ExpressionType.JUEL + getExpression() == '> 20' + getNameAlias() == null + } + + with(yamlDecision.getRules().get(0).getIn().get('inputTwo')) { + getEvaluationMode() == null + getExpressionType() == ExpressionType.JUEL + getExpression() == 3 + getNameAlias() == null + } + + with(yamlDecision.getRules().get(0).getOut().get('outputOne')) { + getExpressionType() == ExpressionType.JAVASCRIPT + getExpression() == 'someVariable1 || someVariable2' + } + } + + void 'should convert advanced decision to yaml'() { + given: + final InputStream inputStream = this.class.getResourceAsStream('converter-advanced.yml') + final Decision decision = new YamlDecisionReader().read(inputStream).get() + + when: + final YamlDecision yamlDecision = converter.to(decision) + + then: + yamlDecision != null + + with(yamlDecision) { + getId() == 'some_table_id' + getName() == 'Some Table Name' + getHitPolicy() == HitPolicy.COLLECT + getExpressionType() == ExpressionType.GROOVY + getEvaluationMode() == EvaluationMode.INPUT_COMPARISON + getFields().getIn().size() == 2 + getFields().getOut().size() == 1 + getRules().size() == 1 + } + + with(yamlDecision.getFields().getIn().get('inputOne')) { + getType() == ValueType.INTEGER + getEvaluationMode() == EvaluationMode.BOOLEAN + getExpressionType() == ExpressionType.JAVASCRIPT + getExpression() == null + getNameAlias() == 'inputOneAlias' + getDescription() == null + } + + with(yamlDecision.getFields().getIn().get('inputTwo')) { + getType() == ValueType.STRING + getEvaluationMode() == null + getExpressionType() == ExpressionType.FEEL + getExpression() == null + getNameAlias() == 'inputTwoAlias' + getDescription() == null + } + + with(yamlDecision.getFields().getOut().get('outputOne')) { + getType() == ValueType.BOOLEAN + getDescription() == null + } + + yamlDecision.getRules().get(0).getDescription() == null + + with(yamlDecision.getRules().get(0).getIn().get('inputOne')) { + getEvaluationMode() == EvaluationMode.INPUT_COMPARISON + getExpressionType() == ExpressionType.JUEL + getExpression() == '> 20' + getNameAlias() == 'inputOneAliasOverridden' + } + + with(yamlDecision.getRules().get(0).getIn().get('inputTwo')) { + getEvaluationMode() == EvaluationMode.BOOLEAN + getExpressionType() == ExpressionType.JAVASCRIPT + getExpression() == 3 + getNameAlias() == null + } + + with(yamlDecision.getRules().get(0).getOut().get('outputOne')) { + getExpressionType() == ExpressionType.JUEL + getExpression() == 'someVariable1 || someVariable2' + } + } +} diff --git a/src/test/groovy/org/powerflows/dmn/io/yaml/YamlDecisionReaderSpec.groovy b/src/test/groovy/org/powerflows/dmn/io/yaml/YamlDecisionReaderSpec.groovy index 51500fd..0e20bad 100644 --- a/src/test/groovy/org/powerflows/dmn/io/yaml/YamlDecisionReaderSpec.groovy +++ b/src/test/groovy/org/powerflows/dmn/io/yaml/YamlDecisionReaderSpec.groovy @@ -112,7 +112,7 @@ class YamlDecisionReaderSpec extends Specification { with(decision.inputs[1]) { name == 'colour' expression.value == null - expression.type == ExpressionType.LITERAL + expression.type == ExpressionType.GROOVY description == 'This is something about colour' type == ValueType.STRING } @@ -126,37 +126,37 @@ class YamlDecisionReaderSpec extends Specification { with(decision.rules[0]) { description == '3 allows always' inputEntries[0].name == 'age' - inputEntries[0].expression.type == ExpressionType.LITERAL + inputEntries[0].expression.type == ExpressionType.GROOVY inputEntries[0].expression.value == 3 outputEntries[0].name == 'allow' - outputEntries[0].expression.type == ExpressionType.LITERAL + outputEntries[0].expression.type == ExpressionType.GROOVY outputEntries[0].expression.value == true } with(decision.rules[1]) { description == null inputEntries[0].name == 'age' - inputEntries[0].expression.type == ExpressionType.LITERAL + inputEntries[0].expression.type == ExpressionType.GROOVY inputEntries[0].expression.value == 8 inputEntries[1].name == 'colour' - inputEntries[1].expression.type == ExpressionType.LITERAL + inputEntries[1].expression.type == ExpressionType.GROOVY inputEntries[1].expression.value == 'red' outputEntries[0].name == 'allow' - outputEntries[0].expression.type == ExpressionType.LITERAL + outputEntries[0].expression.type == ExpressionType.GROOVY outputEntries[0].expression.value == true } with(decision.rules[2]) { description == 'Green allows always' inputEntries[0].name == 'colour' - inputEntries[0].expression.type == ExpressionType.LITERAL + inputEntries[0].expression.type == ExpressionType.GROOVY inputEntries[0].expression.value == 'green' outputEntries[0].name == 'allow' - outputEntries[0].expression.type == ExpressionType.LITERAL + outputEntries[0].expression.type == ExpressionType.GROOVY outputEntries[0].expression.value == true } @@ -168,11 +168,11 @@ class YamlDecisionReaderSpec extends Specification { inputEntries[0].expression.value == 'not("blue", "purple")' inputEntries[1].name == 'age' - inputEntries[1].expression.type == ExpressionType.LITERAL + inputEntries[1].expression.type == ExpressionType.GROOVY inputEntries[1].expression.value == 10 outputEntries[0].name == 'allow' - outputEntries[0].expression.type == ExpressionType.LITERAL + outputEntries[0].expression.type == ExpressionType.GROOVY outputEntries[0].expression.value == true } @@ -184,11 +184,11 @@ class YamlDecisionReaderSpec extends Specification { inputEntries[0].expression.value == 'not( "red", "pink" )' inputEntries[1].name == 'age' - inputEntries[1].expression.type == ExpressionType.LITERAL + inputEntries[1].expression.type == ExpressionType.GROOVY inputEntries[1].expression.value == 20 outputEntries[0].name == 'allow' - outputEntries[0].expression.type == ExpressionType.LITERAL + outputEntries[0].expression.type == ExpressionType.GROOVY outputEntries[0].expression.value == true } diff --git a/src/test/groovy/org/powerflows/dmn/io/yaml/YamlDecisionWriterSpec.groovy b/src/test/groovy/org/powerflows/dmn/io/yaml/YamlDecisionWriterSpec.groovy index bbf6a8c..a46e780 100644 --- a/src/test/groovy/org/powerflows/dmn/io/yaml/YamlDecisionWriterSpec.groovy +++ b/src/test/groovy/org/powerflows/dmn/io/yaml/YamlDecisionWriterSpec.groovy @@ -27,7 +27,7 @@ class YamlDecisionWriterSpec extends Specification { final String someTableId1 = 'some_table_id_1' final String someTableId2 = 'some_table_id_2' final String someTableName = 'Some Table Name' - final HitPolicy someHitPolicy = HitPolicy.UNIQUE + final HitPolicy someHitPolicy = HitPolicy.COLLECT final ExpressionType someExpressionType = ExpressionType.GROOVY final EvaluationMode someEvaluationMode1 = EvaluationMode.BOOLEAN final EvaluationMode someEvaluationMode2 = EvaluationMode.INPUT_COMPARISON @@ -149,12 +149,12 @@ class YamlDecisionWriterSpec extends Specification { result.hitPolicy == decision.hitPolicy result.name == decision.name result.inputs[0].name == decision.inputs[0].name - result.inputs[0].evaluationMode == decision.evaluationMode + result.inputs[0].evaluationMode == decision.inputs[0].evaluationMode result.inputs[0].type == decision.inputs[0].type result.inputs[0].description == decision.inputs[0].description result.inputs[0].expression == decision.inputs[0].expression result.inputs[1].name == decision.inputs[1].name - result.inputs[1].evaluationMode == decision.evaluationMode + result.inputs[1].evaluationMode == decision.inputs[1].evaluationMode result.inputs[1].type == decision.inputs[1].type result.inputs[1].description == decision.inputs[1].description result.inputs[1].expression == decision.inputs[1].expression @@ -168,22 +168,23 @@ class YamlDecisionWriterSpec extends Specification { result.rules[0].description == decision.rules[0].description result.rules[0].inputEntries.size() == 2 result.rules[0].inputEntries[0].expression == decision.rules[0].inputEntries[0].expression - result.rules[0].inputEntries[0].evaluationMode == decision.evaluationMode + result.rules[0].inputEntries[0].evaluationMode == decision.rules[0].inputEntries[0].evaluationMode result.rules[0].inputEntries[0].name == decision.rules[0].inputEntries[0].name result.rules[0].inputEntries[1].expression == decision.rules[0].inputEntries[1].expression - result.rules[0].inputEntries[1].evaluationMode == decision.evaluationMode + result.rules[0].inputEntries[1].evaluationMode == decision.rules[0].inputEntries[1].evaluationMode result.rules[0].inputEntries[1].name == decision.rules[0].inputEntries[1].name result.rules[0].outputEntries.size() == 1 - result.rules[0].outputEntries[0].expression == decision.rules[0].outputEntries[0].expression + result.rules[0].outputEntries[0].expression.value == decision.rules[0].outputEntries[0].expression.value + result.rules[0].outputEntries[0].expression.type == decision.rules[0].outputEntries[0].expression.type result.rules[0].outputEntries[0].name == decision.rules[0].outputEntries[0].name result.rules[1].description == decision.rules[1].description result.rules[1].inputEntries.size() == 2 result.rules[1].inputEntries[0].expression == decision.rules[1].inputEntries[0].expression - result.rules[1].inputEntries[0].evaluationMode == decision.evaluationMode + result.rules[1].inputEntries[0].evaluationMode == decision.rules[1].inputEntries[0].evaluationMode result.rules[1].inputEntries[0].name == decision.rules[1].inputEntries[0].name result.rules[1].inputEntries[1].expression == decision.rules[1].inputEntries[1].expression - result.rules[1].inputEntries[1].evaluationMode == decision.evaluationMode + result.rules[1].inputEntries[1].evaluationMode == decision.rules[1].inputEntries[1].evaluationMode result.rules[1].inputEntries[1].name == decision.rules[1].inputEntries[1].name result.rules[1].outputEntries.size() == 2 result.rules[1].outputEntries[0].expression == decision.rules[1].outputEntries[0].expression diff --git a/src/test/resources/org/powerflows/dmn/io/yaml/converter-advanced.yml b/src/test/resources/org/powerflows/dmn/io/yaml/converter-advanced.yml new file mode 100644 index 0000000..845bda9 --- /dev/null +++ b/src/test/resources/org/powerflows/dmn/io/yaml/converter-advanced.yml @@ -0,0 +1,35 @@ +id: some_table_id +name: Some Table Name +hit-policy: COLLECT +expression-type: GROOVY +evaluation-mode: INPUT_COMPARISON +fields: + in: + inputOne: + name-alias: inputOneAlias + type: INTEGER + expression-type: JAVASCRIPT + evaluation-mode: BOOLEAN + inputTwo: + name-alias: inputTwoAlias + type: STRING + expression-type: FEEL + evaluation-mode: INPUT_COMPARISON + out: + outputOne: + type: BOOLEAN +rules: +- in: + inputOne: + name-alias: inputOneAliasOverridden + expression: '> 20' + expression-type: JUEL + evaluation-mode: INPUT_COMPARISON + inputTwo: + expression: 3 + expression-type: JAVASCRIPT + evaluation-mode: BOOLEAN + out: + outputOne: + expression: someVariable1 || someVariable2 + expression-type: JUEL diff --git a/src/test/resources/org/powerflows/dmn/io/yaml/converter-simple-with-expression-type.yml b/src/test/resources/org/powerflows/dmn/io/yaml/converter-simple-with-expression-type.yml new file mode 100644 index 0000000..271e5f5 --- /dev/null +++ b/src/test/resources/org/powerflows/dmn/io/yaml/converter-simple-with-expression-type.yml @@ -0,0 +1,23 @@ +id: some_table_id +name: Some Table Name +fields: + in: + inputOne: + type: INTEGER + inputTwo: + type: STRING + out: + outputOne: + type: BOOLEAN +rules: +- in: + inputOne: + expression: '> 20' + expression-type: JUEL + inputTwo: + expression: 3 + expression-type: JUEL + out: + outputOne: + expression: someVariable1 || someVariable2 + expression-type: JAVASCRIPT diff --git a/src/test/resources/org/powerflows/dmn/io/yaml/converter-simple.yml b/src/test/resources/org/powerflows/dmn/io/yaml/converter-simple.yml new file mode 100644 index 0000000..47e54b4 --- /dev/null +++ b/src/test/resources/org/powerflows/dmn/io/yaml/converter-simple.yml @@ -0,0 +1,17 @@ +id: some_table_id +name: Some Table Name +fields: + in: + inputOne: + type: INTEGER + inputTwo: + type: STRING + out: + outputOne: + type: BOOLEAN +rules: +- in: + inputOne: '> 20' + inputTwo: 3 + out: + outputOne: someVariable1 || someVariable2 \ No newline at end of file diff --git a/src/test/resources/org/powerflows/dmn/io/yaml/reference-multiple.yml b/src/test/resources/org/powerflows/dmn/io/yaml/reference-multiple.yml index ed8b10b..3b9d00c 100644 --- a/src/test/resources/org/powerflows/dmn/io/yaml/reference-multiple.yml +++ b/src/test/resources/org/powerflows/dmn/io/yaml/reference-multiple.yml @@ -1,6 +1,6 @@ id: some_table_id_1 name: Some Table Name -hit-policy: UNIQUE +hit-policy: COLLECT expression-type: GROOVY evaluation-mode: INPUT_COMPARISON fields: @@ -10,8 +10,10 @@ fields: type: INTEGER expression-type: FEEL expression: '> 5' + evaluation-mode: BOOLEAN inputTwo: type: INTEGER + evaluation-mode: BOOLEAN out: outputOne: description: Some Output 1 Description @@ -22,30 +24,34 @@ fields: rules: - description: Some Rule 1 Description in: - inputOne: - expression-type: GROOVY - expression: '> 20' + inputOne: '> 20' inputTwo: expression-type: FEEL expression: not("blue", "purple") out: - outputOne: - expression-type: GROOVY - expression: someVariable1 || someVariable2 + outputOne: someVariable1 || someVariable2 - in: - inputOne: 5 + inputOne: + expression-type: LITERAL + expression: 5 inputTwo: - - one - - two + expression-type: LITERAL + expression: + - one + - two out: - outputOne: true + outputOne: + expression-type: LITERAL + expression: true outputTwo: - - The output value 1 - - The output value 2 + expression-type: LITERAL + expression: + - The output value 1 + - The output value 2 --- id: some_table_id_2 name: Some Table Name -hit-policy: UNIQUE +hit-policy: COLLECT expression-type: GROOVY evaluation-mode: INPUT_COMPARISON fields: @@ -55,8 +61,10 @@ fields: type: INTEGER expression-type: FEEL expression: '> 5' + evaluation-mode: BOOLEAN inputTwo: type: INTEGER + evaluation-mode: BOOLEAN out: outputOne: description: Some Output 1 Description @@ -67,23 +75,27 @@ fields: rules: - description: Some Rule 1 Description in: - inputOne: - expression-type: GROOVY - expression: '> 20' + inputOne: '> 20' inputTwo: expression-type: FEEL expression: not("blue", "purple") out: - outputOne: - expression-type: GROOVY - expression: someVariable1 || someVariable2 + outputOne: someVariable1 || someVariable2 - in: - inputOne: 5 + inputOne: + expression-type: LITERAL + expression: 5 inputTwo: - - one - - two + expression-type: LITERAL + expression: + - one + - two out: - outputOne: true + outputOne: + expression-type: LITERAL + expression: true outputTwo: - - The output value 1 - - The output value 2 + expression-type: LITERAL + expression: + - The output value 1 + - The output value 2 diff --git a/src/test/resources/org/powerflows/dmn/io/yaml/reference-single.yml b/src/test/resources/org/powerflows/dmn/io/yaml/reference-single.yml index ec9376a..9a24f68 100644 --- a/src/test/resources/org/powerflows/dmn/io/yaml/reference-single.yml +++ b/src/test/resources/org/powerflows/dmn/io/yaml/reference-single.yml @@ -1,6 +1,6 @@ id: some_table_id_1 name: Some Table Name -hit-policy: UNIQUE +hit-policy: COLLECT expression-type: GROOVY evaluation-mode: INPUT_COMPARISON fields: @@ -10,8 +10,10 @@ fields: type: INTEGER expression-type: FEEL expression: '> 5' + evaluation-mode: BOOLEAN inputTwo: type: INTEGER + evaluation-mode: BOOLEAN out: outputOne: description: Some Output 1 Description @@ -22,23 +24,27 @@ fields: rules: - description: Some Rule 1 Description in: - inputOne: - expression-type: GROOVY - expression: '> 20' + inputOne: '> 20' inputTwo: expression-type: FEEL expression: not("blue", "purple") out: - outputOne: - expression-type: GROOVY - expression: someVariable1 || someVariable2 + outputOne: someVariable1 || someVariable2 - in: - inputOne: 5 + inputOne: + expression-type: LITERAL + expression: 5 inputTwo: - - one - - two + expression-type: LITERAL + expression: + - one + - two out: - outputOne: true + outputOne: + expression-type: LITERAL + expression: true outputTwo: - - The output value 1 - - The output value 2 + expression-type: LITERAL + expression: + - The output value 1 + - The output value 2