From 31b859db7ff20c0694309755d7ee52e3cb2ccbfb Mon Sep 17 00:00:00 2001 From: athira Date: Mon, 30 Dec 2024 11:19:58 +0530 Subject: [PATCH 01/15] [incubator-kie-issues-162105] Code fix to return list of dates --- .../java/org/kie/dmn/feel/lang/ast/ForExpressionNode.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/ForExpressionNode.java b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/ForExpressionNode.java index 1229c354457..62cf8889766 100644 --- a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/ForExpressionNode.java +++ b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/ForExpressionNode.java @@ -25,6 +25,7 @@ import org.kie.dmn.feel.lang.Type; import org.kie.dmn.feel.lang.ast.forexpressioniterators.ForIteration; import org.kie.dmn.feel.lang.types.BuiltInType; +import org.kie.dmn.feel.runtime.Range; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -132,8 +133,7 @@ private ForIteration createForIteration(EvaluationContext ctx, IterationContextN Object result = iterationContextNode.evaluate(ctx); Object rangeEnd = iterationContextNode.evaluateRangeEnd(ctx); if (rangeEnd == null) { - Iterable values = result instanceof Iterable iterable? iterable : Collections.singletonList(result); - toReturn = new ForIteration(name, values); + toReturn = (result instanceof Iterable iterable) ? new ForIteration(name, iterable) : getForIteration(ctx, name, ((Range) result).getLowEndPoint(), ((Range) result).getHighEndPoint()); } else { toReturn = getForIteration(ctx, name, result, rangeEnd); } From 0cefa71179450ce4761b7630766cf11d53636ba0 Mon Sep 17 00:00:00 2001 From: athira Date: Thu, 9 Jan 2025 12:29:23 +0530 Subject: [PATCH 02/15] [incubator-kie-issues-162105] WIP --- .../dmn/feel/lang/ast/ForExpressionNode.java | 11 +++++- .../ForIterationUtils.java | 37 +++++++++++++++++-- 2 files changed, 43 insertions(+), 5 deletions(-) diff --git a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/ForExpressionNode.java b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/ForExpressionNode.java index 62cf8889766..dc2ed857b12 100644 --- a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/ForExpressionNode.java +++ b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/ForExpressionNode.java @@ -33,6 +33,7 @@ import java.util.Collections; import java.util.List; +import static org.kie.dmn.feel.lang.ast.forexpressioniterators.ForIterationUtils.computeResultForRange; import static org.kie.dmn.feel.lang.ast.forexpressioniterators.ForIterationUtils.getForIteration; public class ForExpressionNode @@ -128,12 +129,18 @@ public Type getResultType() { private ForIteration createForIteration(EvaluationContext ctx, IterationContextNode iterationContextNode) { LOG.trace("Creating ForIteration for {}", iterationContextNode); - ForIteration toReturn; + ForIteration toReturn = null; String name = iterationContextNode.evaluateName(ctx); Object result = iterationContextNode.evaluate(ctx); Object rangeEnd = iterationContextNode.evaluateRangeEnd(ctx); if (rangeEnd == null) { - toReturn = (result instanceof Iterable iterable) ? new ForIteration(name, iterable) : getForIteration(ctx, name, ((Range) result).getLowEndPoint(), ((Range) result).getHighEndPoint()); + if (result instanceof Iterable iterable) { + new ForIteration(name, iterable); + } else if (result instanceof Range) { + toReturn = computeResultForRange(((Range) result), name, ctx, toReturn); + } else { + toReturn = new ForIteration(name, Collections.singletonList(result)); + } } else { toReturn = getForIteration(ctx, name, result, rangeEnd); } diff --git a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/forexpressioniterators/ForIterationUtils.java b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/forexpressioniterators/ForIterationUtils.java index 2e02c5df99c..d5ef90367bd 100644 --- a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/forexpressioniterators/ForIterationUtils.java +++ b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/forexpressioniterators/ForIterationUtils.java @@ -18,16 +18,18 @@ */ package org.kie.dmn.feel.lang.ast.forexpressioniterators; -import java.math.BigDecimal; -import java.time.LocalDate; - import org.kie.dmn.api.feel.runtime.events.FEELEvent; import org.kie.dmn.feel.exceptions.EndpointOfRangeNotValidTypeException; import org.kie.dmn.feel.exceptions.EndpointOfRangeOfDifferentTypeException; import org.kie.dmn.feel.lang.EvaluationContext; +import org.kie.dmn.feel.lang.ast.RangeNode; +import org.kie.dmn.feel.runtime.Range; import org.kie.dmn.feel.runtime.events.ASTEventBase; import org.kie.dmn.feel.util.Msg; +import java.math.BigDecimal; +import java.time.LocalDate; + public class ForIterationUtils { private ForIterationUtils() { @@ -63,4 +65,33 @@ static void valueMustBeValid(EvaluationContext ctx, Object value) { } } + public static ForIteration computeResultForRange(Range result, String name, EvaluationContext ctx, ForIteration toReturn) { + validateValues(ctx, result.getLowEndPoint(), result.getHighEndPoint()); + if (result.getLowEndPoint() instanceof BigDecimal && result.getHighEndPoint() instanceof BigDecimal) { + BigDecimal start = (BigDecimal) result.getLowEndPoint(); + BigDecimal end = (BigDecimal) result.getHighEndPoint(); + if (result.getLowEndPoint() == RangeNode.IntervalBoundary.OPEN) { + start = start.add(BigDecimal.ONE); + } + if (result.getHighEndPoint() == RangeNode.IntervalBoundary.OPEN) { + end = end.subtract(BigDecimal.ONE); + } + toReturn = getForIteration(ctx, name, start, end); + } else if (result.getLowEndPoint() instanceof LocalDate && result.getHighEndPoint() instanceof LocalDate) { + LocalDate start = (LocalDate) result.getLowEndPoint(); + LocalDate end = (LocalDate) result.getHighEndPoint(); + if (result.getLowEndPoint() == RangeNode.IntervalBoundary.OPEN) { + start = start.plusDays(1); + } + if (result.getHighEndPoint() == RangeNode.IntervalBoundary.OPEN) { + end = end.minusDays(1); + } + toReturn = getForIteration(ctx, name, start, end); + } else { + toReturn = getForIteration(ctx, name, result.getLowEndPoint(), result.getHighEndPoint()); + } + return toReturn; + } } + + From 4a190d4b0d4e066d1d59fe417a897f5145897178 Mon Sep 17 00:00:00 2001 From: athira Date: Thu, 9 Jan 2025 19:44:04 +0530 Subject: [PATCH 03/15] [incubator-kie-issues-162105] WIP --- .../org/kie/dmn/core/DMNInputRuntimeTest.java | 21 +++++++++++++++++++ .../ForIterationUtils.java | 4 ++-- .../dmn/feel/runtime/impl/RangeImplTest.java | 12 +++++++++++ 3 files changed, 35 insertions(+), 2 deletions(-) diff --git a/kie-dmn/kie-dmn-core/src/test/java/org/kie/dmn/core/DMNInputRuntimeTest.java b/kie-dmn/kie-dmn-core/src/test/java/org/kie/dmn/core/DMNInputRuntimeTest.java index 5f245869683..1001fb53b39 100644 --- a/kie-dmn/kie-dmn-core/src/test/java/org/kie/dmn/core/DMNInputRuntimeTest.java +++ b/kie-dmn/kie-dmn-core/src/test/java/org/kie/dmn/core/DMNInputRuntimeTest.java @@ -75,6 +75,27 @@ void inputStringEvaluateAll(boolean useExecModelCompiler) { assertThat( result.get( "Greeting Message" )).isEqualTo("Hello John Doe" ); } + + @ParameterizedTest + @MethodSource("params") + void evaluateRange(boolean useExecModelCompiler) { + init(useExecModelCompiler); + final DMNRuntime runtime = DMNRuntimeUtil.createRuntime( "0084-feel-for-loops.dmn", this.getClass() ); + final DMNModel dmnModel = runtime.getModel( "http://www.montera.com.au/spec/DMN/0084-feel-for-loops", "0084-feel-for-loops" ); + assertThat(dmnModel).isNotNull(); + + final DMNContext context = DMNFactory.newContext(); + context.set( "Full Name", "John Doe" ); + + final DMNResult dmnResult = runtime.evaluateByName( dmnModel, context, "decision_024" ); + + 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" ); + } @ParameterizedTest @MethodSource("params") void inputStringEvaluateDecisionByName(boolean useExecModelCompiler) { diff --git a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/forexpressioniterators/ForIterationUtils.java b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/forexpressioniterators/ForIterationUtils.java index d5ef90367bd..ddab3df060f 100644 --- a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/forexpressioniterators/ForIterationUtils.java +++ b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/forexpressioniterators/ForIterationUtils.java @@ -80,10 +80,10 @@ public static ForIteration computeResultForRange(Range result, String name, Eval } else if (result.getLowEndPoint() instanceof LocalDate && result.getHighEndPoint() instanceof LocalDate) { LocalDate start = (LocalDate) result.getLowEndPoint(); LocalDate end = (LocalDate) result.getHighEndPoint(); - if (result.getLowEndPoint() == RangeNode.IntervalBoundary.OPEN) { + if (result.getLowBoundary() == Range.RangeBoundary.OPEN) { start = start.plusDays(1); } - if (result.getHighEndPoint() == RangeNode.IntervalBoundary.OPEN) { + if (result.getHighBoundary() == Range.RangeBoundary.OPEN) { end = end.minusDays(1); } toReturn = getForIteration(ctx, name, start, end); diff --git a/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/runtime/impl/RangeImplTest.java b/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/runtime/impl/RangeImplTest.java index 521abb12fc7..8155c1dfde1 100644 --- a/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/runtime/impl/RangeImplTest.java +++ b/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/runtime/impl/RangeImplTest.java @@ -19,8 +19,12 @@ package org.kie.dmn.feel.runtime.impl; import org.junit.jupiter.api.Test; +import org.kie.dmn.feel.FEEL; +import org.kie.dmn.feel.lang.impl.FEELBuilder; import org.kie.dmn.feel.runtime.Range; +import java.util.List; + import static org.assertj.core.api.Assertions.assertThat; class RangeImplTest { @@ -159,4 +163,12 @@ void hashCodeTest() { rangeImpl2 = new RangeImpl(Range.RangeBoundary.CLOSED, 12, 17, Range.RangeBoundary.CLOSED); assertThat(rangeImpl2).doesNotHaveSameHashCodeAs(rangeImpl); } + + @Test + void testRangeExpansion() { + FEEL feel = FEELBuilder.builder().build(); + Object result = feel.evaluate("for i in @\"1980-01-01\"..@\"1980-01-03\" return i"); + assertThat(result.toString()).isEqualTo(List.of("1980-01-01", "1980-01-02", "1980-01-03")); + } + } \ No newline at end of file From bc073e10456f5c144339b9b0384d70575dcda174 Mon Sep 17 00:00:00 2001 From: athira Date: Thu, 9 Jan 2025 23:35:00 +0530 Subject: [PATCH 04/15] [incubator-kie-issues#1743] Updated test cases --- .../dmn/feel/lang/ast/ForExpressionNode.java | 2 +- .../ForIterationUtils.java | 58 +++++++++------- .../ForIterationUtilsTest.java | 68 ++++++++++++++++++- 3 files changed, 100 insertions(+), 28 deletions(-) diff --git a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/ForExpressionNode.java b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/ForExpressionNode.java index dc2ed857b12..06c80202820 100644 --- a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/ForExpressionNode.java +++ b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/ForExpressionNode.java @@ -137,7 +137,7 @@ private ForIteration createForIteration(EvaluationContext ctx, IterationContextN if (result instanceof Iterable iterable) { new ForIteration(name, iterable); } else if (result instanceof Range) { - toReturn = computeResultForRange(((Range) result), name, ctx, toReturn); + toReturn = computeResultForRange(((Range) result), name, ctx); } else { toReturn = new ForIteration(name, Collections.singletonList(result)); } diff --git a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/forexpressioniterators/ForIterationUtils.java b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/forexpressioniterators/ForIterationUtils.java index ddab3df060f..4f81b565c65 100644 --- a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/forexpressioniterators/ForIterationUtils.java +++ b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/forexpressioniterators/ForIterationUtils.java @@ -22,7 +22,6 @@ import org.kie.dmn.feel.exceptions.EndpointOfRangeNotValidTypeException; import org.kie.dmn.feel.exceptions.EndpointOfRangeOfDifferentTypeException; import org.kie.dmn.feel.lang.EvaluationContext; -import org.kie.dmn.feel.lang.ast.RangeNode; import org.kie.dmn.feel.runtime.Range; import org.kie.dmn.feel.runtime.events.ASTEventBase; import org.kie.dmn.feel.util.Msg; @@ -48,6 +47,17 @@ public static ForIteration getForIteration(EvaluationContext ctx, String name, O throw new EndpointOfRangeOfDifferentTypeException(); } + public static ForIteration computeResultForRange(Range result, String name, EvaluationContext ctx) { + validateValues(ctx, result.getLowEndPoint(), result.getHighEndPoint()); + if (result.getLowEndPoint() instanceof BigDecimal && result.getHighEndPoint() instanceof BigDecimal) { + return computeResultForBigDecimalRange(result,name,ctx); + } + if (result.getLowEndPoint() instanceof LocalDate && result.getHighEndPoint() instanceof LocalDate) { + return computeResultForLocalDateRange(result, name, ctx); + } + return null; + } + static void validateValues(EvaluationContext ctx, Object start, Object end) { if (start.getClass() != end.getClass()) { ctx.notifyEvt(() -> new ASTEventBase(FEELEvent.Severity.ERROR, @@ -65,32 +75,28 @@ static void valueMustBeValid(EvaluationContext ctx, Object value) { } } - public static ForIteration computeResultForRange(Range result, String name, EvaluationContext ctx, ForIteration toReturn) { - validateValues(ctx, result.getLowEndPoint(), result.getHighEndPoint()); - if (result.getLowEndPoint() instanceof BigDecimal && result.getHighEndPoint() instanceof BigDecimal) { - BigDecimal start = (BigDecimal) result.getLowEndPoint(); - BigDecimal end = (BigDecimal) result.getHighEndPoint(); - if (result.getLowEndPoint() == RangeNode.IntervalBoundary.OPEN) { - start = start.add(BigDecimal.ONE); - } - if (result.getHighEndPoint() == RangeNode.IntervalBoundary.OPEN) { - end = end.subtract(BigDecimal.ONE); - } - toReturn = getForIteration(ctx, name, start, end); - } else if (result.getLowEndPoint() instanceof LocalDate && result.getHighEndPoint() instanceof LocalDate) { - LocalDate start = (LocalDate) result.getLowEndPoint(); - LocalDate end = (LocalDate) result.getHighEndPoint(); - if (result.getLowBoundary() == Range.RangeBoundary.OPEN) { - start = start.plusDays(1); - } - if (result.getHighBoundary() == Range.RangeBoundary.OPEN) { - end = end.minusDays(1); - } - toReturn = getForIteration(ctx, name, start, end); - } else { - toReturn = getForIteration(ctx, name, result.getLowEndPoint(), result.getHighEndPoint()); + static ForIteration computeResultForBigDecimalRange(Range result, String name, EvaluationContext ctx) { + BigDecimal start = (BigDecimal) result.getLowEndPoint(); + BigDecimal end = (BigDecimal) result.getHighEndPoint(); + if (result.getLowBoundary() == Range.RangeBoundary.OPEN) { + start = start.add(BigDecimal.ONE); + } + if (result.getHighBoundary() == Range.RangeBoundary.OPEN) { + end = end.subtract(BigDecimal.ONE); + } + return getForIteration(ctx, name, start, end); + } + + static ForIteration computeResultForLocalDateRange(Range result, String name, EvaluationContext ctx) { + LocalDate start = (LocalDate) result.getLowEndPoint(); + LocalDate end = (LocalDate) result.getHighEndPoint(); + if (result.getLowBoundary() == Range.RangeBoundary.OPEN) { + start = start.plusDays(1); + } + if (result.getHighBoundary() == Range.RangeBoundary.OPEN) { + end = end.minusDays(1); } - return toReturn; + return getForIteration(ctx, name, start, end); } } diff --git a/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/lang/ast/forexpressioniterators/ForIterationUtilsTest.java b/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/lang/ast/forexpressioniterators/ForIterationUtilsTest.java index 852ed9e2057..302fcff448e 100644 --- a/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/lang/ast/forexpressioniterators/ForIterationUtilsTest.java +++ b/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/lang/ast/forexpressioniterators/ForIterationUtilsTest.java @@ -29,9 +29,13 @@ import org.kie.dmn.feel.exceptions.EndpointOfRangeOfDifferentTypeException; import org.kie.dmn.feel.lang.EvaluationContext; import org.kie.dmn.feel.lang.impl.FEELEventListenersManager; +import org.kie.dmn.feel.runtime.Range; import org.mockito.ArgumentCaptor; import static org.assertj.core.api.Assertions.assertThat; +import static org.kie.dmn.feel.lang.ast.forexpressioniterators.ForIterationUtils.computeResultForBigDecimalRange; +import static org.kie.dmn.feel.lang.ast.forexpressioniterators.ForIterationUtils.computeResultForLocalDateRange; +import static org.kie.dmn.feel.lang.ast.forexpressioniterators.ForIterationUtils.computeResultForRange; import static org.kie.dmn.feel.util.EvaluationContextTestUtil.newEmptyEvaluationContext; import static org.kie.dmn.feel.lang.ast.forexpressioniterators.ForIterationUtils.getForIteration; import static org.kie.dmn.feel.lang.ast.forexpressioniterators.ForIterationUtils.validateValues; @@ -42,6 +46,7 @@ import static org.mockito.Mockito.reset; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; class ForIterationUtilsTest { @@ -148,4 +153,65 @@ void validateValuesFalseTest() { reset(listener); } } -} \ No newline at end of file + + @Test + void testComputeResultForRange() { + Range range = mock(Range.class); + EvaluationContext ctx = mock(EvaluationContext.class); + + when(range.getLowBoundary()).thenReturn(Range.RangeBoundary.CLOSED); + when(range.getHighBoundary()).thenReturn(Range.RangeBoundary.OPEN); + when(range.getLowEndPoint()).thenReturn(new BigDecimal("10.0")); + when(range.getHighEndPoint()).thenReturn(new BigDecimal("20.0")); + ForIteration result = computeResultForRange(range, "rangeTest", ctx); + assertThat(result).isNotNull(); + } + + @Test + void testComputeResultForBigDecimalRangeOpenBoundary() { + Range range = mock(Range.class); + when(range.getLowBoundary()).thenReturn(Range.RangeBoundary.OPEN); + when(range.getHighBoundary()).thenReturn(Range.RangeBoundary.OPEN); + when(range.getLowEndPoint()).thenReturn(new BigDecimal("10.0")); + when(range.getHighEndPoint()).thenReturn(new BigDecimal("20.0")); + + ForIteration result = computeResultForBigDecimalRange(range, "BigDecimalRange", ctx); + assertThat(result).isNotNull(); + } + + @Test + void testComputeResultForBigDecimalRangeClosedBoundary() { + Range range = mock(Range.class); + when(range.getLowBoundary()).thenReturn(Range.RangeBoundary.CLOSED); + when(range.getHighBoundary()).thenReturn(Range.RangeBoundary.CLOSED); + when(range.getLowEndPoint()).thenReturn(new BigDecimal("10.0")); + when(range.getHighEndPoint()).thenReturn(new BigDecimal("20.0")); + + ForIteration result = computeResultForBigDecimalRange(range, "BigDecimalRange", ctx); + assertThat(result).isNotNull(); + } + + @Test + void testComputeResultForLocalDateRangeOpenBoundary() { + Range range = mock(Range.class); + when(range.getLowBoundary()).thenReturn(Range.RangeBoundary.OPEN); + when(range.getHighBoundary()).thenReturn(Range.RangeBoundary.OPEN); + when(range.getLowEndPoint()).thenReturn(LocalDate.of(2025, 1, 1)); + when(range.getHighEndPoint()).thenReturn(LocalDate.of(2025, 1, 7)); + + ForIteration result = computeResultForLocalDateRange(range, "dateRange", ctx); + assertThat(result).isNotNull(); + } + + @Test + void testComputeResultForLocalDateRangeClosedBoundary() { + Range range = mock(Range.class); + when(range.getLowBoundary()).thenReturn(Range.RangeBoundary.CLOSED); + when(range.getHighBoundary()).thenReturn(Range.RangeBoundary.CLOSED); + when(range.getLowEndPoint()).thenReturn(LocalDate.of(2025, 1, 1)); + when(range.getHighEndPoint()).thenReturn(LocalDate.of(2025, 1, 7)); + + ForIteration result = computeResultForLocalDateRange(range, "dateRange", ctx); + assertThat(result).isNotNull(); + } +} From 3f68c989e532ddec86679589c41598a3c8a214f6 Mon Sep 17 00:00:00 2001 From: athira Date: Fri, 10 Jan 2025 19:06:04 +0530 Subject: [PATCH 05/15] [incubator-kie-issues#1743] Code refactoring --- .../org/kie/dmn/core/DMNInputRuntimeTest.java | 23 ------------------- .../dmn/feel/lang/ast/ForExpressionNode.java | 2 +- 2 files changed, 1 insertion(+), 24 deletions(-) diff --git a/kie-dmn/kie-dmn-core/src/test/java/org/kie/dmn/core/DMNInputRuntimeTest.java b/kie-dmn/kie-dmn-core/src/test/java/org/kie/dmn/core/DMNInputRuntimeTest.java index 1001fb53b39..136aa0102a2 100644 --- a/kie-dmn/kie-dmn-core/src/test/java/org/kie/dmn/core/DMNInputRuntimeTest.java +++ b/kie-dmn/kie-dmn-core/src/test/java/org/kie/dmn/core/DMNInputRuntimeTest.java @@ -25,7 +25,6 @@ import java.util.List; import java.util.Set; -import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; import org.kie.dmn.api.core.DMNContext; @@ -43,7 +42,6 @@ import org.kie.dmn.api.core.event.AfterConditionalEvaluationEvent; import org.kie.dmn.api.core.event.AfterEvaluateConditionalEvent; import org.kie.dmn.api.core.event.AfterEvaluateDecisionTableEvent; -import org.kie.dmn.api.core.event.DMNRuntimeEventListener; import org.kie.dmn.core.api.DMNFactory; import org.kie.dmn.core.api.event.DefaultDMNRuntimeEventListener; import org.kie.dmn.core.util.DMNRuntimeUtil; @@ -75,27 +73,6 @@ void inputStringEvaluateAll(boolean useExecModelCompiler) { assertThat( result.get( "Greeting Message" )).isEqualTo("Hello John Doe" ); } - - @ParameterizedTest - @MethodSource("params") - void evaluateRange(boolean useExecModelCompiler) { - init(useExecModelCompiler); - final DMNRuntime runtime = DMNRuntimeUtil.createRuntime( "0084-feel-for-loops.dmn", this.getClass() ); - final DMNModel dmnModel = runtime.getModel( "http://www.montera.com.au/spec/DMN/0084-feel-for-loops", "0084-feel-for-loops" ); - assertThat(dmnModel).isNotNull(); - - final DMNContext context = DMNFactory.newContext(); - context.set( "Full Name", "John Doe" ); - - final DMNResult dmnResult = runtime.evaluateByName( dmnModel, context, "decision_024" ); - - 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" ); - } @ParameterizedTest @MethodSource("params") void inputStringEvaluateDecisionByName(boolean useExecModelCompiler) { diff --git a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/ForExpressionNode.java b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/ForExpressionNode.java index 06c80202820..0ca9b2aa662 100644 --- a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/ForExpressionNode.java +++ b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/ForExpressionNode.java @@ -135,7 +135,7 @@ private ForIteration createForIteration(EvaluationContext ctx, IterationContextN Object rangeEnd = iterationContextNode.evaluateRangeEnd(ctx); if (rangeEnd == null) { if (result instanceof Iterable iterable) { - new ForIteration(name, iterable); + toReturn = new ForIteration(name, iterable); } else if (result instanceof Range) { toReturn = computeResultForRange(((Range) result), name, ctx); } else { From ed5379719487a9bf168aba7a1a3c61bc77ea5c00 Mon Sep 17 00:00:00 2001 From: athira Date: Fri, 10 Jan 2025 19:10:33 +0530 Subject: [PATCH 06/15] [incubator-kie-issues#1743] Code refactoring --- .../test/java/org/kie/dmn/core/DMNInputRuntimeTest.java | 2 ++ .../ast/forexpressioniterators/ForIterationUtils.java | 6 +++--- .../java/org/kie/dmn/feel/runtime/impl/RangeImplTest.java | 8 -------- 3 files changed, 5 insertions(+), 11 deletions(-) diff --git a/kie-dmn/kie-dmn-core/src/test/java/org/kie/dmn/core/DMNInputRuntimeTest.java b/kie-dmn/kie-dmn-core/src/test/java/org/kie/dmn/core/DMNInputRuntimeTest.java index 136aa0102a2..5f245869683 100644 --- a/kie-dmn/kie-dmn-core/src/test/java/org/kie/dmn/core/DMNInputRuntimeTest.java +++ b/kie-dmn/kie-dmn-core/src/test/java/org/kie/dmn/core/DMNInputRuntimeTest.java @@ -25,6 +25,7 @@ import java.util.List; import java.util.Set; +import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; import org.kie.dmn.api.core.DMNContext; @@ -42,6 +43,7 @@ import org.kie.dmn.api.core.event.AfterConditionalEvaluationEvent; import org.kie.dmn.api.core.event.AfterEvaluateConditionalEvent; import org.kie.dmn.api.core.event.AfterEvaluateDecisionTableEvent; +import org.kie.dmn.api.core.event.DMNRuntimeEventListener; import org.kie.dmn.core.api.DMNFactory; import org.kie.dmn.core.api.event.DefaultDMNRuntimeEventListener; import org.kie.dmn.core.util.DMNRuntimeUtil; diff --git a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/forexpressioniterators/ForIterationUtils.java b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/forexpressioniterators/ForIterationUtils.java index 4f81b565c65..e77ec7d40fa 100644 --- a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/forexpressioniterators/ForIterationUtils.java +++ b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/forexpressioniterators/ForIterationUtils.java @@ -18,6 +18,9 @@ */ package org.kie.dmn.feel.lang.ast.forexpressioniterators; +import java.math.BigDecimal; +import java.time.LocalDate; + import org.kie.dmn.api.feel.runtime.events.FEELEvent; import org.kie.dmn.feel.exceptions.EndpointOfRangeNotValidTypeException; import org.kie.dmn.feel.exceptions.EndpointOfRangeOfDifferentTypeException; @@ -26,9 +29,6 @@ import org.kie.dmn.feel.runtime.events.ASTEventBase; import org.kie.dmn.feel.util.Msg; -import java.math.BigDecimal; -import java.time.LocalDate; - public class ForIterationUtils { private ForIterationUtils() { diff --git a/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/runtime/impl/RangeImplTest.java b/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/runtime/impl/RangeImplTest.java index 8155c1dfde1..945df362ee3 100644 --- a/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/runtime/impl/RangeImplTest.java +++ b/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/runtime/impl/RangeImplTest.java @@ -163,12 +163,4 @@ void hashCodeTest() { rangeImpl2 = new RangeImpl(Range.RangeBoundary.CLOSED, 12, 17, Range.RangeBoundary.CLOSED); assertThat(rangeImpl2).doesNotHaveSameHashCodeAs(rangeImpl); } - - @Test - void testRangeExpansion() { - FEEL feel = FEELBuilder.builder().build(); - Object result = feel.evaluate("for i in @\"1980-01-01\"..@\"1980-01-03\" return i"); - assertThat(result.toString()).isEqualTo(List.of("1980-01-01", "1980-01-02", "1980-01-03")); - } - } \ No newline at end of file From 45a5e2345a87eed01e789f12f3be321e7ee5241e Mon Sep 17 00:00:00 2001 From: athira Date: Sun, 12 Jan 2025 12:51:10 +0530 Subject: [PATCH 07/15] [incubator-kie-issues#1743] Code clean up --- .../feel/lang/ast/ForExpressionNodeTest.java | 17 +++++++++++++++++ .../dmn/feel/runtime/impl/RangeImplTest.java | 4 ---- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/lang/ast/ForExpressionNodeTest.java b/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/lang/ast/ForExpressionNodeTest.java index f09f03caa66..7a5553acd9f 100644 --- a/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/lang/ast/ForExpressionNodeTest.java +++ b/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/lang/ast/ForExpressionNodeTest.java @@ -27,6 +27,7 @@ import org.junit.jupiter.api.Test; import org.kie.dmn.feel.util.EvaluationContextTestUtil; +import org.kie.dmn.feel.lang.ast.RangeNode.IntervalBoundary; import org.kie.dmn.feel.lang.Type; import org.kie.dmn.feel.lang.types.BuiltInType; @@ -58,6 +59,15 @@ void evaluateNestedArray() { } + @Test + void evaluateRange() { + IterationContextNode x = getIterationContextNode("x", getRangeNode("[1..5]", BigDecimal.ONE, BigDecimal.valueOf(5), RangeNode.IntervalBoundary.CLOSED, RangeNode.IntervalBoundary.CLOSED ), "x in [1..5]"); + ForExpressionNode forExpressionNode = new ForExpressionNode(Collections.singletonList(x), getNameRefNode(BuiltInType.NUMBER, "x"), "for x in [1..5] return x"); + Object retrieved = forExpressionNode.evaluate(EvaluationContextTestUtil.newEmptyEvaluationContext()); + assertThat(retrieved).isInstanceOf(List.class).asList().containsExactly( + BigDecimal.valueOf(1), BigDecimal.valueOf(2), BigDecimal.valueOf(3), BigDecimal.valueOf(4), BigDecimal.valueOf(5)); + } + private IterationContextNode getIterationContextNode(String variableName, BaseNode expression, String text) { return new IterationContextNode(getNameDefNode(variableName), expression, null, text); } @@ -86,4 +96,11 @@ private ListNode getListNode(String text, List values) { .toList(); return new ListNode(elements, text); } + + private RangeNode getRangeNode(String text, BigDecimal start, BigDecimal end, IntervalBoundary lowerBound, IntervalBoundary upperBound) { + BaseNode startNode = new NumberNode(start, start.toString()); + BaseNode endNode = new NumberNode(end, end.toString()); + return new RangeNode(lowerBound, upperBound, startNode, endNode, text); + } + } \ No newline at end of file diff --git a/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/runtime/impl/RangeImplTest.java b/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/runtime/impl/RangeImplTest.java index 945df362ee3..521abb12fc7 100644 --- a/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/runtime/impl/RangeImplTest.java +++ b/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/runtime/impl/RangeImplTest.java @@ -19,12 +19,8 @@ package org.kie.dmn.feel.runtime.impl; import org.junit.jupiter.api.Test; -import org.kie.dmn.feel.FEEL; -import org.kie.dmn.feel.lang.impl.FEELBuilder; import org.kie.dmn.feel.runtime.Range; -import java.util.List; - import static org.assertj.core.api.Assertions.assertThat; class RangeImplTest { From 0360f93bde7ce542218eca0b5d3fabb74140c6eb Mon Sep 17 00:00:00 2001 From: athira Date: Wed, 15 Jan 2025 15:51:11 +0530 Subject: [PATCH 08/15] [incubator-kie-issues#1743] Updated test cases --- .../org/kie/dmn/feel/lang/ast/DateNode.java | 46 ++++++++++++ .../dmn/feel/lang/ast/ForExpressionNode.java | 4 +- .../ForIterationUtils.java | 10 +-- .../feel/lang/ast/ForExpressionNodeTest.java | 52 +++---------- .../ForIterationUtilsTest.java | 26 +++---- .../dmn/feel/util/ForExpressionNodeUtils.java | 73 +++++++++++++++++++ 6 files changed, 149 insertions(+), 62 deletions(-) create mode 100644 kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/DateNode.java create mode 100644 kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/util/ForExpressionNodeUtils.java diff --git a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/DateNode.java b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/DateNode.java new file mode 100644 index 00000000000..e7402fee9f9 --- /dev/null +++ b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/DateNode.java @@ -0,0 +1,46 @@ +/** + * 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.ast; + +import org.kie.dmn.feel.lang.EvaluationContext; + +import java.time.LocalDate; + +public class DateNode extends BaseNode{ + LocalDate value; + + public DateNode(LocalDate value, String text) { + this.value = value; + this.setText(text); + } + + public LocalDate getValue() { + return value; + } + + public void setValue(LocalDate value) { + this.value = value; + } + + @Override + public Object evaluate(EvaluationContext ctx) { + return value; + } + +} diff --git a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/ForExpressionNode.java b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/ForExpressionNode.java index 0ca9b2aa662..02be98f495a 100644 --- a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/ForExpressionNode.java +++ b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/ForExpressionNode.java @@ -33,8 +33,8 @@ import java.util.Collections; import java.util.List; -import static org.kie.dmn.feel.lang.ast.forexpressioniterators.ForIterationUtils.computeResultForRange; import static org.kie.dmn.feel.lang.ast.forexpressioniterators.ForIterationUtils.getForIteration; +import static org.kie.dmn.feel.lang.ast.forexpressioniterators.ForIterationUtils.getForIterationRangeValues; public class ForExpressionNode extends BaseNode { @@ -137,7 +137,7 @@ private ForIteration createForIteration(EvaluationContext ctx, IterationContextN if (result instanceof Iterable iterable) { toReturn = new ForIteration(name, iterable); } else if (result instanceof Range) { - toReturn = computeResultForRange(((Range) result), name, ctx); + toReturn = getForIterationRangeValues(((Range) result), name, ctx); } else { toReturn = new ForIteration(name, Collections.singletonList(result)); } diff --git a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/forexpressioniterators/ForIterationUtils.java b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/forexpressioniterators/ForIterationUtils.java index e77ec7d40fa..9c8e4f945cb 100644 --- a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/forexpressioniterators/ForIterationUtils.java +++ b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/forexpressioniterators/ForIterationUtils.java @@ -47,13 +47,13 @@ public static ForIteration getForIteration(EvaluationContext ctx, String name, O throw new EndpointOfRangeOfDifferentTypeException(); } - public static ForIteration computeResultForRange(Range result, String name, EvaluationContext ctx) { + public static ForIteration getForIterationRangeValues(Range result, String name, EvaluationContext ctx) { validateValues(ctx, result.getLowEndPoint(), result.getHighEndPoint()); if (result.getLowEndPoint() instanceof BigDecimal && result.getHighEndPoint() instanceof BigDecimal) { - return computeResultForBigDecimalRange(result,name,ctx); + return getForIterationBigDecimalRange(result,name,ctx); } if (result.getLowEndPoint() instanceof LocalDate && result.getHighEndPoint() instanceof LocalDate) { - return computeResultForLocalDateRange(result, name, ctx); + return getForIterationLocalDateRange(result, name, ctx); } return null; } @@ -75,7 +75,7 @@ static void valueMustBeValid(EvaluationContext ctx, Object value) { } } - static ForIteration computeResultForBigDecimalRange(Range result, String name, EvaluationContext ctx) { + static ForIteration getForIterationBigDecimalRange(Range result, String name, EvaluationContext ctx) { BigDecimal start = (BigDecimal) result.getLowEndPoint(); BigDecimal end = (BigDecimal) result.getHighEndPoint(); if (result.getLowBoundary() == Range.RangeBoundary.OPEN) { @@ -87,7 +87,7 @@ static ForIteration computeResultForBigDecimalRange(Range result, String name, E return getForIteration(ctx, name, start, end); } - static ForIteration computeResultForLocalDateRange(Range result, String name, EvaluationContext ctx) { + static ForIteration getForIterationLocalDateRange(Range result, String name, EvaluationContext ctx) { LocalDate start = (LocalDate) result.getLowEndPoint(); LocalDate end = (LocalDate) result.getHighEndPoint(); if (result.getLowBoundary() == Range.RangeBoundary.OPEN) { diff --git a/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/lang/ast/ForExpressionNodeTest.java b/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/lang/ast/ForExpressionNodeTest.java index 7a5553acd9f..37a9da00ea5 100644 --- a/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/lang/ast/ForExpressionNodeTest.java +++ b/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/lang/ast/ForExpressionNodeTest.java @@ -19,6 +19,7 @@ package org.kie.dmn.feel.lang.ast; import java.math.BigDecimal; +import java.time.LocalDate; import java.util.Arrays; import java.util.Collections; import java.util.LinkedHashMap; @@ -27,11 +28,14 @@ import org.junit.jupiter.api.Test; import org.kie.dmn.feel.util.EvaluationContextTestUtil; -import org.kie.dmn.feel.lang.ast.RangeNode.IntervalBoundary; -import org.kie.dmn.feel.lang.Type; import org.kie.dmn.feel.lang.types.BuiltInType; import static org.assertj.core.api.Assertions.assertThat; +import static org.kie.dmn.feel.util.ForExpressionNodeUtils.getIterationContextNode; +import static org.kie.dmn.feel.util.ForExpressionNodeUtils.getListNode; +import static org.kie.dmn.feel.util.ForExpressionNodeUtils.getNameRefNode; +import static org.kie.dmn.feel.util.ForExpressionNodeUtils.getNestedListNode; +import static org.kie.dmn.feel.util.ForExpressionNodeUtils.getRangeNode; class ForExpressionNodeTest { @@ -61,46 +65,10 @@ void evaluateNestedArray() { @Test void evaluateRange() { - IterationContextNode x = getIterationContextNode("x", getRangeNode("[1..5]", BigDecimal.ONE, BigDecimal.valueOf(5), RangeNode.IntervalBoundary.CLOSED, RangeNode.IntervalBoundary.CLOSED ), "x in [1..5]"); - ForExpressionNode forExpressionNode = new ForExpressionNode(Collections.singletonList(x), getNameRefNode(BuiltInType.NUMBER, "x"), "for x in [1..5] return x"); + IterationContextNode x = getIterationContextNode("x", getRangeNode("[1980-01-01 .. 1980-01-03]", LocalDate.of(1980, 1, 1), LocalDate.of(1980, 1, 3), RangeNode.IntervalBoundary.CLOSED, RangeNode.IntervalBoundary.CLOSED ), "x in [1980-01-01 .. 1980-01-03]"); + ForExpressionNode forExpressionNode = new ForExpressionNode(Collections.singletonList(x), getNameRefNode(BuiltInType.NUMBER, "x"), "for x in [1980-01-01 .. 1980-01-03] return x"); Object retrieved = forExpressionNode.evaluate(EvaluationContextTestUtil.newEmptyEvaluationContext()); - assertThat(retrieved).isInstanceOf(List.class).asList().containsExactly( - BigDecimal.valueOf(1), BigDecimal.valueOf(2), BigDecimal.valueOf(3), BigDecimal.valueOf(4), BigDecimal.valueOf(5)); + assertThat(retrieved).isInstanceOf(List.class).asList().containsExactly(LocalDate.of(1980, 1, 1), + LocalDate.of(1980, 1, 2), LocalDate.of(1980, 1, 3)); } - - private IterationContextNode getIterationContextNode(String variableName, BaseNode expression, String text) { - return new IterationContextNode(getNameDefNode(variableName), expression, null, text); - } - - private NameDefNode getNameDefNode(String text) { - return new NameDefNode(Collections.singletonList(text), null, text); - } - - private NameRefNode getNameRefNode(Type type, String text) { - return new NameRefNode(type, text); - } - - private ListNode getNestedListNode(String text, Map> values) { - List elements = values.entrySet() - .stream() - .map(entry -> getListNode(entry.getKey(), entry.getValue())) - .map(BaseNode.class::cast) - .toList(); - return new ListNode(elements, text); - } - - private ListNode getListNode(String text, List values) { - List elements = values.stream() - .map(value -> new NumberNode(new BigDecimal(value), value)) - .map(BaseNode.class::cast) - .toList(); - return new ListNode(elements, text); - } - - private RangeNode getRangeNode(String text, BigDecimal start, BigDecimal end, IntervalBoundary lowerBound, IntervalBoundary upperBound) { - BaseNode startNode = new NumberNode(start, start.toString()); - BaseNode endNode = new NumberNode(end, end.toString()); - return new RangeNode(lowerBound, upperBound, startNode, endNode, text); - } - } \ No newline at end of file diff --git a/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/lang/ast/forexpressioniterators/ForIterationUtilsTest.java b/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/lang/ast/forexpressioniterators/ForIterationUtilsTest.java index 302fcff448e..966afb75cc2 100644 --- a/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/lang/ast/forexpressioniterators/ForIterationUtilsTest.java +++ b/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/lang/ast/forexpressioniterators/ForIterationUtilsTest.java @@ -33,9 +33,9 @@ import org.mockito.ArgumentCaptor; import static org.assertj.core.api.Assertions.assertThat; -import static org.kie.dmn.feel.lang.ast.forexpressioniterators.ForIterationUtils.computeResultForBigDecimalRange; -import static org.kie.dmn.feel.lang.ast.forexpressioniterators.ForIterationUtils.computeResultForLocalDateRange; -import static org.kie.dmn.feel.lang.ast.forexpressioniterators.ForIterationUtils.computeResultForRange; +import static org.kie.dmn.feel.lang.ast.forexpressioniterators.ForIterationUtils.getForIterationBigDecimalRange; +import static org.kie.dmn.feel.lang.ast.forexpressioniterators.ForIterationUtils.getForIterationLocalDateRange; +import static org.kie.dmn.feel.lang.ast.forexpressioniterators.ForIterationUtils.getForIterationRangeValues; import static org.kie.dmn.feel.util.EvaluationContextTestUtil.newEmptyEvaluationContext; import static org.kie.dmn.feel.lang.ast.forexpressioniterators.ForIterationUtils.getForIteration; import static org.kie.dmn.feel.lang.ast.forexpressioniterators.ForIterationUtils.validateValues; @@ -155,7 +155,7 @@ void validateValuesFalseTest() { } @Test - void testComputeResultForRange() { + void testGetForIterationRangeValues() { Range range = mock(Range.class); EvaluationContext ctx = mock(EvaluationContext.class); @@ -163,55 +163,55 @@ void testComputeResultForRange() { when(range.getHighBoundary()).thenReturn(Range.RangeBoundary.OPEN); when(range.getLowEndPoint()).thenReturn(new BigDecimal("10.0")); when(range.getHighEndPoint()).thenReturn(new BigDecimal("20.0")); - ForIteration result = computeResultForRange(range, "rangeTest", ctx); + ForIteration result = getForIterationRangeValues(range, "rangeTest", ctx); assertThat(result).isNotNull(); } @Test - void testComputeResultForBigDecimalRangeOpenBoundary() { + void testGetForIterationBigDecimalRangeOpenBoundary() { Range range = mock(Range.class); when(range.getLowBoundary()).thenReturn(Range.RangeBoundary.OPEN); when(range.getHighBoundary()).thenReturn(Range.RangeBoundary.OPEN); when(range.getLowEndPoint()).thenReturn(new BigDecimal("10.0")); when(range.getHighEndPoint()).thenReturn(new BigDecimal("20.0")); - ForIteration result = computeResultForBigDecimalRange(range, "BigDecimalRange", ctx); + ForIteration result = getForIterationBigDecimalRange(range, "BigDecimalRange", ctx); assertThat(result).isNotNull(); } @Test - void testComputeResultForBigDecimalRangeClosedBoundary() { + void testGetForIterationBigDecimalRangeClosedBoundary() { Range range = mock(Range.class); when(range.getLowBoundary()).thenReturn(Range.RangeBoundary.CLOSED); when(range.getHighBoundary()).thenReturn(Range.RangeBoundary.CLOSED); when(range.getLowEndPoint()).thenReturn(new BigDecimal("10.0")); when(range.getHighEndPoint()).thenReturn(new BigDecimal("20.0")); - ForIteration result = computeResultForBigDecimalRange(range, "BigDecimalRange", ctx); + ForIteration result = getForIterationBigDecimalRange(range, "BigDecimalRange", ctx); assertThat(result).isNotNull(); } @Test - void testComputeResultForLocalDateRangeOpenBoundary() { + void testGetForIterationLocalDateRangeOpenBoundary() { Range range = mock(Range.class); when(range.getLowBoundary()).thenReturn(Range.RangeBoundary.OPEN); when(range.getHighBoundary()).thenReturn(Range.RangeBoundary.OPEN); when(range.getLowEndPoint()).thenReturn(LocalDate.of(2025, 1, 1)); when(range.getHighEndPoint()).thenReturn(LocalDate.of(2025, 1, 7)); - ForIteration result = computeResultForLocalDateRange(range, "dateRange", ctx); + ForIteration result = getForIterationLocalDateRange(range, "dateRange", ctx); assertThat(result).isNotNull(); } @Test - void testComputeResultForLocalDateRangeClosedBoundary() { + void testGetForIterationLocalDateRangeClosedBoundary() { Range range = mock(Range.class); when(range.getLowBoundary()).thenReturn(Range.RangeBoundary.CLOSED); when(range.getHighBoundary()).thenReturn(Range.RangeBoundary.CLOSED); when(range.getLowEndPoint()).thenReturn(LocalDate.of(2025, 1, 1)); when(range.getHighEndPoint()).thenReturn(LocalDate.of(2025, 1, 7)); - ForIteration result = computeResultForLocalDateRange(range, "dateRange", ctx); + ForIteration result = getForIterationLocalDateRange(range, "dateRange", ctx); assertThat(result).isNotNull(); } } diff --git a/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/util/ForExpressionNodeUtils.java b/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/util/ForExpressionNodeUtils.java new file mode 100644 index 00000000000..f5495b375a9 --- /dev/null +++ b/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/util/ForExpressionNodeUtils.java @@ -0,0 +1,73 @@ +/** + * 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.kie.dmn.feel.lang.Type; +import org.kie.dmn.feel.lang.ast.BaseNode; +import org.kie.dmn.feel.lang.ast.DateNode; +import org.kie.dmn.feel.lang.ast.IterationContextNode; +import org.kie.dmn.feel.lang.ast.ListNode; +import org.kie.dmn.feel.lang.ast.NameDefNode; +import org.kie.dmn.feel.lang.ast.NameRefNode; +import org.kie.dmn.feel.lang.ast.NumberNode; +import org.kie.dmn.feel.lang.ast.RangeNode; + +import java.math.BigDecimal; +import java.time.LocalDate; +import java.util.Collections; +import java.util.List; +import java.util.Map; + +public class ForExpressionNodeUtils { + + public static IterationContextNode getIterationContextNode(String variableName, BaseNode expression, String text) { + return new IterationContextNode(getNameDefNode(variableName), expression, null, text); + } + + public static NameDefNode getNameDefNode(String text) { + return new NameDefNode(Collections.singletonList(text), null, text); + } + + public static NameRefNode getNameRefNode(Type type, String text) { + return new NameRefNode(type, text); + } + + public static ListNode getNestedListNode(String text, Map> values) { + List elements = values.entrySet() + .stream() + .map(entry -> getListNode(entry.getKey(), entry.getValue())) + .map(BaseNode.class::cast) + .toList(); + return new ListNode(elements, text); + } + + public static ListNode getListNode(String text, List values) { + List elements = values.stream() + .map(value -> new NumberNode(new BigDecimal(value), value)) + .map(BaseNode.class::cast) + .toList(); + return new ListNode(elements, text); + } + + public static RangeNode getRangeNode(String text, LocalDate start, LocalDate end, RangeNode.IntervalBoundary lowerBound, RangeNode.IntervalBoundary upperBound) { + BaseNode startNode = new DateNode(start, start.toString()); + BaseNode endNode = new DateNode(end, end.toString()); + return new RangeNode(lowerBound, upperBound, startNode, endNode, text); + } +} From 2a793c5f983164b0fef9abab0a0476089d979e72 Mon Sep 17 00:00:00 2001 From: athira Date: Sun, 19 Jan 2025 17:36:14 +0530 Subject: [PATCH 09/15] [incubator-kie-issues#1743] Code fixes --- .../dmn/feel/lang/ast/ForExpressionNode.java | 3 +- .../ForIterationUtils.java | 2 +- .../feel/lang/ast/ForExpressionNodeTest.java | 12 ++-- .../ForIterationUtilsTest.java | 72 ++++++++----------- ...s.java => ExpressionNodeFactoryUtils.java} | 35 +++++++-- 5 files changed, 67 insertions(+), 57 deletions(-) rename kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/util/{ForExpressionNodeUtils.java => ExpressionNodeFactoryUtils.java} (64%) diff --git a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/ForExpressionNode.java b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/ForExpressionNode.java index 02be98f495a..3f66eb3e7d5 100644 --- a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/ForExpressionNode.java +++ b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/ForExpressionNode.java @@ -34,7 +34,6 @@ import java.util.List; import static org.kie.dmn.feel.lang.ast.forexpressioniterators.ForIterationUtils.getForIteration; -import static org.kie.dmn.feel.lang.ast.forexpressioniterators.ForIterationUtils.getForIterationRangeValues; public class ForExpressionNode extends BaseNode { @@ -137,7 +136,7 @@ private ForIteration createForIteration(EvaluationContext ctx, IterationContextN if (result instanceof Iterable iterable) { toReturn = new ForIteration(name, iterable); } else if (result instanceof Range) { - toReturn = getForIterationRangeValues(((Range) result), name, ctx); + toReturn = getForIteration(((Range) result), name, ctx); } else { toReturn = new ForIteration(name, Collections.singletonList(result)); } diff --git a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/forexpressioniterators/ForIterationUtils.java b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/forexpressioniterators/ForIterationUtils.java index 9c8e4f945cb..629bbb23f44 100644 --- a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/forexpressioniterators/ForIterationUtils.java +++ b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/forexpressioniterators/ForIterationUtils.java @@ -47,7 +47,7 @@ public static ForIteration getForIteration(EvaluationContext ctx, String name, O throw new EndpointOfRangeOfDifferentTypeException(); } - public static ForIteration getForIterationRangeValues(Range result, String name, EvaluationContext ctx) { + public static ForIteration getForIteration(Range result, String name, EvaluationContext ctx) { validateValues(ctx, result.getLowEndPoint(), result.getHighEndPoint()); if (result.getLowEndPoint() instanceof BigDecimal && result.getHighEndPoint() instanceof BigDecimal) { return getForIterationBigDecimalRange(result,name,ctx); diff --git a/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/lang/ast/ForExpressionNodeTest.java b/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/lang/ast/ForExpressionNodeTest.java index 37a9da00ea5..fc7e9b17d0d 100644 --- a/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/lang/ast/ForExpressionNodeTest.java +++ b/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/lang/ast/ForExpressionNodeTest.java @@ -31,11 +31,11 @@ import org.kie.dmn.feel.lang.types.BuiltInType; import static org.assertj.core.api.Assertions.assertThat; -import static org.kie.dmn.feel.util.ForExpressionNodeUtils.getIterationContextNode; -import static org.kie.dmn.feel.util.ForExpressionNodeUtils.getListNode; -import static org.kie.dmn.feel.util.ForExpressionNodeUtils.getNameRefNode; -import static org.kie.dmn.feel.util.ForExpressionNodeUtils.getNestedListNode; -import static org.kie.dmn.feel.util.ForExpressionNodeUtils.getRangeNode; +import static org.kie.dmn.feel.util.ExpressionNodeFactoryUtils.getIterationContextNode; +import static org.kie.dmn.feel.util.ExpressionNodeFactoryUtils.getListNode; +import static org.kie.dmn.feel.util.ExpressionNodeFactoryUtils.getNameRefNode; +import static org.kie.dmn.feel.util.ExpressionNodeFactoryUtils.getNestedListNode; +import static org.kie.dmn.feel.util.ExpressionNodeFactoryUtils.getRangeNode; class ForExpressionNodeTest { @@ -66,7 +66,7 @@ void evaluateNestedArray() { @Test void evaluateRange() { IterationContextNode x = getIterationContextNode("x", getRangeNode("[1980-01-01 .. 1980-01-03]", LocalDate.of(1980, 1, 1), LocalDate.of(1980, 1, 3), RangeNode.IntervalBoundary.CLOSED, RangeNode.IntervalBoundary.CLOSED ), "x in [1980-01-01 .. 1980-01-03]"); - ForExpressionNode forExpressionNode = new ForExpressionNode(Collections.singletonList(x), getNameRefNode(BuiltInType.NUMBER, "x"), "for x in [1980-01-01 .. 1980-01-03] return x"); + ForExpressionNode forExpressionNode = new ForExpressionNode(Collections.singletonList(x), getNameRefNode(BuiltInType.DATE, "x"), "for x in [1980-01-01 .. 1980-01-03] return x"); Object retrieved = forExpressionNode.evaluate(EvaluationContextTestUtil.newEmptyEvaluationContext()); assertThat(retrieved).isInstanceOf(List.class).asList().containsExactly(LocalDate.of(1980, 1, 1), LocalDate.of(1980, 1, 2), LocalDate.of(1980, 1, 3)); diff --git a/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/lang/ast/forexpressioniterators/ForIterationUtilsTest.java b/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/lang/ast/forexpressioniterators/ForIterationUtilsTest.java index 966afb75cc2..8a0a08115c7 100644 --- a/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/lang/ast/forexpressioniterators/ForIterationUtilsTest.java +++ b/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/lang/ast/forexpressioniterators/ForIterationUtilsTest.java @@ -30,12 +30,13 @@ import org.kie.dmn.feel.lang.EvaluationContext; import org.kie.dmn.feel.lang.impl.FEELEventListenersManager; import org.kie.dmn.feel.runtime.Range; +import org.kie.dmn.feel.runtime.impl.RangeImpl; import org.mockito.ArgumentCaptor; import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; import static org.kie.dmn.feel.lang.ast.forexpressioniterators.ForIterationUtils.getForIterationBigDecimalRange; import static org.kie.dmn.feel.lang.ast.forexpressioniterators.ForIterationUtils.getForIterationLocalDateRange; -import static org.kie.dmn.feel.lang.ast.forexpressioniterators.ForIterationUtils.getForIterationRangeValues; import static org.kie.dmn.feel.util.EvaluationContextTestUtil.newEmptyEvaluationContext; import static org.kie.dmn.feel.lang.ast.forexpressioniterators.ForIterationUtils.getForIteration; import static org.kie.dmn.feel.lang.ast.forexpressioniterators.ForIterationUtils.validateValues; @@ -46,7 +47,6 @@ import static org.mockito.Mockito.reset; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; class ForIterationUtilsTest { @@ -156,62 +156,52 @@ void validateValuesFalseTest() { @Test void testGetForIterationRangeValues() { - Range range = mock(Range.class); + Range range = new RangeImpl(Range.RangeBoundary.CLOSED, BigDecimal.TEN, BigDecimal.valueOf(20), Range.RangeBoundary.OPEN); EvaluationContext ctx = mock(EvaluationContext.class); - when(range.getLowBoundary()).thenReturn(Range.RangeBoundary.CLOSED); - when(range.getHighBoundary()).thenReturn(Range.RangeBoundary.OPEN); - when(range.getLowEndPoint()).thenReturn(new BigDecimal("10.0")); - when(range.getHighEndPoint()).thenReturn(new BigDecimal("20.0")); - ForIteration result = getForIterationRangeValues(range, "rangeTest", ctx); - assertThat(result).isNotNull(); + ForIteration expectedResult = new ForIteration("rangeTest", null); + ForIteration actualResult = getForIteration(range, "rangeTest", ctx); + assertThat(actualResult).isNotNull(); + assertEquals(actualResult.toString(), expectedResult.toString()); } @Test void testGetForIterationBigDecimalRangeOpenBoundary() { - Range range = mock(Range.class); - when(range.getLowBoundary()).thenReturn(Range.RangeBoundary.OPEN); - when(range.getHighBoundary()).thenReturn(Range.RangeBoundary.OPEN); - when(range.getLowEndPoint()).thenReturn(new BigDecimal("10.0")); - when(range.getHighEndPoint()).thenReturn(new BigDecimal("20.0")); - - ForIteration result = getForIterationBigDecimalRange(range, "BigDecimalRange", ctx); - assertThat(result).isNotNull(); + Range range = new RangeImpl(Range.RangeBoundary.OPEN, BigDecimal.TEN, BigDecimal.valueOf(20), Range.RangeBoundary.OPEN); + + ForIteration expectedResult = new ForIteration("BigDecimalRange", null); + ForIteration actualResult = getForIterationBigDecimalRange(range, "BigDecimalRange", ctx); + assertThat(actualResult).isNotNull(); + assertEquals(actualResult.toString(), expectedResult.toString()); } @Test void testGetForIterationBigDecimalRangeClosedBoundary() { - Range range = mock(Range.class); - when(range.getLowBoundary()).thenReturn(Range.RangeBoundary.CLOSED); - when(range.getHighBoundary()).thenReturn(Range.RangeBoundary.CLOSED); - when(range.getLowEndPoint()).thenReturn(new BigDecimal("10.0")); - when(range.getHighEndPoint()).thenReturn(new BigDecimal("20.0")); - - ForIteration result = getForIterationBigDecimalRange(range, "BigDecimalRange", ctx); - assertThat(result).isNotNull(); + Range range = new RangeImpl(Range.RangeBoundary.CLOSED, BigDecimal.TEN, BigDecimal.valueOf(20), Range.RangeBoundary.CLOSED); + + ForIteration expectedResult = new ForIteration("BigDecimalRange", null); + ForIteration actualResult = getForIterationBigDecimalRange(range, "BigDecimalRange", ctx); + assertThat(actualResult).isNotNull(); + assertEquals(actualResult.toString(), expectedResult.toString()); } @Test void testGetForIterationLocalDateRangeOpenBoundary() { - Range range = mock(Range.class); - when(range.getLowBoundary()).thenReturn(Range.RangeBoundary.OPEN); - when(range.getHighBoundary()).thenReturn(Range.RangeBoundary.OPEN); - when(range.getLowEndPoint()).thenReturn(LocalDate.of(2025, 1, 1)); - when(range.getHighEndPoint()).thenReturn(LocalDate.of(2025, 1, 7)); - - ForIteration result = getForIterationLocalDateRange(range, "dateRange", ctx); - assertThat(result).isNotNull(); + Range range = new RangeImpl(Range.RangeBoundary.OPEN, LocalDate.of(2025, 1, 1), LocalDate.of(2025, 1, 7), Range.RangeBoundary.OPEN); + + ForIteration expectedResult = new ForIteration("dateRange", null); + ForIteration actualResult = getForIterationLocalDateRange(range, "dateRange", ctx); + assertThat(actualResult).isNotNull(); + assertEquals(actualResult.toString(), expectedResult.toString()); } @Test void testGetForIterationLocalDateRangeClosedBoundary() { - Range range = mock(Range.class); - when(range.getLowBoundary()).thenReturn(Range.RangeBoundary.CLOSED); - when(range.getHighBoundary()).thenReturn(Range.RangeBoundary.CLOSED); - when(range.getLowEndPoint()).thenReturn(LocalDate.of(2025, 1, 1)); - when(range.getHighEndPoint()).thenReturn(LocalDate.of(2025, 1, 7)); - - ForIteration result = getForIterationLocalDateRange(range, "dateRange", ctx); - assertThat(result).isNotNull(); + Range range = new RangeImpl(Range.RangeBoundary.CLOSED, LocalDate.of(2025, 1, 1), LocalDate.of(2025, 1, 7), Range.RangeBoundary.CLOSED); + + ForIteration expectedResult = new ForIteration("dateRange", null); + ForIteration actualResult = getForIterationLocalDateRange(range, "dateRange", ctx); + assertThat(actualResult).isNotNull(); + assertEquals(actualResult.toString(), expectedResult.toString()); } } diff --git a/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/util/ForExpressionNodeUtils.java b/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/util/ExpressionNodeFactoryUtils.java similarity index 64% rename from kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/util/ForExpressionNodeUtils.java rename to kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/util/ExpressionNodeFactoryUtils.java index f5495b375a9..f7afe8f0c78 100644 --- a/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/util/ForExpressionNodeUtils.java +++ b/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/util/ExpressionNodeFactoryUtils.java @@ -20,13 +20,16 @@ import org.kie.dmn.feel.lang.Type; import org.kie.dmn.feel.lang.ast.BaseNode; -import org.kie.dmn.feel.lang.ast.DateNode; +import org.kie.dmn.feel.lang.ast.FunctionInvocationNode; import org.kie.dmn.feel.lang.ast.IterationContextNode; import org.kie.dmn.feel.lang.ast.ListNode; import org.kie.dmn.feel.lang.ast.NameDefNode; import org.kie.dmn.feel.lang.ast.NameRefNode; import org.kie.dmn.feel.lang.ast.NumberNode; import org.kie.dmn.feel.lang.ast.RangeNode; +import org.kie.dmn.feel.lang.ast.StringNode; +import org.kie.dmn.feel.lang.ast.TemporalConstantNode; +import org.kie.dmn.feel.lang.types.BuiltInType; import java.math.BigDecimal; import java.time.LocalDate; @@ -34,18 +37,18 @@ import java.util.List; import java.util.Map; -public class ForExpressionNodeUtils { +public class ExpressionNodeFactoryUtils { public static IterationContextNode getIterationContextNode(String variableName, BaseNode expression, String text) { return new IterationContextNode(getNameDefNode(variableName), expression, null, text); } public static NameDefNode getNameDefNode(String text) { - return new NameDefNode(Collections.singletonList(text), null, text); + return new NameDefNode(Collections.singletonList(text), null, text); } public static NameRefNode getNameRefNode(Type type, String text) { - return new NameRefNode(type, text); + return new NameRefNode(type, text); } public static ListNode getNestedListNode(String text, Map> values) { @@ -59,15 +62,33 @@ public static ListNode getNestedListNode(String text, Map> public static ListNode getListNode(String text, List values) { List elements = values.stream() - .map(value -> new NumberNode(new BigDecimal(value), value)) + .map(value -> { + if (value.matches("-?\\d+(\\.\\d+)?")) { + return new NumberNode(new BigDecimal(value), value); + } else if (value.matches("\\d{4}-\\d{2}-\\d{2}")) { + return new StringNode(value); + } else { + return new StringNode(value); + } + }) .map(BaseNode.class::cast) .toList(); + return new ListNode(elements, text); } + public static TemporalConstantNode getTemporalConstantNode(Object value) { + return new TemporalConstantNode(value, null, null, null); + } + public static RangeNode getRangeNode(String text, LocalDate start, LocalDate end, RangeNode.IntervalBoundary lowerBound, RangeNode.IntervalBoundary upperBound) { - BaseNode startNode = new DateNode(start, start.toString()); - BaseNode endNode = new DateNode(end, end.toString()); + BaseNode nameRefNode = getNameRefNode(BuiltInType.DATE, "x"); + ListNode startParams = getListNode(start.toString(), List.of(start.toString())); + ListNode endParams = getListNode(end.toString(), List.of(end.toString())); + BaseNode startNode = new FunctionInvocationNode(nameRefNode, startParams, getTemporalConstantNode(start), start.toString()); + BaseNode endNode = new FunctionInvocationNode(nameRefNode, endParams, getTemporalConstantNode(end), end.toString()); + return new RangeNode(lowerBound, upperBound, startNode, endNode, text); } + } From 946114ce8bf08ce6ff9fc487553077a25d703a11 Mon Sep 17 00:00:00 2001 From: athira Date: Sun, 19 Jan 2025 17:37:34 +0530 Subject: [PATCH 10/15] [incubator-kie-issues#1743] Code clean up --- .../org/kie/dmn/feel/lang/ast/DateNode.java | 46 ------------------- 1 file changed, 46 deletions(-) delete mode 100644 kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/DateNode.java diff --git a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/DateNode.java b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/DateNode.java deleted file mode 100644 index e7402fee9f9..00000000000 --- a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/DateNode.java +++ /dev/null @@ -1,46 +0,0 @@ -/** - * 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.ast; - -import org.kie.dmn.feel.lang.EvaluationContext; - -import java.time.LocalDate; - -public class DateNode extends BaseNode{ - LocalDate value; - - public DateNode(LocalDate value, String text) { - this.value = value; - this.setText(text); - } - - public LocalDate getValue() { - return value; - } - - public void setValue(LocalDate value) { - this.value = value; - } - - @Override - public Object evaluate(EvaluationContext ctx) { - return value; - } - -} From 419e23291a98b693e10f029f5369fb354549765c Mon Sep 17 00:00:00 2001 From: athira Date: Mon, 20 Jan 2025 15:38:27 +0530 Subject: [PATCH 11/15] [incubator-kie-issues#1743] Fix review comments --- .../forexpressioniterators/ForIterationUtilsTest.java | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/lang/ast/forexpressioniterators/ForIterationUtilsTest.java b/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/lang/ast/forexpressioniterators/ForIterationUtilsTest.java index 8a0a08115c7..b2304ef21ed 100644 --- a/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/lang/ast/forexpressioniterators/ForIterationUtilsTest.java +++ b/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/lang/ast/forexpressioniterators/ForIterationUtilsTest.java @@ -34,7 +34,6 @@ import org.mockito.ArgumentCaptor; import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.assertEquals; import static org.kie.dmn.feel.lang.ast.forexpressioniterators.ForIterationUtils.getForIterationBigDecimalRange; import static org.kie.dmn.feel.lang.ast.forexpressioniterators.ForIterationUtils.getForIterationLocalDateRange; import static org.kie.dmn.feel.util.EvaluationContextTestUtil.newEmptyEvaluationContext; @@ -162,7 +161,7 @@ void testGetForIterationRangeValues() { ForIteration expectedResult = new ForIteration("rangeTest", null); ForIteration actualResult = getForIteration(range, "rangeTest", ctx); assertThat(actualResult).isNotNull(); - assertEquals(actualResult.toString(), expectedResult.toString()); + assertThat(actualResult.toString()).isEqualTo(expectedResult.toString()); } @Test @@ -172,7 +171,7 @@ void testGetForIterationBigDecimalRangeOpenBoundary() { ForIteration expectedResult = new ForIteration("BigDecimalRange", null); ForIteration actualResult = getForIterationBigDecimalRange(range, "BigDecimalRange", ctx); assertThat(actualResult).isNotNull(); - assertEquals(actualResult.toString(), expectedResult.toString()); + assertThat(actualResult.toString()).isEqualTo(expectedResult.toString()); } @Test @@ -182,7 +181,7 @@ void testGetForIterationBigDecimalRangeClosedBoundary() { ForIteration expectedResult = new ForIteration("BigDecimalRange", null); ForIteration actualResult = getForIterationBigDecimalRange(range, "BigDecimalRange", ctx); assertThat(actualResult).isNotNull(); - assertEquals(actualResult.toString(), expectedResult.toString()); + assertThat(actualResult.toString()).isEqualTo(expectedResult.toString()); } @Test @@ -192,7 +191,7 @@ void testGetForIterationLocalDateRangeOpenBoundary() { ForIteration expectedResult = new ForIteration("dateRange", null); ForIteration actualResult = getForIterationLocalDateRange(range, "dateRange", ctx); assertThat(actualResult).isNotNull(); - assertEquals(actualResult.toString(), expectedResult.toString()); + assertThat(actualResult.toString()).isEqualTo(expectedResult.toString()); } @Test @@ -202,6 +201,6 @@ void testGetForIterationLocalDateRangeClosedBoundary() { ForIteration expectedResult = new ForIteration("dateRange", null); ForIteration actualResult = getForIterationLocalDateRange(range, "dateRange", ctx); assertThat(actualResult).isNotNull(); - assertEquals(actualResult.toString(), expectedResult.toString()); + assertThat(actualResult.toString()).isEqualTo(expectedResult.toString()); } } From 13efdbf85d53729a0c371721d13974839bc22078 Mon Sep 17 00:00:00 2001 From: athira Date: Mon, 20 Jan 2025 18:24:48 +0530 Subject: [PATCH 12/15] [incubator-kie-issues#1743] Code fix --- ...tOfForIterationDifferentTypeException.java | 23 +++ ...ntOfForIterationNotValidTypeException.java | 23 +++ .../dmn/feel/lang/ast/ForExpressionNode.java | 4 +- .../ForIterationUtils.java | 50 +----- .../java/org/kie/dmn/feel/runtime/Range.java | 29 ++++ .../main/java/org/kie/dmn/feel/util/Msg.java | 1 + .../ForIterationUtilsTest.java | 55 ------- .../org/kie/dmn/feel/runtime/RangeTest.java | 143 ++++++++++++++++++ 8 files changed, 229 insertions(+), 99 deletions(-) create mode 100644 kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/exceptions/EndpointOfForIterationDifferentTypeException.java create mode 100644 kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/exceptions/EndpointOfForIterationNotValidTypeException.java create mode 100644 kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/runtime/RangeTest.java diff --git a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/exceptions/EndpointOfForIterationDifferentTypeException.java b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/exceptions/EndpointOfForIterationDifferentTypeException.java new file mode 100644 index 00000000000..fd762a0e7af --- /dev/null +++ b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/exceptions/EndpointOfForIterationDifferentTypeException.java @@ -0,0 +1,23 @@ +/** + * 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.exceptions; + +public class EndpointOfForIterationDifferentTypeException extends RuntimeException { + private static final long serialVersionUID = 1L; +} \ No newline at end of file diff --git a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/exceptions/EndpointOfForIterationNotValidTypeException.java b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/exceptions/EndpointOfForIterationNotValidTypeException.java new file mode 100644 index 00000000000..9e1b3d69e6c --- /dev/null +++ b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/exceptions/EndpointOfForIterationNotValidTypeException.java @@ -0,0 +1,23 @@ +/** + * 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.exceptions; + +public class EndpointOfForIterationNotValidTypeException extends RuntimeException { + private static final long serialVersionUID = 1L; +} \ No newline at end of file diff --git a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/ForExpressionNode.java b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/ForExpressionNode.java index 3f66eb3e7d5..a9cae3a6a0d 100644 --- a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/ForExpressionNode.java +++ b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/ForExpressionNode.java @@ -34,6 +34,8 @@ import java.util.List; import static org.kie.dmn.feel.lang.ast.forexpressioniterators.ForIterationUtils.getForIteration; +import static org.kie.dmn.feel.runtime.Range.getEnd; +import static org.kie.dmn.feel.runtime.Range.getStart; public class ForExpressionNode extends BaseNode { @@ -136,7 +138,7 @@ private ForIteration createForIteration(EvaluationContext ctx, IterationContextN if (result instanceof Iterable iterable) { toReturn = new ForIteration(name, iterable); } else if (result instanceof Range) { - toReturn = getForIteration(((Range) result), name, ctx); + toReturn = getForIteration(ctx, name, getStart((Range) result), getEnd((Range) result)); } else { toReturn = new ForIteration(name, Collections.singletonList(result)); } diff --git a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/forexpressioniterators/ForIterationUtils.java b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/forexpressioniterators/ForIterationUtils.java index 629bbb23f44..2c53802edbf 100644 --- a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/forexpressioniterators/ForIterationUtils.java +++ b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/forexpressioniterators/ForIterationUtils.java @@ -22,10 +22,9 @@ import java.time.LocalDate; import org.kie.dmn.api.feel.runtime.events.FEELEvent; -import org.kie.dmn.feel.exceptions.EndpointOfRangeNotValidTypeException; -import org.kie.dmn.feel.exceptions.EndpointOfRangeOfDifferentTypeException; +import org.kie.dmn.feel.exceptions.EndpointOfForIterationDifferentTypeException; +import org.kie.dmn.feel.exceptions.EndpointOfForIterationNotValidTypeException; import org.kie.dmn.feel.lang.EvaluationContext; -import org.kie.dmn.feel.runtime.Range; import org.kie.dmn.feel.runtime.events.ASTEventBase; import org.kie.dmn.feel.util.Msg; @@ -43,26 +42,15 @@ public static ForIteration getForIteration(EvaluationContext ctx, String name, O return new ForIteration(name, localDate, (LocalDate) end); } ctx.notifyEvt(() -> new ASTEventBase(FEELEvent.Severity.ERROR, - Msg.createMessage(Msg.VALUE_X_NOT_A_VALID_ENDPOINT_FOR_RANGE_BECAUSE_NOT_A_NUMBER_NOT_A_DATE, start), null)); - throw new EndpointOfRangeOfDifferentTypeException(); - } - - public static ForIteration getForIteration(Range result, String name, EvaluationContext ctx) { - validateValues(ctx, result.getLowEndPoint(), result.getHighEndPoint()); - if (result.getLowEndPoint() instanceof BigDecimal && result.getHighEndPoint() instanceof BigDecimal) { - return getForIterationBigDecimalRange(result,name,ctx); - } - if (result.getLowEndPoint() instanceof LocalDate && result.getHighEndPoint() instanceof LocalDate) { - return getForIterationLocalDateRange(result, name, ctx); - } - return null; + Msg.createMessage(Msg.VALUE_X_NOT_A_VALID_ENDPOINT_FOR_FORITERATION_BECAUSE_NOT_A_NUMBER_NOT_A_DATE, start), null)); + throw new EndpointOfForIterationDifferentTypeException(); } static void validateValues(EvaluationContext ctx, Object start, Object end) { if (start.getClass() != end.getClass()) { ctx.notifyEvt(() -> new ASTEventBase(FEELEvent.Severity.ERROR, Msg.createMessage(Msg.X_TYPE_INCOMPATIBLE_WITH_Y_TYPE, start, end), null)); - throw new EndpointOfRangeOfDifferentTypeException(); + throw new EndpointOfForIterationDifferentTypeException(); } valueMustBeValid(ctx, start); valueMustBeValid(ctx, end); @@ -70,33 +58,9 @@ static void validateValues(EvaluationContext ctx, Object start, Object end) { static void valueMustBeValid(EvaluationContext ctx, Object value) { if (!(value instanceof BigDecimal) && !(value instanceof LocalDate)) { - ctx.notifyEvt(() -> new ASTEventBase(FEELEvent.Severity.ERROR, Msg.createMessage(Msg.VALUE_X_NOT_A_VALID_ENDPOINT_FOR_RANGE_BECAUSE_NOT_A_NUMBER_NOT_A_DATE, value), null)); - throw new EndpointOfRangeNotValidTypeException(); - } - } - - static ForIteration getForIterationBigDecimalRange(Range result, String name, EvaluationContext ctx) { - BigDecimal start = (BigDecimal) result.getLowEndPoint(); - BigDecimal end = (BigDecimal) result.getHighEndPoint(); - if (result.getLowBoundary() == Range.RangeBoundary.OPEN) { - start = start.add(BigDecimal.ONE); - } - if (result.getHighBoundary() == Range.RangeBoundary.OPEN) { - end = end.subtract(BigDecimal.ONE); - } - return getForIteration(ctx, name, start, end); - } - - static ForIteration getForIterationLocalDateRange(Range result, String name, EvaluationContext ctx) { - LocalDate start = (LocalDate) result.getLowEndPoint(); - LocalDate end = (LocalDate) result.getHighEndPoint(); - if (result.getLowBoundary() == Range.RangeBoundary.OPEN) { - start = start.plusDays(1); - } - if (result.getHighBoundary() == Range.RangeBoundary.OPEN) { - end = end.minusDays(1); + ctx.notifyEvt(() -> new ASTEventBase(FEELEvent.Severity.ERROR, Msg.createMessage(Msg.VALUE_X_NOT_A_VALID_ENDPOINT_FOR_FORITERATION_BECAUSE_NOT_A_NUMBER_NOT_A_DATE, value), null)); + throw new EndpointOfForIterationNotValidTypeException(); } - return getForIteration(ctx, name, start, end); } } diff --git a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/Range.java b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/Range.java index 3ca1ec857b7..b84a7802100 100644 --- a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/Range.java +++ b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/Range.java @@ -18,6 +18,9 @@ */ package org.kie.dmn.feel.runtime; +import java.math.BigDecimal; +import java.time.LocalDate; + public interface Range { enum RangeBoundary { @@ -36,4 +39,30 @@ enum RangeBoundary { boolean isWithUndefined(); + + static Comparable getStart(Range result) { + if(result.getLowEndPoint() instanceof BigDecimal) { + BigDecimal start = (BigDecimal) result.getLowEndPoint(); + start = result.getLowBoundary() == Range.RangeBoundary.OPEN ? start.add(BigDecimal.ONE) : start; + return start; + } else if (result.getLowEndPoint() instanceof LocalDate) { + LocalDate start = (LocalDate) result.getLowEndPoint(); + start = result.getLowBoundary() == Range.RangeBoundary.OPEN ? start.plusDays(1) : start; + return start; + } + return result.getLowEndPoint(); + } + + static Comparable getEnd(Range result) { + if (result.getHighEndPoint() instanceof BigDecimal) { + BigDecimal end = (BigDecimal) result.getHighEndPoint(); + end = result.getHighBoundary() == Range.RangeBoundary.OPEN ? end.subtract(BigDecimal.ONE) : end; + return end; + } else if (result.getHighEndPoint() instanceof LocalDate) { + LocalDate end = (LocalDate) result.getHighEndPoint(); + end = result.getHighBoundary() == Range.RangeBoundary.OPEN ? end.minusDays(1) : end; + return end; + } + return result.getHighEndPoint(); + } } diff --git a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/util/Msg.java b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/util/Msg.java index 1eb8b5a01df..f1715d3cc01 100644 --- a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/util/Msg.java +++ b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/util/Msg.java @@ -39,6 +39,7 @@ public final class Msg { public static final Message2 X_TYPE_INCOMPATIBLE_WITH_Y_TYPE = new Message2("%s type incompatible with %s type"); public static final Message1 INCOMPATIBLE_TYPE_FOR_RANGE = new Message1("Type %s can not be used in a range unary test"); public static final Message1 VALUE_X_NOT_A_VALID_ENDPOINT_FOR_RANGE_BECAUSE_NOT_A_NUMBER_NOT_A_DATE = new Message1("Value %s is not a valid endpoint for range, because neither a feel:number nor a feel:date"); + public static final Message1 VALUE_X_NOT_A_VALID_ENDPOINT_FOR_FORITERATION_BECAUSE_NOT_A_NUMBER_NOT_A_DATE = new Message1("Value %s is not a valid value for forIteration, because neither a feel:number nor a feel:date"); public static final Message1 EVALUATED_TO_NULL = new Message1("%s evaluated to null"); public static final Message1 IS_NULL = new Message1("%s is null"); public static final Message0 BASE_NODE_EVALUATE_CALLED = new Message0("BaseNode evaluate called"); diff --git a/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/lang/ast/forexpressioniterators/ForIterationUtilsTest.java b/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/lang/ast/forexpressioniterators/ForIterationUtilsTest.java index b2304ef21ed..11db00f084b 100644 --- a/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/lang/ast/forexpressioniterators/ForIterationUtilsTest.java +++ b/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/lang/ast/forexpressioniterators/ForIterationUtilsTest.java @@ -29,13 +29,9 @@ import org.kie.dmn.feel.exceptions.EndpointOfRangeOfDifferentTypeException; import org.kie.dmn.feel.lang.EvaluationContext; import org.kie.dmn.feel.lang.impl.FEELEventListenersManager; -import org.kie.dmn.feel.runtime.Range; -import org.kie.dmn.feel.runtime.impl.RangeImpl; import org.mockito.ArgumentCaptor; import static org.assertj.core.api.Assertions.assertThat; -import static org.kie.dmn.feel.lang.ast.forexpressioniterators.ForIterationUtils.getForIterationBigDecimalRange; -import static org.kie.dmn.feel.lang.ast.forexpressioniterators.ForIterationUtils.getForIterationLocalDateRange; import static org.kie.dmn.feel.util.EvaluationContextTestUtil.newEmptyEvaluationContext; import static org.kie.dmn.feel.lang.ast.forexpressioniterators.ForIterationUtils.getForIteration; import static org.kie.dmn.feel.lang.ast.forexpressioniterators.ForIterationUtils.validateValues; @@ -152,55 +148,4 @@ void validateValuesFalseTest() { reset(listener); } } - - @Test - void testGetForIterationRangeValues() { - Range range = new RangeImpl(Range.RangeBoundary.CLOSED, BigDecimal.TEN, BigDecimal.valueOf(20), Range.RangeBoundary.OPEN); - EvaluationContext ctx = mock(EvaluationContext.class); - - ForIteration expectedResult = new ForIteration("rangeTest", null); - ForIteration actualResult = getForIteration(range, "rangeTest", ctx); - assertThat(actualResult).isNotNull(); - assertThat(actualResult.toString()).isEqualTo(expectedResult.toString()); - } - - @Test - void testGetForIterationBigDecimalRangeOpenBoundary() { - Range range = new RangeImpl(Range.RangeBoundary.OPEN, BigDecimal.TEN, BigDecimal.valueOf(20), Range.RangeBoundary.OPEN); - - ForIteration expectedResult = new ForIteration("BigDecimalRange", null); - ForIteration actualResult = getForIterationBigDecimalRange(range, "BigDecimalRange", ctx); - assertThat(actualResult).isNotNull(); - assertThat(actualResult.toString()).isEqualTo(expectedResult.toString()); - } - - @Test - void testGetForIterationBigDecimalRangeClosedBoundary() { - Range range = new RangeImpl(Range.RangeBoundary.CLOSED, BigDecimal.TEN, BigDecimal.valueOf(20), Range.RangeBoundary.CLOSED); - - ForIteration expectedResult = new ForIteration("BigDecimalRange", null); - ForIteration actualResult = getForIterationBigDecimalRange(range, "BigDecimalRange", ctx); - assertThat(actualResult).isNotNull(); - assertThat(actualResult.toString()).isEqualTo(expectedResult.toString()); - } - - @Test - void testGetForIterationLocalDateRangeOpenBoundary() { - Range range = new RangeImpl(Range.RangeBoundary.OPEN, LocalDate.of(2025, 1, 1), LocalDate.of(2025, 1, 7), Range.RangeBoundary.OPEN); - - ForIteration expectedResult = new ForIteration("dateRange", null); - ForIteration actualResult = getForIterationLocalDateRange(range, "dateRange", ctx); - assertThat(actualResult).isNotNull(); - assertThat(actualResult.toString()).isEqualTo(expectedResult.toString()); - } - - @Test - void testGetForIterationLocalDateRangeClosedBoundary() { - Range range = new RangeImpl(Range.RangeBoundary.CLOSED, LocalDate.of(2025, 1, 1), LocalDate.of(2025, 1, 7), Range.RangeBoundary.CLOSED); - - ForIteration expectedResult = new ForIteration("dateRange", null); - ForIteration actualResult = getForIterationLocalDateRange(range, "dateRange", ctx); - assertThat(actualResult).isNotNull(); - assertThat(actualResult.toString()).isEqualTo(expectedResult.toString()); - } } diff --git a/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/runtime/RangeTest.java b/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/runtime/RangeTest.java new file mode 100644 index 00000000000..c7ee62388f6 --- /dev/null +++ b/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/runtime/RangeTest.java @@ -0,0 +1,143 @@ +/** + * 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.runtime; + +import org.junit.jupiter.api.Test; +import org.kie.dmn.feel.runtime.impl.RangeImpl; + +import java.math.BigDecimal; +import java.time.Duration; +import java.time.LocalDate; + +import static org.assertj.core.api.Assertions.assertThat; + +public class RangeTest { + + @Test + void getStartForBigDecimalRangeOpenBoundary() { + Range range = new RangeImpl(Range.RangeBoundary.OPEN, BigDecimal.TEN, BigDecimal.valueOf(20), Range.RangeBoundary.OPEN); + + Comparable expectedResult = BigDecimal.valueOf(11); + Comparable actualResult = Range.getStart(range); + assertThat(actualResult).isEqualTo(expectedResult); + } + + @Test + void getStartForBigDecimalRangeClosedBoundary() { + Range range = new RangeImpl(Range.RangeBoundary.CLOSED, BigDecimal.TEN, BigDecimal.valueOf(20), Range.RangeBoundary.OPEN); + + Comparable expectedResult = BigDecimal.TEN; + Comparable actualResult = Range.getStart(range); + assertThat(actualResult).isEqualTo(expectedResult); + } + + @Test + void getEndForBigDecimalRangeOpenBoundary() { + Range range = new RangeImpl(Range.RangeBoundary.OPEN, BigDecimal.TEN, BigDecimal.valueOf(20), Range.RangeBoundary.OPEN); + + Comparable expectedResult = BigDecimal.valueOf(19); + Comparable actualResult = Range.getEnd(range); + assertThat(actualResult).isEqualTo(expectedResult); + } + + @Test + void getEndForBigDecimalRangeClosedBoundary() { + Range range = new RangeImpl(Range.RangeBoundary.CLOSED, BigDecimal.TEN, BigDecimal.valueOf(20), Range.RangeBoundary.CLOSED); + + Comparable expectedResult = BigDecimal.valueOf(20); + Comparable actualResult = Range.getEnd(range); + assertThat(actualResult).isEqualTo(expectedResult); + } + + @Test + void getStartForLocalDateRangeOpenBoundary() { + Range range = new RangeImpl(Range.RangeBoundary.OPEN, LocalDate.of(2025, 1, 1), LocalDate.of(2025, 1, 7), Range.RangeBoundary.OPEN); + + Comparable expectedResult = LocalDate.of(2025, 1, 2); + Comparable actualResult = Range.getStart(range); + assertThat(actualResult).isEqualTo(expectedResult); + } + + @Test + void getStartForLocalDateRangeClosedBoundary() { + Range range = new RangeImpl(Range.RangeBoundary.CLOSED, LocalDate.of(2025, 1, 1), LocalDate.of(2025, 1, 7), Range.RangeBoundary.OPEN); + + Comparable expectedResult = LocalDate.of(2025, 1, 1); + Comparable actualResult = Range.getStart(range); + assertThat(actualResult).isEqualTo(expectedResult); + } + + @Test + void getEndForLocalDateRangeOpenBoundary() { + Range range = new RangeImpl(Range.RangeBoundary.OPEN, LocalDate.of(2025, 1, 1), LocalDate.of(2025, 1, 7), Range.RangeBoundary.OPEN); + + Comparable expectedResult = LocalDate.of(2025, 1, 6); + Comparable actualResult = Range.getEnd(range); + assertThat(actualResult).isEqualTo(expectedResult); + } + + @Test + void getEndForLocalDateRangeClosedBoundary() { + Range range = new RangeImpl(Range.RangeBoundary.CLOSED, LocalDate.of(2025, 1, 1), LocalDate.of(2025, 1, 7), Range.RangeBoundary.CLOSED); + + Comparable expectedResult = LocalDate.of(2025, 1, 7); + Comparable actualResult = Range.getEnd(range); + assertThat(actualResult).isEqualTo(expectedResult); + } + + @Test + void getStartForStringRangeClosedBoundary() { + Range range = new RangeImpl(Range.RangeBoundary.CLOSED, "a", "z", Range.RangeBoundary.OPEN); + + Comparable expectedResult = "a"; + Comparable actualResult = Range.getStart(range); + assertThat(actualResult).isEqualTo(expectedResult); + + } + + @Test + void getEndForStringRangeOpenBoundary() { + Range range = new RangeImpl(Range.RangeBoundary.CLOSED, "a", "z", Range.RangeBoundary.OPEN); + + Comparable expectedResult = "z"; + Comparable actualResult = Range.getEnd(range); + assertThat(actualResult).isEqualTo(expectedResult); + + } + + @Test + void getStartForDurationRangeOpenBoundary() { + Range range = new RangeImpl(Range.RangeBoundary.OPEN, Duration.parse("P2DT20H14M"), Duration.parse("P3DT20H14M"), Range.RangeBoundary.CLOSED); + + Comparable expectedResult = Duration.parse("P2DT20H14M"); + Comparable actualResult = Range.getStart(range); + assertThat(actualResult).isEqualTo(expectedResult); + + } + + @Test + void getEndForDurationRangeClosedBoundary() { + Range range = new RangeImpl(Range.RangeBoundary.CLOSED, Duration.parse("P2DT20H14M"), Duration.parse("P3DT20H14M"), Range.RangeBoundary.CLOSED); + + Comparable expectedResult = Duration.parse("P3DT20H14M"); + Comparable actualResult = Range.getEnd(range); + assertThat(actualResult).isEqualTo(expectedResult); + + } +} From 0cccc08f1d1a7cc9b882118c22065b8d0e9ad68e Mon Sep 17 00:00:00 2001 From: athira Date: Mon, 20 Jan 2025 19:27:02 +0530 Subject: [PATCH 13/15] [incubator-kie-issues#1743] Fix review comments --- .../dmn/feel/lang/ast/ForExpressionNode.java | 4 +- .../java/org/kie/dmn/feel/runtime/Range.java | 27 +--- .../kie/dmn/feel/runtime/impl/RangeImpl.java | 30 ++++ .../org/kie/dmn/feel/runtime/RangeTest.java | 143 ------------------ .../dmn/feel/runtime/impl/RangeImplTest.java | 116 ++++++++++++++ 5 files changed, 150 insertions(+), 170 deletions(-) delete mode 100644 kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/runtime/RangeTest.java diff --git a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/ForExpressionNode.java b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/ForExpressionNode.java index a9cae3a6a0d..af293be3db4 100644 --- a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/ForExpressionNode.java +++ b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/ForExpressionNode.java @@ -34,8 +34,6 @@ import java.util.List; import static org.kie.dmn.feel.lang.ast.forexpressioniterators.ForIterationUtils.getForIteration; -import static org.kie.dmn.feel.runtime.Range.getEnd; -import static org.kie.dmn.feel.runtime.Range.getStart; public class ForExpressionNode extends BaseNode { @@ -138,7 +136,7 @@ private ForIteration createForIteration(EvaluationContext ctx, IterationContextN if (result instanceof Iterable iterable) { toReturn = new ForIteration(name, iterable); } else if (result instanceof Range) { - toReturn = getForIteration(ctx, name, getStart((Range) result), getEnd((Range) result)); + toReturn = getForIteration(ctx, name, ((Range) result).getStart(), ((Range) result).getEnd()); } else { toReturn = new ForIteration(name, Collections.singletonList(result)); } diff --git a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/Range.java b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/Range.java index b84a7802100..70c93d32b01 100644 --- a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/Range.java +++ b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/Range.java @@ -39,30 +39,9 @@ enum RangeBoundary { boolean isWithUndefined(); + Comparable getStart(); + + Comparable getEnd(); - static Comparable getStart(Range result) { - if(result.getLowEndPoint() instanceof BigDecimal) { - BigDecimal start = (BigDecimal) result.getLowEndPoint(); - start = result.getLowBoundary() == Range.RangeBoundary.OPEN ? start.add(BigDecimal.ONE) : start; - return start; - } else if (result.getLowEndPoint() instanceof LocalDate) { - LocalDate start = (LocalDate) result.getLowEndPoint(); - start = result.getLowBoundary() == Range.RangeBoundary.OPEN ? start.plusDays(1) : start; - return start; - } - return result.getLowEndPoint(); - } - static Comparable getEnd(Range result) { - if (result.getHighEndPoint() instanceof BigDecimal) { - BigDecimal end = (BigDecimal) result.getHighEndPoint(); - end = result.getHighBoundary() == Range.RangeBoundary.OPEN ? end.subtract(BigDecimal.ONE) : end; - return end; - } else if (result.getHighEndPoint() instanceof LocalDate) { - LocalDate end = (LocalDate) result.getHighEndPoint(); - end = result.getHighBoundary() == Range.RangeBoundary.OPEN ? end.minusDays(1) : end; - return end; - } - return result.getHighEndPoint(); - } } diff --git a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/impl/RangeImpl.java b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/impl/RangeImpl.java index 51893062d91..d4c4195bc64 100644 --- a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/impl/RangeImpl.java +++ b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/impl/RangeImpl.java @@ -18,6 +18,8 @@ */ package org.kie.dmn.feel.runtime.impl; +import java.math.BigDecimal; +import java.time.LocalDate; import java.util.function.BiPredicate; import org.kie.dmn.feel.runtime.Range; @@ -97,6 +99,34 @@ public boolean isWithUndefined() { return withUndefined; } + @Override + public Comparable getStart() { + if(lowEndPoint instanceof BigDecimal) { + BigDecimal start = (BigDecimal) lowEndPoint; + start = lowBoundary == Range.RangeBoundary.OPEN ? start.add(BigDecimal.ONE) : start; + return start; + } else if (lowEndPoint instanceof LocalDate) { + LocalDate start = (LocalDate) lowEndPoint; + start = lowBoundary == Range.RangeBoundary.OPEN ? start.plusDays(1) : start; + return start; + } + return lowEndPoint; + } + + @Override + public Comparable getEnd() { + if (highEndPoint instanceof BigDecimal) { + BigDecimal end = (BigDecimal) highEndPoint; + end = highBoundary == Range.RangeBoundary.OPEN ? end.subtract(BigDecimal.ONE) : end; + return end; + } else if (highEndPoint instanceof LocalDate) { + LocalDate end = (LocalDate) highEndPoint; + end = highBoundary == Range.RangeBoundary.OPEN ? end.minusDays(1) : end; + return end; + } + return highEndPoint; + } + private Boolean finiteRangeIncludes(Object param) { if (lowBoundary == RangeBoundary.OPEN && highBoundary == RangeBoundary.OPEN) { return bothOrThrow(compare(lowEndPoint, param, (l, r) -> l.compareTo(r) < 0) , compare(highEndPoint, param, (l, r) -> l.compareTo(r) > 0), param); diff --git a/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/runtime/RangeTest.java b/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/runtime/RangeTest.java deleted file mode 100644 index c7ee62388f6..00000000000 --- a/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/runtime/RangeTest.java +++ /dev/null @@ -1,143 +0,0 @@ -/** - * 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.runtime; - -import org.junit.jupiter.api.Test; -import org.kie.dmn.feel.runtime.impl.RangeImpl; - -import java.math.BigDecimal; -import java.time.Duration; -import java.time.LocalDate; - -import static org.assertj.core.api.Assertions.assertThat; - -public class RangeTest { - - @Test - void getStartForBigDecimalRangeOpenBoundary() { - Range range = new RangeImpl(Range.RangeBoundary.OPEN, BigDecimal.TEN, BigDecimal.valueOf(20), Range.RangeBoundary.OPEN); - - Comparable expectedResult = BigDecimal.valueOf(11); - Comparable actualResult = Range.getStart(range); - assertThat(actualResult).isEqualTo(expectedResult); - } - - @Test - void getStartForBigDecimalRangeClosedBoundary() { - Range range = new RangeImpl(Range.RangeBoundary.CLOSED, BigDecimal.TEN, BigDecimal.valueOf(20), Range.RangeBoundary.OPEN); - - Comparable expectedResult = BigDecimal.TEN; - Comparable actualResult = Range.getStart(range); - assertThat(actualResult).isEqualTo(expectedResult); - } - - @Test - void getEndForBigDecimalRangeOpenBoundary() { - Range range = new RangeImpl(Range.RangeBoundary.OPEN, BigDecimal.TEN, BigDecimal.valueOf(20), Range.RangeBoundary.OPEN); - - Comparable expectedResult = BigDecimal.valueOf(19); - Comparable actualResult = Range.getEnd(range); - assertThat(actualResult).isEqualTo(expectedResult); - } - - @Test - void getEndForBigDecimalRangeClosedBoundary() { - Range range = new RangeImpl(Range.RangeBoundary.CLOSED, BigDecimal.TEN, BigDecimal.valueOf(20), Range.RangeBoundary.CLOSED); - - Comparable expectedResult = BigDecimal.valueOf(20); - Comparable actualResult = Range.getEnd(range); - assertThat(actualResult).isEqualTo(expectedResult); - } - - @Test - void getStartForLocalDateRangeOpenBoundary() { - Range range = new RangeImpl(Range.RangeBoundary.OPEN, LocalDate.of(2025, 1, 1), LocalDate.of(2025, 1, 7), Range.RangeBoundary.OPEN); - - Comparable expectedResult = LocalDate.of(2025, 1, 2); - Comparable actualResult = Range.getStart(range); - assertThat(actualResult).isEqualTo(expectedResult); - } - - @Test - void getStartForLocalDateRangeClosedBoundary() { - Range range = new RangeImpl(Range.RangeBoundary.CLOSED, LocalDate.of(2025, 1, 1), LocalDate.of(2025, 1, 7), Range.RangeBoundary.OPEN); - - Comparable expectedResult = LocalDate.of(2025, 1, 1); - Comparable actualResult = Range.getStart(range); - assertThat(actualResult).isEqualTo(expectedResult); - } - - @Test - void getEndForLocalDateRangeOpenBoundary() { - Range range = new RangeImpl(Range.RangeBoundary.OPEN, LocalDate.of(2025, 1, 1), LocalDate.of(2025, 1, 7), Range.RangeBoundary.OPEN); - - Comparable expectedResult = LocalDate.of(2025, 1, 6); - Comparable actualResult = Range.getEnd(range); - assertThat(actualResult).isEqualTo(expectedResult); - } - - @Test - void getEndForLocalDateRangeClosedBoundary() { - Range range = new RangeImpl(Range.RangeBoundary.CLOSED, LocalDate.of(2025, 1, 1), LocalDate.of(2025, 1, 7), Range.RangeBoundary.CLOSED); - - Comparable expectedResult = LocalDate.of(2025, 1, 7); - Comparable actualResult = Range.getEnd(range); - assertThat(actualResult).isEqualTo(expectedResult); - } - - @Test - void getStartForStringRangeClosedBoundary() { - Range range = new RangeImpl(Range.RangeBoundary.CLOSED, "a", "z", Range.RangeBoundary.OPEN); - - Comparable expectedResult = "a"; - Comparable actualResult = Range.getStart(range); - assertThat(actualResult).isEqualTo(expectedResult); - - } - - @Test - void getEndForStringRangeOpenBoundary() { - Range range = new RangeImpl(Range.RangeBoundary.CLOSED, "a", "z", Range.RangeBoundary.OPEN); - - Comparable expectedResult = "z"; - Comparable actualResult = Range.getEnd(range); - assertThat(actualResult).isEqualTo(expectedResult); - - } - - @Test - void getStartForDurationRangeOpenBoundary() { - Range range = new RangeImpl(Range.RangeBoundary.OPEN, Duration.parse("P2DT20H14M"), Duration.parse("P3DT20H14M"), Range.RangeBoundary.CLOSED); - - Comparable expectedResult = Duration.parse("P2DT20H14M"); - Comparable actualResult = Range.getStart(range); - assertThat(actualResult).isEqualTo(expectedResult); - - } - - @Test - void getEndForDurationRangeClosedBoundary() { - Range range = new RangeImpl(Range.RangeBoundary.CLOSED, Duration.parse("P2DT20H14M"), Duration.parse("P3DT20H14M"), Range.RangeBoundary.CLOSED); - - Comparable expectedResult = Duration.parse("P3DT20H14M"); - Comparable actualResult = Range.getEnd(range); - assertThat(actualResult).isEqualTo(expectedResult); - - } -} diff --git a/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/runtime/impl/RangeImplTest.java b/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/runtime/impl/RangeImplTest.java index 521abb12fc7..06cfea60758 100644 --- a/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/runtime/impl/RangeImplTest.java +++ b/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/runtime/impl/RangeImplTest.java @@ -21,6 +21,10 @@ import org.junit.jupiter.api.Test; import org.kie.dmn.feel.runtime.Range; +import java.math.BigDecimal; +import java.time.Duration; +import java.time.LocalDate; + import static org.assertj.core.api.Assertions.assertThat; class RangeImplTest { @@ -159,4 +163,116 @@ void hashCodeTest() { rangeImpl2 = new RangeImpl(Range.RangeBoundary.CLOSED, 12, 17, Range.RangeBoundary.CLOSED); assertThat(rangeImpl2).doesNotHaveSameHashCodeAs(rangeImpl); } + + @Test + void getStartForBigDecimalRangeOpenBoundary() { + RangeImpl rangeImpl = new RangeImpl(Range.RangeBoundary.OPEN, BigDecimal.TEN, BigDecimal.valueOf(20), Range.RangeBoundary.OPEN); + + Comparable expectedResult = BigDecimal.valueOf(11); + Comparable actualResult = rangeImpl.getStart(); + assertThat(actualResult).isEqualTo(expectedResult); + } + + @Test + void getStartForBigDecimalRangeClosedBoundary() { + RangeImpl rangeImpl = new RangeImpl(Range.RangeBoundary.CLOSED, BigDecimal.TEN, BigDecimal.valueOf(20), Range.RangeBoundary.OPEN); + + Comparable expectedResult = BigDecimal.TEN; + Comparable actualResult = rangeImpl.getStart(); + assertThat(actualResult).isEqualTo(expectedResult); + } + + @Test + void getEndForBigDecimalRangeOpenBoundary() { + RangeImpl rangeImpl = new RangeImpl(Range.RangeBoundary.OPEN, BigDecimal.TEN, BigDecimal.valueOf(20), Range.RangeBoundary.OPEN); + + Comparable expectedResult = BigDecimal.valueOf(19); + Comparable actualResult = rangeImpl.getEnd(); + assertThat(actualResult).isEqualTo(expectedResult); + } + + @Test + void getEndForBigDecimalRangeClosedBoundary() { + RangeImpl rangeImpl = new RangeImpl(Range.RangeBoundary.CLOSED, BigDecimal.TEN, BigDecimal.valueOf(20), Range.RangeBoundary.CLOSED); + + Comparable expectedResult = BigDecimal.valueOf(20); + Comparable actualResult = rangeImpl.getEnd(); + assertThat(actualResult).isEqualTo(expectedResult); + } + + @Test + void getStartForLocalDateRangeOpenBoundary() { + RangeImpl rangeImpl = new RangeImpl(Range.RangeBoundary.OPEN, LocalDate.of(2025, 1, 1), LocalDate.of(2025, 1, 7), Range.RangeBoundary.OPEN); + + Comparable expectedResult = LocalDate.of(2025, 1, 2); + Comparable actualResult = rangeImpl.getStart(); + assertThat(actualResult).isEqualTo(expectedResult); + } + + @Test + void getStartForLocalDateRangeClosedBoundary() { + RangeImpl rangeImpl = new RangeImpl(Range.RangeBoundary.CLOSED, LocalDate.of(2025, 1, 1), LocalDate.of(2025, 1, 7), Range.RangeBoundary.OPEN); + + Comparable expectedResult = LocalDate.of(2025, 1, 1); + Comparable actualResult = rangeImpl.getStart(); + assertThat(actualResult).isEqualTo(expectedResult); + } + + @Test + void getEndForLocalDateRangeOpenBoundary() { + RangeImpl rangeImpl = new RangeImpl(Range.RangeBoundary.OPEN, LocalDate.of(2025, 1, 1), LocalDate.of(2025, 1, 7), Range.RangeBoundary.OPEN); + + Comparable expectedResult = LocalDate.of(2025, 1, 6); + Comparable actualResult = rangeImpl.getEnd(); + assertThat(actualResult).isEqualTo(expectedResult); + } + + @Test + void getEndForLocalDateRangeClosedBoundary() { + RangeImpl rangeImpl = new RangeImpl(Range.RangeBoundary.CLOSED, LocalDate.of(2025, 1, 1), LocalDate.of(2025, 1, 7), Range.RangeBoundary.CLOSED); + + Comparable expectedResult = LocalDate.of(2025, 1, 7); + Comparable actualResult = rangeImpl.getEnd(); + assertThat(actualResult).isEqualTo(expectedResult); + } + + @Test + void getStartForStringRangeClosedBoundary() { + RangeImpl rangeImpl = new RangeImpl(Range.RangeBoundary.CLOSED, "a", "z", Range.RangeBoundary.OPEN); + + Comparable expectedResult = "a"; + Comparable actualResult = rangeImpl.getStart(); + assertThat(actualResult).isEqualTo(expectedResult); + + } + + @Test + void getEndForStringRangeOpenBoundary() { + RangeImpl rangeImpl = new RangeImpl(Range.RangeBoundary.CLOSED, "a", "z", Range.RangeBoundary.OPEN); + + Comparable expectedResult = "z"; + Comparable actualResult = rangeImpl.getEnd(); + assertThat(actualResult).isEqualTo(expectedResult); + + } + + @Test + void getStartForDurationRangeOpenBoundary() { + RangeImpl rangeImpl = new RangeImpl(Range.RangeBoundary.OPEN, Duration.parse("P2DT20H14M"), Duration.parse("P3DT20H14M"), Range.RangeBoundary.CLOSED); + + Comparable expectedResult = Duration.parse("P2DT20H14M"); + Comparable actualResult = rangeImpl.getStart(); + assertThat(actualResult).isEqualTo(expectedResult); + + } + + @Test + void getEndForDurationRangeClosedBoundary() { + RangeImpl rangeImpl = new RangeImpl(Range.RangeBoundary.CLOSED, Duration.parse("P2DT20H14M"), Duration.parse("P3DT20H14M"), Range.RangeBoundary.CLOSED); + + Comparable expectedResult = Duration.parse("P3DT20H14M"); + Comparable actualResult = rangeImpl.getEnd(); + assertThat(actualResult).isEqualTo(expectedResult); + + } } \ No newline at end of file From 97ab953b9ca1d7b0bfd9000d0c685bf97125606e Mon Sep 17 00:00:00 2001 From: athira Date: Mon, 20 Jan 2025 19:47:26 +0530 Subject: [PATCH 14/15] [incubator-kie-issues#1743] Fix merge conflicts --- .../src/main/java/org/kie/dmn/feel/runtime/impl/RangeImpl.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/impl/RangeImpl.java b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/impl/RangeImpl.java index 85a152012d9..ce49c8cf6d7 100644 --- a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/impl/RangeImpl.java +++ b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/runtime/impl/RangeImpl.java @@ -100,7 +100,6 @@ public boolean isWithUndefined() { return withUndefined; } - private Boolean finiteRangeIncludes(FEELDialect feelDialect, Object param) { @Override public Comparable getStart() { if(lowEndPoint instanceof BigDecimal) { @@ -129,7 +128,7 @@ public Comparable getEnd() { return highEndPoint; } - private Boolean finiteRangeIncludes(Object param) { + private Boolean finiteRangeIncludes(FEELDialect feelDialect, Object param) { if (lowBoundary == RangeBoundary.OPEN && highBoundary == RangeBoundary.OPEN) { return bothOrThrow(compare(feelDialect, lowEndPoint, param, (l, r) -> l.compareTo(r) < 0) , compare(feelDialect, highEndPoint, param, (l, r) -> l.compareTo(r) > 0), param); } else if (lowBoundary == RangeBoundary.OPEN && highBoundary == RangeBoundary.CLOSED) { From 951afdf2519b7073cbaba307dc58d4427454d5d2 Mon Sep 17 00:00:00 2001 From: athira Date: Mon, 20 Jan 2025 22:21:04 +0530 Subject: [PATCH 15/15] [incubator-kie-issues#1743] Fix broken testcases and remove unused classes --- .../EndpointOfRangeNotOfNumberException.java | 22 ------------------ .../EndpointOfRangeNotValidTypeException.java | 23 ------------------- ...dpointOfRangeOfDifferentTypeException.java | 23 ------------------- .../dmn/feel/lang/ast/ForExpressionNode.java | 6 ++--- .../ForIterationUtilsTest.java | 18 +++++++-------- 5 files changed, 12 insertions(+), 80 deletions(-) delete mode 100644 kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/exceptions/EndpointOfRangeNotOfNumberException.java delete mode 100644 kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/exceptions/EndpointOfRangeNotValidTypeException.java delete mode 100644 kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/exceptions/EndpointOfRangeOfDifferentTypeException.java diff --git a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/exceptions/EndpointOfRangeNotOfNumberException.java b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/exceptions/EndpointOfRangeNotOfNumberException.java deleted file mode 100644 index 3c6ce52b788..00000000000 --- a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/exceptions/EndpointOfRangeNotOfNumberException.java +++ /dev/null @@ -1,22 +0,0 @@ -/** - * 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.exceptions; - -public class EndpointOfRangeNotOfNumberException extends RuntimeException { -} \ No newline at end of file diff --git a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/exceptions/EndpointOfRangeNotValidTypeException.java b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/exceptions/EndpointOfRangeNotValidTypeException.java deleted file mode 100644 index f49115f618f..00000000000 --- a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/exceptions/EndpointOfRangeNotValidTypeException.java +++ /dev/null @@ -1,23 +0,0 @@ -/** - * 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.exceptions; - -public class EndpointOfRangeNotValidTypeException extends RuntimeException { - private static final long serialVersionUID = 1L; -} \ No newline at end of file diff --git a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/exceptions/EndpointOfRangeOfDifferentTypeException.java b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/exceptions/EndpointOfRangeOfDifferentTypeException.java deleted file mode 100644 index 4c62799beae..00000000000 --- a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/exceptions/EndpointOfRangeOfDifferentTypeException.java +++ /dev/null @@ -1,23 +0,0 @@ -/** - * 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.exceptions; - -public class EndpointOfRangeOfDifferentTypeException extends RuntimeException { - private static final long serialVersionUID = 1L; -} \ No newline at end of file diff --git a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/ForExpressionNode.java b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/ForExpressionNode.java index af293be3db4..e8b32efdbff 100644 --- a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/ForExpressionNode.java +++ b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/ForExpressionNode.java @@ -19,8 +19,8 @@ package org.kie.dmn.feel.lang.ast; import org.antlr.v4.runtime.ParserRuleContext; -import org.kie.dmn.feel.exceptions.EndpointOfRangeNotValidTypeException; -import org.kie.dmn.feel.exceptions.EndpointOfRangeOfDifferentTypeException; +import org.kie.dmn.feel.exceptions.EndpointOfForIterationNotValidTypeException; +import org.kie.dmn.feel.exceptions.EndpointOfForIterationDifferentTypeException; import org.kie.dmn.feel.lang.EvaluationContext; import org.kie.dmn.feel.lang.Type; import org.kie.dmn.feel.lang.ast.forexpressioniterators.ForIteration; @@ -83,7 +83,7 @@ public Object evaluate(EvaluationContext ctx) { populateToReturn(0, ctx, toReturn); LOG.trace("returning {}", toReturn); return toReturn; - } catch (EndpointOfRangeNotValidTypeException | EndpointOfRangeOfDifferentTypeException e) { + } catch (EndpointOfForIterationNotValidTypeException | EndpointOfForIterationDifferentTypeException e) { // ast error already reported return null; } finally { diff --git a/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/lang/ast/forexpressioniterators/ForIterationUtilsTest.java b/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/lang/ast/forexpressioniterators/ForIterationUtilsTest.java index 11db00f084b..7b068a1d4c0 100644 --- a/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/lang/ast/forexpressioniterators/ForIterationUtilsTest.java +++ b/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/lang/ast/forexpressioniterators/ForIterationUtilsTest.java @@ -25,8 +25,8 @@ import org.junit.jupiter.api.Test; import org.kie.dmn.api.feel.runtime.events.FEELEvent; import org.kie.dmn.api.feel.runtime.events.FEELEventListener; -import org.kie.dmn.feel.exceptions.EndpointOfRangeNotValidTypeException; -import org.kie.dmn.feel.exceptions.EndpointOfRangeOfDifferentTypeException; +import org.kie.dmn.feel.exceptions.EndpointOfForIterationDifferentTypeException; +import org.kie.dmn.feel.exceptions.EndpointOfForIterationNotValidTypeException; import org.kie.dmn.feel.lang.EvaluationContext; import org.kie.dmn.feel.lang.impl.FEELEventListenersManager; import org.mockito.ArgumentCaptor; @@ -71,7 +71,7 @@ void getForIterationNotValidTest() { try { getForIteration(ctx, "iteration", "NOT", "VALID"); } catch (Exception e) { - assertThat(e).isInstanceOf(EndpointOfRangeNotValidTypeException.class); + assertThat(e).isInstanceOf(EndpointOfForIterationNotValidTypeException.class); final ArgumentCaptor captor = ArgumentCaptor.forClass(FEELEvent.class); verify(listener, times(1)).onEvent(captor.capture()); reset(listener); @@ -79,7 +79,7 @@ void getForIterationNotValidTest() { try { getForIteration(ctx, "iteration", BigDecimal.valueOf(1), LocalDate.of(2021, 1, 1)); } catch (Exception e) { - assertThat(e).isInstanceOf(EndpointOfRangeOfDifferentTypeException.class); + assertThat(e).isInstanceOf(EndpointOfForIterationDifferentTypeException.class); final ArgumentCaptor captor = ArgumentCaptor.forClass(FEELEvent.class); verify(listener, times(1)).onEvent(captor.capture()); reset(listener); @@ -87,7 +87,7 @@ void getForIterationNotValidTest() { try { getForIteration(ctx, "iteration", LocalDate.of(2021, 1, 1), BigDecimal.valueOf(1)); } catch (Exception e) { - assertThat(e).isInstanceOf(EndpointOfRangeOfDifferentTypeException.class); + assertThat(e).isInstanceOf(EndpointOfForIterationDifferentTypeException.class); final ArgumentCaptor captor = ArgumentCaptor.forClass(FEELEvent.class); verify(listener, times(1)).onEvent(captor.capture()); reset(listener); @@ -107,7 +107,7 @@ void valueMustBeValidFalseTest() { try { valueMustBeValid(ctx, "INVALID"); } catch (Exception e) { - assertThat(e).isInstanceOf(EndpointOfRangeNotValidTypeException.class); + assertThat(e).isInstanceOf(EndpointOfForIterationNotValidTypeException.class); final ArgumentCaptor captor = ArgumentCaptor.forClass(FEELEvent.class); verify(listener, times(1)).onEvent(captor.capture()); } @@ -126,7 +126,7 @@ void validateValuesFalseTest() { try { validateValues(ctx, "INVALID", "INVALID"); } catch (Exception e) { - assertThat(e).isInstanceOf(EndpointOfRangeNotValidTypeException.class); + assertThat(e).isInstanceOf(EndpointOfForIterationNotValidTypeException.class); final ArgumentCaptor captor = ArgumentCaptor.forClass(FEELEvent.class); verify(listener, times(1)).onEvent(captor.capture()); reset(listener); @@ -134,7 +134,7 @@ void validateValuesFalseTest() { try { validateValues(ctx, BigDecimal.valueOf(1), LocalDate.of(2021, 1, 1)); } catch (Exception e) { - assertThat(e).isInstanceOf(EndpointOfRangeOfDifferentTypeException.class); + assertThat(e).isInstanceOf(EndpointOfForIterationDifferentTypeException.class); final ArgumentCaptor captor = ArgumentCaptor.forClass(FEELEvent.class); verify(listener, times(1)).onEvent(captor.capture()); reset(listener); @@ -142,7 +142,7 @@ void validateValuesFalseTest() { try { validateValues(ctx, LocalDate.of(2021, 1, 1), BigDecimal.valueOf(1)); } catch (Exception e) { - assertThat(e).isInstanceOf(EndpointOfRangeOfDifferentTypeException.class); + assertThat(e).isInstanceOf(EndpointOfForIterationDifferentTypeException.class); final ArgumentCaptor captor = ArgumentCaptor.forClass(FEELEvent.class); verify(listener, times(1)).onEvent(captor.capture()); reset(listener);