Skip to content

Commit

Permalink
Add TCK test for new LambdaExpression to functional interface coercion
Browse files Browse the repository at this point in the history
  • Loading branch information
markt-asf committed Dec 20, 2021
1 parent 9c9b056 commit 7ca569b
Show file tree
Hide file tree
Showing 2 changed files with 135 additions and 11 deletions.
47 changes: 37 additions & 10 deletions internal/docs/el/ELSpecAssertions.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<!DOCTYPE spec SYSTEM "https://raw.githubusercontent.com/eclipse-ee4j/jakartaee-tck/master/internal/docs/dtd/spec_assertions.dtd">
<!--
Copyright (c) 2018, 2020 Oracle and/or its affiliates and others.
Copyright (c) 2018, 2021 Oracle and/or its affiliates and others.
All rights reserved.
This program and the accompanying materials are made available under the
Expand All @@ -22,7 +22,7 @@
<?xml-stylesheet href = 'file:///files/workspaces/tools/docs/xsl/assertions/spec_assertions_comments.xsl' type = 'text/xsl'?>
<spec>
<!-- @(#)ELSpecAssertions.xml 1.0 03/23/06 -->
<next-available-id>52</next-available-id>
<next-available-id>80</next-available-id>
<previous-id>48</previous-id>
<technology>EL</technology>
<id>EL</id>
Expand Down Expand Up @@ -78,7 +78,8 @@
<section id="23.4" name="Coerce A to Character" />
<section id="23.5" name="Coerce A to Boolean or boolean" />
<section id="23.6" name="Coerce A to an Enum Type T" />
<section id="23.7" name="Coerce A to Any Other Type T" />
<section id="23.7" name="Coerce A to functional interface method invocation" />
<section id="23.8" name="Coerce A to Any Other Type T" />
<section id="19" name="Collected Syntax " />
</sections>
</chapter>
Expand Down Expand Up @@ -1810,51 +1811,77 @@
</assertion>
</sub-assertions>
</assertion>
<assertion required="true" impl-spec="false" defined-by="technology"
status="active" testable="false">
<id>EL:SPEC:79</id>
<description>Coerce A to functional interface method invocation</description>
<location chapter="1" section="23.7" />
<sub-assertions>
<assertion required="true" impl-spec="false" defined-by="technology"
status="active" testable="true">
<id>EL:SPEC:79.1</id>
<description>If A is LamdaEXpression and parameters are an exact match, coerce to functional interface invocation.</description>
<location chapter="1" section="23.1" />
</assertion>
<assertion required="true" impl-spec="false" defined-by="technology"
status="active" testable="true">
<id>EL:SPEC:79.2</id>
<description>If A is not LamdaEXpression, follow 1.23.8 and throw an exception.</description>
<location chapter="1" section="23.1" />
</assertion>
<assertion required="true" impl-spec="false" defined-by="technology"
status="active" testable="true">
<id>EL:SPEC:79.3</id>
<description>If A is LamdaEXpression and parameters match if coerced, coerce to functional interface invocation.</description>
<location chapter="1" section="23.1" />
</assertion>
</sub-assertions>
</assertion>
<assertion required="true" impl-spec="false" defined-by="technology"
status="active" testable="false">
<id>EL:SPEC:43</id>
<description>Coerce A to any other type T</description>
<location chapter="1" section="23.7" />
<location chapter="1" section="23.8" />
<sub-assertions>
<assertion required="true" impl-spec="false" defined-by="technology"
status="active" testable="true">
<id>EL:SPEC:43.1</id>
<description>If A is null, return null.</description>
<location chapter="1" section="23.7" />
<location chapter="1" section="23.8" />
</assertion>
<assertion required="true" impl-spec="false" defined-by="technology"
status="active" testable="true">
<id>EL:SPEC:43.2</id>
<description>If A is assignable to T, coerce quietly.</description>
<location chapter="1" section="23.7" />
<location chapter="1" section="23.8" />
</assertion>
<assertion required="true" impl-spec="false" defined-by="technology"
status="active" testable="true">
<id>EL:SPEC:43.3</id>
<description>If A is String, and T has no Property Editor, then if
A is ""
return null, otherwise error.</description>
<location chapter="1" section="23.7" />
<location chapter="1" section="23.8" />
</assertion>
<assertion required="true" impl-spec="false" defined-by="technology"
status="active" testable="true">
<id>EL:SPEC:43.4</id>
<description>If A is String, and T's PropertyEditor throws
exception, then
if A is "" return null, otherwise error.</description>
<location chapter="1" section="23.7" />
<location chapter="1" section="23.8" />
</assertion>
<assertion required="true" impl-spec="false" defined-by="technology"
status="active" testable="true">
<id>EL:SPEC:43.5</id>
<description>Otherwise, apply T's PropertyEditor</description>
<location chapter="1" section="23.7" />
<location chapter="1" section="23.8" />
</assertion>
<assertion required="true" impl-spec="false" defined-by="technology"
status="active" testable="true">
<id>EL:SPEC:43.6</id>
<description>Otherwise, error</description>
<location chapter="1" section="23.7" />
<location chapter="1" section="23.8" />
</assertion>
</sub-assertions>
</assertion>
Expand Down
99 changes: 98 additions & 1 deletion src/com/sun/ts/tests/el/spec/coercion/ELClient.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2009, 2020 Oracle and/or its affiliates and others.
* Copyright (c) 2009, 2021 Oracle and/or its affiliates and others.
* All rights reserved.
*
* This program and the accompanying materials are made available under the
Expand Down Expand Up @@ -28,6 +28,7 @@
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Properties;
import java.util.function.Predicate;

import com.sun.javatest.Status;
import com.sun.ts.lib.harness.ServiceEETest;
Expand All @@ -36,6 +37,7 @@
import com.sun.ts.tests.el.common.util.NameValuePair;

import jakarta.el.ELException;
import jakarta.el.ELProcessor;

public class ELClient extends ServiceEETest {

Expand Down Expand Up @@ -1652,6 +1654,101 @@ public void elCoerceToEnumTypeTest() throws Fault {
throw new Fault("TEST FAILED");
}

/**
* @testName: elCoerceLambdaExpressionToFunctionalInterfaceTest
* @assertion_ids: EL:SPEC:79.1; EL:SPEC:79.2; EL:SPEC:79.3
* @test_Strategy: Validate that - a lambda expression can be coerced to a
* functional interface invocation if the parameter types
* match or can be made to match via the standard coercion
* rules.
*/
public void elCoerceLambdaExpressionToFunctionalInterfaceTest() throws Fault {

boolean fail = false;
boolean[] pass = { false, false, false, false, false };
Object result = null;

try {
// Coercible lambda expression where filter matches
ELProcessor elp0 = new ELProcessor();
elp0.defineFunction("", "", "com.sun.ts.tests.el.spec.coercion.ELClient", "testPredicateString");
result = elp0.eval("testPredicateString(x -> x.equals('data'))");
pass[0] = ExprEval.compareClass(result, String.class)
&& ExprEval.compareValue(result, "PASS");

// Coercible lambda expression where filter does not match
ELProcessor elp1 = new ELProcessor();
elp1.defineFunction("", "", "com.sun.ts.tests.el.spec.coercion.ELClient", "testPredicateString");
result = elp1.eval("testPredicateString(x -> x.equals('other'))");
pass[1] = ExprEval.compareClass(result, String.class)
&& ExprEval.compareValue(result, "BLOCK");

// Not a lambda expression
ELProcessor elp2 = new ELProcessor();
elp2.defineFunction("", "", "com.sun.ts.tests.el.spec.coercion.ELClient", "testPredicateString");
pass[2] = ExprEval.compareClass(result, String.class)
&& ExprEval.compareValue(result, "BLOCK");
try {
result = elp2.eval("testPredicateString('notLambdaExpression)");
} catch (ELException e) {
pass[2] = true;
}

// Coercible lambda expression with wrong type
ELProcessor elp3 = new ELProcessor();
elp3.defineFunction("", "", "com.sun.ts.tests.el.spec.coercion.ELClient", "testPredicateString");
try {
result = elp3.eval("testPredicateLong(x -> x.equals('data'))");
} catch (ELException e) {
pass[3] = true;
}

// Coercible lambda expression where filter does not match and parameter needs to be coerced
ELProcessor elp4 = new ELProcessor();
elp4.defineFunction("", "", "com.sun.ts.tests.el.spec.coercion.ELClient", "testPredicateString");
result = elp4.eval("testPredicateString(x -> x.equals(1234))");
pass[4] = ExprEval.compareClass(result, String.class)
&& ExprEval.compareValue(result, "BLOCK");

} catch (Exception e) {
TestUtil.logErr("Testing coercion of lambda expressions to functional interfaces " +
"threw an Exception!" + TestUtil.NEW_LINE + "Received: " + e.toString() + TestUtil.NEW_LINE);

throw new Fault(e);
} finally {
ExprEval.cleanup();
}

for (int i = 0; i < pass.length; ++i) {
if (!pass[i]) {
fail = true;
TestUtil.logErr("Unexpected result for test case " + i);
}
}

if (fail)
throw new Fault("TEST FAILED");
}


public static String testPredicateString(Predicate<String> filter) {
String s = "data";
if (filter.test(s)) {
return "PASS";
} else {
return "BLOCK";
}
}

public static String testPredicateLong(Predicate<Long> filter) {
Long l = Long.valueOf("1234");
if (filter.test(l)) {
return "PASS";
} else {
return "BLOCK";
}
}

/**
* @testName: elCoerceToOtherTypeTest
* @assertion_ids: EL:SPEC:43.1; EL:SPEC:43.2
Expand Down

0 comments on commit 7ca569b

Please sign in to comment.