This is an automated email from the ASF dual-hosted git repository.

yamer pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-kie-drools.git


The following commit(s) were added to refs/heads/main by this push:
     new e804cdc4b0 [Incubator-kie-issues#2184] Fix for Range Node issue (#6542)
e804cdc4b0 is described below

commit e804cdc4b0c087fb3207654b3961403e99412df1
Author: ChinchuAjith <[email protected]>
AuthorDate: Wed Dec 17 15:50:58 2025 +0530

    [Incubator-kie-issues#2184] Fix for Range Node issue (#6542)
    
    * Fix for Range Node issue
    
    * Fix for Range Node issue - cleanup
    
    * unit test for RangeImpl with boolean inputs
    
    * unit test for RangeImpl
---
 .../ast/dialectHandlers/BFEELDialectHandler.java   |  22 +-
 .../ast/dialectHandlers/DefaultDialectHandler.java |  18 +-
 .../lang/ast/dialectHandlers/DialectHandler.java   |   7 +-
 .../ast/dialectHandlers/FEELDialectHandler.java    |   6 +
 .../org/kie/dmn/feel/runtime/impl/RangeImpl.java   |  25 +-
 .../kie/dmn/feel/runtime/impl/RangeImplTest.java   | 329 +++++++++++++--------
 6 files changed, 235 insertions(+), 172 deletions(-)

diff --git 
a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/dialectHandlers/BFEELDialectHandler.java
 
b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/dialectHandlers/BFEELDialectHandler.java
index 251d578f3d..626c94cff7 100644
--- 
a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/dialectHandlers/BFEELDialectHandler.java
+++ 
b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/dialectHandlers/BFEELDialectHandler.java
@@ -26,6 +26,7 @@ import java.util.LinkedHashMap;
 import java.util.Map;
 import java.util.Objects;
 import java.util.function.BiFunction;
+import java.util.function.BiPredicate;
 
 import org.kie.dmn.feel.lang.EvaluationContext;
 import org.kie.dmn.feel.lang.FEELDialect;
@@ -160,9 +161,7 @@ public class BFEELDialectHandler extends 
DefaultDialectHandler implements Dialec
         map.put(
                 new CheckedPredicate((left, right) -> true, false),
                 (left, right) -> {
-                    Boolean greater = compare(left, right, (l, r) -> 
l.compareTo(r) > 0,
-                            () -> Boolean.FALSE,
-                            () -> Boolean.FALSE);
+                    Boolean greater = compare(left, right, (l, r) -> 
l.compareTo(r) > 0);
                     //Boolean equal = BooleanEvalHelper.isEqual(left, right, 
ctx.getFEELDialect());
                     Boolean equal = (EqExecutor.instance().evaluate(left, 
right, ctx) instanceof Boolean)
                             ? (Boolean) EqExecutor.instance().evaluate(left, 
right, ctx)
@@ -210,9 +209,7 @@ public class BFEELDialectHandler extends 
DefaultDialectHandler implements Dialec
                 new CheckedPredicate((left, right) -> true, false),
                 (left, right) -> {
                     Boolean greater = compare(left, right,
-                            (l, r) -> l.compareTo(r) > 0,
-                            () -> Boolean.FALSE,
-                            () -> Boolean.FALSE);
+                            (l, r) -> l.compareTo(r) > 0);
                     return Objects.requireNonNullElse(greater, Boolean.FALSE);
                 });
 
@@ -248,9 +245,7 @@ public class BFEELDialectHandler extends 
DefaultDialectHandler implements Dialec
                 new CheckedPredicate((left, right) -> true, false),
                 (left, right) -> {
                     Boolean less = compare(left, right,
-                            (l, r) -> l.compareTo(r) < 0,
-                            () -> Boolean.FALSE,
-                            () -> Boolean.FALSE);
+                            (l, r) -> l.compareTo(r) < 0);
                     Boolean equal = (EqExecutor.instance().evaluate(left, 
right, ctx) instanceof Boolean)
                             ? (Boolean) EqExecutor.instance().evaluate(left, 
right, ctx)
                             : null;
@@ -296,9 +291,7 @@ public class BFEELDialectHandler extends 
DefaultDialectHandler implements Dialec
                 new CheckedPredicate((left, right) -> true, false),
                 (left, right) -> {
                     Boolean less = compare(left, right,
-                            (l, r) -> l.compareTo(r) < 0,
-                            () -> Boolean.FALSE,
-                            () -> Boolean.FALSE);
+                            (l, r) -> l.compareTo(r) < 0);
                     return Objects.requireNonNullElse(less, Boolean.FALSE);
                 });
         map.putAll(getCommonLtOperations(ctx));
@@ -483,4 +476,9 @@ public class BFEELDialectHandler extends 
DefaultDialectHandler implements Dialec
         map.putAll(getCommonDivisionOperations(ctx));
         return map;
     }
+
+    @Override
+    public Boolean compare(Object left, Object right, BiPredicate<Comparable, 
Comparable> op) {
+        return compare(left, right, op, () -> Boolean.FALSE, () -> 
Boolean.FALSE);
+    }
 }
diff --git 
a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/dialectHandlers/DefaultDialectHandler.java
 
b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/dialectHandlers/DefaultDialectHandler.java
index 11fe10fdd6..24ab68074e 100644
--- 
a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/dialectHandlers/DefaultDialectHandler.java
+++ 
b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/dialectHandlers/DefaultDialectHandler.java
@@ -211,10 +211,7 @@ public abstract class DefaultDialectHandler implements 
DialectHandler {
                 new CheckedPredicate((left, right) -> true, false),
                 (left, right) -> {
                     Boolean greater = compare(left, right,
-                            (leftNum, rightNum) -> leftNum.compareTo(rightNum) 
> 0,
-                            () -> null, // nullFallback for Default dialect
-                            () -> null // defaultFallback for unknown types
-                    );
+                            (leftNum, rightNum) -> leftNum.compareTo(rightNum) 
> 0);
                     //Boolean equal = BooleanEvalHelper.isEqual(left, right, 
dialect);
                     Boolean equal = (EqExecutor.instance().evaluate(left, 
right, ctx) instanceof Boolean)
                             ? (Boolean) EqExecutor.instance().evaluate(left, 
right, ctx)
@@ -244,9 +241,7 @@ public abstract class DefaultDialectHandler implements 
DialectHandler {
 
                     // default dialect: keep null
                     return compare(left, right,
-                            (l, r) -> l.compareTo(r) > 0,
-                            () -> null,
-                            () -> null);
+                            (l, r) -> l.compareTo(r) > 0);
                 });
         return map;
     }
@@ -279,9 +274,7 @@ public abstract class DefaultDialectHandler implements 
DialectHandler {
                 new CheckedPredicate((left, right) -> true, false),
                 (left, right) -> {
                     Boolean less = compare(left, right,
-                            (l, r) -> l.compareTo(r) < 0,
-                            () -> null,
-                            () -> null);
+                            (l, r) -> l.compareTo(r) < 0);
                     // Boolean equal = BooleanEvalHelper.isEqual(left, right, 
dialect);
                     Boolean equal = (EqExecutor.instance().evaluate(left, 
right, ctx) instanceof Boolean)
                             ? (Boolean) EqExecutor.instance().evaluate(left, 
right, ctx)
@@ -312,9 +305,7 @@ public abstract class DefaultDialectHandler implements 
DialectHandler {
                 new CheckedPredicate((left, right) -> true, false),
                 (left, right) -> {
                     return compare(left, right,
-                            (l, r) -> l.compareTo(r) < 0,
-                            () -> null,
-                            () -> null);
+                            (l, r) -> l.compareTo(r) < 0);
                 });
         return map;
     }
@@ -768,7 +759,6 @@ public abstract class DefaultDialectHandler implements 
DialectHandler {
             BigDecimal r = getBigDecimalOrNull(right);
             return op.test(l, r);
         }
-        // last fallback:
         if ((left instanceof String && right instanceof String) ||
                 (left instanceof Boolean && right instanceof Boolean) ||
                 (left instanceof Comparable && 
left.getClass().isAssignableFrom(right.getClass()))) {
diff --git 
a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/dialectHandlers/DialectHandler.java
 
b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/dialectHandlers/DialectHandler.java
index 13ad1bb005..7a75fabea6 100644
--- 
a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/dialectHandlers/DialectHandler.java
+++ 
b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/dialectHandlers/DialectHandler.java
@@ -18,10 +18,11 @@
  */
 package org.kie.dmn.feel.lang.ast.dialectHandlers;
 
-import org.kie.dmn.feel.lang.EvaluationContext;
-
 import java.util.Map;
 import java.util.function.BiFunction;
+import java.util.function.BiPredicate;
+
+import org.kie.dmn.feel.lang.EvaluationContext;
 
 public interface DialectHandler {
 
@@ -77,4 +78,6 @@ public interface DialectHandler {
 
     Object executeDivision(Object left, Object right, EvaluationContext ctx);
 
+    Boolean compare(Object left, Object right, BiPredicate<Comparable, 
Comparable> op);
+
 }
diff --git 
a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/dialectHandlers/FEELDialectHandler.java
 
b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/dialectHandlers/FEELDialectHandler.java
index c43795df14..15bae2e6c4 100644
--- 
a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/dialectHandlers/FEELDialectHandler.java
+++ 
b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/dialectHandlers/FEELDialectHandler.java
@@ -25,6 +25,7 @@ import java.time.temporal.Temporal;
 import java.util.LinkedHashMap;
 import java.util.Map;
 import java.util.function.BiFunction;
+import java.util.function.BiPredicate;
 
 import org.kie.dmn.feel.lang.EvaluationContext;
 
@@ -414,4 +415,9 @@ public class FEELDialectHandler extends 
DefaultDialectHandler implements Dialect
         return map;
     }
 
+    @Override
+    public Boolean compare(Object left, Object right, BiPredicate<Comparable, 
Comparable> op) {
+        return compare(left, right, op, () -> null, () -> null);
+    }
+
 }
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 c466153ff1..66edd12e2a 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
@@ -131,17 +131,13 @@ public class RangeImpl
     private Boolean finiteRangeIncludes(EvaluationContext ctx, Object param) {
         DialectHandler handler = DialectHandlerFactory.getHandler(ctx);
         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);
-            return bothOrThrow((Boolean) handler.executeLt(lowEndPoint, param, 
ctx), (Boolean) handler.executeGt(highEndPoint, param, ctx), param);
+            return bothOrThrow(handler.compare(lowEndPoint, param, (l, r) -> 
l.compareTo(r) < 0), handler.compare(highEndPoint, param, (l, r) -> 
l.compareTo(r) > 0), param);
         } else if (lowBoundary == RangeBoundary.OPEN && highBoundary == 
RangeBoundary.CLOSED) {
-            //return bothOrThrow(compare(feelDialect, lowEndPoint, param, (l, 
r) -> l.compareTo(r) < 0), compare(feelDialect, highEndPoint, param, (l, r) -> 
l.compareTo(r) >= 0), param);
-            return bothOrThrow((Boolean) handler.executeLt(lowEndPoint, param, 
ctx), (Boolean) handler.executeGte(highEndPoint, param, ctx), param);
+            return bothOrThrow(handler.compare(lowEndPoint, param, (l, r) -> 
l.compareTo(r) < 0), handler.compare(highEndPoint, param, (l, r) -> 
l.compareTo(r) >= 0), param);
         } else if (lowBoundary == RangeBoundary.CLOSED && 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);
-            return bothOrThrow((Boolean) handler.executeLte(lowEndPoint, 
param, ctx), (Boolean) handler.executeGt(highEndPoint, param, ctx), param);
+            return bothOrThrow(handler.compare(lowEndPoint, param, (l, r) -> 
l.compareTo(r) <= 0), handler.compare(highEndPoint, param, (l, r) -> 
l.compareTo(r) > 0), param);
         } else if (lowBoundary == RangeBoundary.CLOSED && highBoundary == 
RangeBoundary.CLOSED) {
-            //return bothOrThrow(compare(feelDialect, lowEndPoint, param, (l, 
r) -> l.compareTo(r) <= 0), compare(feelDialect, highEndPoint, param, (l, r) -> 
l.compareTo(r) >= 0), param);
-            return bothOrThrow((Boolean) handler.executeLte(lowEndPoint, 
param, ctx), (Boolean) handler.executeGte(highEndPoint, param, ctx), param);
+            return bothOrThrow(handler.compare(lowEndPoint, param, (l, r) -> 
l.compareTo(r) <= 0), handler.compare(highEndPoint, param, (l, r) -> 
l.compareTo(r) >= 0), param);
         }
         throw new RuntimeException("unknown boundary combination");
     }
@@ -149,22 +145,18 @@ public class RangeImpl
     private Boolean posInfRangeIncludes(EvaluationContext ctx, Object param) {
         DialectHandler handler = DialectHandlerFactory.getHandler(ctx);
         if (lowBoundary == RangeBoundary.OPEN) {
-            //return compare(feelDialect, lowEndPoint, param, (l, r) -> 
l.compareTo(r) < 0);
-            return (Boolean) handler.executeLt(lowEndPoint, param, ctx);
+            return handler.compare(lowEndPoint, param, (l, r) -> 
l.compareTo(r) < 0);
         } else {
-            //return compare(feelDialect, lowEndPoint, param, (l, r) -> 
l.compareTo(r) <= 0);
-            return (Boolean) handler.executeLte(lowEndPoint, param, ctx);
+            return handler.compare(lowEndPoint, param, (l, r) -> 
l.compareTo(r) <= 0);
         }
     }
 
     private Boolean negInfRangeIncludes(EvaluationContext ctx, Object param) {
         DialectHandler handler = DialectHandlerFactory.getHandler(ctx);
         if (highBoundary == RangeBoundary.OPEN) {
-            //return compare(ctx, highEndPoint, param, (l, r) -> 
l.compareTo(r) > 0);
-            return (Boolean) handler.executeGt(highEndPoint, param, ctx);
+            return handler.compare(highEndPoint, param, (l, r) -> 
l.compareTo(r) > 0);
         } else {
-            //return compare(ctx, highEndPoint, param, (l, r) -> 
l.compareTo(r) >= 0);
-            return (Boolean) handler.executeGte(highEndPoint, param, ctx);
+            return handler.compare(highEndPoint, param, (l, r) -> 
l.compareTo(r) >= 0);
         }
     }
 
@@ -241,5 +233,4 @@ public class RangeImpl
         sb.append(" )");
         return sb.toString();
     }
-
 }
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 9e63208667..d8630fdf10 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,154 +21,50 @@ package org.kie.dmn.feel.runtime.impl;
 import java.math.BigDecimal;
 import java.time.Duration;
 import java.time.LocalDate;
+import java.util.stream.Stream;
 
 import org.junit.jupiter.api.Test;
-import org.kie.dmn.feel.lang.EvaluationContext;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.MethodSource;
 import org.kie.dmn.feel.runtime.Range;
 
 import static org.assertj.core.api.Assertions.assertThat;
+import static org.kie.dmn.feel.runtime.Range.RangeBoundary.CLOSED;
+import static org.kie.dmn.feel.runtime.Range.RangeBoundary.OPEN;
 
 class RangeImplTest {
 
-    @Test
-    void isWithUndefined() {
-        RangeImpl rangeImpl = new RangeImpl(Range.RangeBoundary.CLOSED, null, 
null, Range.RangeBoundary.OPEN);
-        assertThat(rangeImpl.isWithUndefined()).isFalse();
-        rangeImpl = new RangeImpl(Range.RangeBoundary.CLOSED, 10, null, 
Range.RangeBoundary.OPEN);
-        assertThat(rangeImpl.isWithUndefined()).isFalse();
-        rangeImpl = new RangeImpl(Range.RangeBoundary.CLOSED, null, 10, 
Range.RangeBoundary.OPEN);
-        assertThat(rangeImpl.isWithUndefined()).isFalse();
-        rangeImpl = new RangeImpl(Range.RangeBoundary.CLOSED, null, new 
UndefinedValueComparable(), Range.RangeBoundary.OPEN);
-        assertThat(rangeImpl.isWithUndefined()).isTrue();
-        rangeImpl = new RangeImpl(Range.RangeBoundary.CLOSED, new 
UndefinedValueComparable(), null, Range.RangeBoundary.OPEN);
-        assertThat(rangeImpl.isWithUndefined()).isTrue();
-        rangeImpl = new RangeImpl(Range.RangeBoundary.CLOSED, 10, new 
UndefinedValueComparable(), Range.RangeBoundary.OPEN);
-        assertThat(rangeImpl.isWithUndefined()).isTrue();
-        rangeImpl = new RangeImpl(Range.RangeBoundary.CLOSED, new 
UndefinedValueComparable(), 10, Range.RangeBoundary.OPEN);
-        assertThat(rangeImpl.isWithUndefined()).isTrue();
-    }
-
     @Test
     void getLowBoundary() {
-        final Range.RangeBoundary lowBoundary = Range.RangeBoundary.CLOSED;
-        final RangeImpl rangeImpl = new RangeImpl(lowBoundary, 10, 15, 
Range.RangeBoundary.OPEN);
+        final Range.RangeBoundary lowBoundary = CLOSED;
+        final RangeImpl rangeImpl = new RangeImpl(lowBoundary, 10, 15, OPEN);
         assertThat(rangeImpl.getLowBoundary()).isEqualTo(lowBoundary);
     }
 
     @Test
     void getLowEndPoint() {
         final Integer lowEndPoint = 1;
-        final RangeImpl rangeImpl = new RangeImpl(Range.RangeBoundary.OPEN, 
lowEndPoint, 15, Range.RangeBoundary.CLOSED);
+        final RangeImpl rangeImpl = new RangeImpl(OPEN, lowEndPoint, 15, 
CLOSED);
         assertThat(rangeImpl.getLowEndPoint()).isEqualTo(lowEndPoint);
     }
 
     @Test
     void getHighEndPoint() {
         final Integer highEndPoint = 15;
-        final RangeImpl rangeImpl = new RangeImpl(Range.RangeBoundary.OPEN, 1, 
highEndPoint, Range.RangeBoundary.CLOSED);
+        final RangeImpl rangeImpl = new RangeImpl(OPEN, 1, highEndPoint, 
CLOSED);
         assertThat(rangeImpl.getHighEndPoint()).isEqualTo(highEndPoint);
     }
 
     @Test
     void getHighBoundary() {
-        final Range.RangeBoundary highBoundary = Range.RangeBoundary.CLOSED;
-        final RangeImpl rangeImpl = new RangeImpl(Range.RangeBoundary.OPEN, 
10, 15, highBoundary);
+        final Range.RangeBoundary highBoundary = CLOSED;
+        final RangeImpl rangeImpl = new RangeImpl(OPEN, 10, 15, highBoundary);
         assertThat(rangeImpl.getHighBoundary()).isEqualTo(highBoundary);
     }
 
-    @Test
-    void includes() {
-        RangeImpl rangeImpl = new RangeImpl(Range.RangeBoundary.OPEN, 10, 15, 
Range.RangeBoundary.OPEN);
-        EvaluationContext ctx = null;
-        assertThat(rangeImpl.includes(null, -15)).isFalse();
-        assertThat(rangeImpl.includes(null, 5)).isFalse();
-        assertThat(rangeImpl.includes(null, 10)).isFalse();
-        assertThat(rangeImpl.includes(null, 12)).isTrue();
-        assertThat(rangeImpl.includes(null, 15)).isFalse();
-        assertThat(rangeImpl.includes(null, 156)).isFalse();
-
-        rangeImpl = new RangeImpl(Range.RangeBoundary.CLOSED, 10, 15, 
Range.RangeBoundary.OPEN);
-        assertThat(rangeImpl.includes(null, 10)).isTrue();
-        assertThat(rangeImpl.includes(null, 12)).isTrue();
-        assertThat(rangeImpl.includes(null, 15)).isFalse();
-
-        rangeImpl = new RangeImpl(Range.RangeBoundary.OPEN, 10, 15, 
Range.RangeBoundary.CLOSED);
-        assertThat(rangeImpl.includes(null, 10)).isFalse();
-        assertThat(rangeImpl.includes(null, 12)).isTrue();
-        assertThat(rangeImpl.includes(null, 15)).isTrue();
-
-        rangeImpl = new RangeImpl(Range.RangeBoundary.CLOSED, 10, 15, 
Range.RangeBoundary.CLOSED);
-        assertThat(rangeImpl.includes(null, 10)).isTrue();
-        assertThat(rangeImpl.includes(null, 12)).isTrue();
-        assertThat(rangeImpl.includes(null, 15)).isTrue();
-
-        rangeImpl = new RangeImpl(Range.RangeBoundary.CLOSED, new 
UndefinedValueComparable(), 15, Range.RangeBoundary.CLOSED);
-        assertThat(rangeImpl.includes(null, -1456)).isTrue();
-        assertThat(rangeImpl.includes(null, 20)).isFalse();
-        assertThat(rangeImpl.includes(null, null)).isNull();
-
-        rangeImpl = new RangeImpl(Range.RangeBoundary.CLOSED, 15, new 
UndefinedValueComparable(), Range.RangeBoundary.CLOSED);
-        assertThat(rangeImpl.includes(null, -1456)).isFalse();
-        assertThat(rangeImpl.includes(null, 20)).isTrue();
-        assertThat(rangeImpl.includes(null, null)).isNull();
-
-        rangeImpl = new RangeImpl(Range.RangeBoundary.CLOSED, null, new 
UndefinedValueComparable(), Range.RangeBoundary.CLOSED);
-        assertThat(rangeImpl.includes(null, -1456)).isNull();
-        assertThat(rangeImpl.includes(null, 20)).isNull();
-        assertThat(rangeImpl.includes(null, null)).isNull();
-
-        rangeImpl = new RangeImpl(Range.RangeBoundary.CLOSED, new 
UndefinedValueComparable(), null, Range.RangeBoundary.CLOSED);
-        assertThat(rangeImpl.includes(null, -1456)).isNull();
-        assertThat(rangeImpl.includes(null, 20)).isNull();
-        assertThat(rangeImpl.includes(null, null)).isNull();
-    }
-
-    @Test
-    void equals() {
-        RangeImpl rangeImpl = new RangeImpl(Range.RangeBoundary.OPEN, 10, 15, 
Range.RangeBoundary.OPEN);
-        assertThat(rangeImpl).isEqualTo(rangeImpl);
-
-        RangeImpl rangeImpl2 = new RangeImpl(Range.RangeBoundary.OPEN, 10, 15, 
Range.RangeBoundary.OPEN);
-        assertThat(rangeImpl2).isEqualTo(rangeImpl);
-
-        rangeImpl2 = new RangeImpl(Range.RangeBoundary.OPEN, 10, 15, 
Range.RangeBoundary.CLOSED);
-        assertThat(rangeImpl2).isNotEqualTo(rangeImpl);
-        rangeImpl2 = new RangeImpl(Range.RangeBoundary.CLOSED, 10, 15, 
Range.RangeBoundary.OPEN);
-        assertThat(rangeImpl2).isNotEqualTo(rangeImpl);
-        rangeImpl2 = new RangeImpl(Range.RangeBoundary.CLOSED, 10, 15, 
Range.RangeBoundary.CLOSED);
-        assertThat(rangeImpl2).isNotEqualTo(rangeImpl);
-        rangeImpl2 = new RangeImpl(Range.RangeBoundary.CLOSED, 12, 15, 
Range.RangeBoundary.CLOSED);
-        assertThat(rangeImpl2).isNotEqualTo(rangeImpl);
-        rangeImpl2 = new RangeImpl(Range.RangeBoundary.CLOSED, 12, 17, 
Range.RangeBoundary.CLOSED);
-        assertThat(rangeImpl2).isNotEqualTo(rangeImpl);
-
-        rangeImpl = new RangeImpl();
-        assertThat(rangeImpl).isEqualTo(rangeImpl);
-    }
-
-    @Test
-    void hashCodeTest() {
-        final RangeImpl rangeImpl = new RangeImpl(Range.RangeBoundary.OPEN, 
10, 15, Range.RangeBoundary.OPEN);
-        assertThat(rangeImpl.hashCode()).isEqualTo(rangeImpl.hashCode());
-
-        RangeImpl rangeImpl2 = new RangeImpl(Range.RangeBoundary.OPEN, 10, 15, 
Range.RangeBoundary.OPEN);
-        assertThat(rangeImpl2.hashCode()).isEqualTo(rangeImpl.hashCode());
-
-        rangeImpl2 = new RangeImpl(Range.RangeBoundary.OPEN, 10, 15, 
Range.RangeBoundary.CLOSED);
-        assertThat(rangeImpl2).doesNotHaveSameHashCodeAs(rangeImpl);
-        rangeImpl2 = new RangeImpl(Range.RangeBoundary.CLOSED, 10, 15, 
Range.RangeBoundary.OPEN);
-        assertThat(rangeImpl2).doesNotHaveSameHashCodeAs(rangeImpl);
-        rangeImpl2 = new RangeImpl(Range.RangeBoundary.CLOSED, 10, 15, 
Range.RangeBoundary.CLOSED);
-        assertThat(rangeImpl2).doesNotHaveSameHashCodeAs(rangeImpl);
-        rangeImpl2 = new RangeImpl(Range.RangeBoundary.CLOSED, 12, 15, 
Range.RangeBoundary.CLOSED);
-        assertThat(rangeImpl2).doesNotHaveSameHashCodeAs(rangeImpl);
-        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);
+        RangeImpl rangeImpl = new RangeImpl(OPEN, BigDecimal.TEN, 
BigDecimal.valueOf(20), OPEN);
 
         Comparable expectedResult = BigDecimal.valueOf(11);
         Comparable actualResult = rangeImpl.getStart();
@@ -177,7 +73,7 @@ class RangeImplTest {
 
     @Test
     void getStartForBigDecimalRangeClosedBoundary() {
-        RangeImpl rangeImpl = new RangeImpl(Range.RangeBoundary.CLOSED, 
BigDecimal.TEN, BigDecimal.valueOf(20), Range.RangeBoundary.OPEN);
+        RangeImpl rangeImpl = new RangeImpl(CLOSED, BigDecimal.TEN, 
BigDecimal.valueOf(20), OPEN);
 
         Comparable expectedResult = BigDecimal.TEN;
         Comparable actualResult = rangeImpl.getStart();
@@ -186,7 +82,7 @@ class RangeImplTest {
 
     @Test
     void getEndForBigDecimalRangeOpenBoundary() {
-        RangeImpl rangeImpl = new RangeImpl(Range.RangeBoundary.OPEN, 
BigDecimal.TEN, BigDecimal.valueOf(20), Range.RangeBoundary.OPEN);
+        RangeImpl rangeImpl = new RangeImpl(OPEN, BigDecimal.TEN, 
BigDecimal.valueOf(20), OPEN);
 
         Comparable expectedResult = BigDecimal.valueOf(19);
         Comparable actualResult = rangeImpl.getEnd();
@@ -195,7 +91,7 @@ class RangeImplTest {
 
     @Test
     void getEndForBigDecimalRangeClosedBoundary() {
-        RangeImpl rangeImpl = new RangeImpl(Range.RangeBoundary.CLOSED, 
BigDecimal.TEN, BigDecimal.valueOf(20), Range.RangeBoundary.CLOSED);
+        RangeImpl rangeImpl = new RangeImpl(CLOSED, BigDecimal.TEN, 
BigDecimal.valueOf(20), CLOSED);
 
         Comparable expectedResult = BigDecimal.valueOf(20);
         Comparable actualResult = rangeImpl.getEnd();
@@ -204,7 +100,7 @@ class RangeImplTest {
 
     @Test
     void getStartForLocalDateRangeOpenBoundary() {
-        RangeImpl rangeImpl = new RangeImpl(Range.RangeBoundary.OPEN, 
LocalDate.of(2025, 1, 1), LocalDate.of(2025, 1, 7), Range.RangeBoundary.OPEN);
+        RangeImpl rangeImpl = new RangeImpl(OPEN, LocalDate.of(2025, 1, 1), 
LocalDate.of(2025, 1, 7), OPEN);
 
         Comparable expectedResult = LocalDate.of(2025, 1, 2);
         Comparable actualResult = rangeImpl.getStart();
@@ -213,7 +109,7 @@ class RangeImplTest {
 
     @Test
     void getStartForLocalDateRangeClosedBoundary() {
-        RangeImpl rangeImpl = new RangeImpl(Range.RangeBoundary.CLOSED, 
LocalDate.of(2025, 1, 1), LocalDate.of(2025, 1, 7), Range.RangeBoundary.OPEN);
+        RangeImpl rangeImpl = new RangeImpl(CLOSED, LocalDate.of(2025, 1, 1), 
LocalDate.of(2025, 1, 7), OPEN);
 
         Comparable expectedResult = LocalDate.of(2025, 1, 1);
         Comparable actualResult = rangeImpl.getStart();
@@ -222,7 +118,7 @@ class RangeImplTest {
 
     @Test
     void getEndForLocalDateRangeOpenBoundary() {
-        RangeImpl rangeImpl = new RangeImpl(Range.RangeBoundary.OPEN, 
LocalDate.of(2025, 1, 1), LocalDate.of(2025, 1, 7), Range.RangeBoundary.OPEN);
+        RangeImpl rangeImpl = new RangeImpl(OPEN, LocalDate.of(2025, 1, 1), 
LocalDate.of(2025, 1, 7), OPEN);
 
         Comparable expectedResult = LocalDate.of(2025, 1, 6);
         Comparable actualResult = rangeImpl.getEnd();
@@ -231,7 +127,7 @@ class RangeImplTest {
 
     @Test
     void getEndForLocalDateRangeClosedBoundary() {
-        RangeImpl rangeImpl = new RangeImpl(Range.RangeBoundary.CLOSED, 
LocalDate.of(2025, 1, 1), LocalDate.of(2025, 1, 7), Range.RangeBoundary.CLOSED);
+        RangeImpl rangeImpl = new RangeImpl(CLOSED, LocalDate.of(2025, 1, 1), 
LocalDate.of(2025, 1, 7), CLOSED);
 
         Comparable expectedResult = LocalDate.of(2025, 1, 7);
         Comparable actualResult = rangeImpl.getEnd();
@@ -240,7 +136,7 @@ class RangeImplTest {
 
     @Test
     void getStartForStringRangeClosedBoundary() {
-        RangeImpl rangeImpl = new RangeImpl(Range.RangeBoundary.CLOSED, "a", 
"z", Range.RangeBoundary.OPEN);
+        RangeImpl rangeImpl = new RangeImpl(CLOSED, "a", "z", OPEN);
 
         Comparable expectedResult = "a";
         Comparable actualResult = rangeImpl.getStart();
@@ -250,7 +146,7 @@ class RangeImplTest {
 
     @Test
     void getEndForStringRangeOpenBoundary() {
-        RangeImpl rangeImpl = new RangeImpl(Range.RangeBoundary.CLOSED, "a", 
"z", Range.RangeBoundary.OPEN);
+        RangeImpl rangeImpl = new RangeImpl(CLOSED, "a", "z", OPEN);
 
         Comparable expectedResult = "z";
         Comparable actualResult = rangeImpl.getEnd();
@@ -260,7 +156,7 @@ class RangeImplTest {
 
     @Test
     void getStartForDurationRangeOpenBoundary() {
-        RangeImpl rangeImpl = new RangeImpl(Range.RangeBoundary.OPEN, 
Duration.parse("P2DT20H14M"), Duration.parse("P3DT20H14M"), 
Range.RangeBoundary.CLOSED);
+        RangeImpl rangeImpl = new RangeImpl(OPEN, 
Duration.parse("P2DT20H14M"), Duration.parse("P3DT20H14M"), CLOSED);
 
         Comparable expectedResult = Duration.parse("P2DT20H14M");
         Comparable actualResult = rangeImpl.getStart();
@@ -270,11 +166,190 @@ class RangeImplTest {
 
     @Test
     void getEndForDurationRangeClosedBoundary() {
-        RangeImpl rangeImpl = new RangeImpl(Range.RangeBoundary.CLOSED, 
Duration.parse("P2DT20H14M"), Duration.parse("P3DT20H14M"), 
Range.RangeBoundary.CLOSED);
+        RangeImpl rangeImpl = new RangeImpl(CLOSED, 
Duration.parse("P2DT20H14M"), Duration.parse("P3DT20H14M"), CLOSED);
 
         Comparable expectedResult = Duration.parse("P3DT20H14M");
         Comparable actualResult = rangeImpl.getEnd();
         assertThat(actualResult).isEqualTo(expectedResult);
 
     }
+
+    @ParameterizedTest
+    @MethodSource("includesData")
+    void includes(IncludesCase c) {
+        RangeImpl range = new RangeImpl(
+                c.lowBoundary(),
+                c.lowEndPoint(),
+                c.highEndPoint(),
+                c.highBoundary());
+
+        Boolean actual = range.includes(null, c.value());
+        assertThat(actual).isEqualTo(c.expected());
+    }
+
+    @ParameterizedTest
+    @MethodSource("isWithUndefinedData")
+    void isWithUndefined(IncludesCase c) {
+        RangeImpl range = new RangeImpl(
+                c.lowBoundary(),
+                c.lowEndPoint(),
+                c.highEndPoint(),
+                c.highBoundary());
+
+        assertThat(range.isWithUndefined())
+                .isEqualTo(c.expected());
+    }
+
+    @ParameterizedTest
+    @MethodSource("equalsData")
+    void testEquals(IncludesCase c) {
+        RangeImpl base = new RangeImpl(OPEN, 10, 15, OPEN);
+        RangeImpl other;
+        // Special case: default constructor
+        if (c.lowBoundary() == null && c.highBoundary() == null) {
+            other = new RangeImpl();
+            assertThat(other).isEqualTo(other);
+            return;
+        }
+        other = new RangeImpl(
+                c.lowBoundary(),
+                c.lowEndPoint(),
+                c.highEndPoint(),
+                c.highBoundary());
+
+        if (Boolean.TRUE.equals(c.expected())) {
+            assertThat(other).isEqualTo(base);
+        } else {
+            assertThat(other).isNotEqualTo(base);
+        }
+    }
+
+    @ParameterizedTest
+    @MethodSource("hashCodeData")
+    void testHashCode(IncludesCase c) {
+        RangeImpl base = new RangeImpl(OPEN, 10, 15, OPEN);
+
+        RangeImpl other = new RangeImpl(
+                c.lowBoundary(),
+                c.lowEndPoint(),
+                c.highEndPoint(),
+                c.highBoundary());
+
+        if (Boolean.TRUE.equals(c.expected())) {
+            assertThat(other.hashCode()).isEqualTo(base.hashCode());
+        } else {
+            assertThat(other).doesNotHaveSameHashCodeAs(base);
+        }
+    }
+
+    private static Stream<IncludesCase> includesData() {
+        return Stream.of(
+                // (10,15)
+                new IncludesCase(OPEN, 10, 15, OPEN, -15, false),
+                new IncludesCase(OPEN, 10, 15, OPEN, 5, false),
+                new IncludesCase(OPEN, 10, 15, OPEN, 10, false),
+                new IncludesCase(OPEN, 10, 15, OPEN, 12, true),
+                new IncludesCase(OPEN, 10, 15, OPEN, 15, false),
+                new IncludesCase(OPEN, 10, 15, OPEN, 156, false),
+
+                // [10,15)
+                new IncludesCase(CLOSED, 10, 15, OPEN, 10, true),
+                new IncludesCase(CLOSED, 10, 15, OPEN, 12, true),
+                new IncludesCase(CLOSED, 10, 15, OPEN, 15, false),
+
+                // (10,15]
+                new IncludesCase(OPEN, 10, 15, CLOSED, 10, false),
+                new IncludesCase(OPEN, 10, 15, CLOSED, 12, true),
+                new IncludesCase(OPEN, 10, 15, CLOSED, 15, true),
+
+                // [10,15]
+                new IncludesCase(CLOSED, 10, 15, CLOSED, 10, true),
+                new IncludesCase(CLOSED, 10, 15, CLOSED, 12, true),
+                new IncludesCase(CLOSED, 10, 15, CLOSED, 15, true),
+
+                // UndefinedValueComparable cases
+                new IncludesCase(CLOSED, new UndefinedValueComparable(), 15, 
CLOSED, -1456, true),
+                new IncludesCase(CLOSED, new UndefinedValueComparable(), 15, 
CLOSED, 20, false),
+                new IncludesCase(CLOSED, new UndefinedValueComparable(), 15, 
CLOSED, null, null),
+
+                new IncludesCase(CLOSED, 15, new UndefinedValueComparable(), 
CLOSED, -1456, false),
+                new IncludesCase(CLOSED, 15, new UndefinedValueComparable(), 
CLOSED, 20, true),
+                new IncludesCase(CLOSED, 15, new UndefinedValueComparable(), 
CLOSED, null, null),
+
+                new IncludesCase(CLOSED, null, new UndefinedValueComparable(), 
CLOSED, -1456, null),
+                new IncludesCase(CLOSED, null, new UndefinedValueComparable(), 
CLOSED, 20, null),
+                new IncludesCase(CLOSED, null, new UndefinedValueComparable(), 
CLOSED, null, null),
+
+                new IncludesCase(CLOSED, new UndefinedValueComparable(), null, 
CLOSED, -1456, null),
+                new IncludesCase(CLOSED, new UndefinedValueComparable(), null, 
CLOSED, 20, null),
+                new IncludesCase(CLOSED, new UndefinedValueComparable(), null, 
CLOSED, null, null),
+
+                // Boolean ranges
+                new IncludesCase(CLOSED, false, false, CLOSED, true, false),
+                new IncludesCase(CLOSED, false, false, CLOSED, false, true),
+
+                new IncludesCase(CLOSED, false, false, OPEN, true, false),
+                new IncludesCase(CLOSED, false, false, OPEN, false, false),
+
+                new IncludesCase(OPEN, false, false, CLOSED, true, false),
+                new IncludesCase(OPEN, false, false, CLOSED, false, false),
+
+                new IncludesCase(OPEN, false, false, OPEN, true, false),
+                new IncludesCase(OPEN, false, false, OPEN, false, false),
+
+                new IncludesCase(CLOSED, false, new 
UndefinedValueComparable(), CLOSED, true, true),
+                new IncludesCase(CLOSED, false, new 
UndefinedValueComparable(), CLOSED, false, true),
+
+                new IncludesCase(OPEN, false, new UndefinedValueComparable(), 
CLOSED, true, true),
+                new IncludesCase(OPEN, false, new UndefinedValueComparable(), 
CLOSED, false, false),
+
+                new IncludesCase(CLOSED, new UndefinedValueComparable(), 
false, CLOSED, true, false),
+                new IncludesCase(CLOSED, new UndefinedValueComparable(), 
false, CLOSED, false, true),
+
+                new IncludesCase(CLOSED, new UndefinedValueComparable(), 
false, OPEN, true, false),
+                new IncludesCase(CLOSED, new UndefinedValueComparable(), 
false, OPEN, false, false));
+    }
+
+    private static Stream<IncludesCase> isWithUndefinedData() {
+        return Stream.of(
+                new IncludesCase(CLOSED, null, null, OPEN, null, false),
+                new IncludesCase(CLOSED, 10, null, OPEN, null, false),
+                new IncludesCase(CLOSED, null, 10, OPEN, null, false),
+                new IncludesCase(CLOSED, null, new UndefinedValueComparable(), 
OPEN, null, true),
+                new IncludesCase(CLOSED, new UndefinedValueComparable(), null, 
OPEN, null, true),
+                new IncludesCase(CLOSED, 10, new UndefinedValueComparable(), 
OPEN, null, true),
+                new IncludesCase(CLOSED, new UndefinedValueComparable(), 10, 
OPEN, null, true));
+    }
+
+    private static Stream<IncludesCase> equalsData() {
+        return Stream.of(
+                new IncludesCase(OPEN, 10, 15, OPEN, null, true),
+                new IncludesCase(OPEN, 10, 15, OPEN, null, true),
+                new IncludesCase(OPEN, 10, 15, CLOSED, null, false),
+                new IncludesCase(CLOSED, 10, 15, OPEN, null, false),
+                new IncludesCase(CLOSED, 10, 15, CLOSED, null, false),
+                new IncludesCase(CLOSED, 12, 15, CLOSED, null, false),
+                new IncludesCase(CLOSED, 12, 17, CLOSED, null, false),
+                new IncludesCase(null, null, null, null, null, true));
+    }
+
+    private static Stream<IncludesCase> hashCodeData() {
+        return Stream.of(
+                new IncludesCase(OPEN, 10, 15, OPEN, null, true),
+                new IncludesCase(OPEN, 10, 15, OPEN, null, true),
+                new IncludesCase(OPEN, 10, 15, CLOSED, null, false),
+                new IncludesCase(CLOSED, 10, 15, OPEN, null, false),
+                new IncludesCase(CLOSED, 10, 15, CLOSED, null, false),
+                new IncludesCase(CLOSED, 12, 15, CLOSED, null, false),
+                new IncludesCase(CLOSED, 12, 17, CLOSED, null, false));
+    }
+
+    private record IncludesCase(
+            Range.RangeBoundary lowBoundary,
+            Comparable lowEndPoint,
+            Comparable highEndPoint,
+            Range.RangeBoundary highBoundary,
+            Object value,
+            Boolean expected) {
+    }
 }
\ No newline at end of file


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]


Reply via email to