Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[incubator-kie-issues-1752] TCK failure-Lambda function returns null #6261

Open
wants to merge 25 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
404c291
null returned from lambda -issue fixed and added tests
bncriju Feb 20, 2025
f5731cd
Restored singleton patterns for functions used for test
bncriju Feb 20, 2025
367f0e1
Refactored test class and added more tests
bncriju Feb 24, 2025
8bc77b2
Added apache header on new class
bncriju Feb 24, 2025
56620c8
Merge remote-tracking branch 'origin/main' into kie-issues#1752
bncriju Feb 24, 2025
5d4b68f
making doc correct
bncriju Feb 24, 2025
c0123fb
checking invoke method and incorporating review comments
bncriju Feb 26, 2025
5cb934c
Merge remote-tracking branch 'origin/main' into kie-issues#1752
bncriju Feb 26, 2025
61699e3
[incubator-kie-issues#1752] WIP
Feb 26, 2025
17a8abb
isCompatible method test and candidate method modification
bncriju Feb 27, 2025
6f56cfc
Util class added for BuiltInType. Used util method
bncriju Mar 3, 2025
b2b0b03
Merge remote-tracking branch 'origin/main' into kie-issues#1752
bncriju Mar 3, 2025
fe19990
resolved merge conflicts
bncriju Mar 3, 2025
93e22ab
reverting pom changes
bncriju Mar 3, 2025
bc6e374
[incubator-kie-issues#1752] Improve parameters check on BaseFEELFunction
Mar 3, 2025
0560f1f
[incubator-kie-issues#1752] Fix usage of BuiltInTypeUtils inside drl …
Mar 4, 2025
7013c13
adding tests
bncriju Mar 5, 2025
55d173b
Merge remote-tracking branch 'origin/main' into kie-issues#1752
bncriju Mar 5, 2025
62ce7a1
[incubator-kie-issues#1752] WIP - Test suggestion
Mar 5, 2025
365eb15
test suggestions incorporated
bncriju Mar 6, 2025
4995fbd
[incubator-kie-issues#1752] Managing arrays conversion. Begin BuiltIn…
Mar 6, 2025
a69fbe7
tests updated
bncriju Mar 6, 2025
0cc7c2c
Merge remote-tracking branch 'origin/main' into kie-issues#1752
bncriju Mar 7, 2025
5c44070
license header corrected and managed unused imports
bncriju Mar 7, 2025
19fc323
license header corrected
bncriju Mar 7, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@
* specific language governing permissions and limitations
* under the License.
*/

package org.kie.dmn.feel.lang.types;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

import org.kie.dmn.feel.lang.SimpleType;
Expand All @@ -40,18 +40,15 @@ public GenFnType(List<Type> argsGen, Type returnGen) {

@Override
public boolean isInstanceOf(Object o) {
if (o instanceof FEELFunction) {
FEELFunction oFn = (FEELFunction) o;
List<List<Param>> signatures = oFn.getParameters().stream().filter(signature -> signature.size() == argsGen.size()).collect(Collectors.toList());
for (List<Param> signature : signatures) {
if (signature.size() == argsGen.size() && IntStream.range(0, argsGen.size()).allMatch(i -> argsGen.get(i).conformsTo(signature.get(i).type))) {
return true;
}
if (o instanceof FEELFunction oFn) {
List<List<Param>> parameters = oFn.getParameters();
if(parameters.isEmpty()){
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if(parameters.isEmpty()){
if (parameters.isEmpty()) {

Please use the same formatting style of the code base

//this is used to consider function as parameter
return true;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

HI @bncriju
on second thought, I think we need to implement more check here, i.e. if the expected input/output of the current GenFnType are compatible with invoke methods of the provided function

}
return false;
} else {
return false;
return checkSignatures(parameters,argsGen);
}
return false;
}

@Override
Expand All @@ -69,13 +66,22 @@ public String getName() {

@Override
public boolean conformsTo(Type t) {
if (t instanceof GenFnType) {
GenFnType fnT = (GenFnType) t;
if (t instanceof GenFnType fnT) {
return fnT.argsGen.size() == this.argsGen.size() &&
IntStream.range(0, argsGen.size()).allMatch(i -> fnT.argsGen.get(i).conformsTo(this.argsGen.get(i))) &&
this.returnGen.conformsTo(fnT.returnGen);
IntStream.range(0, argsGen.size()).allMatch(i -> fnT.argsGen.get(i).conformsTo(this.argsGen.get(i))) &&
this.returnGen.conformsTo(fnT.returnGen);
} else {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bncriju Please remove those 2 whitespaces

return t == BuiltInType.FUNCTION;
}
}
}

static boolean checkSignatures(List<List<Param>> parameters, List<Type> argsGen){
List<List<Param>> signatures = parameters.stream().filter(signature -> signature.size() == argsGen.size()).toList();
for (List<Param> signature : signatures) {
if (signature.size() == argsGen.size() && IntStream.range(0, argsGen.size()).allMatch(i -> argsGen.get(i).conformsTo(signature.get(i).type))) {
return true;
}
}
return false;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,227 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

package org.kie.dmn.feel.lang.types;

import static org.assertj.core.api.Assertions.assertThat;

import org.junit.jupiter.api.Test;
import org.kie.dmn.feel.lang.Type;
import org.kie.dmn.feel.runtime.functions.AbsFunction;
import org.kie.dmn.feel.runtime.functions.AnyFunction;
import org.kie.dmn.feel.runtime.functions.FEELFnResult;
import org.kie.dmn.feel.runtime.FEELFunction.Param;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.ArrayList;

class GenFnTypeTest {

private static final AbsFunction absFunctionInstance = AbsFunction.INSTANCE;
private static final AnyFunction anyFunctionInstance = AnyFunction.INSTANCE;

private final GenFnType genFnType = new GenFnType(
Arrays.asList(new SomeType(), new AnotherType()),
new SomeType()
);

@Test
public void testIsInstanceOfWithNoParameters() {
assertThat(genFnType.isInstanceOf(absFunctionInstance)).isTrue();
}

@Test
public void testIsInstanceOfWithNonMatchingParameters() {
FEELFnResult<Boolean> feelFn = anyFunctionInstance.invoke(new Object[]{Boolean.TRUE, Boolean.TRUE});
assertThat(genFnType.isInstanceOf(feelFn)).isFalse();
}

@Test
public void testIsInstanceOfWithMatchingFunctionSignature() {
GenFnType matchingGenFnType = new GenFnType(
Arrays.asList(new SomeType(), new AnotherType()),
new SomeType()
);
assertThat(matchingGenFnType.isInstanceOf(absFunctionInstance)).isTrue();
}

@Test
public void testIsAssignableValueWithNullValue() {
assertThat(genFnType.isAssignableValue(null)).isTrue();
}

@Test
public void testIsAssignableValueWithFunction() {
assertThat(genFnType.isAssignableValue(absFunctionInstance)).isTrue();
}

@Test
public void testConformsToWithSignature() {
GenFnType matchingGenFnType = new GenFnType(
Collections.singletonList(new SomeType()),
new SomeType()
);
assertThat(genFnType.conformsTo(matchingGenFnType)).isFalse();
}

@Test
public void testConformsToWithFunctionType() {
assertThat(genFnType.conformsTo(BuiltInType.FUNCTION)).isTrue();
}

@Test
void testCheckSignatures_withMatchingSignatures() {
List<Type> argsGen = Arrays.asList(new SomeType(), new AnotherType());
List<Type> paramTypes = Arrays.asList(new SomeType(), new AnotherType());
List<String> paramNames = Arrays.asList("param1", "param2");
List<List<Param>> params = createParams(paramTypes, paramNames);

assertThat(GenFnType.checkSignatures(params, argsGen)).isTrue();
}

@Test
void testCheckSignatures_withNonMatchingSignatures() {
List<Type> argsGen = Arrays.asList(new SomeType(), new AnotherType());
List<Type> paramTypes = Arrays.asList(new SomeType(), new YetAnotherType());
List<String> paramNames = Arrays.asList("param1", "param2");
List<List<Param>> params = createParams(paramTypes, paramNames);

assertThat(GenFnType.checkSignatures(params, argsGen)).isFalse();
}

@Test
void testCheckSignatures_withSignatureSizeMismatch() {
List<Type> argsGen = Arrays.asList(new SomeType(), new AnotherType());
List<Type> paramTypes = List.of(new SomeType());
List<String> paramNames = List.of("param1");
List<List<Param>> params = createParams(paramTypes, paramNames);

assertThat(GenFnType.checkSignatures(params, argsGen)).isFalse();
}

@Test
void testCheckSignatures_withEmptyParams() {
List<Type> argsGen = Arrays.asList(new SomeType(), new AnotherType());
List<List<Param>> params = List.of();

assertThat(GenFnType.checkSignatures(params, argsGen)).isFalse();
}

@Test
void testCheckSignatures_withEmptyArgsGen() {
List<Type> argsGen = List.of();
List<Type> paramTypes = Arrays.asList(new SomeType(), new AnotherType());
List<String> paramNames = Arrays.asList("param1", "param2");
List<List<Param>> params = createParams(paramTypes, paramNames);

assertThat(GenFnType.checkSignatures(params, argsGen)).isFalse();
}

@Test
void testCheckSignatures_withMatchingEmptySignature() {
List<Type> argsGen = List.of();
List<List<Param>> params = List.of();

assertThat(GenFnType.checkSignatures(params, argsGen)).isFalse();
}

static class SomeType implements Type {
@Override
public String getName() {
return "SomeType";
}

@Override
public boolean isInstanceOf(Object o) {
return o instanceof SomeType;
}

@Override
public boolean isAssignableValue(Object value) {
return value instanceof SomeType;
}

@Override
public boolean conformsTo(Type t) {
return t instanceof SomeType;
}
}

static class AnotherType implements Type {
@Override
public String getName() {
return "AnotherType";
}

@Override
public boolean isInstanceOf(Object o) {
return o instanceof AnotherType;
}

@Override
public boolean isAssignableValue(Object value) {
return value instanceof AnotherType;
}

@Override
public boolean conformsTo(Type t) {
return t instanceof AnotherType;
}
}

static class YetAnotherType implements Type {
@Override
public String getName() {
return "YetAnotherType";
}

@Override
public boolean isInstanceOf(Object o) {
return o instanceof YetAnotherType;
}

@Override
public boolean isAssignableValue(Object value) {
return value instanceof YetAnotherType;
}

@Override
public boolean conformsTo(Type t) {
return t instanceof YetAnotherType;
}
}

private List<List<Param>> createParams(List<Type> types, List<String> names) {
if (types.size() != names.size()) {
throw new IllegalArgumentException("The number of types and names must match");
}

List<List<Param>> params = new ArrayList<>();
List<Param> paramList = new ArrayList<>();

for (int i = 0; i < types.size(); i++) {
paramList.add(new Param(names.get(i), types.get(i)));
}

params.add(paramList);
return params;
}
}