Copilot commented on code in PR #6557:
URL: 
https://github.com/apache/incubator-kie-drools/pull/6557#discussion_r2711935826


##########
kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/UnaryTestNode.java:
##########
@@ -158,15 +159,68 @@ public UnaryTest getUnaryTest() {
      * For a Unary Test an = (equal) semantic depends on the RIGHT value.
      * If the RIGHT is NOT a list, then standard equals semantic applies
      * If the RIGHT is a LIST, then the semantic is "right contains left"
+     * When both are Collections:
+     * - Verify that the two objects have the same size
+     * - Verify that the element at each position in the left object equals 
the element at the same position in the right object.
      */
     private Boolean utEqualSemantic(Object left, Object right) {
-        if (right instanceof Collection) {
-            return ((Collection) right).contains(left);
+        if (left instanceof Collection && right instanceof Collection) {
+            return areCollectionsEqual((Collection<?>) left, (Collection<?>) 
right);
+        } else if (right instanceof Collection) {
+            return isElementInCollection((Collection<?>) right, left);
         } else {
-            // evaluate single entity
-            return DefaultDialectHandler.isEqual(left, right, () -> (left == 
null && right == null), () -> Boolean.FALSE);
+            return areElementsEqual(left, right);
+        }
+    }
+
+    /**
+     * Checks if two collections are equal by comparing elements in order.
+     * Both collections must have the same size and each element at position i 
in left
+     * must equal the element at position i in right.
+     *
+     * @param left the left collection
+     * @param right the right collection
+     * @return true if collections have same size and elements match in order, 
false otherwise
+     */
+    static Boolean areCollectionsEqual(Collection<?> left, Collection<?> 
right) {
+        if (left.size() != right.size()) {
+            return false;
+        }
 
+        Iterator<?> leftIterator = left.iterator();
+        Iterator<?> rightIterator = right.iterator();
+        while (leftIterator.hasNext() && rightIterator.hasNext()) {
+            if (!areElementsEqual(leftIterator.next(), rightIterator.next())) {
+                return false;
+            }
         }
+        return true;
+    }
+
+    /**
+     * Checks if a collection contains a specific element.
+     *
+     * @param collection the collection to search in
+     * @param element the element to search for
+     * @return true if collection contains the element, false otherwise
+     */
+    static Boolean isElementInCollection(Collection<?> collection, Object 
element) {
+        return collection.contains(element);

Review Comment:
   The isElementInCollection method uses the standard Collection.contains 
method, which relies on the equals implementation of the elements. This may not 
correctly handle FEEL-specific types that require custom equality semantics, 
such as Range objects or other types that need special comparison logic as 
implemented in DefaultDialectHandler.isEqual. Consider iterating through the 
collection and using areElementsEqual for each comparison to ensure consistent 
FEEL equality semantics across all types.
   ```suggestion
        * Checks if a collection contains a specific element using FEEL 
equality semantics.
        *
        * @param collection the collection to search in
        * @param element the element to search for
        * @return true if collection contains the element, false otherwise
        */
       static Boolean isElementInCollection(Collection<?> collection, Object 
element) {
           if (collection == null) {
               return false;
           }
           for (Object item : collection) {
               if (areElementsEqual(item, element)) {
                   return true;
               }
           }
           return false;
   ```



##########
kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/lang/ast/UnaryTestNodeTest.java:
##########
@@ -0,0 +1,223 @@
+/*
+ * 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 java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+class UnaryTestNodeTest {
+
+    @Test
+    void testAreCollectionsEqualInOrder_withEqualCollections() {
+        List<Integer> left = Arrays.asList(1, 2, 3);
+        List<Integer> right = Arrays.asList(1, 2, 3);
+
+        Boolean result = UnaryTestNode.areCollectionsEqual(left, right);
+        assertThat(result).isTrue();
+    }
+
+    @Test
+    void testAreCollectionsEqualInOrder_withDifferentSizes() {
+        List<Integer> left = Arrays.asList(1, 2, 3);
+        List<Integer> right = Arrays.asList(1, 2, 3, 4);
+
+        Boolean result = UnaryTestNode.areCollectionsEqual(left, right);
+        assertThat(result).isFalse();
+    }
+
+    @Test
+    void testAreCollectionsEqualInOrder_withDifferentElements() {
+        List<Integer> left = Arrays.asList(1, 2, 3);
+        List<Integer> right = Arrays.asList(1, 5, 3);
+
+        Boolean result = UnaryTestNode.areCollectionsEqual(left, right);
+        assertThat(result).isFalse();
+    }
+
+    @Test
+    void testAreCollectionsEqualInOrder_withDifferentOrder() {
+        List<Integer> left = Arrays.asList(1, 2, 3);
+        List<Integer> right = Arrays.asList(3, 2, 1);
+
+        Boolean result = UnaryTestNode.areCollectionsEqual(left, right);
+        assertThat(result).isFalse();
+    }
+
+    @Test
+    void testAreCollectionsEqualInOrder_withEmptyCollections() {
+        List<Integer> left = Collections.emptyList();
+        List<Integer> right = Collections.emptyList();
+
+        Boolean result = UnaryTestNode.areCollectionsEqual(left, right);
+        assertThat(result).isTrue();
+    }

Review Comment:
   The test method name "testAreCollectionsEqualInOrder_withEqualCollections" 
includes "InOrder" but other related test methods like 
"testAreCollectionsEqualInOrder_withDifferentSizes" and 
"testAreCollectionsEqualInOrder_withDifferentElements" also include "InOrder". 
However, the actual method being tested is named "areCollectionsEqual" without 
any "InOrder" suffix. Consider either removing "InOrder" from all test method 
names or renaming the method to "areCollectionsEqualInOrder" to maintain 
consistency between method and test names.



##########
kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/lang/ast/UnaryTestNodeTest.java:
##########
@@ -0,0 +1,223 @@
+/*
+ * 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 java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+class UnaryTestNodeTest {
+
+    @Test
+    void testAreCollectionsEqualInOrder_withEqualCollections() {
+        List<Integer> left = Arrays.asList(1, 2, 3);
+        List<Integer> right = Arrays.asList(1, 2, 3);
+
+        Boolean result = UnaryTestNode.areCollectionsEqual(left, right);
+        assertThat(result).isTrue();
+    }
+
+    @Test
+    void testAreCollectionsEqualInOrder_withDifferentSizes() {
+        List<Integer> left = Arrays.asList(1, 2, 3);
+        List<Integer> right = Arrays.asList(1, 2, 3, 4);
+
+        Boolean result = UnaryTestNode.areCollectionsEqual(left, right);
+        assertThat(result).isFalse();
+    }
+
+    @Test
+    void testAreCollectionsEqualInOrder_withDifferentElements() {
+        List<Integer> left = Arrays.asList(1, 2, 3);
+        List<Integer> right = Arrays.asList(1, 5, 3);
+
+        Boolean result = UnaryTestNode.areCollectionsEqual(left, right);
+        assertThat(result).isFalse();
+    }
+
+    @Test
+    void testAreCollectionsEqualInOrder_withDifferentOrder() {
+        List<Integer> left = Arrays.asList(1, 2, 3);
+        List<Integer> right = Arrays.asList(3, 2, 1);
+
+        Boolean result = UnaryTestNode.areCollectionsEqual(left, right);
+        assertThat(result).isFalse();
+    }
+
+    @Test
+    void testAreCollectionsEqualInOrder_withEmptyCollections() {
+        List<Integer> left = Collections.emptyList();
+        List<Integer> right = Collections.emptyList();
+
+        Boolean result = UnaryTestNode.areCollectionsEqual(left, right);
+        assertThat(result).isTrue();
+    }
+
+    @Test
+    void testAreCollectionsEqualInOrder_withNullElements() {
+        List<Integer> left = Arrays.asList(1, null, 3);
+        List<Integer> right = Arrays.asList(1, null, 3);
+
+        Boolean result = UnaryTestNode.areCollectionsEqual(left, right);
+        assertThat(result).isTrue();
+    }
+
+    @Test
+    void testAreCollectionsEqualInOrder_withMismatchedNulls() {
+        List<Integer> left = Arrays.asList(1, null, 3);
+        List<Integer> right = Arrays.asList(1, 2, 3);
+
+        Boolean result = UnaryTestNode.areCollectionsEqual(left, right);
+        assertThat(result).isFalse();
+    }
+
+    @Test
+    void testAreCollectionsEqualInOrder_withEqualStringCollections() {
+        List<String> left = Arrays.asList("a", "b", "c");
+        List<String> right = Arrays.asList("a", "b", "c");
+
+        Boolean result = UnaryTestNode.areCollectionsEqual(left, right);
+        assertThat(result).isTrue();
+    }
+
+    @Test
+    void testCollectionContainsListElement() {
+        List<Integer> element = Arrays.asList(1, 2, 3);
+        List<List<Integer>> collection = Arrays.asList(
+            Arrays.asList(1, 2, 3, 4), Arrays.asList(1, 2, 3));
+
+        Boolean result = UnaryTestNode.isElementInCollection(collection, 
element);
+        assertThat(result).isTrue();
+    }
+
+    @Test
+    void testListInCollection_NoMatch() {
+        List<Integer> element = Arrays.asList(1, 2, 3);
+        List<List<Integer>> collection = Arrays.asList(
+            Arrays.asList(1, 2, 3, 4), Arrays.asList(1, 2));
+
+        Boolean result = UnaryTestNode.isElementInCollection(collection, 
element);
+        assertThat(result)
+            .as("List [1,2,3] should not be found in collection ([1,2,3,4], 
[1,2])")
+            .isFalse();
+    }
+
+    @Test
+    void testCollectionContainsElement_whenElementExists() {
+        List<Integer> collection = Arrays.asList(1, 2, 3, 4, 5);
+        Integer element = 3;
+
+        Boolean result = UnaryTestNode.isElementInCollection(collection, 
element);
+        assertThat(result).isTrue();
+    }
+
+    @Test
+    void testCollectionContainsElement_whenElementDoesNotExist() {
+        List<Integer> collection = Arrays.asList(1, 2, 3, 4, 5);
+        Integer element = 10;
+
+        Boolean result = UnaryTestNode.isElementInCollection(collection, 
element);
+        assertThat(result).isFalse();
+    }
+
+    @Test
+    void testCollectionContainsElement_withNullElement() {
+        List<Integer> collection = Arrays.asList(1, null, 3);
+        Object element = null;
+
+        Boolean result = UnaryTestNode.isElementInCollection(collection, 
element);
+        assertThat(result).isTrue();
+    }
+
+    @Test
+    void testCollectionContainsElement_withEmptyCollection() {
+        List<Integer> collection = Collections.emptyList();
+        Integer element = 1;
+
+        Boolean result = UnaryTestNode.isElementInCollection(collection, 
element);
+        assertThat(result).isFalse();
+    }
+
+    @Test
+    void testAreElementsEqual_withEqualIntegers() {
+        Integer left = 42;
+        Integer right = 42;
+
+        Boolean result = UnaryTestNode.areElementsEqual(left, right);
+        assertThat(result).isTrue();
+    }
+
+    @Test
+    void testAreElementsEqual_withDifferentIntegers() {
+        Integer left = 42;
+        Integer right = 24;
+
+        Boolean result = UnaryTestNode.areElementsEqual(left, right);
+        assertThat(result).isFalse();
+    }
+
+    @Test
+    void testAreElementsEqual_withEqualStrings() {
+        String left = "hello";
+        String right = "hello";
+
+        Boolean result = UnaryTestNode.areElementsEqual(left, right);
+        assertThat(result).isTrue();
+    }
+
+    @Test
+    void testAreElementsEqual_withDifferentStrings() {
+        String left = "hello";
+        String right = "world";
+
+        Boolean result = UnaryTestNode.areElementsEqual(left, right);
+        assertThat(result).isFalse();
+    }
+
+    @Test
+    void testAreElementsEqual_withBothNull() {
+        Object left = null;
+        Object right = null;
+
+        Boolean result = UnaryTestNode.areElementsEqual(left, right);
+        assertThat(result).isTrue();
+    }
+
+    @Test
+    void testAreElementsEqual_withOneNull() {
+        Integer left = 42;
+        Object right = null;
+
+        Boolean result = UnaryTestNode.areElementsEqual(left, right);
+        assertThat(result).isFalse();
+    }
+
+    @Test
+    void testAreElementsEqual_withNullLeft() {
+        Object left = null;
+        Integer right = 42;
+
+        Boolean result = UnaryTestNode.areElementsEqual(left, right);
+        assertThat(result).isFalse();
+    }
+}

Review Comment:
   While the unit tests for areCollectionsEqual, isElementInCollection, and 
areElementsEqual provide good coverage of the helper methods, there appear to 
be no integration tests that verify the actual FEEL expression evaluation for 
list comparisons. Consider adding integration tests in FEELListsTest or 
FEELOperatorsTest that test expressions like "[1,2,3] = [1,2,3]" or "[1,2,3] in 
[[1,2,3], [4,5,6]]" to ensure the full end-to-end functionality works correctly.



##########
kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/parser/feel11/ASTBuilderVisitor.java:
##########
@@ -184,14 +184,16 @@ public BaseNode 
visitInterval(FEEL_1_1Parser.IntervalContext ctx) {
     public BaseNode 
visitPositiveUnaryTestIneq(FEEL_1_1Parser.PositiveUnaryTestIneqContext ctx) {
         BaseNode value = visit( ctx.endpoint() );
         String op = ctx.op.getText();
-        UnaryOperator unaryOperator = UnaryOperator.determineOperator(op);
         return ASTBuilderFactory.newUnaryTestNode( ctx, op, value );
     }
 
     @Override
     public BaseNode 
visitPositiveUnaryTestIneqInterval(FEEL_1_1Parser.PositiveUnaryTestIneqIntervalContext
 ctx) {
         BaseNode value = visit(ctx.endpoint());
         String op = ctx.op.getText();
+        if (value instanceof ListNode) {

Review Comment:
   The code now creates a UnaryTestNode for any operator when the value is a 
ListNode, including comparison operators like GT, LT, GTE, and LTE. However, 
these comparison operators may not have well-defined semantics when applied to 
lists. Consider either restricting this early return to only the EQ operator 
(which is the one being fixed based on the issue), or ensuring that 
UnaryTestNode.getUnaryTest properly handles or rejects comparison operators 
with list values.
   ```suggestion
           if (value instanceof ListNode && UnaryOperator.determineOperator(op) 
== UnaryOperator.EQ) {
   ```



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


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

Reply via email to