You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tapestry.apache.org by th...@apache.org on 2022/03/04 03:02:17 UTC
[tapestry-5] 05/05: TAP5-2700: changes to run tests on Java 17
This is an automated email from the ASF dual-hosted git repository.
thiagohp pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/tapestry-5.git
commit f4b3e7a4979dc84e8486614ab2f3a6baa12a735a
Author: Thiago H. de Paula Figueiredo <th...@arsmachina.com.br>
AuthorDate: Tue Jan 18 23:48:53 2022 -0300
TAP5-2700: changes to run tests on Java 17
Adding JDK 17 testing in Travis
TAP5-2700: allowing module classes written in Groovy again
This fixes GridSymbolDemoTests
TAP5-2700: fixing two broken tests
GridSymbolDemoTests and XMLTokenStreamTests. testStreamEncoding
TAP5-2700: trying to fix XMLTokenStreamTests.testStreamEncoding()
TAP5-2700: fixing bad JavaVersion enum value for Java 9
TAP5-2700: Tests covering new Java features from versions 9 to 17
TAP5-2700: fixing failing tests in CookiesImplTest
Fixing TapestryBeanValidationIntegrationTests > beaneditform_validation
Trying to get ParameterTests.null_bound_to_primitive_field_is_an_error
to pass in Jenkins
---
build.gradle | 5 +-
tapestry-beanvalidator/build.gradle | 6 +
.../TapestryBeanValidationIntegrationTests.java | 8 +
tapestry-core/build.gradle | 3 +-
.../integration/app1/ParameterTests.groovy | 3 +
.../symbolparam/GridSymbolDemoTests.groovy | 4 +-
.../internal/services/CookiesImplTest.java | 24 ++-
.../ioc/internal/DefaultModuleDefImpl.java | 67 ++++++--
tapestry-latest-java-tests/build.gradle | 16 +-
.../tapestry5/ioc/services/AndExpression.java | 32 ++++
.../apache/tapestry5/ioc/services/Appliance.java | 33 ++++
.../tapestry5/ioc/services/BinaryExpression.java | 20 +++
.../ioc/services/ConsolePortableHybrid.java | 24 +++
.../ioc/services/ConstantBinaryExpression.java | 31 ++++
.../ioc/services/ConstantIntExpression.java | 24 +++
.../tapestry5/ioc/services/CoolingMachine.java | 23 +++
.../org/apache/tapestry5/ioc/services/Freezer.java | 23 +++
.../apache/tapestry5/ioc/services/HomeConsole.java | 24 +++
.../tapestry5/ioc/services/IntExpression.java | 20 +++
.../apache/tapestry5/ioc/services/IntTuple.java | 20 +++
.../ioc/services/Java10And11ConcreteService.java | 68 +++++++++
.../ioc/services/Java10And11NewFeatureTests.java | 54 +++++++
.../tapestry5/ioc/services/Java10And11Service.java | 17 +++
.../ioc/services/Java10And11ServiceImpl.java | 69 +++++++++
.../ioc/services/Java12And13ConcreteService.java | 71 +++++++++
.../ioc/services/Java12And13NewFeatureTests.java | 69 +++++++++
.../tapestry5/ioc/services/Java12And13Service.java | 28 ++++
.../ioc/services/Java12And13ServiceImpl.java | 69 +++++++++
.../ioc/services/Java14ConcreteService.java | 73 +++++++++
.../ioc/services/Java14NewFeatureTests.java | 101 ++++++++++++
.../tapestry5/ioc/services/Java14Service.java | 37 +++++
.../tapestry5/ioc/services/Java14ServiceImpl.java | 71 +++++++++
.../ioc/services/Java15To17ConcreteService.java | 63 ++++++++
.../ioc/services/Java15To17NewFeatureTests.java | 169 +++++++++++++++++++++
.../tapestry5/ioc/services/Java15To17Service.java | 34 +++++
.../ioc/services/Java15To17ServiceImpl.java | 66 ++++++++
.../ioc/services/Java9ConcreteService.java | 69 +++++++++
.../ioc/services/Java9NewFeatureTests.java | 60 ++++++++
.../tapestry5/ioc/services/Java9Service.java | 33 ++++
.../tapestry5/ioc/services/Java9ServiceImpl.java | 70 +++++++++
.../tapestry5/ioc/services/OrExpression.java | 32 ++++
.../tapestry5/ioc/services/PlusExpression.java | 24 +++
.../tapestry5/ioc/services/Refrigerator.java | 23 +++
.../tapestry5/ioc/services/SquareExpression.java | 24 +++
.../apache/tapestry5/ioc/services/Videogame.java | 19 +++
.../tapestry5/ioc/services/WashingMachine.java | 23 +++
46 files changed, 1819 insertions(+), 27 deletions(-)
diff --git a/build.gradle b/build.gradle
index c888bdb..d037de0 100755
--- a/build.gradle
+++ b/build.gradle
@@ -11,7 +11,7 @@ apply from: "sha256.gradle"
project.ext.versions = [
jetty: "8.1.19.v20160209",
tomcat: "7.0.70",
- testng: "6.8.21",
+ testng: "6.14.3",
easymock: "3.3.1",
servletapi: "3.0.1",
spock: "2.1-M2-groovy-3.0",
@@ -165,7 +165,7 @@ subprojects {
apply plugin: "jacoco"
jacoco {
- toolVersion = "0.8.6"
+ toolVersion = "0.8.7"
}
sourceCompatibility = "1.8"
@@ -221,7 +221,6 @@ subprojects {
// Needed to have XMLTokenStreamTests.testStreamEncoding() passing on Java 9+
if (JavaVersion.current().isCompatibleWith(JavaVersion.VERSION_1_9)) {
- println "Java 9+ JVM arg: --add-opens=java.base/java.nio.charset=ALL-UNNAMED"
jvmArgs("--add-opens=java.base/java.nio.charset=ALL-UNNAMED");
}
diff --git a/tapestry-beanvalidator/build.gradle b/tapestry-beanvalidator/build.gradle
index 4db1bba..9c22ede 100644
--- a/tapestry-beanvalidator/build.gradle
+++ b/tapestry-beanvalidator/build.gradle
@@ -9,6 +9,12 @@ dependencies {
implementation "org.hibernate:hibernate-validator:4.3.2.Final"
testImplementation project(':tapestry-test')
+ implementation "org.seleniumhq.selenium:selenium-leg-rc:${versions.selenium}", {
+ exclude group: "org.seleniumhq.selenium", module: "jetty-repacked"
+ exclude group: "org.testng", module: "testng"
+ exclude group: "javax.servlet", module: "javax.servlet-api"
+ }
+
}
task compileCoffeeScript(type: CompileCoffeeScript) {
diff --git a/tapestry-beanvalidator/src/test/java/org/apache/tapestry5/beanvalidator/integration/TapestryBeanValidationIntegrationTests.java b/tapestry-beanvalidator/src/test/java/org/apache/tapestry5/beanvalidator/integration/TapestryBeanValidationIntegrationTests.java
index bd0c889..6e945fc 100644
--- a/tapestry-beanvalidator/src/test/java/org/apache/tapestry5/beanvalidator/integration/TapestryBeanValidationIntegrationTests.java
+++ b/tapestry-beanvalidator/src/test/java/org/apache/tapestry5/beanvalidator/integration/TapestryBeanValidationIntegrationTests.java
@@ -15,6 +15,8 @@ package org.apache.tapestry5.beanvalidator.integration;
import org.apache.tapestry5.test.SeleniumTestCase;
import org.apache.tapestry5.test.TapestryTestConfiguration;
+import org.openqa.selenium.By;
+import org.openqa.selenium.support.ui.ExpectedConditions;
import org.testng.annotations.Test;
@Test(sequential = true, groups = "integration")
@@ -108,6 +110,12 @@ public class TapestryBeanValidationIntegrationTests extends SeleniumTestCase
public void beaneditform_validation() throws Exception
{
openLinks("BeanEditForm Validation Demo");
+
+ // Ugly hack to fix the "Unable to locate element: //input[@type='submit']" error.
+ // I have no idea why it's failing here but not in other tests and pages.
+ // I have no idea why it's falling to begin with.
+ // waitForCondition(ExpectedConditions.presenceOfElementLocated(By.xpath(SUBMIT)));
+ Thread.sleep(5000);
clickAndWait(SUBMIT);
diff --git a/tapestry-core/build.gradle b/tapestry-core/build.gradle
index 60d6d9c..35f5289 100644
--- a/tapestry-core/build.gradle
+++ b/tapestry-core/build.gradle
@@ -72,10 +72,9 @@ jar {
}
}
-// Needed to have XMLTokenStreamTests.testStreamEncoding() passing on Java 17
+// Needed to have XMLTokenStreamTests.testStreamEncoding() passing on Java 9+
test {
if (JavaVersion.current().isCompatibleWith(JavaVersion.VERSION_1_9)) {
- println "Java 9+ JVM arg: --add-opens=java.base/java.nio.charset=ALL-UNNAMED"
jvmArgs("--add-opens=java.base/java.nio.charset=ALL-UNNAMED");
}
}
diff --git a/tapestry-core/src/test/groovy/org/apache/tapestry5/integration/app1/ParameterTests.groovy b/tapestry-core/src/test/groovy/org/apache/tapestry5/integration/app1/ParameterTests.groovy
index 6f35e60..f7a401b 100644
--- a/tapestry-core/src/test/groovy/org/apache/tapestry5/integration/app1/ParameterTests.groovy
+++ b/tapestry-core/src/test/groovy/org/apache/tapestry5/integration/app1/ParameterTests.groovy
@@ -29,6 +29,9 @@ class ParameterTests extends App1TestCase
void null_bound_to_primitive_field_is_an_error()
{
openLinks "Null Bound to Primitive Demo"
+
+ // Hack to try to avoid test to fail in Jenkins even though it passes locally.
+ Thread.sleep(5000);
assertTextPresent "Parameter 'value' of component NullBindingToPrimitive:showint is bound to null. This parameter is not allowed to be null."
}
diff --git a/tapestry-core/src/test/groovy/org/apache/tapestry5/integration/symbolparam/GridSymbolDemoTests.groovy b/tapestry-core/src/test/groovy/org/apache/tapestry5/integration/symbolparam/GridSymbolDemoTests.groovy
index c351e46..600ab6d 100644
--- a/tapestry-core/src/test/groovy/org/apache/tapestry5/integration/symbolparam/GridSymbolDemoTests.groovy
+++ b/tapestry-core/src/test/groovy/org/apache/tapestry5/integration/symbolparam/GridSymbolDemoTests.groovy
@@ -1,4 +1,4 @@
-// Copyright 2011-2013 The Apache Software Foundation
+// Copyright 2011-2021 The Apache Software Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -15,11 +15,13 @@
package org.apache.tapestry5.integration.symbolparam
import org.apache.tapestry5.integration.TapestryCoreTestCase
+import org.apache.tapestry5.test.TapestryTestConfiguration
import org.testng.annotations.Test
/**
* Tests for the Grid's symbol parameter support added in 5.3.
*/
+@TapestryTestConfiguration(webAppFolder = "src/test/symbolparam")
class GridSymbolDemoTests extends TapestryCoreTestCase
{
@Test
diff --git a/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/CookiesImplTest.java b/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/CookiesImplTest.java
index a24ec20..1e4c677 100644
--- a/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/CookiesImplTest.java
+++ b/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/CookiesImplTest.java
@@ -31,6 +31,11 @@ public class CookiesImplTest extends Assert
{
private static class ComparableCookie extends Cookie
{
+ public ComparableCookie(Cookie cookie)
+ {
+ this(cookie.getName(), cookie.getValue(), cookie.getMaxAge());
+ }
+
public ComparableCookie(String name, String value, int maxAge)
{
super(name, value);
@@ -118,7 +123,7 @@ public class CookiesImplTest extends Assert
expectedCookie.setPath("/context/");
expectedCookie.setDomain("fobar.com");
assertEquals(cookies.size(), 1);
- assertEquals(cookies.get(0), expectedCookie);
+ assertFirstCookieEquals(cookies, expectedCookie);
}
private CookiesImpl createCookiesFixture(String contextPath, final List<Cookie> cookies)
@@ -141,7 +146,7 @@ public class CookiesImplTest extends Assert
Cookie expectedCookie = new ComparableCookie("foo", "bar", -1);
expectedCookie.setPath("/ctx/");
assertEquals(cookies.size(), 1);
- assertEquals(cookies.get(0), expectedCookie);
+ assertFirstCookieEquals(cookies, expectedCookie);
}
public void test_Write_Cookie()
@@ -153,7 +158,7 @@ public class CookiesImplTest extends Assert
Cookie expectedCookie = new ComparableCookie("foo", "bar", 1000);
expectedCookie.setPath("/ctx/");
assertEquals(cookies.size(), 1);
- assertEquals(cookies.get(0), expectedCookie);
+ assertFirstCookieEquals(cookies, expectedCookie);
}
public void test_Remove_Cookie()
@@ -165,7 +170,7 @@ public class CookiesImplTest extends Assert
Cookie expectedCookie = new ComparableCookie("foo", null, 0);
expectedCookie.setPath("/ctx/");
assertEquals(cookies.size(), 1);
- assertEquals(cookies.get(0), expectedCookie);
+ assertFirstCookieEquals(cookies, expectedCookie);
}
public void test_remove_cookie_with_nondefault_path()
@@ -177,6 +182,15 @@ public class CookiesImplTest extends Assert
Cookie expectedCookie = new ComparableCookie("foo", null, 0);
expectedCookie.setPath("/nondefault/");
assertEquals(cookies.size(), 1);
- assertEquals(cookies.get(0), expectedCookie);
+ assertFirstCookieEquals(cookies, expectedCookie);
}
+
+ // Needed since assertEquals() tests both arg1.equals(arg2) and arg2.equals(arg1),
+ // something it apparently didn't in the past, and Cookie from Servlet API doesn't
+ // implements equals()
+ private void assertFirstCookieEquals(final List<Cookie> cookies, Cookie expectedCookie) {
+ assertEquals(new ComparableCookie(cookies.get(0)),
+ new ComparableCookie(expectedCookie));
+ }
+
}
diff --git a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/DefaultModuleDefImpl.java b/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/DefaultModuleDefImpl.java
index adbd8e0..b444a69 100644
--- a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/DefaultModuleDefImpl.java
+++ b/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/DefaultModuleDefImpl.java
@@ -14,7 +14,22 @@
package org.apache.tapestry5.ioc.internal;
-import org.apache.tapestry5.commons.*;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.tapestry5.commons.Configuration;
+import org.apache.tapestry5.commons.MappedConfiguration;
+import org.apache.tapestry5.commons.ObjectCreator;
+import org.apache.tapestry5.commons.OrderedConfiguration;
import org.apache.tapestry5.commons.internal.util.TapestryException;
import org.apache.tapestry5.commons.services.PlasticProxyFactory;
import org.apache.tapestry5.commons.util.CollectionFactory;
@@ -26,23 +41,26 @@ import org.apache.tapestry5.ioc.MethodAdviceReceiver;
import org.apache.tapestry5.ioc.ScopeConstants;
import org.apache.tapestry5.ioc.ServiceBinder;
import org.apache.tapestry5.ioc.ServiceBuilderResources;
-import org.apache.tapestry5.ioc.annotations.*;
-import org.apache.tapestry5.ioc.def.*;
+import org.apache.tapestry5.ioc.annotations.Advise;
+import org.apache.tapestry5.ioc.annotations.Contribute;
+import org.apache.tapestry5.ioc.annotations.Decorate;
+import org.apache.tapestry5.ioc.annotations.EagerLoad;
+import org.apache.tapestry5.ioc.annotations.Marker;
+import org.apache.tapestry5.ioc.annotations.Match;
+import org.apache.tapestry5.ioc.annotations.Optional;
+import org.apache.tapestry5.ioc.annotations.Order;
+import org.apache.tapestry5.ioc.annotations.PreventServiceDecoration;
+import org.apache.tapestry5.ioc.annotations.Scope;
+import org.apache.tapestry5.ioc.annotations.Startup;
+import org.apache.tapestry5.ioc.def.ContributionDef;
+import org.apache.tapestry5.ioc.def.ContributionDef3;
+import org.apache.tapestry5.ioc.def.DecoratorDef;
+import org.apache.tapestry5.ioc.def.ModuleDef2;
+import org.apache.tapestry5.ioc.def.ServiceDef;
+import org.apache.tapestry5.ioc.def.StartupDef;
import org.apache.tapestry5.ioc.internal.util.InternalUtils;
import org.slf4j.Logger;
-import java.lang.annotation.Annotation;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Set;
-
/**
* Starting from the Class for a module, identifies all the services (service builder methods),
* decorators (service
@@ -157,6 +175,7 @@ public class DefaultModuleDefImpl implements ModuleDef2, ServiceDefAccumulator
}
removeSyntheticMethods(methods);
+ removeGroovyObjectMethods(methods);
boolean modulePreventsServiceDecoration = moduleClass.getAnnotation(PreventServiceDecoration.class) != null;
@@ -215,6 +234,24 @@ public class DefaultModuleDefImpl implements ModuleDef2, ServiceDefAccumulator
{
return serviceDefs.get(serviceId);
}
+
+ private void removeGroovyObjectMethods(Set<Method> methods)
+ {
+ Iterator<Method> iterator = methods.iterator();
+
+ while (iterator.hasNext())
+ {
+ Method m = iterator.next();
+ final String name = m.getName();
+
+ if (m.getDeclaringClass().getName().equals("groovy.lang.GroovyObject")
+ || (name.equals("getMetaClass") && m.getReturnType().getName().equals("groovy.lang.MetaClass"))
+ || (m.getParameterCount() == 1 && m.getParameterTypes()[0].getName().equals("groovy.lang.MetaClass")))
+ {
+ iterator.remove();
+ }
+ }
+ }
private void removeSyntheticMethods(Set<Method> methods)
{
diff --git a/tapestry-latest-java-tests/build.gradle b/tapestry-latest-java-tests/build.gradle
index 54c9223..92267af 100644
--- a/tapestry-latest-java-tests/build.gradle
+++ b/tapestry-latest-java-tests/build.gradle
@@ -1,5 +1,19 @@
description = "Test suite for making sure Tapestry runs on latest Java"
+sourceCompatibility = "17"
+targetCompatibility = "17"
+
+tasks.withType(JavaCompile).each {
+ it.options.compilerArgs.add("--enable-preview")
+}
+
+test {
+ useTestNG()
+ jvmArgs(["--enable-preview"])
+}
+
dependencies {
- api project(':tapestry-ioc')
+ testImplementation project(':tapestry-ioc')
+ testImplementation "org.slf4j:slf4j-api:${versions.slf4j}"
+ testImplementation "org.testng:testng:${versions.testng}"
}
\ No newline at end of file
diff --git a/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/AndExpression.java b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/AndExpression.java
new file mode 100644
index 0000000..3696898
--- /dev/null
+++ b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/AndExpression.java
@@ -0,0 +1,32 @@
+// Licensed 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.apache.tapestry5.ioc.services;
+
+/**
+ * Just for use in Record Classes tests.
+ */
+public final class AndExpression implements BinaryExpression
+{
+ private final BinaryExpression operand1, operand2;
+
+ public AndExpression(BinaryExpression operand1, BinaryExpression operand2) {
+ super();
+ this.operand1 = operand1;
+ this.operand2 = operand2;
+ }
+
+ @Override
+ public boolean evaluate()
+ {
+ return operand1.evaluate() && operand2.evaluate();
+ }
+}
diff --git a/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Appliance.java b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Appliance.java
new file mode 100644
index 0000000..8e25feea
--- /dev/null
+++ b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Appliance.java
@@ -0,0 +1,33 @@
+// Licensed 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.apache.tapestry5.ioc.services;
+
+/**
+ * Just for use in Pattern Matching for the instanceof Operator tests.
+ */
+public sealed abstract class Appliance permits WashingMachine, CoolingMachine
+{
+
+ final String name;
+
+ public Appliance(String name)
+ {
+ super();
+ this.name = name;
+ }
+
+ public String getName()
+ {
+ return name;
+ }
+
+}
diff --git a/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/BinaryExpression.java b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/BinaryExpression.java
new file mode 100644
index 0000000..1202bf9
--- /dev/null
+++ b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/BinaryExpression.java
@@ -0,0 +1,20 @@
+// Licensed 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.apache.tapestry5.ioc.services;
+
+/**
+ * Just for use in Record Classes tests.
+ */
+public sealed interface BinaryExpression permits ConstantBinaryExpression, AndExpression, OrExpression
+{
+ boolean evaluate();
+}
diff --git a/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/ConsolePortableHybrid.java b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/ConsolePortableHybrid.java
new file mode 100644
index 0000000..3e0559b
--- /dev/null
+++ b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/ConsolePortableHybrid.java
@@ -0,0 +1,24 @@
+// Licensed 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.apache.tapestry5.ioc.services;
+
+/**
+ * Just for use in Pattern Matching for the instanceof Operator tests.
+ */
+public class ConsolePortableHybrid extends HomeConsole
+{
+ void turnEmbeddedScreenOn()
+ {
+
+ }
+
+}
diff --git a/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/ConstantBinaryExpression.java b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/ConstantBinaryExpression.java
new file mode 100644
index 0000000..6bc19ec
--- /dev/null
+++ b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/ConstantBinaryExpression.java
@@ -0,0 +1,31 @@
+// Licensed 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.apache.tapestry5.ioc.services;
+
+/**
+ * Just for use in Record Classes tests.
+ */
+public final class ConstantBinaryExpression implements BinaryExpression
+{
+ private final boolean value;
+
+ public ConstantBinaryExpression(boolean value)
+ {
+ this.value = value;
+ }
+
+ @Override
+ public boolean evaluate()
+ {
+ return value;
+ }
+}
diff --git a/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/ConstantIntExpression.java b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/ConstantIntExpression.java
new file mode 100644
index 0000000..ca0cad1
--- /dev/null
+++ b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/ConstantIntExpression.java
@@ -0,0 +1,24 @@
+// Licensed 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.apache.tapestry5.ioc.services;
+
+/**
+ * Just for use in Record Classes tests.
+ */
+public final record ConstantIntExpression(int value) implements IntExpression
+{
+ @Override
+ public int evaluate()
+ {
+ return value;
+ }
+}
diff --git a/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/CoolingMachine.java b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/CoolingMachine.java
new file mode 100644
index 0000000..6df55ae
--- /dev/null
+++ b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/CoolingMachine.java
@@ -0,0 +1,23 @@
+// Licensed 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.apache.tapestry5.ioc.services;
+
+/**
+ * Just for use in Pattern Matching for the instanceof Operator tests.
+ */
+public non-sealed abstract class CoolingMachine extends Appliance
+{
+ public CoolingMachine(String name)
+ {
+ super(name);
+ }
+}
\ No newline at end of file
diff --git a/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Freezer.java b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Freezer.java
new file mode 100644
index 0000000..eae1a6b
--- /dev/null
+++ b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Freezer.java
@@ -0,0 +1,23 @@
+// Licensed 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.apache.tapestry5.ioc.services;
+
+/**
+ * Just for use in Pattern Matching for the instanceof Operator tests.
+ */
+public final class Freezer extends CoolingMachine
+{
+ public Freezer()
+ {
+ super("Freezer");
+ }
+}
\ No newline at end of file
diff --git a/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/HomeConsole.java b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/HomeConsole.java
new file mode 100644
index 0000000..6179de3
--- /dev/null
+++ b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/HomeConsole.java
@@ -0,0 +1,24 @@
+// Licensed 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.apache.tapestry5.ioc.services;
+
+/**
+ * Just for use in Pattern Matching for the instanceof Operator tests.
+ */
+public class HomeConsole implements Videogame
+{
+ void turnConnectedTVOn()
+ {
+
+ }
+
+}
diff --git a/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/IntExpression.java b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/IntExpression.java
new file mode 100644
index 0000000..5538728
--- /dev/null
+++ b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/IntExpression.java
@@ -0,0 +1,20 @@
+// Licensed 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.apache.tapestry5.ioc.services;
+
+/**
+ * Just for use in Record Classes tests.
+ */
+public sealed interface IntExpression permits ConstantIntExpression, PlusExpression, SquareExpression
+{
+ int evaluate();
+}
diff --git a/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/IntTuple.java b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/IntTuple.java
new file mode 100644
index 0000000..69ef256
--- /dev/null
+++ b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/IntTuple.java
@@ -0,0 +1,20 @@
+// Licensed 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.apache.tapestry5.ioc.services;
+
+/**
+ * Just used for tests
+ */
+public record IntTuple(int x, int y)
+{
+
+}
diff --git a/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java10And11ConcreteService.java b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java10And11ConcreteService.java
new file mode 100644
index 0000000..206dd88
--- /dev/null
+++ b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java10And11ConcreteService.java
@@ -0,0 +1,68 @@
+// Licensed 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.apache.tapestry5.ioc.services;
+
+import java.io.BufferedReader;
+import java.io.FileInputStream;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.function.BiFunction;
+
+public class Java10And11ConcreteService
+{
+
+ public Java10And11ConcreteService() throws Exception
+ {
+ localVariableTypeInference();
+ }
+
+ /**
+ * Tests Local Variable Type Inference.
+ * Examples taken from https://docs.oracle.com/en/java/javase/17/language/local-variable-type-inference.html.
+ */
+ @SuppressWarnings("unused")
+ public void localVariableTypeInference() throws Exception
+ {
+
+ var url = new URL("http://www.oracle.com/");
+ var conn = url.openConnection();
+ var reader = new BufferedReader(
+ new InputStreamReader(conn.getInputStream()));
+
+ reader.close();
+
+
+ var fileName = "LICENSE.txt";
+ var list = new ArrayList<String>(); // infers ArrayList<String>
+ var stream = list.stream(); // infers Stream<String>
+ var path = Paths.get(fileName); // infers Path
+ var bytes = Files.readAllBytes(path); // infers bytes[]
+
+ List<String> myList = Arrays.asList("a", "b", "c");
+ for (var element : myList) { element += " " ;} // infers String
+
+ for (var counter = 0; counter < 10; counter++) { Math.max(counter, counter); } // infers int
+
+ try (var input =
+ new FileInputStream(fileName)) {} // infers FileInputStream
+
+ BiFunction<Integer, Integer, Integer> biFunction = (a, b) -> a + b;
+ biFunction = (var a, var b) -> a + b;
+
+ }
+
+}
\ No newline at end of file
diff --git a/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java10And11NewFeatureTests.java b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java10And11NewFeatureTests.java
new file mode 100644
index 0000000..f91db00
--- /dev/null
+++ b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java10And11NewFeatureTests.java
@@ -0,0 +1,54 @@
+// Licensed 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.apache.tapestry5.ioc.services;
+
+import org.apache.tapestry5.ioc.RegistryBuilder;
+import org.apache.tapestry5.ioc.ServiceBinder;
+import org.testng.annotations.BeforeSuite;
+import org.testng.annotations.Test;
+
+/**
+ * Tests for Tapestry-IoC and the only Java language feature introduced in Java SE 10 and 11,
+ * local variable type inference (introduced in 10 and improved in 11).
+ */
+public class Java10And11NewFeatureTests
+{
+
+ public static class Java10And11Module
+ {
+ public static void bind(ServiceBinder binder)
+ {
+ binder.bind(Java10And11Service.class, Java10And11ServiceImpl.class);
+ binder.bind(Java10And11ConcreteService.class);
+ }
+ }
+
+ private Java10And11Service java10And11Service;
+
+ private Java10And11ConcreteService java10And11ConcreteService;
+
+ @BeforeSuite
+ public void setup()
+ {
+ var registry = RegistryBuilder.buildAndStartupRegistry(Java10And11Module.class);
+ java10And11Service = registry.getService(Java10And11Service.class);
+ java10And11ConcreteService = registry.getService(Java10And11ConcreteService.class);
+ }
+
+ @Test
+ public void localVariableTypeInference() throws Exception
+ {
+ java10And11Service.localVariableTypeInference();
+ java10And11ConcreteService.localVariableTypeInference();;
+ }
+
+}
diff --git a/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java10And11Service.java b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java10And11Service.java
new file mode 100644
index 0000000..b68e29e
--- /dev/null
+++ b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java10And11Service.java
@@ -0,0 +1,17 @@
+// Licensed 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.apache.tapestry5.ioc.services;
+
+public interface Java10And11Service
+{
+ void localVariableTypeInference() throws Exception;
+}
\ No newline at end of file
diff --git a/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java10And11ServiceImpl.java b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java10And11ServiceImpl.java
new file mode 100644
index 0000000..1fdccfd
--- /dev/null
+++ b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java10And11ServiceImpl.java
@@ -0,0 +1,69 @@
+// Licensed 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.apache.tapestry5.ioc.services;
+
+import java.io.BufferedReader;
+import java.io.FileInputStream;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.function.BiFunction;
+
+public class Java10And11ServiceImpl implements Java10And11Service
+{
+
+ public Java10And11ServiceImpl() throws Exception
+ {
+ localVariableTypeInference();
+ }
+
+ /**
+ * Tests Local Variable Type Inference.
+ * Examples taken from https://docs.oracle.com/en/java/javase/17/language/local-variable-type-inference.html.
+ */
+ @SuppressWarnings("unused")
+ @Override
+ public void localVariableTypeInference() throws Exception
+ {
+
+ var url = new URL("http://www.oracle.com/");
+ var conn = url.openConnection();
+ var reader = new BufferedReader(
+ new InputStreamReader(conn.getInputStream()));
+
+ reader.close();
+
+
+ var fileName = "LICENSE.txt";
+ var list = new ArrayList<String>(); // infers ArrayList<String>
+ var stream = list.stream(); // infers Stream<String>
+ var path = Paths.get(fileName); // infers Path
+ var bytes = Files.readAllBytes(path); // infers bytes[]
+
+ List<String> myList = Arrays.asList("a", "b", "c");
+ for (var element : myList) { element += " " ;} // infers String
+
+ for (var counter = 0; counter < 10; counter++) { Math.max(counter, counter); } // infers int
+
+ try (var input =
+ new FileInputStream(fileName)) {} // infers FileInputStream
+
+ BiFunction<Integer, Integer, Integer> biFunction = (a, b) -> a + b;
+ biFunction = (var a, var b) -> a + b;
+
+ }
+
+}
\ No newline at end of file
diff --git a/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java12And13ConcreteService.java b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java12And13ConcreteService.java
new file mode 100644
index 0000000..38eb3c5
--- /dev/null
+++ b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java12And13ConcreteService.java
@@ -0,0 +1,71 @@
+// Licensed 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.apache.tapestry5.ioc.services;
+
+import java.time.LocalDate;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class Java12And13ConcreteService
+{
+
+ private static final String DAY_OF_WEEK_STRING = "Work!";
+ private static final String WEEKEND_STRING = "Rest!";
+ private static final Logger LOGGER = LoggerFactory.getLogger(Java12And13ServiceImpl.class);
+
+ public Java12And13ConcreteService()
+ {
+ textBlocks();
+ switchExpressions();
+ }
+
+ /**
+ * Tests Text Blocks
+ * https://docs.oracle.com/en/java/javase/17/language/text-blocks.html
+ */
+ public void textBlocks()
+ {
+ String string = """
+ <html>
+ <body>
+ <p>Hello, Tapestry world!>/p>
+ </body>
+ </html>
+ """;
+ LOGGER.info("Text block: " + string);
+ }
+
+ /**
+ * Tests Switch Expressions
+ * https://docs.oracle.com/en/java/javase/17/language/switch-expressions.html
+ */
+ public void switchExpressions()
+ {
+ LocalDate date = LocalDate.now();
+ String string = switch(date.getDayOfWeek())
+ {
+ case MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY ->
+ {
+ LOGGER.info(DAY_OF_WEEK_STRING);
+ yield DAY_OF_WEEK_STRING;
+ }
+ default ->
+ {
+ LOGGER.info(WEEKEND_STRING);
+ yield WEEKEND_STRING;
+ }
+ };
+ LOGGER.info("Result: " + string);
+ }
+
+}
\ No newline at end of file
diff --git a/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java12And13NewFeatureTests.java b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java12And13NewFeatureTests.java
new file mode 100644
index 0000000..051b586
--- /dev/null
+++ b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java12And13NewFeatureTests.java
@@ -0,0 +1,69 @@
+// Licensed 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.apache.tapestry5.ioc.services;
+
+import org.apache.tapestry5.ioc.RegistryBuilder;
+import org.apache.tapestry5.ioc.ServiceBinder;
+import org.testng.annotations.BeforeSuite;
+import org.testng.annotations.Test;
+
+/**
+ * Tests for Tapestry-IoC and the Java language features introduced in Java SE 12 and 13,
+ * switch expressiosn and text blocks.
+ */
+public class Java12And13NewFeatureTests
+{
+
+ public static class Java12And13Module
+ {
+ public static void bind(ServiceBinder binder)
+ {
+ binder.bind(Java12And13Service.class, Java12And13ServiceImpl.class);
+ binder.bind(Java12And13ConcreteService.class);
+ }
+ }
+
+ private Java12And13Service java12And13Service;
+
+ private Java12And13ConcreteService java12And13ConcreteService;
+
+ @BeforeSuite
+ public void setup()
+ {
+ var registry = RegistryBuilder.buildAndStartupRegistry(Java12And13Module.class);
+ java12And13Service = registry.getService(Java12And13Service.class);
+ java12And13ConcreteService = registry.getService(Java12And13ConcreteService.class);
+ }
+
+ /**
+ * Tests Text Blocks
+ * https://docs.oracle.com/en/java/javase/17/language/text-blocks.html
+ */
+ @Test
+ public void textBlocks() throws Exception
+ {
+ java12And13Service.textBlocks();
+ java12And13ConcreteService.textBlocks();
+ }
+
+ /**
+ * Tests Switch Expressions
+ * https://docs.oracle.com/en/java/javase/17/language/switch-expressions.html
+ */
+ @Test
+ public void switchExpressions() throws Exception
+ {
+ java12And13Service.switchExpressions();
+ java12And13ConcreteService.switchExpressions();
+ }
+
+}
diff --git a/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java12And13Service.java b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java12And13Service.java
new file mode 100644
index 0000000..0c97386
--- /dev/null
+++ b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java12And13Service.java
@@ -0,0 +1,28 @@
+// Licensed 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.apache.tapestry5.ioc.services;
+
+public interface Java12And13Service
+{
+
+ /**
+ * Tests Text Blocks
+ * https://docs.oracle.com/en/java/javase/17/language/text-blocks.html
+ */
+ void textBlocks();
+
+ /**
+ * Tests Switch Expressions
+ * https://docs.oracle.com/en/java/javase/17/language/switch-expressions.html
+ */
+ void switchExpressions();
+}
\ No newline at end of file
diff --git a/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java12And13ServiceImpl.java b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java12And13ServiceImpl.java
new file mode 100644
index 0000000..76f22cd
--- /dev/null
+++ b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java12And13ServiceImpl.java
@@ -0,0 +1,69 @@
+// Licensed 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.apache.tapestry5.ioc.services;
+
+import java.time.LocalDate;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class Java12And13ServiceImpl implements Java12And13Service
+{
+
+ private static final String DAY_OF_WEEK_STRING = "Work!";
+ private static final String WEEKEND_STRING = "Rest!";
+ private static final Logger LOGGER = LoggerFactory.getLogger(Java12And13ServiceImpl.class);
+
+ public Java12And13ServiceImpl()
+ {
+ textBlocks();
+ switchExpressions();
+ }
+
+ /**
+ * Tests Text Blocks
+ * https://docs.oracle.com/en/java/javase/17/language/text-blocks.html
+ */
+ @Override
+ public void textBlocks()
+ {
+ String string = """
+ <html>
+ <body>
+ <p>Hello, Tapestry world!>/p>
+ </body>
+ </html>
+ """;
+ LOGGER.info("Text block: " + string);
+ }
+
+ @Override
+ public void switchExpressions()
+ {
+ LocalDate date = LocalDate.now();
+ String string = switch(date.getDayOfWeek())
+ {
+ case MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY ->
+ {
+ LOGGER.info(DAY_OF_WEEK_STRING);
+ yield DAY_OF_WEEK_STRING;
+ }
+ default ->
+ {
+ LOGGER.info(WEEKEND_STRING);
+ yield WEEKEND_STRING;
+ }
+ };
+ LOGGER.info("Result: " + string);
+ }
+
+}
\ No newline at end of file
diff --git a/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java14ConcreteService.java b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java14ConcreteService.java
new file mode 100644
index 0000000..8c99405
--- /dev/null
+++ b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java14ConcreteService.java
@@ -0,0 +1,73 @@
+// Licensed 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.apache.tapestry5.ioc.services;
+
+import org.slf4j.LoggerFactory;
+
+public class Java14ConcreteService
+{
+
+ public Java14ConcreteService()
+ {
+ patternMatchingForTheInstanceOfOperator();
+ records();
+ localRecord();
+ }
+
+ /**
+ * For testing Pattern Matching for the instanceof Operator
+ * http://www.oracle.com/pls/topic/lookup?ctx=javase14&id=GUID-843060B5-240C-4F47-A7B0-95C42E5B08A7
+ */
+ public void patternMatchingForTheInstanceOfOperator()
+ {
+ handleVideogame(new HomeConsole());
+ handleVideogame(new ConsolePortableHybrid());
+ }
+
+ @SuppressWarnings("preview")
+ private void handleVideogame(Videogame videogame)
+ {
+ if (videogame instanceof HomeConsole homeConsole)
+ {
+ homeConsole.turnConnectedTVOn();
+ }
+ if (videogame instanceof ConsolePortableHybrid hybrid)
+ {
+ hybrid.turnEmbeddedScreenOn();
+ }
+ }
+
+ /**
+ * For testing Records
+ * https://docs.oracle.com/en/java/javase/17/language/records.html
+ */
+ public IntTuple records()
+ {
+ return new IntTuple(1, 1);
+ }
+
+ /**
+ * For testing Local Record Classes
+ * GUID-6699E26F-4A9B-4393-A08B-1E47D4B2D263__GUID-FB8EDC85-2C6A-4591-8E00-248DA900723A
+ */
+ public void localRecord()
+ {
+
+ record Local(String name)
+ {
+
+ }
+
+ LoggerFactory.getLogger(this.getClass()).info("Local record " + new Local("test"));
+ }
+
+}
\ No newline at end of file
diff --git a/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java14NewFeatureTests.java b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java14NewFeatureTests.java
new file mode 100644
index 0000000..35746c2
--- /dev/null
+++ b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java14NewFeatureTests.java
@@ -0,0 +1,101 @@
+// Licensed 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.apache.tapestry5.ioc.services;
+
+import org.apache.tapestry5.ioc.Registry;
+import org.apache.tapestry5.ioc.RegistryBuilder;
+import org.apache.tapestry5.ioc.ServiceBinder;
+import org.slf4j.LoggerFactory;
+import org.testng.annotations.BeforeSuite;
+import org.testng.annotations.Test;
+
+/**
+ * Tests for Tapestry-IoC and Java language features introduced in Java SE 14: pattern matching for the
+ * <code>instanceof</code> operator and records.
+ */
+public class Java14NewFeatureTests
+{
+
+ private Registry registry;
+
+ public static class Java14Module
+ {
+ public static void bind(ServiceBinder binder)
+ {
+ binder.bind(Java14Service.class, Java14ServiceImpl.class);
+ binder.bind(Java14ConcreteService.class);
+ }
+ public static IntTuple buildIntTuple()
+ {
+ return new IntTuple(10, 15);
+ }
+ }
+
+ private Java14Service java14Service;
+
+ private Java14ConcreteService java14ConcreteService;
+
+ @BeforeSuite
+ public void setup()
+ {
+ registry = RegistryBuilder.buildAndStartupRegistry(Java14Module.class);
+ java14Service = registry.getService(Java14Service.class);
+ java14ConcreteService = registry.getService(Java14ConcreteService.class);
+ }
+
+ /**
+ * For testing Pattern Matching for the instanceof Operator
+ * http://www.oracle.com/pls/topic/lookup?ctx=javase14&id=GUID-843060B5-240C-4F47-A7B0-95C42E5B08A7
+ */
+ @Test
+ public void patternMatchingForTheInstanceOfOperator()
+ {
+ java14Service.patternMatchingForTheInstanceOfOperator();
+ java14ConcreteService.patternMatchingForTheInstanceOfOperator();
+ }
+
+ /**
+ * For testing Records
+ * https://docs.oracle.com/en/java/javase/17/language/records.html
+ */
+ @Test
+ public void records()
+ {
+ process(java14Service.records());
+ process(java14ConcreteService.records());
+ }
+
+ /**
+ * For testing services whose type is a record.
+ */
+ @Test
+ public void recordsAsServices()
+ {
+ process(registry.getService(IntTuple.class));
+ }
+
+ private void process(IntTuple record) {
+ LoggerFactory.getLogger(this.getClass()).info("Record: " + record);
+ }
+
+ /**
+ * For testing Local Record Classes
+ * GUID-6699E26F-4A9B-4393-A08B-1E47D4B2D263__GUID-FB8EDC85-2C6A-4591-8E00-248DA900723A
+ */
+ @Test
+ public void localRecord()
+ {
+ java14Service.localRecord();
+ java14ConcreteService.localRecord();
+ }
+
+}
diff --git a/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java14Service.java b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java14Service.java
new file mode 100644
index 0000000..a0096c2
--- /dev/null
+++ b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java14Service.java
@@ -0,0 +1,37 @@
+// Licensed 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.apache.tapestry5.ioc.services;
+
+import org.slf4j.LoggerFactory;
+
+public interface Java14Service
+{
+
+ /**
+ * For testing Pattern Matching for the instanceof Operator
+ * http://www.oracle.com/pls/topic/lookup?ctx=javase14&id=GUID-843060B5-240C-4F47-A7B0-95C42E5B08A7
+ */
+ void patternMatchingForTheInstanceOfOperator();
+
+ /**
+ * For testing Records
+ * https://docs.oracle.com/en/java/javase/17/language/records.html
+ */
+ IntTuple records();
+
+ /**
+ * For testing Local Record Classes
+ * GUID-6699E26F-4A9B-4393-A08B-1E47D4B2D263__GUID-FB8EDC85-2C6A-4591-8E00-248DA900723A
+ */
+ void localRecord();
+
+}
\ No newline at end of file
diff --git a/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java14ServiceImpl.java b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java14ServiceImpl.java
new file mode 100644
index 0000000..a35b10f
--- /dev/null
+++ b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java14ServiceImpl.java
@@ -0,0 +1,71 @@
+// Licensed 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.apache.tapestry5.ioc.services;
+
+import org.slf4j.LoggerFactory;
+
+public class Java14ServiceImpl implements Java14Service
+{
+
+ public Java14ServiceImpl()
+ {
+ patternMatchingForTheInstanceOfOperator();
+ records();
+ }
+
+ /**
+ * For testing Pattern Matching for the instanceof Operator
+ * http://www.oracle.com/pls/topic/lookup?ctx=javase14&id=GUID-843060B5-240C-4F47-A7B0-95C42E5B08A7
+ */
+ public void patternMatchingForTheInstanceOfOperator()
+ {
+ handleVideogame(new HomeConsole());
+ handleVideogame(new ConsolePortableHybrid());
+ }
+
+ @SuppressWarnings("preview")
+ private void handleVideogame(Videogame videogame)
+ {
+ if (videogame instanceof HomeConsole homeConsole)
+ {
+ homeConsole.turnConnectedTVOn();
+ }
+ if (videogame instanceof ConsolePortableHybrid hybrid)
+ {
+ hybrid.turnEmbeddedScreenOn();
+ }
+ }
+
+ /**
+ * For testing Records
+ * https://docs.oracle.com/en/java/javase/17/language/records.html
+ */
+ public IntTuple records()
+ {
+ return new IntTuple(1, 1);
+ }
+
+ /**
+ * For testing Local Record Classes
+ * GUID-6699E26F-4A9B-4393-A08B-1E47D4B2D263__GUID-FB8EDC85-2C6A-4591-8E00-248DA900723A
+ */
+ public void localRecord() {
+
+ record Local(String name)
+ {
+
+ }
+ LoggerFactory.getLogger(this.getClass()).info("Local record " + new Local("test"));
+ }
+
+
+}
\ No newline at end of file
diff --git a/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java15To17ConcreteService.java b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java15To17ConcreteService.java
new file mode 100644
index 0000000..f76a77f
--- /dev/null
+++ b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java15To17ConcreteService.java
@@ -0,0 +1,63 @@
+// Licensed 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.apache.tapestry5.ioc.services;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class Java15To17ConcreteService
+{
+ private static final Logger LOGGER = LoggerFactory.getLogger(Java15To17ConcreteService.class);
+
+ public Java15To17ConcreteService()
+ {
+ recordsWithoutInterfacesNorRecords();
+ }
+
+ /**
+ * Tests Record Classes, regular ones (no interfaces, no records).
+ * https://docs.oracle.com/en/java/javase/17/language/records.html
+ */
+ public void recordsWithoutInterfacesNorRecords()
+ {
+ Appliance appliance = new WashingMachine();
+ CoolingMachine coolingMachine = new Freezer();
+ coolingMachine = new Refrigerator();
+ LOGGER.info("Appliance: " + appliance.getName());
+ LOGGER.info("Cooling machine: " + coolingMachine.getName());
+ }
+
+ /**
+ * Tests Record Classes with interfaces but no records.
+ * https://docs.oracle.com/en/java/javase/17/language/records.html
+ */
+ public void recordsWithInterfacesButNotRecords()
+ {
+ BinaryExpression expression = new AndExpression(
+ new OrExpression(new ConstantBinaryExpression(false), new ConstantBinaryExpression(true)),
+ new AndExpression(new ConstantBinaryExpression(false), new ConstantBinaryExpression(true))
+ );
+ LOGGER.info("Binary expression: " + expression.evaluate());
+ }
+
+ /**
+ * Tests Record Classes with interfaces and records.
+ * https://docs.oracle.com/en/java/javase/17/language/records.html
+ */
+ public void recordsWithInterfacesAndRecords()
+ {
+ IntExpression expression = new SquareExpression(
+ new PlusExpression(new ConstantIntExpression(2), new ConstantIntExpression(3)));
+ LOGGER.info("Int expression: " + expression.evaluate());
+ }
+
+}
\ No newline at end of file
diff --git a/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java15To17NewFeatureTests.java b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java15To17NewFeatureTests.java
new file mode 100644
index 0000000..f8fb60d
--- /dev/null
+++ b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java15To17NewFeatureTests.java
@@ -0,0 +1,169 @@
+// Licensed 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 To
+// limitations under the License.
+package org.apache.tapestry5.ioc.services;
+
+import org.apache.tapestry5.ioc.Registry;
+import org.apache.tapestry5.ioc.RegistryBuilder;
+import org.apache.tapestry5.ioc.ServiceBinder;
+import org.apache.tapestry5.ioc.annotations.Marker;
+import org.apache.tapestry5.ioc.annotations.Primary;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.annotations.BeforeSuite;
+import org.testng.annotations.Test;
+
+/**
+ * Tests for Tapestry-IoC To the only Java language feature introduced in Java SE 10 To 11,
+ * local variable type inference (introduced in 10 To improved in 11).
+ */
+public class Java15To17NewFeatureTests
+{
+
+ // TODO: test ChainBuilder and company
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(Java15To17NewFeatureTests.class);
+
+ public static class Java15To17Module
+ {
+
+ public static void bind(ServiceBinder binder)
+ {
+ binder.bind(Java15To17Service.class, Java15To17ServiceImpl.class);
+ binder.bind(Java15To17ConcreteService.class);
+ }
+
+ // Two service for each case of sealed classes (no record and no interface, interface
+ // and no record, interface and record): one for the sealed class itself,
+ // another for the subclasses.
+ //
+ @Marker(Primary.class)
+ public static Appliance buildAppliance()
+ {
+ return new Freezer();
+ }
+
+ public static Refrigerator buildRefridgerator()
+ {
+ return new Refrigerator();
+ }
+
+ @Marker(Primary.class)
+ public static BinaryExpression buildBinaryExpression()
+ {
+ return new OrExpression(new ConstantBinaryExpression(false), new ConstantBinaryExpression(true));
+ }
+
+ public static ConstantBinaryExpression buildConstantBinaryExpression()
+ {
+ return new ConstantBinaryExpression(true);
+ }
+
+ @Marker(Primary.class)
+ public static IntExpression buildIntExpression()
+ {
+ return new SquareExpression(new ConstantIntExpression(42));
+ }
+
+ public static ConstantIntExpression buildConstantIntExpression()
+ {
+ return new ConstantIntExpression(3);
+ }
+
+ }
+
+ private Java15To17Service java15To17Service;
+
+ private Java15To17ConcreteService java15To17ConcreteService;
+
+ private Registry registry;
+
+ @BeforeSuite
+ public void setup()
+ {
+ registry = RegistryBuilder.buildAndStartupRegistry(Java15To17Module.class);
+ java15To17Service = registry.getService(Java15To17Service.class);
+ java15To17ConcreteService = registry.getService(Java15To17ConcreteService.class);
+ }
+
+ /**
+ * Tests Record Classes, regular ones (no interfaces, no records).
+ * https://docs.oracle.com/en/java/javase/17/language/records.html
+ */
+ @Test
+ public void recordsWithoutInterfacesNorRecords()
+ {
+ java15To17Service.recordsWithoutInterfacesNorRecords();
+ java15To17ConcreteService.recordsWithoutInterfacesNorRecords();
+ }
+
+ /**
+ * Tests Record Classes with interfaces but no records.
+ * https://docs.oracle.com/en/java/javase/17/language/records.html
+ */
+ @Test
+ public void recordsWithInterfacesButNotRecords()
+ {
+ java15To17Service.recordsWithInterfacesButNotRecords();
+ java15To17ConcreteService.recordsWithInterfacesButNotRecords();
+ }
+
+ /**
+ * Tests Record Classes with interfaces and records.
+ * https://docs.oracle.com/en/java/javase/17/language/records.html
+ */
+ @Test
+ public void recordsWithInterfacesAndRecords()
+ {
+ java15To17Service.recordsWithInterfacesAndRecords();
+ java15To17ConcreteService.recordsWithInterfacesAndRecords();
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test
+ public void recordsWithoutInterfacesNorRecords_service_sealedClass()
+ {
+ LOGGER.info(registry.getService(Appliance.class, Primary.class).getName());
+ }
+
+ @Test
+ public void recordsWithoutInterfacesNorRecords_service_subclass()
+ {
+ LOGGER.info(registry.getService(Refrigerator.class).getName());
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test
+ public void recordsWithInterfacesButNotRecords_service_sealedClass()
+ {
+ LOGGER.info(String.valueOf(registry.getService(BinaryExpression.class, Primary.class).evaluate()));
+ }
+
+ @Test
+ public void recordsWithInterfacesButNotRecords_service_subclass()
+ {
+ LOGGER.info(String.valueOf(registry.getService(ConstantBinaryExpression.class).evaluate()));
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test
+ public void recordsWithInterfacesAndRecords_service_sealedClass()
+ {
+ LOGGER.info(String.valueOf(registry.getService(IntExpression.class, Primary.class).evaluate()));
+ }
+
+ @Test
+ public void recordsWithInterfacesAndRecords_service_subclass()
+ {
+ LOGGER.info(String.valueOf(registry.getService(ConstantIntExpression.class).evaluate()));
+ }
+
+}
diff --git a/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java15To17Service.java b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java15To17Service.java
new file mode 100644
index 0000000..d18f8b3
--- /dev/null
+++ b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java15To17Service.java
@@ -0,0 +1,34 @@
+// Licensed 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.apache.tapestry5.ioc.services;
+
+public interface Java15To17Service
+{
+ /**
+ * Tests Record Classes, regular ones (no interfaces, no records).
+ * https://docs.oracle.com/en/java/javase/17/language/records.html
+ */
+ public void recordsWithoutInterfacesNorRecords();
+
+ /**
+ * Tests Record Classes with interfaces but no records.
+ * https://docs.oracle.com/en/java/javase/17/language/records.html
+ */
+ public void recordsWithInterfacesButNotRecords();
+
+ /**
+ * Tests Record Classes with interfaces and records.
+ * https://docs.oracle.com/en/java/javase/17/language/records.html
+ */
+ public void recordsWithInterfacesAndRecords();
+
+}
\ No newline at end of file
diff --git a/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java15To17ServiceImpl.java b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java15To17ServiceImpl.java
new file mode 100644
index 0000000..942aecd
--- /dev/null
+++ b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java15To17ServiceImpl.java
@@ -0,0 +1,66 @@
+// Licensed 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.apache.tapestry5.ioc.services;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class Java15To17ServiceImpl implements Java15To17Service
+{
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(Java15To17ServiceImpl.class);
+
+ public Java15To17ServiceImpl()
+ {
+ recordsWithInterfacesAndRecords();
+ recordsWithInterfacesButNotRecords();
+ recordsWithoutInterfacesNorRecords();
+ }
+
+ /**
+ * Tests Record Classes, regular ones (no interfaces, no records).
+ * https://docs.oracle.com/en/java/javase/17/language/records.html
+ */
+ public void recordsWithoutInterfacesNorRecords()
+ {
+ Appliance appliance = new WashingMachine();
+ CoolingMachine coolingMachine = new Freezer();
+ coolingMachine = new Refrigerator();
+ LOGGER.info("Appliance: " + appliance.getName());
+ LOGGER.info("Cooling machine: " + coolingMachine.getName());
+ }
+
+ /**
+ * Tests Record Classes with interfaces but no records.
+ * https://docs.oracle.com/en/java/javase/17/language/records.html
+ */
+ public void recordsWithInterfacesButNotRecords()
+ {
+ BinaryExpression expression = new AndExpression(
+ new OrExpression(new ConstantBinaryExpression(false), new ConstantBinaryExpression(true)),
+ new AndExpression(new ConstantBinaryExpression(false), new ConstantBinaryExpression(true))
+ );
+ LOGGER.info("Binary expression: " + expression.evaluate());
+ }
+
+ /**
+ * Tests Record Classes with interfaces and records.
+ * https://docs.oracle.com/en/java/javase/17/language/records.html
+ */
+ public void recordsWithInterfacesAndRecords()
+ {
+ IntExpression expression = new SquareExpression(
+ new PlusExpression(new ConstantIntExpression(2), new ConstantIntExpression(3)));
+ LOGGER.info("Int expression: " + expression.evaluate());
+ }
+
+}
\ No newline at end of file
diff --git a/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java9ConcreteService.java b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java9ConcreteService.java
new file mode 100644
index 0000000..921a60e
--- /dev/null
+++ b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java9ConcreteService.java
@@ -0,0 +1,69 @@
+// Licensed 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.apache.tapestry5.ioc.services;
+
+import java.util.ArrayList;
+import java.util.Formatter;
+import java.util.List;
+
+public class Java9ConcreteService
+{
+
+ public Java9ConcreteService()
+ {
+ tryWithResources();
+ callSafeVarArgs();
+ diamondSyntaxAndAnonymousInnerClasses();
+ }
+
+ /**
+ * For resting More Concise try-with-resources Statements
+ * https://docs.oracle.com/en/java/javase/17/language/java-language-changes.html#GUID-A920DB06-0FD1-4F9C-8A9A-15FC979D5DA3
+ */
+ public void tryWithResources()
+ {
+ Formatter formatter = new Formatter();
+ try (formatter)
+ {
+ formatter.format("nothing");
+ }
+ }
+
+ public void callSafeVarArgs()
+ {
+ safeVarags("1");
+ }
+
+ /**
+ * For testing @SafeVarargs Annotation Allowed on Proviate Instance Methods.
+ * https://docs.oracle.com/en/java/javase/17/language/java-language-changes.html#GUID-015392DB-F5C4-4A8E-B190-E797707E7BFB
+ */
+ @SafeVarargs
+ private void safeVarags( String...strings)
+ {
+
+ }
+
+ /**
+ * For testing Diamond Syntax and Anonymous Inner Classes
+ * https://docs.oracle.com/en/java/javase/17/language/java-language-changes.html#GUID-0DF89F53-9232-44E3-80A4-48DD0C2CF359
+ */
+ private class Inner
+ {
+
+ }
+
+ private void diamondSyntaxAndAnonymousInnerClasses() {
+ List<Inner> list = new ArrayList<>();
+ list.add(new Inner());
+ }
+}
\ No newline at end of file
diff --git a/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java9NewFeatureTests.java b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java9NewFeatureTests.java
new file mode 100644
index 0000000..f2ddcc6
--- /dev/null
+++ b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java9NewFeatureTests.java
@@ -0,0 +1,60 @@
+// Licensed 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.apache.tapestry5.ioc.services;
+
+import org.apache.tapestry5.ioc.RegistryBuilder;
+import org.apache.tapestry5.ioc.ServiceBinder;
+import org.testng.annotations.BeforeSuite;
+import org.testng.annotations.Test;
+
+/**
+ * Tests for Tapestry-IoC and Java language features introduced in Java SE 9.
+ */
+public class Java9NewFeatureTests
+{
+
+ public static class Java9Module
+ {
+ public static void bind(ServiceBinder binder)
+ {
+ binder.bind(Java9Service.class, Java9ServiceImpl.class);
+ binder.bind(Java9ConcreteService.class);
+ }
+ }
+
+ private Java9Service java9Service;
+
+ private Java9ConcreteService java9ConcreteService;
+
+ @BeforeSuite
+ public void setup()
+ {
+ var registry = RegistryBuilder.buildAndStartupRegistry(Java9Module.class);
+ java9Service = registry.getService(Java9Service.class);
+ java9ConcreteService = registry.getService(Java9ConcreteService.class);
+ }
+
+ @Test
+ public void safevarargs()
+ {
+ java9Service.callSafeVarArgs();
+ java9ConcreteService.callSafeVarArgs();
+ }
+
+ @Test
+ public void tryWithResources()
+ {
+ java9Service.tryWithResources();
+ java9ConcreteService.tryWithResources();
+ }
+
+}
diff --git a/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java9Service.java b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java9Service.java
new file mode 100644
index 0000000..15b3f77
--- /dev/null
+++ b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java9Service.java
@@ -0,0 +1,33 @@
+// Licensed 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.apache.tapestry5.ioc.services;
+
+public interface Java9Service
+{
+
+ void tryWithResources();
+
+ void callSafeVarArgs();
+
+ default void defaultMethod()
+ {
+ privateMethodInInterface();
+ }
+
+ /**
+ * For testing Support for Private Interface Methods
+ * https://docs.oracle.com/en/java/javase/17/language/java-language-changes.html#GUID-015392DB-F5C4-4A8E-B190-E797707E7BFB
+ */
+ private void privateMethodInInterface()
+ {
+ }
+}
\ No newline at end of file
diff --git a/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java9ServiceImpl.java b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java9ServiceImpl.java
new file mode 100644
index 0000000..3fd2117
--- /dev/null
+++ b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Java9ServiceImpl.java
@@ -0,0 +1,70 @@
+// Licensed 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.apache.tapestry5.ioc.services;
+
+import java.util.ArrayList;
+import java.util.Formatter;
+import java.util.List;
+
+public class Java9ServiceImpl implements Java9Service
+{
+
+ public Java9ServiceImpl()
+ {
+ diamondSyntaxAndAnonymousInnerClasses();
+ tryWithResources();
+ callSafeVarArgs();
+ }
+
+ /**
+ * For testing More Concise try-with-resources Statements
+ * https://docs.oracle.com/en/java/javase/17/language/java-language-changes.html#GUID-A920DB06-0FD1-4F9C-8A9A-15FC979D5DA3
+ */
+ public void tryWithResources()
+ {
+ Formatter formatter = new Formatter();
+ try (formatter)
+ {
+ formatter.format("nothing");
+ }
+ }
+
+ public void callSafeVarArgs()
+ {
+ safeVarags("1");
+ }
+
+ /**
+ * For testing @SafeVarargs Annotation Allowed on Proviate Instance Methods.
+ * https://docs.oracle.com/en/java/javase/17/language/java-language-changes.html#GUID-015392DB-F5C4-4A8E-B190-E797707E7BFB
+ */
+ @SafeVarargs
+ private void safeVarags(String...strings)
+ {
+
+ }
+
+ /**
+ * For testing Diamond Syntax and Anonymous Inner Classes
+ * https://docs.oracle.com/en/java/javase/17/language/java-language-changes.html#GUID-0DF89F53-9232-44E3-80A4-48DD0C2CF359
+ */
+ private class Inner
+ {
+
+ }
+
+ private void diamondSyntaxAndAnonymousInnerClasses() {
+ List<Inner> list = new ArrayList<>();
+ list.add(new Inner());
+ }
+
+}
\ No newline at end of file
diff --git a/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/OrExpression.java b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/OrExpression.java
new file mode 100644
index 0000000..632136b
--- /dev/null
+++ b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/OrExpression.java
@@ -0,0 +1,32 @@
+// Licensed 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.apache.tapestry5.ioc.services;
+
+/**
+ * Just for use in Record Classes tests.
+ */
+public final class OrExpression implements BinaryExpression
+{
+ private final BinaryExpression operand1, operand2;
+
+ public OrExpression(BinaryExpression operand1, BinaryExpression operand2) {
+ super();
+ this.operand1 = operand1;
+ this.operand2 = operand2;
+ }
+
+ @Override
+ public boolean evaluate()
+ {
+ return operand1.evaluate() || operand2.evaluate();
+ }
+}
diff --git a/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/PlusExpression.java b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/PlusExpression.java
new file mode 100644
index 0000000..7538231
--- /dev/null
+++ b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/PlusExpression.java
@@ -0,0 +1,24 @@
+// Licensed 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.apache.tapestry5.ioc.services;
+
+/**
+ * Just for use in Record Classes tests.
+ */
+public final record PlusExpression(IntExpression operand1, IntExpression operand2) implements IntExpression
+{
+ @Override
+ public int evaluate()
+ {
+ return operand1.evaluate() + operand2.evaluate();
+ }
+}
diff --git a/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Refrigerator.java b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Refrigerator.java
new file mode 100644
index 0000000..1f02a6b
--- /dev/null
+++ b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Refrigerator.java
@@ -0,0 +1,23 @@
+// Licensed 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.apache.tapestry5.ioc.services;
+
+/**
+ * Just for use in Pattern Matching for the instanceof Operator tests.
+ */
+public final class Refrigerator extends CoolingMachine
+{
+ public Refrigerator()
+ {
+ super("Refrigerator");
+ }
+}
\ No newline at end of file
diff --git a/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/SquareExpression.java b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/SquareExpression.java
new file mode 100644
index 0000000..94a5787
--- /dev/null
+++ b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/SquareExpression.java
@@ -0,0 +1,24 @@
+// Licensed 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.apache.tapestry5.ioc.services;
+
+/**
+ * Just for use in Record Classes tests.
+ */
+public final record SquareExpression (IntExpression expression) implements IntExpression
+{
+ @Override
+ public int evaluate()
+ {
+ return expression.evaluate() * expression.evaluate();
+ }
+}
diff --git a/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Videogame.java b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Videogame.java
new file mode 100644
index 0000000..c0a4e1d
--- /dev/null
+++ b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/Videogame.java
@@ -0,0 +1,19 @@
+// Licensed 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.apache.tapestry5.ioc.services;
+
+/**
+ * Just for use in Pattern Matching for the instanceof Operator tests.
+ */
+public interface Videogame
+{
+}
diff --git a/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/WashingMachine.java b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/WashingMachine.java
new file mode 100644
index 0000000..df6dd5f
--- /dev/null
+++ b/tapestry-latest-java-tests/src/test/java/org/apache/tapestry5/ioc/services/WashingMachine.java
@@ -0,0 +1,23 @@
+// Licensed 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.apache.tapestry5.ioc.services;
+
+/**
+ * Just for use in Pattern Matching for the instanceof Operator tests.
+ */
+public final class WashingMachine extends Appliance
+{
+ public WashingMachine()
+ {
+ super("Washing machine");
+ }
+}
\ No newline at end of file