mirror of
https://github.com/spring-projects/spring-framework
synced 2026-06-08 17:33:33 +00:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ab5a6a5e48 |
@@ -1,3 +0,0 @@
|
||||
# Enable auto-env through the sdkman_auto_env config
|
||||
# Add key=value pairs of SDKs to use below
|
||||
java=8.0.322-librca
|
||||
+11
-11
@@ -28,8 +28,8 @@ configure(allprojects) { project ->
|
||||
dependencyManagement {
|
||||
imports {
|
||||
mavenBom "com.fasterxml.jackson:jackson-bom:2.12.6"
|
||||
mavenBom "io.netty:netty-bom:4.1.75.Final"
|
||||
mavenBom "io.projectreactor:reactor-bom:2020.0.17"
|
||||
mavenBom "io.netty:netty-bom:4.1.74.Final"
|
||||
mavenBom "io.projectreactor:reactor-bom:2020.0.16"
|
||||
mavenBom "io.r2dbc:r2dbc-bom:Arabba-SR12"
|
||||
mavenBom "io.rsocket:rsocket-bom:1.1.1"
|
||||
mavenBom "org.eclipse.jetty:jetty-bom:9.4.45.v20220203"
|
||||
@@ -39,13 +39,13 @@ configure(allprojects) { project ->
|
||||
mavenBom "org.junit:junit-bom:5.8.2"
|
||||
}
|
||||
dependencies {
|
||||
dependencySet(group: 'org.apache.logging.log4j', version: '2.17.2') {
|
||||
dependencySet(group: 'org.apache.logging.log4j', version: '2.17.1') {
|
||||
entry 'log4j-api'
|
||||
entry 'log4j-core'
|
||||
entry 'log4j-jul'
|
||||
entry 'log4j-slf4j-impl'
|
||||
}
|
||||
dependency "org.slf4j:slf4j-api:1.7.36"
|
||||
dependency "org.slf4j:slf4j-api:1.7.35"
|
||||
dependency("com.google.code.findbugs:findbugs:3.0.1") {
|
||||
exclude group: "dom4j", name: "dom4j"
|
||||
}
|
||||
@@ -68,7 +68,7 @@ configure(allprojects) { project ->
|
||||
dependency "io.reactivex:rxjava-reactive-streams:1.2.1"
|
||||
dependency "io.reactivex.rxjava2:rxjava:2.2.21"
|
||||
dependency "io.reactivex.rxjava3:rxjava:3.1.3"
|
||||
dependency "io.smallrye.reactive:mutiny:1.4.0"
|
||||
dependency "io.smallrye.reactive:mutiny:1.3.1"
|
||||
dependency "io.projectreactor.tools:blockhound:1.0.6.RELEASE"
|
||||
|
||||
dependency "com.caucho:hessian:4.0.63"
|
||||
@@ -124,18 +124,18 @@ configure(allprojects) { project ->
|
||||
dependency "org.ehcache:jcache:1.0.1"
|
||||
dependency "org.ehcache:ehcache:3.4.0"
|
||||
dependency "org.hibernate:hibernate-core:5.4.33.Final"
|
||||
dependency "org.hibernate:hibernate-validator:6.2.3.Final"
|
||||
dependency "org.hibernate:hibernate-validator:6.2.2.Final"
|
||||
dependency "org.webjars:webjars-locator-core:0.48"
|
||||
dependency "org.webjars:underscorejs:1.8.3"
|
||||
|
||||
dependencySet(group: 'org.apache.tomcat', version: '9.0.60') {
|
||||
dependencySet(group: 'org.apache.tomcat', version: '9.0.58') {
|
||||
entry 'tomcat-util'
|
||||
entry('tomcat-websocket') {
|
||||
exclude group: "org.apache.tomcat", name: "tomcat-servlet-api"
|
||||
exclude group: "org.apache.tomcat", name: "tomcat-websocket-api"
|
||||
}
|
||||
}
|
||||
dependencySet(group: 'org.apache.tomcat.embed', version: '9.0.60') {
|
||||
dependencySet(group: 'org.apache.tomcat.embed', version: '9.0.58') {
|
||||
entry 'tomcat-embed-core'
|
||||
entry 'tomcat-embed-websocket'
|
||||
}
|
||||
@@ -198,7 +198,7 @@ configure(allprojects) { project ->
|
||||
exclude group: "org.hamcrest", name: "hamcrest-core"
|
||||
}
|
||||
}
|
||||
dependencySet(group: 'org.mockito', version: '4.4.0') {
|
||||
dependencySet(group: 'org.mockito', version: '4.3.1') {
|
||||
entry('mockito-core') {
|
||||
exclude group: "org.hamcrest", name: "hamcrest-core"
|
||||
}
|
||||
@@ -206,10 +206,10 @@ configure(allprojects) { project ->
|
||||
}
|
||||
dependency "io.mockk:mockk:1.12.1"
|
||||
|
||||
dependency("net.sourceforge.htmlunit:htmlunit:2.59.0") {
|
||||
dependency("net.sourceforge.htmlunit:htmlunit:2.58.0") {
|
||||
exclude group: "commons-logging", name: "commons-logging"
|
||||
}
|
||||
dependency("org.seleniumhq.selenium:htmlunit-driver:2.59.0") {
|
||||
dependency("org.seleniumhq.selenium:htmlunit-driver:2.58.0") {
|
||||
exclude group: "commons-logging", name: "commons-logging"
|
||||
}
|
||||
dependency("org.seleniumhq.selenium:selenium-java:3.141.59") {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM ubuntu:focal-20220302
|
||||
FROM ubuntu:focal-20220113
|
||||
|
||||
ADD setup.sh /setup.sh
|
||||
ADD get-jdk-url.sh /get-jdk-url.sh
|
||||
|
||||
+1
-1
@@ -14,7 +14,7 @@ rm -rf /var/lib/apt/lists/*
|
||||
|
||||
curl https://raw.githubusercontent.com/spring-io/concourse-java-scripts/v0.0.4/concourse-java.sh > /opt/concourse-java.sh
|
||||
|
||||
curl --output /opt/concourse-release-scripts.jar https://repo.spring.io/release/io/spring/concourse/releasescripts/concourse-release-scripts/0.3.2/concourse-release-scripts-0.3.2.jar
|
||||
curl --output /opt/concourse-release-scripts.jar https://repo.spring.io/release/io/spring/concourse/releasescripts/concourse-release-scripts/0.3.3/concourse-release-scripts-0.3.3.jar
|
||||
|
||||
###########################################################
|
||||
# JAVA
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
version=5.3.17
|
||||
version=5.3.16
|
||||
org.gradle.jvmargs=-Xmx1536M
|
||||
org.gradle.caching=true
|
||||
org.gradle.parallel=true
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -691,25 +691,7 @@ public abstract class BeanUtils {
|
||||
* from each other, as long as the properties match. Any bean properties that the
|
||||
* source bean exposes but the target bean does not will silently be ignored.
|
||||
* <p>This is just a convenience method. For more complex transfer needs,
|
||||
* consider using a full {@link BeanWrapper}.
|
||||
* <p>As of Spring Framework 5.3, this method honors generic type information
|
||||
* when matching properties in the source and target objects.
|
||||
* <p>The following table provides a non-exhaustive set of examples of source
|
||||
* and target property types that can be copied as well as source and target
|
||||
* property types that cannot be copied.
|
||||
* <table border="1">
|
||||
* <tr><th>source property type</th><th>target property type</th><th>copy supported</th></tr>
|
||||
* <tr><td>{@code Integer}</td><td>{@code Integer}</td><td>yes</td></tr>
|
||||
* <tr><td>{@code Integer}</td><td>{@code Number}</td><td>yes</td></tr>
|
||||
* <tr><td>{@code List<Integer>}</td><td>{@code List<Integer>}</td><td>yes</td></tr>
|
||||
* <tr><td>{@code List<?>}</td><td>{@code List<?>}</td><td>yes</td></tr>
|
||||
* <tr><td>{@code List<Integer>}</td><td>{@code List<?>}</td><td>yes</td></tr>
|
||||
* <tr><td>{@code List<Integer>}</td><td>{@code List<? extends Number>}</td><td>yes</td></tr>
|
||||
* <tr><td>{@code String}</td><td>{@code Integer}</td><td>no</td></tr>
|
||||
* <tr><td>{@code Number}</td><td>{@code Integer}</td><td>no</td></tr>
|
||||
* <tr><td>{@code List<Integer>}</td><td>{@code List<Long>}</td><td>no</td></tr>
|
||||
* <tr><td>{@code List<Integer>}</td><td>{@code List<Number>}</td><td>no</td></tr>
|
||||
* </table>
|
||||
* consider using a full BeanWrapper.
|
||||
* @param source the source bean
|
||||
* @param target the target bean
|
||||
* @throws BeansException if the copying failed
|
||||
@@ -726,10 +708,7 @@ public abstract class BeanUtils {
|
||||
* from each other, as long as the properties match. Any bean properties that the
|
||||
* source bean exposes but the target bean does not will silently be ignored.
|
||||
* <p>This is just a convenience method. For more complex transfer needs,
|
||||
* consider using a full {@link BeanWrapper}.
|
||||
* <p>As of Spring Framework 5.3, this method honors generic type information
|
||||
* when matching properties in the source and target objects. See the
|
||||
* documentation for {@link #copyProperties(Object, Object)} for details.
|
||||
* consider using a full BeanWrapper.
|
||||
* @param source the source bean
|
||||
* @param target the target bean
|
||||
* @param editable the class (or interface) to restrict property setting to
|
||||
@@ -747,10 +726,7 @@ public abstract class BeanUtils {
|
||||
* from each other, as long as the properties match. Any bean properties that the
|
||||
* source bean exposes but the target bean does not will silently be ignored.
|
||||
* <p>This is just a convenience method. For more complex transfer needs,
|
||||
* consider using a full {@link BeanWrapper}.
|
||||
* <p>As of Spring Framework 5.3, this method honors generic type information
|
||||
* when matching properties in the source and target objects. See the
|
||||
* documentation for {@link #copyProperties(Object, Object)} for details.
|
||||
* consider using a full BeanWrapper.
|
||||
* @param source the source bean
|
||||
* @param target the target bean
|
||||
* @param ignoreProperties array of property names to ignore
|
||||
@@ -767,8 +743,7 @@ public abstract class BeanUtils {
|
||||
* from each other, as long as the properties match. Any bean properties that the
|
||||
* source bean exposes but the target bean does not will silently be ignored.
|
||||
* <p>As of Spring Framework 5.3, this method honors generic type information
|
||||
* when matching properties in the source and target objects. See the
|
||||
* documentation for {@link #copyProperties(Object, Object)} for details.
|
||||
* when matching properties in the source and target objects.
|
||||
* @param source the source bean
|
||||
* @param target the target bean
|
||||
* @param editable the class (or interface) to restrict property setting to
|
||||
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -302,7 +302,7 @@ public class InitDestroyAnnotationBeanPostProcessor
|
||||
beanDefinition.registerExternallyManagedInitMethod(methodIdentifier);
|
||||
checkedInitMethods.add(element);
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Registered init method on class [" + this.targetClass.getName() + "]: " + methodIdentifier);
|
||||
logger.trace("Registered init method on class [" + this.targetClass.getName() + "]: " + element);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -313,7 +313,7 @@ public class InitDestroyAnnotationBeanPostProcessor
|
||||
beanDefinition.registerExternallyManagedDestroyMethod(methodIdentifier);
|
||||
checkedDestroyMethods.add(element);
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Registered destroy method on class [" + this.targetClass.getName() + "]: " + methodIdentifier);
|
||||
logger.trace("Registered destroy method on class [" + this.targetClass.getName() + "]: " + element);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -1844,7 +1844,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
throws Throwable {
|
||||
|
||||
boolean isInitializingBean = (bean instanceof InitializingBean);
|
||||
if (isInitializingBean && (mbd == null || !mbd.hasAnyExternallyManagedInitMethod("afterPropertiesSet"))) {
|
||||
if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
|
||||
}
|
||||
@@ -1868,7 +1868,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
String initMethodName = mbd.getInitMethodName();
|
||||
if (StringUtils.hasLength(initMethodName) &&
|
||||
!(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
|
||||
!mbd.hasAnyExternallyManagedInitMethod(initMethodName)) {
|
||||
!mbd.isExternallyManagedInitMethod(initMethodName)) {
|
||||
invokeCustomInitMethod(beanName, bean, mbd);
|
||||
}
|
||||
}
|
||||
|
||||
+2
-3
@@ -52,7 +52,6 @@ import org.springframework.util.StringUtils;
|
||||
* @author Juergen Hoeller
|
||||
* @author Costin Leau
|
||||
* @author Stephane Nicoll
|
||||
* @author Sam Brannen
|
||||
* @since 2.0
|
||||
* @see AbstractBeanFactory
|
||||
* @see org.springframework.beans.factory.DisposableBean
|
||||
@@ -110,12 +109,12 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
|
||||
this.beanName = beanName;
|
||||
this.nonPublicAccessAllowed = beanDefinition.isNonPublicAccessAllowed();
|
||||
this.invokeDisposableBean = (bean instanceof DisposableBean &&
|
||||
!beanDefinition.hasAnyExternallyManagedDestroyMethod(DESTROY_METHOD_NAME));
|
||||
!beanDefinition.isExternallyManagedDestroyMethod(DESTROY_METHOD_NAME));
|
||||
|
||||
String destroyMethodName = inferDestroyMethodIfNecessary(bean, beanDefinition);
|
||||
if (destroyMethodName != null &&
|
||||
!(this.invokeDisposableBean && DESTROY_METHOD_NAME.equals(destroyMethodName)) &&
|
||||
!beanDefinition.hasAnyExternallyManagedDestroyMethod(destroyMethodName)) {
|
||||
!beanDefinition.isExternallyManagedDestroyMethod(destroyMethodName)) {
|
||||
|
||||
this.invokeAutoCloseable = (bean instanceof AutoCloseable && CLOSE_METHOD_NAME.equals(destroyMethodName));
|
||||
if (!this.invokeAutoCloseable) {
|
||||
|
||||
@@ -67,7 +67,6 @@ public class ManagedMap<K, V> extends LinkedHashMap<K, V> implements Mergeable,
|
||||
* @return a {@code Map} containing the specified mappings
|
||||
* @since 5.3.16
|
||||
*/
|
||||
@SafeVarargs
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <K,V> ManagedMap<K,V> ofEntries(Entry<? extends K, ? extends V>... entries) {
|
||||
ManagedMap<K,V > map = new ManagedMap<>();
|
||||
|
||||
+8
-95
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -49,7 +49,6 @@ import org.springframework.util.Assert;
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @author Juergen Hoeller
|
||||
* @author Sam Brannen
|
||||
* @see GenericBeanDefinition
|
||||
* @see ChildBeanDefinition
|
||||
*/
|
||||
@@ -437,7 +436,7 @@ public class RootBeanDefinition extends AbstractBeanDefinition {
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the given method or field is an externally managed configuration member.
|
||||
* Check whether the given method or field is an externally managed configuration member.
|
||||
*/
|
||||
public boolean isExternallyManagedConfigMember(Member configMember) {
|
||||
synchronized (this.postProcessingLock) {
|
||||
@@ -447,7 +446,7 @@ public class RootBeanDefinition extends AbstractBeanDefinition {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all externally managed configuration methods and fields (as an immutable Set).
|
||||
* Return all externally managed configuration methods and fields (as an immutable Set).
|
||||
* @since 5.3.11
|
||||
*/
|
||||
public Set<Member> getExternallyManagedConfigMembers() {
|
||||
@@ -459,15 +458,7 @@ public class RootBeanDefinition extends AbstractBeanDefinition {
|
||||
}
|
||||
|
||||
/**
|
||||
* Register an externally managed configuration initialization method —
|
||||
* for example, a method annotated with JSR-250's
|
||||
* {@link javax.annotation.PostConstruct} annotation.
|
||||
* <p>The supplied {@code initMethod} may be the
|
||||
* {@linkplain Method#getName() simple method name} for non-private methods or the
|
||||
* {@linkplain org.springframework.util.ClassUtils#getQualifiedMethodName(Method)
|
||||
* qualified method name} for {@code private} methods. A qualified name is
|
||||
* necessary for {@code private} methods in order to disambiguate between
|
||||
* multiple private methods with the same name within a class hierarchy.
|
||||
* Register an externally managed configuration initialization method.
|
||||
*/
|
||||
public void registerExternallyManagedInitMethod(String initMethod) {
|
||||
synchronized (this.postProcessingLock) {
|
||||
@@ -479,10 +470,7 @@ public class RootBeanDefinition extends AbstractBeanDefinition {
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the given method name indicates an externally managed
|
||||
* initialization method.
|
||||
* <p>See {@link #registerExternallyManagedInitMethod} for details
|
||||
* regarding the format for the supplied {@code initMethod}.
|
||||
* Check whether the given method name indicates an externally managed initialization method.
|
||||
*/
|
||||
public boolean isExternallyManagedInitMethod(String initMethod) {
|
||||
synchronized (this.postProcessingLock) {
|
||||
@@ -491,40 +479,8 @@ public class RootBeanDefinition extends AbstractBeanDefinition {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the given method name indicates an externally managed
|
||||
* initialization method, regardless of method visibility.
|
||||
* <p>In contrast to {@link #isExternallyManagedInitMethod(String)}, this
|
||||
* method also returns {@code true} if there is a {@code private} externally
|
||||
* managed initialization method that has been
|
||||
* {@linkplain #registerExternallyManagedInitMethod(String) registered}
|
||||
* using a qualified method name instead of a simple method name.
|
||||
* @since 5.3.17
|
||||
*/
|
||||
boolean hasAnyExternallyManagedInitMethod(String initMethod) {
|
||||
synchronized (this.postProcessingLock) {
|
||||
if (isExternallyManagedInitMethod(initMethod)) {
|
||||
return true;
|
||||
}
|
||||
if (this.externallyManagedInitMethods != null) {
|
||||
for (String candidate : this.externallyManagedInitMethods) {
|
||||
int indexOfDot = candidate.lastIndexOf('.');
|
||||
if (indexOfDot >= 0) {
|
||||
String methodName = candidate.substring(indexOfDot + 1);
|
||||
if (methodName.equals(initMethod)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return all externally managed initialization methods (as an immutable Set).
|
||||
* <p>See {@link #registerExternallyManagedInitMethod} for details
|
||||
* regarding the format for the initialization methods in the returned set.
|
||||
* @since 5.3.11
|
||||
*/
|
||||
public Set<String> getExternallyManagedInitMethods() {
|
||||
@@ -536,15 +492,7 @@ public class RootBeanDefinition extends AbstractBeanDefinition {
|
||||
}
|
||||
|
||||
/**
|
||||
* Register an externally managed configuration destruction method —
|
||||
* for example, a method annotated with JSR-250's
|
||||
* {@link javax.annotation.PreDestroy} annotation.
|
||||
* <p>The supplied {@code destroyMethod} may be the
|
||||
* {@linkplain Method#getName() simple method name} for non-private methods or the
|
||||
* {@linkplain org.springframework.util.ClassUtils#getQualifiedMethodName(Method)
|
||||
* qualified method name} for {@code private} methods. A qualified name is
|
||||
* necessary for {@code private} methods in order to disambiguate between
|
||||
* multiple private methods with the same name within a class hierarchy.
|
||||
* Register an externally managed configuration destruction method.
|
||||
*/
|
||||
public void registerExternallyManagedDestroyMethod(String destroyMethod) {
|
||||
synchronized (this.postProcessingLock) {
|
||||
@@ -556,10 +504,7 @@ public class RootBeanDefinition extends AbstractBeanDefinition {
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the given method name indicates an externally managed
|
||||
* destruction method.
|
||||
* <p>See {@link #registerExternallyManagedDestroyMethod} for details
|
||||
* regarding the format for the supplied {@code destroyMethod}.
|
||||
* Check whether the given method name indicates an externally managed destruction method.
|
||||
*/
|
||||
public boolean isExternallyManagedDestroyMethod(String destroyMethod) {
|
||||
synchronized (this.postProcessingLock) {
|
||||
@@ -569,39 +514,7 @@ public class RootBeanDefinition extends AbstractBeanDefinition {
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the given method name indicates an externally managed
|
||||
* destruction method, regardless of method visibility.
|
||||
* <p>In contrast to {@link #isExternallyManagedDestroyMethod(String)}, this
|
||||
* method also returns {@code true} if there is a {@code private} externally
|
||||
* managed destruction method that has been
|
||||
* {@linkplain #registerExternallyManagedDestroyMethod(String) registered}
|
||||
* using a qualified method name instead of a simple method name.
|
||||
* @since 5.3.17
|
||||
*/
|
||||
boolean hasAnyExternallyManagedDestroyMethod(String destroyMethod) {
|
||||
synchronized (this.postProcessingLock) {
|
||||
if (isExternallyManagedDestroyMethod(destroyMethod)) {
|
||||
return true;
|
||||
}
|
||||
if (this.externallyManagedDestroyMethods != null) {
|
||||
for (String candidate : this.externallyManagedDestroyMethods) {
|
||||
int indexOfDot = candidate.lastIndexOf('.');
|
||||
if (indexOfDot >= 0) {
|
||||
String methodName = candidate.substring(indexOfDot + 1);
|
||||
if (methodName.equals(destroyMethod)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all externally managed destruction methods (as an immutable Set).
|
||||
* <p>See {@link #registerExternallyManagedDestroyMethod} for details
|
||||
* regarding the format for the destruction methods in the returned set.
|
||||
* Return all externally managed destruction methods (as an immutable Set).
|
||||
* @since 5.3.11
|
||||
*/
|
||||
public Set<String> getExternallyManagedDestroyMethods() {
|
||||
|
||||
+1
-1
@@ -64,6 +64,6 @@ inline fun <reified T : Annotation> ListableBeanFactory.getBeansWithAnnotation()
|
||||
* @author Sebastien Deleuze
|
||||
* @since 5.0
|
||||
*/
|
||||
inline fun <reified T : Annotation> ListableBeanFactory.findAnnotationOnBean(beanName:String): T? =
|
||||
inline fun <reified T : Annotation> ListableBeanFactory.findAnnotationOnBean(beanName:String): Annotation? =
|
||||
findAnnotationOnBean(beanName, T::class.java)
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -203,25 +203,8 @@ class BeanUtilsTests {
|
||||
assertThat(tb2.getTouchy().equals(tb.getTouchy())).as("Touchy copied").isTrue();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@code Integer} can be copied to {@code Number}.
|
||||
*/
|
||||
@Test
|
||||
void copyPropertiesFromSubTypeToSuperType() {
|
||||
IntegerHolder integerHolder = new IntegerHolder();
|
||||
integerHolder.setNumber(42);
|
||||
NumberHolder numberHolder = new NumberHolder();
|
||||
|
||||
BeanUtils.copyProperties(integerHolder, numberHolder);
|
||||
assertThat(integerHolder.getNumber()).isEqualTo(42);
|
||||
assertThat(numberHolder.getNumber()).isEqualTo(42);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@code List<Integer>} can be copied to {@code List<Integer>}.
|
||||
*/
|
||||
@Test
|
||||
void copyPropertiesHonorsGenericTypeMatchesFromIntegerToInteger() {
|
||||
void copyPropertiesHonorsGenericTypeMatches() {
|
||||
IntegerListHolder1 integerListHolder1 = new IntegerListHolder1();
|
||||
integerListHolder1.getList().add(42);
|
||||
IntegerListHolder2 integerListHolder2 = new IntegerListHolder2();
|
||||
@@ -231,68 +214,6 @@ class BeanUtilsTests {
|
||||
assertThat(integerListHolder2.getList()).containsOnly(42);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@code List<?>} can be copied to {@code List<?>}.
|
||||
*/
|
||||
@Test
|
||||
void copyPropertiesHonorsGenericTypeMatchesFromWildcardToWildcard() {
|
||||
List<?> list = Arrays.asList("foo", 42);
|
||||
WildcardListHolder1 wildcardListHolder1 = new WildcardListHolder1();
|
||||
wildcardListHolder1.setList(list);
|
||||
WildcardListHolder2 wildcardListHolder2 = new WildcardListHolder2();
|
||||
assertThat(wildcardListHolder2.getList()).isEmpty();
|
||||
|
||||
BeanUtils.copyProperties(wildcardListHolder1, wildcardListHolder2);
|
||||
assertThat(wildcardListHolder1.getList()).isEqualTo(list);
|
||||
assertThat(wildcardListHolder2.getList()).isEqualTo(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@code List<Integer>} can be copied to {@code List<?>}.
|
||||
*/
|
||||
@Test
|
||||
void copyPropertiesHonorsGenericTypeMatchesFromIntegerToWildcard() {
|
||||
IntegerListHolder1 integerListHolder1 = new IntegerListHolder1();
|
||||
integerListHolder1.getList().add(42);
|
||||
WildcardListHolder2 wildcardListHolder2 = new WildcardListHolder2();
|
||||
|
||||
BeanUtils.copyProperties(integerListHolder1, wildcardListHolder2);
|
||||
assertThat(integerListHolder1.getList()).containsOnly(42);
|
||||
assertThat(wildcardListHolder2.getList()).isEqualTo(Arrays.asList(42));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@code List<Integer>} can be copied to {@code List<? extends Number>}.
|
||||
*/
|
||||
@Test
|
||||
void copyPropertiesHonorsGenericTypeMatchesForUpperBoundedWildcard() {
|
||||
IntegerListHolder1 integerListHolder1 = new IntegerListHolder1();
|
||||
integerListHolder1.getList().add(42);
|
||||
NumberUpperBoundedWildcardListHolder numberListHolder = new NumberUpperBoundedWildcardListHolder();
|
||||
|
||||
BeanUtils.copyProperties(integerListHolder1, numberListHolder);
|
||||
assertThat(integerListHolder1.getList()).containsOnly(42);
|
||||
assertThat(numberListHolder.getList()).hasSize(1);
|
||||
assertThat(numberListHolder.getList().contains(Integer.valueOf(42))).isTrue();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@code Number} can NOT be copied to {@code Integer}.
|
||||
*/
|
||||
@Test
|
||||
void copyPropertiesDoesNotCopyeFromSuperTypeToSubType() {
|
||||
NumberHolder numberHolder = new NumberHolder();
|
||||
numberHolder.setNumber(Integer.valueOf(42));
|
||||
IntegerHolder integerHolder = new IntegerHolder();
|
||||
|
||||
BeanUtils.copyProperties(numberHolder, integerHolder);
|
||||
assertThat(numberHolder.getNumber()).isEqualTo(42);
|
||||
assertThat(integerHolder.getNumber()).isNull();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@code List<Integer>} can NOT be copied to {@code List<Long>}.
|
||||
*/
|
||||
@Test
|
||||
void copyPropertiesDoesNotHonorGenericTypeMismatches() {
|
||||
IntegerListHolder1 integerListHolder = new IntegerListHolder1();
|
||||
@@ -304,20 +225,6 @@ class BeanUtilsTests {
|
||||
assertThat(longListHolder.getList()).isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@code List<Integer>} can NOT be copied to {@code List<Number>}.
|
||||
*/
|
||||
@Test
|
||||
void copyPropertiesDoesNotHonorGenericTypeMismatchesFromSubTypeToSuperType() {
|
||||
IntegerListHolder1 integerListHolder = new IntegerListHolder1();
|
||||
integerListHolder.getList().add(42);
|
||||
NumberListHolder numberListHolder = new NumberListHolder();
|
||||
|
||||
BeanUtils.copyProperties(integerListHolder, numberListHolder);
|
||||
assertThat(integerListHolder.getList()).containsOnly(42);
|
||||
assertThat(numberListHolder.getList()).isEmpty();
|
||||
}
|
||||
|
||||
@Test // gh-26531
|
||||
void copyPropertiesIgnoresGenericsIfSourceOrTargetHasUnresolvableGenerics() throws Exception {
|
||||
Order original = new Order("test", Arrays.asList("foo", "bar"));
|
||||
@@ -506,90 +413,6 @@ class BeanUtilsTests {
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static class NumberHolder {
|
||||
|
||||
private Number number;
|
||||
|
||||
public Number getNumber() {
|
||||
return number;
|
||||
}
|
||||
|
||||
public void setNumber(Number number) {
|
||||
this.number = number;
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static class IntegerHolder {
|
||||
|
||||
private Integer number;
|
||||
|
||||
public Integer getNumber() {
|
||||
return number;
|
||||
}
|
||||
|
||||
public void setNumber(Integer number) {
|
||||
this.number = number;
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static class WildcardListHolder1 {
|
||||
|
||||
private List<?> list = new ArrayList<>();
|
||||
|
||||
public List<?> getList() {
|
||||
return list;
|
||||
}
|
||||
|
||||
public void setList(List<?> list) {
|
||||
this.list = list;
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static class WildcardListHolder2 {
|
||||
|
||||
private List<?> list = new ArrayList<>();
|
||||
|
||||
public List<?> getList() {
|
||||
return list;
|
||||
}
|
||||
|
||||
public void setList(List<?> list) {
|
||||
this.list = list;
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static class NumberUpperBoundedWildcardListHolder {
|
||||
|
||||
private List<? extends Number> list = new ArrayList<>();
|
||||
|
||||
public List<? extends Number> getList() {
|
||||
return list;
|
||||
}
|
||||
|
||||
public void setList(List<? extends Number> list) {
|
||||
this.list = list;
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static class NumberListHolder {
|
||||
|
||||
private List<Number> list = new ArrayList<>();
|
||||
|
||||
public List<Number> getList() {
|
||||
return list;
|
||||
}
|
||||
|
||||
public void setList(List<Number> list) {
|
||||
this.list = list;
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static class IntegerListHolder1 {
|
||||
|
||||
|
||||
+1
-5
@@ -16,11 +16,9 @@
|
||||
|
||||
package org.springframework.beans.factory
|
||||
|
||||
import io.mockk.every
|
||||
import io.mockk.mockk
|
||||
import io.mockk.verify
|
||||
import org.junit.jupiter.api.Test
|
||||
import kotlin.reflect.full.createInstance
|
||||
|
||||
/**
|
||||
* Mock object based tests for ListableBeanFactory Kotlin extensions
|
||||
@@ -79,12 +77,10 @@ class ListableBeanFactoryExtensionsTests {
|
||||
verify { lbf.getBeansWithAnnotation(Bar::class.java) }
|
||||
}
|
||||
|
||||
@Suppress("UNUSED_VARIABLE")
|
||||
@Test
|
||||
fun `findAnnotationOnBean with String and reified type parameters`() {
|
||||
val name = "bar"
|
||||
every { lbf.findAnnotationOnBean(name, Bar::class.java) } returns Bar::class.createInstance()
|
||||
val annotation: Bar? = lbf.findAnnotationOnBean(name)
|
||||
lbf.findAnnotationOnBean<Bar>(name)
|
||||
verify { lbf.findAnnotationOnBean(name, Bar::class.java) }
|
||||
}
|
||||
|
||||
|
||||
+19
-15
@@ -18,7 +18,6 @@ package org.springframework.scheduling.support;
|
||||
|
||||
import java.time.DateTimeException;
|
||||
import java.time.temporal.ChronoField;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.time.temporal.Temporal;
|
||||
import java.time.temporal.ValueRange;
|
||||
import java.util.function.BiFunction;
|
||||
@@ -169,25 +168,22 @@ abstract class CronField {
|
||||
* day-of-month, month, day-of-week.
|
||||
*/
|
||||
protected enum Type {
|
||||
NANO(ChronoField.NANO_OF_SECOND, ChronoUnit.SECONDS),
|
||||
SECOND(ChronoField.SECOND_OF_MINUTE, ChronoUnit.MINUTES, ChronoField.NANO_OF_SECOND),
|
||||
MINUTE(ChronoField.MINUTE_OF_HOUR, ChronoUnit.HOURS, ChronoField.SECOND_OF_MINUTE, ChronoField.NANO_OF_SECOND),
|
||||
HOUR(ChronoField.HOUR_OF_DAY, ChronoUnit.DAYS, ChronoField.MINUTE_OF_HOUR, ChronoField.SECOND_OF_MINUTE, ChronoField.NANO_OF_SECOND),
|
||||
DAY_OF_MONTH(ChronoField.DAY_OF_MONTH, ChronoUnit.MONTHS, ChronoField.HOUR_OF_DAY, ChronoField.MINUTE_OF_HOUR, ChronoField.SECOND_OF_MINUTE, ChronoField.NANO_OF_SECOND),
|
||||
MONTH(ChronoField.MONTH_OF_YEAR, ChronoUnit.YEARS, ChronoField.DAY_OF_MONTH, ChronoField.HOUR_OF_DAY, ChronoField.MINUTE_OF_HOUR, ChronoField.SECOND_OF_MINUTE, ChronoField.NANO_OF_SECOND),
|
||||
DAY_OF_WEEK(ChronoField.DAY_OF_WEEK, ChronoUnit.WEEKS, ChronoField.HOUR_OF_DAY, ChronoField.MINUTE_OF_HOUR, ChronoField.SECOND_OF_MINUTE, ChronoField.NANO_OF_SECOND);
|
||||
NANO(ChronoField.NANO_OF_SECOND),
|
||||
SECOND(ChronoField.SECOND_OF_MINUTE, ChronoField.NANO_OF_SECOND),
|
||||
MINUTE(ChronoField.MINUTE_OF_HOUR, ChronoField.SECOND_OF_MINUTE, ChronoField.NANO_OF_SECOND),
|
||||
HOUR(ChronoField.HOUR_OF_DAY, ChronoField.MINUTE_OF_HOUR, ChronoField.SECOND_OF_MINUTE, ChronoField.NANO_OF_SECOND),
|
||||
DAY_OF_MONTH(ChronoField.DAY_OF_MONTH, ChronoField.HOUR_OF_DAY, ChronoField.MINUTE_OF_HOUR, ChronoField.SECOND_OF_MINUTE, ChronoField.NANO_OF_SECOND),
|
||||
MONTH(ChronoField.MONTH_OF_YEAR, ChronoField.DAY_OF_MONTH, ChronoField.HOUR_OF_DAY, ChronoField.MINUTE_OF_HOUR, ChronoField.SECOND_OF_MINUTE, ChronoField.NANO_OF_SECOND),
|
||||
DAY_OF_WEEK(ChronoField.DAY_OF_WEEK, ChronoField.HOUR_OF_DAY, ChronoField.MINUTE_OF_HOUR, ChronoField.SECOND_OF_MINUTE, ChronoField.NANO_OF_SECOND);
|
||||
|
||||
|
||||
private final ChronoField field;
|
||||
|
||||
private final ChronoUnit higherOrder;
|
||||
|
||||
private final ChronoField[] lowerOrders;
|
||||
|
||||
|
||||
Type(ChronoField field, ChronoUnit higherOrder, ChronoField... lowerOrders) {
|
||||
Type(ChronoField field, ChronoField... lowerOrders) {
|
||||
this.field = field;
|
||||
this.higherOrder = higherOrder;
|
||||
this.lowerOrders = lowerOrders;
|
||||
}
|
||||
|
||||
@@ -270,9 +266,17 @@ abstract class CronField {
|
||||
* @return the rolled forward temporal
|
||||
*/
|
||||
public <T extends Temporal & Comparable<? super T>> T rollForward(T temporal) {
|
||||
T result = this.higherOrder.addTo(temporal, 1);
|
||||
ValueRange range = result.range(this.field);
|
||||
return this.field.adjustInto(result, range.getMinimum());
|
||||
int current = get(temporal);
|
||||
ValueRange range = temporal.range(this.field);
|
||||
long amount = range.getMaximum() - current + 1;
|
||||
T result = this.field.getBaseUnit().addTo(temporal, amount);
|
||||
current = get(result);
|
||||
range = result.range(this.field);
|
||||
// adjust for daylight savings
|
||||
if (current != range.getMinimum()) {
|
||||
result = this.field.adjustInto(result, range.getMinimum());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
-279
@@ -1,279 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://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.springframework.context.annotation;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.annotation.PreDestroy;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||
import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests which verify expected <em>init</em> and <em>destroy</em> bean lifecycle
|
||||
* behavior as requested in
|
||||
* <a href="https://github.com/spring-projects/spring-framework/issues/8455" target="_blank">SPR-3775</a>.
|
||||
*
|
||||
* <p>Specifically, combinations of the following are tested:
|
||||
* <ul>
|
||||
* <li>{@link InitializingBean} & {@link DisposableBean} interfaces</li>
|
||||
* <li>Custom {@link RootBeanDefinition#getInitMethodName() init} &
|
||||
* {@link RootBeanDefinition#getDestroyMethodName() destroy} methods</li>
|
||||
* <li>JSR 250's {@link javax.annotation.PostConstruct @PostConstruct} &
|
||||
* {@link javax.annotation.PreDestroy @PreDestroy} annotations</li>
|
||||
* </ul>
|
||||
*
|
||||
* @author Sam Brannen
|
||||
* @since 2.5
|
||||
*/
|
||||
class InitDestroyMethodLifecycleTests {
|
||||
|
||||
@Test
|
||||
void initDestroyMethods() {
|
||||
Class<?> beanClass = InitDestroyBean.class;
|
||||
DefaultListableBeanFactory beanFactory = createBeanFactoryAndRegisterBean(beanClass, "afterPropertiesSet", "destroy");
|
||||
InitDestroyBean bean = beanFactory.getBean(InitDestroyBean.class);
|
||||
assertThat(bean.initMethods).as("init-methods").containsExactly("afterPropertiesSet");
|
||||
beanFactory.destroySingletons();
|
||||
assertThat(bean.destroyMethods).as("destroy-methods").containsExactly("destroy");
|
||||
}
|
||||
|
||||
@Test
|
||||
void initializingDisposableInterfaces() {
|
||||
Class<?> beanClass = CustomInitializingDisposableBean.class;
|
||||
DefaultListableBeanFactory beanFactory = createBeanFactoryAndRegisterBean(beanClass, "customInit", "customDestroy");
|
||||
CustomInitializingDisposableBean bean = beanFactory.getBean(CustomInitializingDisposableBean.class);
|
||||
assertThat(bean.initMethods).as("init-methods").containsExactly("afterPropertiesSet", "customInit");
|
||||
beanFactory.destroySingletons();
|
||||
assertThat(bean.destroyMethods).as("destroy-methods").containsExactly("destroy", "customDestroy");
|
||||
}
|
||||
|
||||
@Test
|
||||
void initializingDisposableInterfacesWithShadowedMethods() {
|
||||
Class<?> beanClass = InitializingDisposableWithShadowedMethodsBean.class;
|
||||
DefaultListableBeanFactory beanFactory = createBeanFactoryAndRegisterBean(beanClass, "afterPropertiesSet", "destroy");
|
||||
InitializingDisposableWithShadowedMethodsBean bean = beanFactory.getBean(InitializingDisposableWithShadowedMethodsBean.class);
|
||||
assertThat(bean.initMethods).as("init-methods").containsExactly("InitializingBean.afterPropertiesSet");
|
||||
beanFactory.destroySingletons();
|
||||
assertThat(bean.destroyMethods).as("destroy-methods").containsExactly("DisposableBean.destroy");
|
||||
}
|
||||
|
||||
@Test
|
||||
void jsr250Annotations() {
|
||||
Class<?> beanClass = CustomAnnotatedInitDestroyBean.class;
|
||||
DefaultListableBeanFactory beanFactory = createBeanFactoryAndRegisterBean(beanClass, "customInit", "customDestroy");
|
||||
CustomAnnotatedInitDestroyBean bean = beanFactory.getBean(CustomAnnotatedInitDestroyBean.class);
|
||||
assertThat(bean.initMethods).as("init-methods").containsExactly("postConstruct", "afterPropertiesSet", "customInit");
|
||||
beanFactory.destroySingletons();
|
||||
assertThat(bean.destroyMethods).as("destroy-methods").containsExactly("preDestroy", "destroy", "customDestroy");
|
||||
}
|
||||
|
||||
@Test
|
||||
void jsr250AnnotationsWithShadowedMethods() {
|
||||
Class<?> beanClass = CustomAnnotatedInitDestroyWithShadowedMethodsBean.class;
|
||||
DefaultListableBeanFactory beanFactory = createBeanFactoryAndRegisterBean(beanClass, "customInit", "customDestroy");
|
||||
CustomAnnotatedInitDestroyWithShadowedMethodsBean bean = beanFactory.getBean(CustomAnnotatedInitDestroyWithShadowedMethodsBean.class);
|
||||
assertThat(bean.initMethods).as("init-methods").containsExactly("@PostConstruct.afterPropertiesSet", "customInit");
|
||||
beanFactory.destroySingletons();
|
||||
assertThat(bean.destroyMethods).as("destroy-methods").containsExactly("@PreDestroy.destroy", "customDestroy");
|
||||
}
|
||||
|
||||
@Test
|
||||
void jsr250AnnotationsWithCustomPrivateInitDestroyMethods() {
|
||||
Class<?> beanClass = CustomAnnotatedPrivateInitDestroyBean.class;
|
||||
DefaultListableBeanFactory beanFactory = createBeanFactoryAndRegisterBean(beanClass, "customInit1", "customDestroy1");
|
||||
CustomAnnotatedPrivateInitDestroyBean bean = beanFactory.getBean(CustomAnnotatedPrivateInitDestroyBean.class);
|
||||
assertThat(bean.initMethods).as("init-methods").containsExactly("@PostConstruct.privateCustomInit1", "afterPropertiesSet");
|
||||
beanFactory.destroySingletons();
|
||||
assertThat(bean.destroyMethods).as("destroy-methods").containsExactly("@PreDestroy.privateCustomDestroy1", "destroy");
|
||||
}
|
||||
|
||||
@Test
|
||||
void jsr250AnnotationsWithCustomSameMethodNames() {
|
||||
Class<?> beanClass = CustomAnnotatedPrivateSameNameInitDestroyBean.class;
|
||||
DefaultListableBeanFactory beanFactory = createBeanFactoryAndRegisterBean(beanClass, "customInit1", "customDestroy1");
|
||||
CustomAnnotatedPrivateSameNameInitDestroyBean bean = beanFactory.getBean(CustomAnnotatedPrivateSameNameInitDestroyBean.class);
|
||||
assertThat(bean.initMethods).as("init-methods").containsExactly("@PostConstruct.privateCustomInit1", "@PostConstruct.sameNameCustomInit1", "afterPropertiesSet");
|
||||
beanFactory.destroySingletons();
|
||||
assertThat(bean.destroyMethods).as("destroy-methods").containsExactly("@PreDestroy.sameNameCustomDestroy1", "@PreDestroy.privateCustomDestroy1", "destroy");
|
||||
}
|
||||
|
||||
@Test
|
||||
void allLifecycleMechanismsAtOnce() {
|
||||
Class<?> beanClass = AllInOneBean.class;
|
||||
DefaultListableBeanFactory beanFactory = createBeanFactoryAndRegisterBean(beanClass, "afterPropertiesSet", "destroy");
|
||||
AllInOneBean bean = beanFactory.getBean(AllInOneBean.class);
|
||||
assertThat(bean.initMethods).as("init-methods").containsExactly("afterPropertiesSet");
|
||||
beanFactory.destroySingletons();
|
||||
assertThat(bean.destroyMethods).as("destroy-methods").containsExactly("destroy");
|
||||
}
|
||||
|
||||
|
||||
private static DefaultListableBeanFactory createBeanFactoryAndRegisterBean(Class<?> beanClass,
|
||||
String initMethodName, String destroyMethodName) {
|
||||
|
||||
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
|
||||
RootBeanDefinition beanDefinition = new RootBeanDefinition(beanClass);
|
||||
beanDefinition.setInitMethodName(initMethodName);
|
||||
beanDefinition.setDestroyMethodName(destroyMethodName);
|
||||
beanFactory.addBeanPostProcessor(new CommonAnnotationBeanPostProcessor());
|
||||
beanFactory.registerBeanDefinition("lifecycleTestBean", beanDefinition);
|
||||
return beanFactory;
|
||||
}
|
||||
|
||||
|
||||
static class InitDestroyBean {
|
||||
|
||||
final List<String> initMethods = new ArrayList<>();
|
||||
final List<String> destroyMethods = new ArrayList<>();
|
||||
|
||||
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
this.initMethods.add("afterPropertiesSet");
|
||||
}
|
||||
|
||||
public void destroy() throws Exception {
|
||||
this.destroyMethods.add("destroy");
|
||||
}
|
||||
}
|
||||
|
||||
static class InitializingDisposableWithShadowedMethodsBean extends InitDestroyBean implements
|
||||
InitializingBean, DisposableBean {
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
this.initMethods.add("InitializingBean.afterPropertiesSet");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() throws Exception {
|
||||
this.destroyMethods.add("DisposableBean.destroy");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static class CustomInitDestroyBean {
|
||||
|
||||
final List<String> initMethods = new ArrayList<>();
|
||||
final List<String> destroyMethods = new ArrayList<>();
|
||||
|
||||
public void customInit() throws Exception {
|
||||
this.initMethods.add("customInit");
|
||||
}
|
||||
|
||||
public void customDestroy() throws Exception {
|
||||
this.destroyMethods.add("customDestroy");
|
||||
}
|
||||
}
|
||||
|
||||
static class CustomAnnotatedPrivateInitDestroyBean extends CustomInitializingDisposableBean {
|
||||
|
||||
@PostConstruct
|
||||
private void customInit1() throws Exception {
|
||||
this.initMethods.add("@PostConstruct.privateCustomInit1");
|
||||
}
|
||||
|
||||
@PreDestroy
|
||||
private void customDestroy1() throws Exception {
|
||||
this.destroyMethods.add("@PreDestroy.privateCustomDestroy1");
|
||||
}
|
||||
}
|
||||
|
||||
static class CustomAnnotatedPrivateSameNameInitDestroyBean extends CustomAnnotatedPrivateInitDestroyBean {
|
||||
|
||||
@PostConstruct
|
||||
@SuppressWarnings("unused")
|
||||
private void customInit1() throws Exception {
|
||||
this.initMethods.add("@PostConstruct.sameNameCustomInit1");
|
||||
}
|
||||
|
||||
@PreDestroy
|
||||
@SuppressWarnings("unused")
|
||||
private void customDestroy1() throws Exception {
|
||||
this.destroyMethods.add("@PreDestroy.sameNameCustomDestroy1");
|
||||
}
|
||||
}
|
||||
|
||||
static class CustomInitializingDisposableBean extends CustomInitDestroyBean
|
||||
implements InitializingBean, DisposableBean {
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
this.initMethods.add("afterPropertiesSet");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() throws Exception {
|
||||
this.destroyMethods.add("destroy");
|
||||
}
|
||||
}
|
||||
|
||||
static class CustomAnnotatedInitDestroyBean extends CustomInitializingDisposableBean {
|
||||
|
||||
@PostConstruct
|
||||
public void postConstruct() throws Exception {
|
||||
this.initMethods.add("postConstruct");
|
||||
}
|
||||
|
||||
@PreDestroy
|
||||
public void preDestroy() throws Exception {
|
||||
this.destroyMethods.add("preDestroy");
|
||||
}
|
||||
}
|
||||
|
||||
static class CustomAnnotatedInitDestroyWithShadowedMethodsBean extends CustomInitializingDisposableBean {
|
||||
|
||||
@PostConstruct
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
this.initMethods.add("@PostConstruct.afterPropertiesSet");
|
||||
}
|
||||
|
||||
@PreDestroy
|
||||
@Override
|
||||
public void destroy() throws Exception {
|
||||
this.destroyMethods.add("@PreDestroy.destroy");
|
||||
}
|
||||
}
|
||||
|
||||
static class AllInOneBean implements InitializingBean, DisposableBean {
|
||||
|
||||
final List<String> initMethods = new ArrayList<>();
|
||||
final List<String> destroyMethods = new ArrayList<>();
|
||||
|
||||
@PostConstruct
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
this.initMethods.add("afterPropertiesSet");
|
||||
}
|
||||
|
||||
@PreDestroy
|
||||
@Override
|
||||
public void destroy() throws Exception {
|
||||
this.destroyMethods.add("destroy");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+272
@@ -0,0 +1,272 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://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.springframework.context.annotation;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.annotation.PreDestroy;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||
import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* JUnit-3.8-based unit test which verifies expected <em>init</em> and
|
||||
* <em>destroy</em> bean lifecycle behavior as requested in <a
|
||||
* href="https://opensource.atlassian.com/projects/spring/browse/SPR-3775"
|
||||
* target="_blank">SPR-3775</a>.
|
||||
* </p>
|
||||
* <p>
|
||||
* Specifically, combinations of the following are tested:
|
||||
* </p>
|
||||
* <ul>
|
||||
* <li>{@link InitializingBean} & {@link DisposableBean} interfaces</li>
|
||||
* <li>Custom {@link RootBeanDefinition#getInitMethodName() init} &
|
||||
* {@link RootBeanDefinition#getDestroyMethodName() destroy} methods</li>
|
||||
* <li>JSR 250's {@link javax.annotation.PostConstruct @PostConstruct} &
|
||||
* {@link javax.annotation.PreDestroy @PreDestroy} annotations</li>
|
||||
* </ul>
|
||||
*
|
||||
* @author Sam Brannen
|
||||
* @since 2.5
|
||||
*/
|
||||
public class Spr3775InitDestroyLifecycleTests {
|
||||
|
||||
private static final Log logger = LogFactory.getLog(Spr3775InitDestroyLifecycleTests.class);
|
||||
|
||||
/** LIFECYCLE_TEST_BEAN. */
|
||||
private static final String LIFECYCLE_TEST_BEAN = "lifecycleTestBean";
|
||||
|
||||
|
||||
private void debugMethods(Class<?> clazz, String category, List<String> methodNames) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug(clazz.getSimpleName() + ": " + category + ": " + methodNames);
|
||||
}
|
||||
}
|
||||
|
||||
private void assertMethodOrdering(Class<?> clazz, String category, List<String> expectedMethods,
|
||||
List<String> actualMethods) {
|
||||
debugMethods(clazz, category, actualMethods);
|
||||
assertThat(ObjectUtils.nullSafeEquals(expectedMethods, actualMethods)).as("Verifying " + category + ": expected<" + expectedMethods + "> but got<" + actualMethods + ">.").isTrue();
|
||||
}
|
||||
|
||||
private DefaultListableBeanFactory createBeanFactoryAndRegisterBean(final Class<?> beanClass,
|
||||
final String initMethodName, final String destroyMethodName) {
|
||||
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
|
||||
RootBeanDefinition beanDefinition = new RootBeanDefinition(beanClass);
|
||||
beanDefinition.setInitMethodName(initMethodName);
|
||||
beanDefinition.setDestroyMethodName(destroyMethodName);
|
||||
beanFactory.addBeanPostProcessor(new CommonAnnotationBeanPostProcessor());
|
||||
beanFactory.registerBeanDefinition(LIFECYCLE_TEST_BEAN, beanDefinition);
|
||||
return beanFactory;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInitDestroyMethods() {
|
||||
final Class<?> beanClass = InitDestroyBean.class;
|
||||
final DefaultListableBeanFactory beanFactory = createBeanFactoryAndRegisterBean(beanClass,
|
||||
"afterPropertiesSet", "destroy");
|
||||
final InitDestroyBean bean = (InitDestroyBean) beanFactory.getBean(LIFECYCLE_TEST_BEAN);
|
||||
assertMethodOrdering(beanClass, "init-methods", Arrays.asList("afterPropertiesSet"), bean.initMethods);
|
||||
beanFactory.destroySingletons();
|
||||
assertMethodOrdering(beanClass, "destroy-methods", Arrays.asList("destroy"), bean.destroyMethods);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInitializingDisposableInterfaces() {
|
||||
final Class<?> beanClass = CustomInitializingDisposableBean.class;
|
||||
final DefaultListableBeanFactory beanFactory = createBeanFactoryAndRegisterBean(beanClass, "customInit",
|
||||
"customDestroy");
|
||||
final CustomInitializingDisposableBean bean = (CustomInitializingDisposableBean) beanFactory.getBean(LIFECYCLE_TEST_BEAN);
|
||||
assertMethodOrdering(beanClass, "init-methods", Arrays.asList("afterPropertiesSet", "customInit"),
|
||||
bean.initMethods);
|
||||
beanFactory.destroySingletons();
|
||||
assertMethodOrdering(beanClass, "destroy-methods", Arrays.asList("destroy", "customDestroy"),
|
||||
bean.destroyMethods);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInitializingDisposableInterfacesWithShadowedMethods() {
|
||||
final Class<?> beanClass = InitializingDisposableWithShadowedMethodsBean.class;
|
||||
final DefaultListableBeanFactory beanFactory = createBeanFactoryAndRegisterBean(beanClass,
|
||||
"afterPropertiesSet", "destroy");
|
||||
final InitializingDisposableWithShadowedMethodsBean bean = (InitializingDisposableWithShadowedMethodsBean) beanFactory.getBean(LIFECYCLE_TEST_BEAN);
|
||||
assertMethodOrdering(beanClass, "init-methods", Arrays.asList("InitializingBean.afterPropertiesSet"),
|
||||
bean.initMethods);
|
||||
beanFactory.destroySingletons();
|
||||
assertMethodOrdering(beanClass, "destroy-methods", Arrays.asList("DisposableBean.destroy"), bean.destroyMethods);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testJsr250Annotations() {
|
||||
final Class<?> beanClass = CustomAnnotatedInitDestroyBean.class;
|
||||
final DefaultListableBeanFactory beanFactory = createBeanFactoryAndRegisterBean(beanClass, "customInit",
|
||||
"customDestroy");
|
||||
final CustomAnnotatedInitDestroyBean bean = (CustomAnnotatedInitDestroyBean) beanFactory.getBean(LIFECYCLE_TEST_BEAN);
|
||||
assertMethodOrdering(beanClass, "init-methods", Arrays.asList("postConstruct", "afterPropertiesSet",
|
||||
"customInit"), bean.initMethods);
|
||||
beanFactory.destroySingletons();
|
||||
assertMethodOrdering(beanClass, "destroy-methods", Arrays.asList("preDestroy", "destroy", "customDestroy"),
|
||||
bean.destroyMethods);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testJsr250AnnotationsWithShadowedMethods() {
|
||||
final Class<?> beanClass = CustomAnnotatedInitDestroyWithShadowedMethodsBean.class;
|
||||
final DefaultListableBeanFactory beanFactory = createBeanFactoryAndRegisterBean(beanClass, "customInit",
|
||||
"customDestroy");
|
||||
final CustomAnnotatedInitDestroyWithShadowedMethodsBean bean = (CustomAnnotatedInitDestroyWithShadowedMethodsBean) beanFactory.getBean(LIFECYCLE_TEST_BEAN);
|
||||
assertMethodOrdering(beanClass, "init-methods",
|
||||
Arrays.asList("@PostConstruct.afterPropertiesSet", "customInit"), bean.initMethods);
|
||||
beanFactory.destroySingletons();
|
||||
assertMethodOrdering(beanClass, "destroy-methods", Arrays.asList("@PreDestroy.destroy", "customDestroy"),
|
||||
bean.destroyMethods);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAllLifecycleMechanismsAtOnce() {
|
||||
final Class<?> beanClass = AllInOneBean.class;
|
||||
final DefaultListableBeanFactory beanFactory = createBeanFactoryAndRegisterBean(beanClass,
|
||||
"afterPropertiesSet", "destroy");
|
||||
final AllInOneBean bean = (AllInOneBean) beanFactory.getBean(LIFECYCLE_TEST_BEAN);
|
||||
assertMethodOrdering(beanClass, "init-methods", Arrays.asList("afterPropertiesSet"), bean.initMethods);
|
||||
beanFactory.destroySingletons();
|
||||
assertMethodOrdering(beanClass, "destroy-methods", Arrays.asList("destroy"), bean.destroyMethods);
|
||||
}
|
||||
|
||||
|
||||
public static class InitDestroyBean {
|
||||
|
||||
final List<String> initMethods = new ArrayList<>();
|
||||
final List<String> destroyMethods = new ArrayList<>();
|
||||
|
||||
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
this.initMethods.add("afterPropertiesSet");
|
||||
}
|
||||
|
||||
public void destroy() throws Exception {
|
||||
this.destroyMethods.add("destroy");
|
||||
}
|
||||
}
|
||||
|
||||
public static class InitializingDisposableWithShadowedMethodsBean extends InitDestroyBean implements
|
||||
InitializingBean, DisposableBean {
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
this.initMethods.add("InitializingBean.afterPropertiesSet");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() throws Exception {
|
||||
this.destroyMethods.add("DisposableBean.destroy");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static class CustomInitDestroyBean {
|
||||
|
||||
final List<String> initMethods = new ArrayList<>();
|
||||
final List<String> destroyMethods = new ArrayList<>();
|
||||
|
||||
public void customInit() throws Exception {
|
||||
this.initMethods.add("customInit");
|
||||
}
|
||||
|
||||
public void customDestroy() throws Exception {
|
||||
this.destroyMethods.add("customDestroy");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static class CustomInitializingDisposableBean extends CustomInitDestroyBean
|
||||
implements InitializingBean, DisposableBean {
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
this.initMethods.add("afterPropertiesSet");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() throws Exception {
|
||||
this.destroyMethods.add("destroy");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static class CustomAnnotatedInitDestroyBean extends CustomInitializingDisposableBean {
|
||||
|
||||
@PostConstruct
|
||||
public void postConstruct() throws Exception {
|
||||
this.initMethods.add("postConstruct");
|
||||
}
|
||||
|
||||
@PreDestroy
|
||||
public void preDestroy() throws Exception {
|
||||
this.destroyMethods.add("preDestroy");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static class CustomAnnotatedInitDestroyWithShadowedMethodsBean extends CustomInitializingDisposableBean {
|
||||
|
||||
@PostConstruct
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
this.initMethods.add("@PostConstruct.afterPropertiesSet");
|
||||
}
|
||||
|
||||
@PreDestroy
|
||||
@Override
|
||||
public void destroy() throws Exception {
|
||||
this.destroyMethods.add("@PreDestroy.destroy");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static class AllInOneBean implements InitializingBean, DisposableBean {
|
||||
|
||||
final List<String> initMethods = new ArrayList<>();
|
||||
final List<String> destroyMethods = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
@PostConstruct
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
this.initMethods.add("afterPropertiesSet");
|
||||
}
|
||||
|
||||
@Override
|
||||
@PreDestroy
|
||||
public void destroy() throws Exception {
|
||||
this.destroyMethods.add("destroy");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
-8
@@ -1344,14 +1344,6 @@ class CronExpressionTests {
|
||||
actual = cronExpression.next(last);
|
||||
assertThat(actual).isNotNull();
|
||||
assertThat(actual).isEqualTo(expected);
|
||||
|
||||
cronExpression = CronExpression.parse("0 5 0 * * *");
|
||||
|
||||
last = ZonedDateTime.parse("2019-10-27T01:05+02:00[Europe/Amsterdam]");
|
||||
expected = ZonedDateTime.parse("2019-10-28T00:05+01:00[Europe/Amsterdam]");
|
||||
actual = cronExpression.next(last);
|
||||
assertThat(actual).isNotNull();
|
||||
assertThat(actual).isEqualTo(expected);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -76,8 +76,7 @@ jar {
|
||||
dependsOn cglibRepackJar
|
||||
from(zipTree(cglibRepackJar.archivePath)) {
|
||||
include "org/springframework/cglib/**"
|
||||
exclude "org/springframework/cglib/beans/BeanMap.class"
|
||||
exclude "org/springframework/cglib/beans/BeanMap\$*.class"
|
||||
exclude "org/springframework/cglib/beans/BeanMap*.class"
|
||||
exclude "org/springframework/cglib/core/AbstractClassGenerator*.class"
|
||||
exclude "org/springframework/cglib/core/AsmApi*.class"
|
||||
exclude "org/springframework/cglib/core/KeyFactory.class"
|
||||
|
||||
+45
-56
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -85,7 +85,7 @@ import org.springframework.util.Assert;
|
||||
* </tr>
|
||||
* </table>
|
||||
*
|
||||
* <p>{@code MergedAnnotations} can be obtained {@linkplain #from(AnnotatedElement)
|
||||
* <p>{@link MergedAnnotations} can be obtained {@linkplain #from(AnnotatedElement)
|
||||
* from} any Java {@link AnnotatedElement}. They may also be used for sources that
|
||||
* don't use reflection (such as those that directly parse bytecode).
|
||||
*
|
||||
@@ -94,7 +94,7 @@ import org.springframework.util.Assert;
|
||||
* example, {@link SearchStrategy#TYPE_HIERARCHY} will search both superclasses and
|
||||
* implemented interfaces.
|
||||
*
|
||||
* <p>From a {@code MergedAnnotations} instance you can either
|
||||
* <p>From a {@link MergedAnnotations} instance you can either
|
||||
* {@linkplain #get(String) get} a single annotation, or {@linkplain #stream()
|
||||
* stream all annotations} or just those that match {@linkplain #stream(String)
|
||||
* a specific type}. You can also quickly tell if an annotation
|
||||
@@ -138,7 +138,7 @@ import org.springframework.util.Assert;
|
||||
public interface MergedAnnotations extends Iterable<MergedAnnotation<Annotation>> {
|
||||
|
||||
/**
|
||||
* Determine if the specified annotation type is either directly present or
|
||||
* Determine if the specified annotation is either directly present or
|
||||
* meta-present.
|
||||
* <p>Equivalent to calling {@code get(annotationType).isPresent()}.
|
||||
* @param annotationType the annotation type to check
|
||||
@@ -147,7 +147,7 @@ public interface MergedAnnotations extends Iterable<MergedAnnotation<Annotation>
|
||||
<A extends Annotation> boolean isPresent(Class<A> annotationType);
|
||||
|
||||
/**
|
||||
* Determine if the specified annotation type is either directly present or
|
||||
* Determine if the specified annotation is either directly present or
|
||||
* meta-present.
|
||||
* <p>Equivalent to calling {@code get(annotationType).isPresent()}.
|
||||
* @param annotationType the fully qualified class name of the annotation type
|
||||
@@ -157,7 +157,7 @@ public interface MergedAnnotations extends Iterable<MergedAnnotation<Annotation>
|
||||
boolean isPresent(String annotationType);
|
||||
|
||||
/**
|
||||
* Determine if the specified annotation type is directly present.
|
||||
* Determine if the specified annotation is directly present.
|
||||
* <p>Equivalent to calling {@code get(annotationType).isDirectlyPresent()}.
|
||||
* @param annotationType the annotation type to check
|
||||
* @return {@code true} if the annotation is directly present
|
||||
@@ -165,7 +165,7 @@ public interface MergedAnnotations extends Iterable<MergedAnnotation<Annotation>
|
||||
<A extends Annotation> boolean isDirectlyPresent(Class<A> annotationType);
|
||||
|
||||
/**
|
||||
* Determine if the specified annotation type is directly present.
|
||||
* Determine if the specified annotation is directly present.
|
||||
* <p>Equivalent to calling {@code get(annotationType).isDirectlyPresent()}.
|
||||
* @param annotationType the fully qualified class name of the annotation type
|
||||
* to check
|
||||
@@ -256,8 +256,8 @@ public interface MergedAnnotations extends Iterable<MergedAnnotation<Annotation>
|
||||
|
||||
/**
|
||||
* Stream all annotations and meta-annotations that match the specified
|
||||
* type.
|
||||
* <p>The resulting stream follows the same ordering rules as {@link #stream()}.
|
||||
* type. The resulting stream follows the same ordering rules as
|
||||
* {@link #stream()}.
|
||||
* @param annotationType the annotation type to match
|
||||
* @return a stream of matching annotations
|
||||
*/
|
||||
@@ -265,8 +265,8 @@ public interface MergedAnnotations extends Iterable<MergedAnnotation<Annotation>
|
||||
|
||||
/**
|
||||
* Stream all annotations and meta-annotations that match the specified
|
||||
* type.
|
||||
* <p>The resulting stream follows the same ordering rules as {@link #stream()}.
|
||||
* type. The resulting stream follows the same ordering rules as
|
||||
* {@link #stream()}.
|
||||
* @param annotationType the fully qualified class name of the annotation type
|
||||
* to match
|
||||
* @return a stream of matching annotations
|
||||
@@ -275,7 +275,7 @@ public interface MergedAnnotations extends Iterable<MergedAnnotation<Annotation>
|
||||
|
||||
/**
|
||||
* Stream all annotations and meta-annotations contained in this collection.
|
||||
* <p>The resulting stream is ordered first by the
|
||||
* The resulting stream is ordered first by the
|
||||
* {@linkplain MergedAnnotation#getAggregateIndex() aggregate index} and then
|
||||
* by the annotation distance (with the closest annotations first). This ordering
|
||||
* means that, for most use-cases, the most suitable annotations appear
|
||||
@@ -287,13 +287,13 @@ public interface MergedAnnotations extends Iterable<MergedAnnotation<Annotation>
|
||||
|
||||
/**
|
||||
* Create a new {@link MergedAnnotations} instance containing all
|
||||
* annotations and meta-annotations from the specified element.
|
||||
* <p>The resulting instance will not include any inherited annotations. If
|
||||
* you want to include those as well you should use
|
||||
* annotations and meta-annotations from the specified element. The
|
||||
* resulting instance will not include any inherited annotations. If you
|
||||
* want to include those as well you should use
|
||||
* {@link #from(AnnotatedElement, SearchStrategy)} with an appropriate
|
||||
* {@link SearchStrategy}.
|
||||
* @param element the source element
|
||||
* @return a {@code MergedAnnotations} instance containing the element's
|
||||
* @return a {@link MergedAnnotations} instance containing the element's
|
||||
* annotations
|
||||
*/
|
||||
static MergedAnnotations from(AnnotatedElement element) {
|
||||
@@ -306,7 +306,7 @@ public interface MergedAnnotations extends Iterable<MergedAnnotation<Annotation>
|
||||
* depending on the {@link SearchStrategy}, related inherited elements.
|
||||
* @param element the source element
|
||||
* @param searchStrategy the search strategy to use
|
||||
* @return a {@code MergedAnnotations} instance containing the merged
|
||||
* @return a {@link MergedAnnotations} instance containing the merged
|
||||
* element annotations
|
||||
*/
|
||||
static MergedAnnotations from(AnnotatedElement element, SearchStrategy searchStrategy) {
|
||||
@@ -321,7 +321,7 @@ public interface MergedAnnotations extends Iterable<MergedAnnotation<Annotation>
|
||||
* @param searchStrategy the search strategy to use
|
||||
* @param repeatableContainers the repeatable containers that may be used by
|
||||
* the element annotations or the meta-annotations
|
||||
* @return a {@code MergedAnnotations} instance containing the merged
|
||||
* @return a {@link MergedAnnotations} instance containing the merged
|
||||
* element annotations
|
||||
*/
|
||||
static MergedAnnotations from(AnnotatedElement element, SearchStrategy searchStrategy,
|
||||
@@ -340,7 +340,7 @@ public interface MergedAnnotations extends Iterable<MergedAnnotation<Annotation>
|
||||
* the element annotations or the meta-annotations
|
||||
* @param annotationFilter an annotation filter used to restrict the
|
||||
* annotations considered
|
||||
* @return a {@code MergedAnnotations} instance containing the merged
|
||||
* @return a {@link MergedAnnotations} instance containing the merged
|
||||
* annotations for the supplied element
|
||||
*/
|
||||
static MergedAnnotations from(AnnotatedElement element, SearchStrategy searchStrategy,
|
||||
@@ -355,7 +355,7 @@ public interface MergedAnnotations extends Iterable<MergedAnnotation<Annotation>
|
||||
* Create a new {@link MergedAnnotations} instance from the specified
|
||||
* annotations.
|
||||
* @param annotations the annotations to include
|
||||
* @return a {@code MergedAnnotations} instance containing the annotations
|
||||
* @return a {@link MergedAnnotations} instance containing the annotations
|
||||
* @see #from(Object, Annotation...)
|
||||
*/
|
||||
static MergedAnnotations from(Annotation... annotations) {
|
||||
@@ -369,7 +369,7 @@ public interface MergedAnnotations extends Iterable<MergedAnnotation<Annotation>
|
||||
* for information and logging. It does not need to <em>actually</em>
|
||||
* contain the specified annotations, and it will not be searched.
|
||||
* @param annotations the annotations to include
|
||||
* @return a {@code MergedAnnotations} instance containing the annotations
|
||||
* @return a {@link MergedAnnotations} instance containing the annotations
|
||||
* @see #from(Annotation...)
|
||||
* @see #from(AnnotatedElement)
|
||||
*/
|
||||
@@ -386,7 +386,7 @@ public interface MergedAnnotations extends Iterable<MergedAnnotation<Annotation>
|
||||
* @param annotations the annotations to include
|
||||
* @param repeatableContainers the repeatable containers that may be used by
|
||||
* meta-annotations
|
||||
* @return a {@code MergedAnnotations} instance containing the annotations
|
||||
* @return a {@link MergedAnnotations} instance containing the annotations
|
||||
*/
|
||||
static MergedAnnotations from(Object source, Annotation[] annotations, RepeatableContainers repeatableContainers) {
|
||||
return from(source, annotations, repeatableContainers, AnnotationFilter.PLAIN);
|
||||
@@ -403,7 +403,7 @@ public interface MergedAnnotations extends Iterable<MergedAnnotation<Annotation>
|
||||
* meta-annotations
|
||||
* @param annotationFilter an annotation filter used to restrict the
|
||||
* annotations considered
|
||||
* @return a {@code MergedAnnotations} instance containing the annotations
|
||||
* @return a {@link MergedAnnotations} instance containing the annotations
|
||||
*/
|
||||
static MergedAnnotations from(Object source, Annotation[] annotations,
|
||||
RepeatableContainers repeatableContainers, AnnotationFilter annotationFilter) {
|
||||
@@ -416,16 +416,16 @@ public interface MergedAnnotations extends Iterable<MergedAnnotation<Annotation>
|
||||
/**
|
||||
* Create a new {@link MergedAnnotations} instance from the specified
|
||||
* collection of directly present annotations. This method allows a
|
||||
* {@code MergedAnnotations} instance to be created from annotations that
|
||||
* {@link MergedAnnotations} instance to be created from annotations that
|
||||
* are not necessarily loaded using reflection. The provided annotations
|
||||
* must all be {@link MergedAnnotation#isDirectlyPresent() directly present}
|
||||
* and must have an {@link MergedAnnotation#getAggregateIndex() aggregate
|
||||
* index} of {@code 0}.
|
||||
* <p>The resulting {@code MergedAnnotations} instance will contain both the
|
||||
* specified annotations and any meta-annotations that can be read using
|
||||
* <p>The resulting {@link MergedAnnotations} instance will contain both the
|
||||
* specified annotations, and any meta-annotations that can be read using
|
||||
* reflection.
|
||||
* @param annotations the annotations to include
|
||||
* @return a {@code MergedAnnotations} instance containing the annotations
|
||||
* @return a {@link MergedAnnotations} instance containing the annotations
|
||||
* @see MergedAnnotation#of(ClassLoader, Object, Class, java.util.Map)
|
||||
*/
|
||||
static MergedAnnotations of(Collection<MergedAnnotation<?>> annotations) {
|
||||
@@ -435,8 +435,7 @@ public interface MergedAnnotations extends Iterable<MergedAnnotation<Annotation>
|
||||
|
||||
/**
|
||||
* Search strategies supported by
|
||||
* {@link MergedAnnotations#from(AnnotatedElement, SearchStrategy)} and
|
||||
* variants of that method.
|
||||
* {@link MergedAnnotations#from(AnnotatedElement, SearchStrategy)}.
|
||||
*
|
||||
* <p>Each strategy creates a different set of aggregates that will be
|
||||
* combined to create the final {@link MergedAnnotations}.
|
||||
@@ -452,49 +451,39 @@ public interface MergedAnnotations extends Iterable<MergedAnnotation<Annotation>
|
||||
|
||||
/**
|
||||
* Find all directly declared annotations as well as any
|
||||
* {@link Inherited @Inherited} superclass annotations.
|
||||
* <p>This strategy is only really useful when used with {@link Class}
|
||||
* types since the {@link Inherited @Inherited} annotation is ignored for
|
||||
* all other {@linkplain AnnotatedElement annotated elements}.
|
||||
* <p>This strategy does not search implemented interfaces.
|
||||
* {@link Inherited @Inherited} superclass annotations. This strategy
|
||||
* is only really useful when used with {@link Class} types since the
|
||||
* {@link Inherited @Inherited} annotation is ignored for all other
|
||||
* {@linkplain AnnotatedElement annotated elements}. This strategy does
|
||||
* not search implemented interfaces.
|
||||
*/
|
||||
INHERITED_ANNOTATIONS,
|
||||
|
||||
/**
|
||||
* Find all directly declared and superclass annotations.
|
||||
* <p>This strategy is similar to {@link #INHERITED_ANNOTATIONS} except
|
||||
* the annotations do not need to be meta-annotated with
|
||||
* {@link Inherited @Inherited}.
|
||||
* <p>This strategy does not search implemented interfaces.
|
||||
* Find all directly declared and superclass annotations. This strategy
|
||||
* is similar to {@link #INHERITED_ANNOTATIONS} except the annotations
|
||||
* do not need to be meta-annotated with {@link Inherited @Inherited}.
|
||||
* This strategy does not search implemented interfaces.
|
||||
*/
|
||||
SUPERCLASS,
|
||||
|
||||
/**
|
||||
* Perform a full search of the entire type hierarchy, including
|
||||
* superclasses and implemented interfaces.
|
||||
* <p>Superclass annotations do not need to be meta-annotated with
|
||||
* {@link Inherited @Inherited}.
|
||||
* superclasses and implemented interfaces. Superclass annotations do
|
||||
* not need to be meta-annotated with {@link Inherited @Inherited}.
|
||||
*/
|
||||
TYPE_HIERARCHY,
|
||||
|
||||
/**
|
||||
* Perform a full search of the entire type hierarchy on the source
|
||||
* <em>and</em> any enclosing classes.
|
||||
* <p>This strategy is similar to {@link #TYPE_HIERARCHY} except that
|
||||
* {@linkplain Class#getEnclosingClass() enclosing classes} are also
|
||||
* searched.
|
||||
* <p>Superclass and enclosing class annotations do not need to be
|
||||
* meta-annotated with {@link Inherited @Inherited}.
|
||||
* <p>When searching a {@link Method} source, this strategy is identical
|
||||
* to {@link #TYPE_HIERARCHY}.
|
||||
* <p><strong>WARNING:</strong> This strategy searches recursively for
|
||||
* annotations on the enclosing class for any source type, regardless
|
||||
* whether the source type is an <em>inner class</em>, a {@code static}
|
||||
* nested class, or a nested interface. Thus, it may find more annotations
|
||||
* than you would expect.
|
||||
* <em>and</em> any enclosing classes. This strategy is similar to
|
||||
* {@link #TYPE_HIERARCHY} except that {@linkplain Class#getEnclosingClass()
|
||||
* enclosing classes} are also searched. Superclass annotations do not
|
||||
* need to be meta-annotated with {@link Inherited @Inherited}. When
|
||||
* searching a {@link Method} source, this strategy is identical to
|
||||
* {@link #TYPE_HIERARCHY}.
|
||||
*/
|
||||
TYPE_HIERARCHY_AND_ENCLOSING_CLASSES
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -34,9 +34,9 @@ package org.springframework.core.env;
|
||||
* <p><em>Properties</em> play an important role in almost all applications, and may
|
||||
* originate from a variety of sources: properties files, JVM system properties, system
|
||||
* environment variables, JNDI, servlet context parameters, ad-hoc Properties objects,
|
||||
* Maps, and so on. The role of the {@code Environment} object with relation to properties
|
||||
* is to provide the user with a convenient service interface for configuring property
|
||||
* sources and resolving properties from them.
|
||||
* Maps, and so on. The role of the environment object with relation to properties is to
|
||||
* provide the user with a convenient service interface for configuring property sources
|
||||
* and resolving properties from them.
|
||||
*
|
||||
* <p>Beans managed within an {@code ApplicationContext} may register to be {@link
|
||||
* org.springframework.context.EnvironmentAware EnvironmentAware} or {@code @Inject} the
|
||||
@@ -50,7 +50,7 @@ package org.springframework.core.env;
|
||||
* as of Spring 3.1 is registered by default when using
|
||||
* {@code <context:property-placeholder/>}.
|
||||
*
|
||||
* <p>Configuration of the {@code Environment} object must be done through the
|
||||
* <p>Configuration of the environment object must be done through the
|
||||
* {@code ConfigurableEnvironment} interface, returned from all
|
||||
* {@code AbstractApplicationContext} subclass {@code getEnvironment()} methods. See
|
||||
* {@link ConfigurableEnvironment} Javadoc for usage examples demonstrating manipulation
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -65,8 +65,6 @@ public abstract class StringUtils {
|
||||
|
||||
private static final String FOLDER_SEPARATOR = "/";
|
||||
|
||||
private static final char FOLDER_SEPARATOR_CHAR = '/';
|
||||
|
||||
private static final String WINDOWS_FOLDER_SEPARATOR = "\\";
|
||||
|
||||
private static final String TOP_PATH = "..";
|
||||
@@ -583,7 +581,7 @@ public abstract class StringUtils {
|
||||
return null;
|
||||
}
|
||||
|
||||
int separatorIndex = path.lastIndexOf(FOLDER_SEPARATOR_CHAR);
|
||||
int separatorIndex = path.lastIndexOf(FOLDER_SEPARATOR);
|
||||
return (separatorIndex != -1 ? path.substring(separatorIndex + 1) : path);
|
||||
}
|
||||
|
||||
@@ -604,7 +602,7 @@ public abstract class StringUtils {
|
||||
return null;
|
||||
}
|
||||
|
||||
int folderIndex = path.lastIndexOf(FOLDER_SEPARATOR_CHAR);
|
||||
int folderIndex = path.lastIndexOf(FOLDER_SEPARATOR);
|
||||
if (folderIndex > extIndex) {
|
||||
return null;
|
||||
}
|
||||
@@ -624,7 +622,7 @@ public abstract class StringUtils {
|
||||
return path;
|
||||
}
|
||||
|
||||
int folderIndex = path.lastIndexOf(FOLDER_SEPARATOR_CHAR);
|
||||
int folderIndex = path.lastIndexOf(FOLDER_SEPARATOR);
|
||||
if (folderIndex > extIndex) {
|
||||
return path;
|
||||
}
|
||||
@@ -641,11 +639,11 @@ public abstract class StringUtils {
|
||||
* @return the full file path that results from applying the relative path
|
||||
*/
|
||||
public static String applyRelativePath(String path, String relativePath) {
|
||||
int separatorIndex = path.lastIndexOf(FOLDER_SEPARATOR_CHAR);
|
||||
int separatorIndex = path.lastIndexOf(FOLDER_SEPARATOR);
|
||||
if (separatorIndex != -1) {
|
||||
String newPath = path.substring(0, separatorIndex);
|
||||
if (!relativePath.startsWith(FOLDER_SEPARATOR)) {
|
||||
newPath += FOLDER_SEPARATOR_CHAR;
|
||||
newPath += FOLDER_SEPARATOR;
|
||||
}
|
||||
return newPath + relativePath;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -35,7 +35,7 @@ import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException
|
||||
class DataBufferTests extends AbstractDataBufferAllocatingTests {
|
||||
|
||||
@ParameterizedDataBufferAllocatingTest
|
||||
void byteCountsAndPositions(DataBufferFactory bufferFactory) {
|
||||
void byteCountsAndPositions(String displayName, DataBufferFactory bufferFactory) {
|
||||
super.bufferFactory = bufferFactory;
|
||||
|
||||
DataBuffer buffer = createDataBuffer(2);
|
||||
@@ -78,7 +78,7 @@ class DataBufferTests extends AbstractDataBufferAllocatingTests {
|
||||
}
|
||||
|
||||
@ParameterizedDataBufferAllocatingTest
|
||||
void readPositionSmallerThanZero(DataBufferFactory bufferFactory) {
|
||||
void readPositionSmallerThanZero(String displayName, DataBufferFactory bufferFactory) {
|
||||
super.bufferFactory = bufferFactory;
|
||||
|
||||
DataBuffer buffer = createDataBuffer(1);
|
||||
@@ -92,7 +92,7 @@ class DataBufferTests extends AbstractDataBufferAllocatingTests {
|
||||
}
|
||||
|
||||
@ParameterizedDataBufferAllocatingTest
|
||||
void readPositionGreaterThanWritePosition(DataBufferFactory bufferFactory) {
|
||||
void readPositionGreaterThanWritePosition(String displayName, DataBufferFactory bufferFactory) {
|
||||
super.bufferFactory = bufferFactory;
|
||||
|
||||
DataBuffer buffer = createDataBuffer(1);
|
||||
@@ -106,7 +106,7 @@ class DataBufferTests extends AbstractDataBufferAllocatingTests {
|
||||
}
|
||||
|
||||
@ParameterizedDataBufferAllocatingTest
|
||||
void writePositionSmallerThanReadPosition(DataBufferFactory bufferFactory) {
|
||||
void writePositionSmallerThanReadPosition(String displayName, DataBufferFactory bufferFactory) {
|
||||
super.bufferFactory = bufferFactory;
|
||||
|
||||
DataBuffer buffer = createDataBuffer(2);
|
||||
@@ -122,7 +122,7 @@ class DataBufferTests extends AbstractDataBufferAllocatingTests {
|
||||
}
|
||||
|
||||
@ParameterizedDataBufferAllocatingTest
|
||||
void writePositionGreaterThanCapacity(DataBufferFactory bufferFactory) {
|
||||
void writePositionGreaterThanCapacity(String displayName, DataBufferFactory bufferFactory) {
|
||||
super.bufferFactory = bufferFactory;
|
||||
|
||||
DataBuffer buffer = createDataBuffer(1);
|
||||
@@ -136,7 +136,7 @@ class DataBufferTests extends AbstractDataBufferAllocatingTests {
|
||||
}
|
||||
|
||||
@ParameterizedDataBufferAllocatingTest
|
||||
void writeAndRead(DataBufferFactory bufferFactory) {
|
||||
void writeAndRead(String displayName, DataBufferFactory bufferFactory) {
|
||||
super.bufferFactory = bufferFactory;
|
||||
|
||||
DataBuffer buffer = createDataBuffer(5);
|
||||
@@ -157,7 +157,7 @@ class DataBufferTests extends AbstractDataBufferAllocatingTests {
|
||||
}
|
||||
|
||||
@ParameterizedDataBufferAllocatingTest
|
||||
void writeNullString(DataBufferFactory bufferFactory) {
|
||||
void writeNullString(String displayName, DataBufferFactory bufferFactory) {
|
||||
super.bufferFactory = bufferFactory;
|
||||
|
||||
DataBuffer buffer = createDataBuffer(1);
|
||||
@@ -171,7 +171,7 @@ class DataBufferTests extends AbstractDataBufferAllocatingTests {
|
||||
}
|
||||
|
||||
@ParameterizedDataBufferAllocatingTest
|
||||
void writeNullCharset(DataBufferFactory bufferFactory) {
|
||||
void writeNullCharset(String displayName, DataBufferFactory bufferFactory) {
|
||||
super.bufferFactory = bufferFactory;
|
||||
|
||||
DataBuffer buffer = createDataBuffer(1);
|
||||
@@ -185,7 +185,7 @@ class DataBufferTests extends AbstractDataBufferAllocatingTests {
|
||||
}
|
||||
|
||||
@ParameterizedDataBufferAllocatingTest
|
||||
void writeEmptyString(DataBufferFactory bufferFactory) {
|
||||
void writeEmptyString(String displayName, DataBufferFactory bufferFactory) {
|
||||
super.bufferFactory = bufferFactory;
|
||||
|
||||
DataBuffer buffer = createDataBuffer(1);
|
||||
@@ -197,7 +197,7 @@ class DataBufferTests extends AbstractDataBufferAllocatingTests {
|
||||
}
|
||||
|
||||
@ParameterizedDataBufferAllocatingTest
|
||||
void writeUtf8String(DataBufferFactory bufferFactory) {
|
||||
void writeUtf8String(String displayName, DataBufferFactory bufferFactory) {
|
||||
super.bufferFactory = bufferFactory;
|
||||
|
||||
DataBuffer buffer = createDataBuffer(6);
|
||||
@@ -211,7 +211,7 @@ class DataBufferTests extends AbstractDataBufferAllocatingTests {
|
||||
}
|
||||
|
||||
@ParameterizedDataBufferAllocatingTest
|
||||
void writeUtf8StringOutGrowsCapacity(DataBufferFactory bufferFactory) {
|
||||
void writeUtf8StringOutGrowsCapacity(String displayName, DataBufferFactory bufferFactory) {
|
||||
super.bufferFactory = bufferFactory;
|
||||
|
||||
DataBuffer buffer = createDataBuffer(5);
|
||||
@@ -225,7 +225,7 @@ class DataBufferTests extends AbstractDataBufferAllocatingTests {
|
||||
}
|
||||
|
||||
@ParameterizedDataBufferAllocatingTest
|
||||
void writeIsoString(DataBufferFactory bufferFactory) {
|
||||
void writeIsoString(String displayName, DataBufferFactory bufferFactory) {
|
||||
super.bufferFactory = bufferFactory;
|
||||
|
||||
DataBuffer buffer = createDataBuffer(3);
|
||||
@@ -239,7 +239,7 @@ class DataBufferTests extends AbstractDataBufferAllocatingTests {
|
||||
}
|
||||
|
||||
@ParameterizedDataBufferAllocatingTest
|
||||
void writeMultipleUtf8String(DataBufferFactory bufferFactory) {
|
||||
void writeMultipleUtf8String(String displayName, DataBufferFactory bufferFactory) {
|
||||
super.bufferFactory = bufferFactory;
|
||||
|
||||
DataBuffer buffer = createDataBuffer(1);
|
||||
@@ -261,7 +261,7 @@ class DataBufferTests extends AbstractDataBufferAllocatingTests {
|
||||
}
|
||||
|
||||
@ParameterizedDataBufferAllocatingTest
|
||||
void toStringNullCharset(DataBufferFactory bufferFactory) {
|
||||
void toStringNullCharset(String displayName, DataBufferFactory bufferFactory) {
|
||||
super.bufferFactory = bufferFactory;
|
||||
|
||||
DataBuffer buffer = createDataBuffer(1);
|
||||
@@ -275,7 +275,7 @@ class DataBufferTests extends AbstractDataBufferAllocatingTests {
|
||||
}
|
||||
|
||||
@ParameterizedDataBufferAllocatingTest
|
||||
void toStringUtf8(DataBufferFactory bufferFactory) {
|
||||
void toStringUtf8(String displayName, DataBufferFactory bufferFactory) {
|
||||
super.bufferFactory = bufferFactory;
|
||||
|
||||
String spring = "Spring";
|
||||
@@ -290,7 +290,7 @@ class DataBufferTests extends AbstractDataBufferAllocatingTests {
|
||||
}
|
||||
|
||||
@ParameterizedDataBufferAllocatingTest
|
||||
void toStringSection(DataBufferFactory bufferFactory) {
|
||||
void toStringSection(String displayName, DataBufferFactory bufferFactory) {
|
||||
super.bufferFactory = bufferFactory;
|
||||
|
||||
String spring = "Spring";
|
||||
@@ -305,7 +305,7 @@ class DataBufferTests extends AbstractDataBufferAllocatingTests {
|
||||
}
|
||||
|
||||
@ParameterizedDataBufferAllocatingTest
|
||||
void inputStream(DataBufferFactory bufferFactory) throws Exception {
|
||||
void inputStream(String displayName, DataBufferFactory bufferFactory) throws Exception {
|
||||
super.bufferFactory = bufferFactory;
|
||||
|
||||
DataBuffer buffer = createDataBuffer(4);
|
||||
@@ -339,7 +339,7 @@ class DataBufferTests extends AbstractDataBufferAllocatingTests {
|
||||
}
|
||||
|
||||
@ParameterizedDataBufferAllocatingTest
|
||||
void inputStreamReleaseOnClose(DataBufferFactory bufferFactory) throws Exception {
|
||||
void inputStreamReleaseOnClose(String displayName, DataBufferFactory bufferFactory) throws Exception {
|
||||
super.bufferFactory = bufferFactory;
|
||||
|
||||
DataBuffer buffer = createDataBuffer(3);
|
||||
@@ -357,7 +357,7 @@ class DataBufferTests extends AbstractDataBufferAllocatingTests {
|
||||
}
|
||||
|
||||
@ParameterizedDataBufferAllocatingTest
|
||||
void outputStream(DataBufferFactory bufferFactory) throws Exception {
|
||||
void outputStream(String displayName, DataBufferFactory bufferFactory) throws Exception {
|
||||
super.bufferFactory = bufferFactory;
|
||||
|
||||
DataBuffer buffer = createDataBuffer(4);
|
||||
@@ -377,7 +377,7 @@ class DataBufferTests extends AbstractDataBufferAllocatingTests {
|
||||
}
|
||||
|
||||
@ParameterizedDataBufferAllocatingTest
|
||||
void expand(DataBufferFactory bufferFactory) {
|
||||
void expand(String displayName, DataBufferFactory bufferFactory) {
|
||||
super.bufferFactory = bufferFactory;
|
||||
|
||||
DataBuffer buffer = createDataBuffer(1);
|
||||
@@ -391,7 +391,7 @@ class DataBufferTests extends AbstractDataBufferAllocatingTests {
|
||||
}
|
||||
|
||||
@ParameterizedDataBufferAllocatingTest
|
||||
void increaseCapacity(DataBufferFactory bufferFactory) {
|
||||
void increaseCapacity(String displayName, DataBufferFactory bufferFactory) {
|
||||
super.bufferFactory = bufferFactory;
|
||||
|
||||
DataBuffer buffer = createDataBuffer(1);
|
||||
@@ -404,7 +404,7 @@ class DataBufferTests extends AbstractDataBufferAllocatingTests {
|
||||
}
|
||||
|
||||
@ParameterizedDataBufferAllocatingTest
|
||||
void decreaseCapacityLowReadPosition(DataBufferFactory bufferFactory) {
|
||||
void decreaseCapacityLowReadPosition(String displayName, DataBufferFactory bufferFactory) {
|
||||
super.bufferFactory = bufferFactory;
|
||||
|
||||
DataBuffer buffer = createDataBuffer(2);
|
||||
@@ -416,7 +416,7 @@ class DataBufferTests extends AbstractDataBufferAllocatingTests {
|
||||
}
|
||||
|
||||
@ParameterizedDataBufferAllocatingTest
|
||||
void decreaseCapacityHighReadPosition(DataBufferFactory bufferFactory) {
|
||||
void decreaseCapacityHighReadPosition(String displayName, DataBufferFactory bufferFactory) {
|
||||
super.bufferFactory = bufferFactory;
|
||||
|
||||
DataBuffer buffer = createDataBuffer(2);
|
||||
@@ -429,7 +429,7 @@ class DataBufferTests extends AbstractDataBufferAllocatingTests {
|
||||
}
|
||||
|
||||
@ParameterizedDataBufferAllocatingTest
|
||||
void capacityLessThanZero(DataBufferFactory bufferFactory) {
|
||||
void capacityLessThanZero(String displayName, DataBufferFactory bufferFactory) {
|
||||
super.bufferFactory = bufferFactory;
|
||||
|
||||
DataBuffer buffer = createDataBuffer(1);
|
||||
@@ -443,7 +443,7 @@ class DataBufferTests extends AbstractDataBufferAllocatingTests {
|
||||
}
|
||||
|
||||
@ParameterizedDataBufferAllocatingTest
|
||||
void writeByteBuffer(DataBufferFactory bufferFactory) {
|
||||
void writeByteBuffer(String displayName, DataBufferFactory bufferFactory) {
|
||||
super.bufferFactory = bufferFactory;
|
||||
|
||||
DataBuffer buffer1 = createDataBuffer(1);
|
||||
@@ -472,7 +472,7 @@ class DataBufferTests extends AbstractDataBufferAllocatingTests {
|
||||
}
|
||||
|
||||
@ParameterizedDataBufferAllocatingTest
|
||||
void writeDataBuffer(DataBufferFactory bufferFactory) {
|
||||
void writeDataBuffer(String displayName, DataBufferFactory bufferFactory) {
|
||||
super.bufferFactory = bufferFactory;
|
||||
|
||||
DataBuffer buffer1 = createDataBuffer(1);
|
||||
@@ -495,7 +495,7 @@ class DataBufferTests extends AbstractDataBufferAllocatingTests {
|
||||
}
|
||||
|
||||
@ParameterizedDataBufferAllocatingTest
|
||||
void asByteBuffer(DataBufferFactory bufferFactory) {
|
||||
void asByteBuffer(String displayName, DataBufferFactory bufferFactory) {
|
||||
super.bufferFactory = bufferFactory;
|
||||
|
||||
DataBuffer buffer = createDataBuffer(4);
|
||||
@@ -516,7 +516,7 @@ class DataBufferTests extends AbstractDataBufferAllocatingTests {
|
||||
}
|
||||
|
||||
@ParameterizedDataBufferAllocatingTest
|
||||
void asByteBufferIndexLength(DataBufferFactory bufferFactory) {
|
||||
void asByteBufferIndexLength(String displayName, DataBufferFactory bufferFactory) {
|
||||
super.bufferFactory = bufferFactory;
|
||||
|
||||
DataBuffer buffer = createDataBuffer(3);
|
||||
@@ -536,7 +536,7 @@ class DataBufferTests extends AbstractDataBufferAllocatingTests {
|
||||
}
|
||||
|
||||
@ParameterizedDataBufferAllocatingTest
|
||||
void byteBufferContainsDataBufferChanges(DataBufferFactory bufferFactory) {
|
||||
void byteBufferContainsDataBufferChanges(String displayName, DataBufferFactory bufferFactory) {
|
||||
super.bufferFactory = bufferFactory;
|
||||
|
||||
DataBuffer dataBuffer = createDataBuffer(1);
|
||||
@@ -552,7 +552,7 @@ class DataBufferTests extends AbstractDataBufferAllocatingTests {
|
||||
}
|
||||
|
||||
@ParameterizedDataBufferAllocatingTest
|
||||
void dataBufferContainsByteBufferChanges(DataBufferFactory bufferFactory) {
|
||||
void dataBufferContainsByteBufferChanges(String displayName, DataBufferFactory bufferFactory) {
|
||||
super.bufferFactory = bufferFactory;
|
||||
|
||||
DataBuffer dataBuffer = createDataBuffer(1);
|
||||
@@ -568,7 +568,7 @@ class DataBufferTests extends AbstractDataBufferAllocatingTests {
|
||||
}
|
||||
|
||||
@ParameterizedDataBufferAllocatingTest
|
||||
void emptyAsByteBuffer(DataBufferFactory bufferFactory) {
|
||||
void emptyAsByteBuffer(String displayName, DataBufferFactory bufferFactory) {
|
||||
super.bufferFactory = bufferFactory;
|
||||
|
||||
DataBuffer buffer = createDataBuffer(1);
|
||||
@@ -580,7 +580,7 @@ class DataBufferTests extends AbstractDataBufferAllocatingTests {
|
||||
}
|
||||
|
||||
@ParameterizedDataBufferAllocatingTest
|
||||
void indexOf(DataBufferFactory bufferFactory) {
|
||||
void indexOf(String displayName, DataBufferFactory bufferFactory) {
|
||||
super.bufferFactory = bufferFactory;
|
||||
|
||||
DataBuffer buffer = createDataBuffer(3);
|
||||
@@ -602,7 +602,7 @@ class DataBufferTests extends AbstractDataBufferAllocatingTests {
|
||||
}
|
||||
|
||||
@ParameterizedDataBufferAllocatingTest
|
||||
void lastIndexOf(DataBufferFactory bufferFactory) {
|
||||
void lastIndexOf(String displayName, DataBufferFactory bufferFactory) {
|
||||
super.bufferFactory = bufferFactory;
|
||||
|
||||
DataBuffer buffer = createDataBuffer(3);
|
||||
@@ -633,7 +633,7 @@ class DataBufferTests extends AbstractDataBufferAllocatingTests {
|
||||
}
|
||||
|
||||
@ParameterizedDataBufferAllocatingTest
|
||||
void slice(DataBufferFactory bufferFactory) {
|
||||
void slice(String displayName, DataBufferFactory bufferFactory) {
|
||||
super.bufferFactory = bufferFactory;
|
||||
|
||||
DataBuffer buffer = createDataBuffer(3);
|
||||
@@ -662,7 +662,7 @@ class DataBufferTests extends AbstractDataBufferAllocatingTests {
|
||||
}
|
||||
|
||||
@ParameterizedDataBufferAllocatingTest
|
||||
void retainedSlice(DataBufferFactory bufferFactory) {
|
||||
void retainedSlice(String displayName, DataBufferFactory bufferFactory) {
|
||||
super.bufferFactory = bufferFactory;
|
||||
|
||||
DataBuffer buffer = createDataBuffer(3);
|
||||
@@ -691,7 +691,7 @@ class DataBufferTests extends AbstractDataBufferAllocatingTests {
|
||||
}
|
||||
|
||||
@ParameterizedDataBufferAllocatingTest
|
||||
void spr16351(DataBufferFactory bufferFactory) {
|
||||
void spr16351(String displayName, DataBufferFactory bufferFactory) {
|
||||
super.bufferFactory = bufferFactory;
|
||||
|
||||
DataBuffer buffer = createDataBuffer(6);
|
||||
@@ -711,7 +711,7 @@ class DataBufferTests extends AbstractDataBufferAllocatingTests {
|
||||
}
|
||||
|
||||
@ParameterizedDataBufferAllocatingTest
|
||||
void join(DataBufferFactory bufferFactory) {
|
||||
void join(String displayName, DataBufferFactory bufferFactory) {
|
||||
super.bufferFactory = bufferFactory;
|
||||
|
||||
DataBuffer composite = this.bufferFactory.join(Arrays.asList(stringBuffer("a"),
|
||||
@@ -726,7 +726,7 @@ class DataBufferTests extends AbstractDataBufferAllocatingTests {
|
||||
}
|
||||
|
||||
@ParameterizedDataBufferAllocatingTest
|
||||
void getByte(DataBufferFactory bufferFactory) {
|
||||
void getByte(String displayName, DataBufferFactory bufferFactory) {
|
||||
super.bufferFactory = bufferFactory;
|
||||
|
||||
DataBuffer buffer = stringBuffer("abc");
|
||||
|
||||
+46
-46
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -76,7 +76,7 @@ class DataBufferUtilsTests extends AbstractDataBufferAllocatingTests {
|
||||
|
||||
|
||||
@ParameterizedDataBufferAllocatingTest
|
||||
void readInputStream(DataBufferFactory bufferFactory) {
|
||||
void readInputStream(String displayName, DataBufferFactory bufferFactory) {
|
||||
super.bufferFactory = bufferFactory;
|
||||
|
||||
Flux<DataBuffer> flux = DataBufferUtils.readInputStream(
|
||||
@@ -86,7 +86,7 @@ class DataBufferUtilsTests extends AbstractDataBufferAllocatingTests {
|
||||
}
|
||||
|
||||
@ParameterizedDataBufferAllocatingTest
|
||||
void readByteChannel(DataBufferFactory bufferFactory) throws Exception {
|
||||
void readByteChannel(String displayName, DataBufferFactory bufferFactory) throws Exception {
|
||||
super.bufferFactory = bufferFactory;
|
||||
|
||||
URI uri = this.resource.getURI();
|
||||
@@ -98,7 +98,7 @@ class DataBufferUtilsTests extends AbstractDataBufferAllocatingTests {
|
||||
}
|
||||
|
||||
@ParameterizedDataBufferAllocatingTest
|
||||
void readByteChannelError(DataBufferFactory bufferFactory) throws Exception {
|
||||
void readByteChannelError(String displayName, DataBufferFactory bufferFactory) throws Exception {
|
||||
super.bufferFactory = bufferFactory;
|
||||
|
||||
ReadableByteChannel channel = mock(ReadableByteChannel.class);
|
||||
@@ -121,7 +121,7 @@ class DataBufferUtilsTests extends AbstractDataBufferAllocatingTests {
|
||||
}
|
||||
|
||||
@ParameterizedDataBufferAllocatingTest
|
||||
void readByteChannelCancel(DataBufferFactory bufferFactory) throws Exception {
|
||||
void readByteChannelCancel(String displayName, DataBufferFactory bufferFactory) throws Exception {
|
||||
super.bufferFactory = bufferFactory;
|
||||
|
||||
URI uri = this.resource.getURI();
|
||||
@@ -136,7 +136,7 @@ class DataBufferUtilsTests extends AbstractDataBufferAllocatingTests {
|
||||
}
|
||||
|
||||
@ParameterizedDataBufferAllocatingTest
|
||||
void readAsynchronousFileChannel(DataBufferFactory bufferFactory) throws Exception {
|
||||
void readAsynchronousFileChannel(String displayName, DataBufferFactory bufferFactory) throws Exception {
|
||||
super.bufferFactory = bufferFactory;
|
||||
|
||||
URI uri = this.resource.getURI();
|
||||
@@ -148,7 +148,7 @@ class DataBufferUtilsTests extends AbstractDataBufferAllocatingTests {
|
||||
}
|
||||
|
||||
@ParameterizedDataBufferAllocatingTest
|
||||
void readAsynchronousFileChannelPosition(DataBufferFactory bufferFactory) throws Exception {
|
||||
void readAsynchronousFileChannelPosition(String displayName, DataBufferFactory bufferFactory) throws Exception {
|
||||
super.bufferFactory = bufferFactory;
|
||||
|
||||
URI uri = this.resource.getURI();
|
||||
@@ -163,7 +163,7 @@ class DataBufferUtilsTests extends AbstractDataBufferAllocatingTests {
|
||||
}
|
||||
|
||||
@ParameterizedDataBufferAllocatingTest
|
||||
void readAsynchronousFileChannelError(DataBufferFactory bufferFactory) throws Exception {
|
||||
void readAsynchronousFileChannelError(String displayName, DataBufferFactory bufferFactory) throws Exception {
|
||||
super.bufferFactory = bufferFactory;
|
||||
|
||||
AsynchronousFileChannel channel = mock(AsynchronousFileChannel.class);
|
||||
@@ -195,7 +195,7 @@ class DataBufferUtilsTests extends AbstractDataBufferAllocatingTests {
|
||||
}
|
||||
|
||||
@ParameterizedDataBufferAllocatingTest
|
||||
void readAsynchronousFileChannelCancel(DataBufferFactory bufferFactory) throws Exception {
|
||||
void readAsynchronousFileChannelCancel(String displayName, DataBufferFactory bufferFactory) throws Exception {
|
||||
super.bufferFactory = bufferFactory;
|
||||
|
||||
URI uri = this.resource.getURI();
|
||||
@@ -210,7 +210,7 @@ class DataBufferUtilsTests extends AbstractDataBufferAllocatingTests {
|
||||
}
|
||||
|
||||
@ParameterizedDataBufferAllocatingTest // gh-22107
|
||||
void readAsynchronousFileChannelCancelWithoutDemand(DataBufferFactory bufferFactory) throws Exception {
|
||||
void readAsynchronousFileChannelCancelWithoutDemand(String displayName, DataBufferFactory bufferFactory) throws Exception {
|
||||
super.bufferFactory = bufferFactory;
|
||||
|
||||
URI uri = this.resource.getURI();
|
||||
@@ -224,7 +224,7 @@ class DataBufferUtilsTests extends AbstractDataBufferAllocatingTests {
|
||||
}
|
||||
|
||||
@ParameterizedDataBufferAllocatingTest
|
||||
void readPath(DataBufferFactory bufferFactory) throws Exception {
|
||||
void readPath(String displayName, DataBufferFactory bufferFactory) throws Exception {
|
||||
super.bufferFactory = bufferFactory;
|
||||
|
||||
Flux<DataBuffer> flux = DataBufferUtils.read(this.resource.getFile().toPath(), super.bufferFactory, 3);
|
||||
@@ -233,7 +233,7 @@ class DataBufferUtilsTests extends AbstractDataBufferAllocatingTests {
|
||||
}
|
||||
|
||||
@ParameterizedDataBufferAllocatingTest
|
||||
void readResource(DataBufferFactory bufferFactory) throws Exception {
|
||||
void readResource(String displayName, DataBufferFactory bufferFactory) throws Exception {
|
||||
super.bufferFactory = bufferFactory;
|
||||
|
||||
Flux<DataBuffer> flux = DataBufferUtils.read(this.resource, super.bufferFactory, 3);
|
||||
@@ -242,7 +242,7 @@ class DataBufferUtilsTests extends AbstractDataBufferAllocatingTests {
|
||||
}
|
||||
|
||||
@ParameterizedDataBufferAllocatingTest
|
||||
void readResourcePosition(DataBufferFactory bufferFactory) throws Exception {
|
||||
void readResourcePosition(String displayName, DataBufferFactory bufferFactory) throws Exception {
|
||||
super.bufferFactory = bufferFactory;
|
||||
|
||||
Flux<DataBuffer> flux = DataBufferUtils.read(this.resource, 9, super.bufferFactory, 3);
|
||||
@@ -264,7 +264,7 @@ class DataBufferUtilsTests extends AbstractDataBufferAllocatingTests {
|
||||
}
|
||||
|
||||
@ParameterizedDataBufferAllocatingTest
|
||||
void readResourcePositionAndTakeUntil(DataBufferFactory bufferFactory) throws Exception {
|
||||
void readResourcePositionAndTakeUntil(String displayName, DataBufferFactory bufferFactory) throws Exception {
|
||||
super.bufferFactory = bufferFactory;
|
||||
|
||||
Resource resource = new ClassPathResource("DataBufferUtilsTests.txt", getClass());
|
||||
@@ -281,7 +281,7 @@ class DataBufferUtilsTests extends AbstractDataBufferAllocatingTests {
|
||||
}
|
||||
|
||||
@ParameterizedDataBufferAllocatingTest
|
||||
void readByteArrayResourcePositionAndTakeUntil(DataBufferFactory bufferFactory) throws Exception {
|
||||
void readByteArrayResourcePositionAndTakeUntil(String displayName, DataBufferFactory bufferFactory) throws Exception {
|
||||
super.bufferFactory = bufferFactory;
|
||||
|
||||
Resource resource = new ByteArrayResource("foobarbazqux" .getBytes());
|
||||
@@ -298,7 +298,7 @@ class DataBufferUtilsTests extends AbstractDataBufferAllocatingTests {
|
||||
}
|
||||
|
||||
@ParameterizedDataBufferAllocatingTest
|
||||
void writeOutputStream(DataBufferFactory bufferFactory) throws Exception {
|
||||
void writeOutputStream(String displayName, DataBufferFactory bufferFactory) throws Exception {
|
||||
super.bufferFactory = bufferFactory;
|
||||
|
||||
DataBuffer foo = stringBuffer("foo");
|
||||
@@ -315,7 +315,7 @@ class DataBufferUtilsTests extends AbstractDataBufferAllocatingTests {
|
||||
}
|
||||
|
||||
@ParameterizedDataBufferAllocatingTest
|
||||
void writeWritableByteChannel(DataBufferFactory bufferFactory) throws Exception {
|
||||
void writeWritableByteChannel(String displayName, DataBufferFactory bufferFactory) throws Exception {
|
||||
super.bufferFactory = bufferFactory;
|
||||
|
||||
DataBuffer foo = stringBuffer("foo");
|
||||
@@ -332,7 +332,7 @@ class DataBufferUtilsTests extends AbstractDataBufferAllocatingTests {
|
||||
}
|
||||
|
||||
@ParameterizedDataBufferAllocatingTest
|
||||
void writeWritableByteChannelErrorInFlux(DataBufferFactory bufferFactory) throws Exception {
|
||||
void writeWritableByteChannelErrorInFlux(String displayName, DataBufferFactory bufferFactory) throws Exception {
|
||||
super.bufferFactory = bufferFactory;
|
||||
|
||||
DataBuffer foo = stringBuffer("foo");
|
||||
@@ -355,7 +355,7 @@ class DataBufferUtilsTests extends AbstractDataBufferAllocatingTests {
|
||||
}
|
||||
|
||||
@ParameterizedDataBufferAllocatingTest
|
||||
void writeWritableByteChannelErrorInWrite(DataBufferFactory bufferFactory) throws Exception {
|
||||
void writeWritableByteChannelErrorInWrite(String displayName, DataBufferFactory bufferFactory) throws Exception {
|
||||
super.bufferFactory = bufferFactory;
|
||||
|
||||
DataBuffer foo = stringBuffer("foo");
|
||||
@@ -383,7 +383,7 @@ class DataBufferUtilsTests extends AbstractDataBufferAllocatingTests {
|
||||
}
|
||||
|
||||
@ParameterizedDataBufferAllocatingTest
|
||||
void writeWritableByteChannelCancel(DataBufferFactory bufferFactory) throws Exception {
|
||||
void writeWritableByteChannelCancel(String displayName, DataBufferFactory bufferFactory) throws Exception {
|
||||
super.bufferFactory = bufferFactory;
|
||||
|
||||
DataBuffer foo = stringBuffer("foo");
|
||||
@@ -407,7 +407,7 @@ class DataBufferUtilsTests extends AbstractDataBufferAllocatingTests {
|
||||
}
|
||||
|
||||
@ParameterizedDataBufferAllocatingTest
|
||||
void writeAsynchronousFileChannel(DataBufferFactory bufferFactory) throws Exception {
|
||||
void writeAsynchronousFileChannel(String displayName, DataBufferFactory bufferFactory) throws Exception {
|
||||
super.bufferFactory = bufferFactory;
|
||||
|
||||
DataBuffer foo = stringBuffer("foo");
|
||||
@@ -439,7 +439,7 @@ class DataBufferUtilsTests extends AbstractDataBufferAllocatingTests {
|
||||
}
|
||||
|
||||
@ParameterizedDataBufferAllocatingTest
|
||||
void writeAsynchronousFileChannelErrorInFlux(DataBufferFactory bufferFactory) throws Exception {
|
||||
void writeAsynchronousFileChannelErrorInFlux(String displayName, DataBufferFactory bufferFactory) throws Exception {
|
||||
super.bufferFactory = bufferFactory;
|
||||
|
||||
DataBuffer foo = stringBuffer("foo");
|
||||
@@ -465,7 +465,7 @@ class DataBufferUtilsTests extends AbstractDataBufferAllocatingTests {
|
||||
|
||||
@ParameterizedDataBufferAllocatingTest
|
||||
@SuppressWarnings("unchecked")
|
||||
void writeAsynchronousFileChannelErrorInWrite(DataBufferFactory bufferFactory) throws Exception {
|
||||
void writeAsynchronousFileChannelErrorInWrite(String displayName, DataBufferFactory bufferFactory) throws Exception {
|
||||
super.bufferFactory = bufferFactory;
|
||||
|
||||
DataBuffer foo = stringBuffer("foo");
|
||||
@@ -506,7 +506,7 @@ class DataBufferUtilsTests extends AbstractDataBufferAllocatingTests {
|
||||
}
|
||||
|
||||
@ParameterizedDataBufferAllocatingTest
|
||||
void writeAsynchronousFileChannelCanceled(DataBufferFactory bufferFactory) throws Exception {
|
||||
void writeAsynchronousFileChannelCanceled(String displayName, DataBufferFactory bufferFactory) throws Exception {
|
||||
super.bufferFactory = bufferFactory;
|
||||
|
||||
DataBuffer foo = stringBuffer("foo");
|
||||
@@ -531,7 +531,7 @@ class DataBufferUtilsTests extends AbstractDataBufferAllocatingTests {
|
||||
}
|
||||
|
||||
@ParameterizedDataBufferAllocatingTest
|
||||
void writePath(DataBufferFactory bufferFactory) throws Exception {
|
||||
void writePath(String displayName, DataBufferFactory bufferFactory) throws Exception {
|
||||
super.bufferFactory = bufferFactory;
|
||||
|
||||
DataBuffer foo = stringBuffer("foo");
|
||||
@@ -548,7 +548,7 @@ class DataBufferUtilsTests extends AbstractDataBufferAllocatingTests {
|
||||
}
|
||||
|
||||
@ParameterizedDataBufferAllocatingTest
|
||||
void readAndWriteByteChannel(DataBufferFactory bufferFactory) throws Exception {
|
||||
void readAndWriteByteChannel(String displayName, DataBufferFactory bufferFactory) throws Exception {
|
||||
super.bufferFactory = bufferFactory;
|
||||
|
||||
Path source = Paths.get(
|
||||
@@ -582,7 +582,7 @@ class DataBufferUtilsTests extends AbstractDataBufferAllocatingTests {
|
||||
}
|
||||
|
||||
@ParameterizedDataBufferAllocatingTest
|
||||
void readAndWriteAsynchronousFileChannel(DataBufferFactory bufferFactory) throws Exception {
|
||||
void readAndWriteAsynchronousFileChannel(String displayName, DataBufferFactory bufferFactory) throws Exception {
|
||||
super.bufferFactory = bufferFactory;
|
||||
|
||||
Path source = Paths.get(
|
||||
@@ -623,7 +623,7 @@ class DataBufferUtilsTests extends AbstractDataBufferAllocatingTests {
|
||||
}
|
||||
|
||||
@ParameterizedDataBufferAllocatingTest
|
||||
void takeUntilByteCount(DataBufferFactory bufferFactory) {
|
||||
void takeUntilByteCount(String displayName, DataBufferFactory bufferFactory) {
|
||||
super.bufferFactory = bufferFactory;
|
||||
|
||||
Flux<DataBuffer> result = DataBufferUtils.takeUntilByteCount(
|
||||
@@ -637,7 +637,7 @@ class DataBufferUtilsTests extends AbstractDataBufferAllocatingTests {
|
||||
}
|
||||
|
||||
@ParameterizedDataBufferAllocatingTest
|
||||
void takeUntilByteCountCanceled(DataBufferFactory bufferFactory) {
|
||||
void takeUntilByteCountCanceled(String displayName, DataBufferFactory bufferFactory) {
|
||||
super.bufferFactory = bufferFactory;
|
||||
|
||||
Flux<DataBuffer> source = Flux.concat(
|
||||
@@ -654,7 +654,7 @@ class DataBufferUtilsTests extends AbstractDataBufferAllocatingTests {
|
||||
}
|
||||
|
||||
@ParameterizedDataBufferAllocatingTest
|
||||
void takeUntilByteCountError(DataBufferFactory bufferFactory) {
|
||||
void takeUntilByteCountError(String displayName, DataBufferFactory bufferFactory) {
|
||||
super.bufferFactory = bufferFactory;
|
||||
|
||||
Flux<DataBuffer> source = Flux.concat(
|
||||
@@ -671,7 +671,7 @@ class DataBufferUtilsTests extends AbstractDataBufferAllocatingTests {
|
||||
}
|
||||
|
||||
@ParameterizedDataBufferAllocatingTest
|
||||
void takeUntilByteCountExact(DataBufferFactory bufferFactory) {
|
||||
void takeUntilByteCountExact(String displayName, DataBufferFactory bufferFactory) {
|
||||
super.bufferFactory = bufferFactory;
|
||||
|
||||
Flux<DataBuffer> source = Flux.concat(
|
||||
@@ -690,7 +690,7 @@ class DataBufferUtilsTests extends AbstractDataBufferAllocatingTests {
|
||||
}
|
||||
|
||||
@ParameterizedDataBufferAllocatingTest
|
||||
void skipUntilByteCount(DataBufferFactory bufferFactory) {
|
||||
void skipUntilByteCount(String displayName, DataBufferFactory bufferFactory) {
|
||||
super.bufferFactory = bufferFactory;
|
||||
|
||||
Flux<DataBuffer> source = Flux.concat(
|
||||
@@ -708,7 +708,7 @@ class DataBufferUtilsTests extends AbstractDataBufferAllocatingTests {
|
||||
}
|
||||
|
||||
@ParameterizedDataBufferAllocatingTest
|
||||
void skipUntilByteCountCancelled(DataBufferFactory bufferFactory) {
|
||||
void skipUntilByteCountCancelled(String displayName, DataBufferFactory bufferFactory) {
|
||||
super.bufferFactory = bufferFactory;
|
||||
|
||||
Flux<DataBuffer> source = Flux.concat(
|
||||
@@ -724,7 +724,7 @@ class DataBufferUtilsTests extends AbstractDataBufferAllocatingTests {
|
||||
}
|
||||
|
||||
@ParameterizedDataBufferAllocatingTest
|
||||
void skipUntilByteCountErrorInFlux(DataBufferFactory bufferFactory) {
|
||||
void skipUntilByteCountErrorInFlux(String displayName, DataBufferFactory bufferFactory) {
|
||||
super.bufferFactory = bufferFactory;
|
||||
|
||||
DataBuffer foo = stringBuffer("foo");
|
||||
@@ -738,7 +738,7 @@ class DataBufferUtilsTests extends AbstractDataBufferAllocatingTests {
|
||||
}
|
||||
|
||||
@ParameterizedDataBufferAllocatingTest
|
||||
void skipUntilByteCountShouldSkipAll(DataBufferFactory bufferFactory) {
|
||||
void skipUntilByteCountShouldSkipAll(String displayName, DataBufferFactory bufferFactory) {
|
||||
super.bufferFactory = bufferFactory;
|
||||
|
||||
DataBuffer foo = stringBuffer("foo");
|
||||
@@ -753,7 +753,7 @@ class DataBufferUtilsTests extends AbstractDataBufferAllocatingTests {
|
||||
}
|
||||
|
||||
@ParameterizedDataBufferAllocatingTest
|
||||
void releaseConsumer(DataBufferFactory bufferFactory) {
|
||||
void releaseConsumer(String displayName, DataBufferFactory bufferFactory) {
|
||||
super.bufferFactory = bufferFactory;
|
||||
|
||||
DataBuffer foo = stringBuffer("foo");
|
||||
@@ -776,7 +776,7 @@ class DataBufferUtilsTests extends AbstractDataBufferAllocatingTests {
|
||||
}
|
||||
|
||||
@ParameterizedDataBufferAllocatingTest
|
||||
void SPR16070(DataBufferFactory bufferFactory) throws Exception {
|
||||
void SPR16070(String displayName, DataBufferFactory bufferFactory) throws Exception {
|
||||
super.bufferFactory = bufferFactory;
|
||||
|
||||
ReadableByteChannel channel = mock(ReadableByteChannel.class);
|
||||
@@ -807,7 +807,7 @@ class DataBufferUtilsTests extends AbstractDataBufferAllocatingTests {
|
||||
}
|
||||
|
||||
@ParameterizedDataBufferAllocatingTest
|
||||
void join(DataBufferFactory bufferFactory) {
|
||||
void join(String displayName, DataBufferFactory bufferFactory) {
|
||||
super.bufferFactory = bufferFactory;
|
||||
|
||||
DataBuffer foo = stringBuffer("foo");
|
||||
@@ -825,7 +825,7 @@ class DataBufferUtilsTests extends AbstractDataBufferAllocatingTests {
|
||||
}
|
||||
|
||||
@ParameterizedDataBufferAllocatingTest
|
||||
void joinWithLimit(DataBufferFactory bufferFactory) {
|
||||
void joinWithLimit(String displayName, DataBufferFactory bufferFactory) {
|
||||
super.bufferFactory = bufferFactory;
|
||||
|
||||
DataBuffer foo = stringBuffer("foo");
|
||||
@@ -855,7 +855,7 @@ class DataBufferUtilsTests extends AbstractDataBufferAllocatingTests {
|
||||
}
|
||||
|
||||
@ParameterizedDataBufferAllocatingTest
|
||||
void joinErrors(DataBufferFactory bufferFactory) {
|
||||
void joinErrors(String displayName, DataBufferFactory bufferFactory) {
|
||||
super.bufferFactory = bufferFactory;
|
||||
|
||||
DataBuffer foo = stringBuffer("foo");
|
||||
@@ -869,7 +869,7 @@ class DataBufferUtilsTests extends AbstractDataBufferAllocatingTests {
|
||||
}
|
||||
|
||||
@ParameterizedDataBufferAllocatingTest
|
||||
void joinCanceled(DataBufferFactory bufferFactory) {
|
||||
void joinCanceled(String displayName, DataBufferFactory bufferFactory) {
|
||||
super.bufferFactory = bufferFactory;
|
||||
|
||||
Flux<DataBuffer> source = Flux.concat(
|
||||
@@ -885,7 +885,7 @@ class DataBufferUtilsTests extends AbstractDataBufferAllocatingTests {
|
||||
}
|
||||
|
||||
@ParameterizedDataBufferAllocatingTest
|
||||
void matcher(DataBufferFactory bufferFactory) {
|
||||
void matcher(String displayName, DataBufferFactory bufferFactory) {
|
||||
super.bufferFactory = bufferFactory;
|
||||
|
||||
DataBuffer foo = stringBuffer("foo");
|
||||
@@ -903,7 +903,7 @@ class DataBufferUtilsTests extends AbstractDataBufferAllocatingTests {
|
||||
}
|
||||
|
||||
@ParameterizedDataBufferAllocatingTest
|
||||
void matcher2(DataBufferFactory bufferFactory) {
|
||||
void matcher2(String displayName, DataBufferFactory bufferFactory) {
|
||||
super.bufferFactory = bufferFactory;
|
||||
|
||||
DataBuffer foo = stringBuffer("foooobar");
|
||||
@@ -923,7 +923,7 @@ class DataBufferUtilsTests extends AbstractDataBufferAllocatingTests {
|
||||
}
|
||||
|
||||
@ParameterizedDataBufferAllocatingTest
|
||||
void matcher3(DataBufferFactory bufferFactory) {
|
||||
void matcher3(String displayName, DataBufferFactory bufferFactory) {
|
||||
super.bufferFactory = bufferFactory;
|
||||
|
||||
DataBuffer foo = stringBuffer("foooobar");
|
||||
@@ -943,7 +943,7 @@ class DataBufferUtilsTests extends AbstractDataBufferAllocatingTests {
|
||||
}
|
||||
|
||||
@ParameterizedDataBufferAllocatingTest
|
||||
void propagateContextByteChannel(DataBufferFactory bufferFactory) throws IOException {
|
||||
void propagateContextByteChannel(String displayName, DataBufferFactory bufferFactory) throws IOException {
|
||||
Path path = Paths.get(this.resource.getURI());
|
||||
try (SeekableByteChannel out = Files.newByteChannel(this.tempFile, StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING)) {
|
||||
Flux<DataBuffer> result = DataBufferUtils.read(path, bufferFactory, 1024, StandardOpenOption.READ)
|
||||
@@ -967,7 +967,7 @@ class DataBufferUtilsTests extends AbstractDataBufferAllocatingTests {
|
||||
}
|
||||
|
||||
@ParameterizedDataBufferAllocatingTest
|
||||
void propagateContextAsynchronousFileChannel(DataBufferFactory bufferFactory) throws IOException {
|
||||
void propagateContextAsynchronousFileChannel(String displayName, DataBufferFactory bufferFactory) throws IOException {
|
||||
Path path = Paths.get(this.resource.getURI());
|
||||
try (AsynchronousFileChannel out = AsynchronousFileChannel.open(this.tempFile, StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING)) {
|
||||
Flux<DataBuffer> result = DataBufferUtils.read(path, bufferFactory, 1024, StandardOpenOption.READ)
|
||||
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -32,7 +32,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
class DataBufferTestUtilsTests extends AbstractDataBufferAllocatingTests {
|
||||
|
||||
@ParameterizedDataBufferAllocatingTest
|
||||
void dumpBytes(DataBufferFactory bufferFactory) {
|
||||
void dumpBytes(String displayName, DataBufferFactory bufferFactory) {
|
||||
this.bufferFactory = bufferFactory;
|
||||
|
||||
DataBuffer buffer = this.bufferFactory.allocateBuffer(4);
|
||||
@@ -47,7 +47,7 @@ class DataBufferTestUtilsTests extends AbstractDataBufferAllocatingTests {
|
||||
}
|
||||
|
||||
@ParameterizedDataBufferAllocatingTest
|
||||
void dumpString(DataBufferFactory bufferFactory) {
|
||||
void dumpString(String displayName, DataBufferFactory bufferFactory) {
|
||||
this.bufferFactory = bufferFactory;
|
||||
|
||||
DataBuffer buffer = this.bufferFactory.allocateBuffer(4);
|
||||
|
||||
+16
-18
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -81,7 +81,7 @@ public abstract class AbstractEncoderTests<E extends Encoder<?>> extends Abstrac
|
||||
* Helper methods that tests for a variety of encoding scenarios. This methods
|
||||
* invokes:
|
||||
* <ul>
|
||||
* <li>{@link #testEncode(Publisher, ResolvableType, MimeType, Map, Consumer)}</li>
|
||||
* <li>{@link #testEncode(Publisher, ResolvableType, Consumer, MimeType, Map)}</li>
|
||||
* <li>{@link #testEncodeError(Publisher, ResolvableType, MimeType, Map)}</li>
|
||||
* <li>{@link #testEncodeCancel(Publisher, ResolvableType, MimeType, Map)}</li>
|
||||
* <li>{@link #testEncodeEmpty(ResolvableType, MimeType, Map)}</li>
|
||||
@@ -94,32 +94,30 @@ public abstract class AbstractEncoderTests<E extends Encoder<?>> extends Abstrac
|
||||
*/
|
||||
protected <T> void testEncodeAll(Publisher<? extends T> input, Class<? extends T> inputClass,
|
||||
Consumer<StepVerifier.FirstStep<DataBuffer>> stepConsumer) {
|
||||
|
||||
testEncodeAll(input, ResolvableType.forClass(inputClass), null, null, stepConsumer);
|
||||
testEncodeAll(input, ResolvableType.forClass(inputClass), stepConsumer, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper methods that tests for a variety of decoding scenarios. This methods
|
||||
* invokes:
|
||||
* <ul>
|
||||
* <li>{@link #testEncode(Publisher, ResolvableType, MimeType, Map, Consumer)}</li>
|
||||
* <li>{@link #testEncode(Publisher, ResolvableType, Consumer, MimeType, Map)}</li>
|
||||
* <li>{@link #testEncodeError(Publisher, ResolvableType, MimeType, Map)}</li>
|
||||
* <li>{@link #testEncodeCancel(Publisher, ResolvableType, MimeType, Map)}</li>
|
||||
* <li>{@link #testEncodeEmpty(ResolvableType, MimeType, Map)}</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param <T> the output type
|
||||
* @param input the input to be provided to the encoder
|
||||
* @param inputType the input type
|
||||
* @param stepConsumer a consumer to {@linkplain StepVerifier verify} the output
|
||||
* @param mimeType the mime type to use for decoding. May be {@code null}.
|
||||
* @param hints the hints used for decoding. May be {@code null}.
|
||||
* @param stepConsumer a consumer to {@linkplain StepVerifier verify} the output
|
||||
* @param <T> the output type
|
||||
*/
|
||||
protected <T> void testEncodeAll(Publisher<? extends T> input, ResolvableType inputType,
|
||||
@Nullable MimeType mimeType, @Nullable Map<String, Object> hints,
|
||||
Consumer<StepVerifier.FirstStep<DataBuffer>> stepConsumer) {
|
||||
|
||||
testEncode(input, inputType, mimeType, hints, stepConsumer);
|
||||
Consumer<StepVerifier.FirstStep<DataBuffer>> stepConsumer,
|
||||
@Nullable MimeType mimeType, @Nullable Map<String, Object> hints) {
|
||||
testEncode(input, inputType, stepConsumer, mimeType, hints);
|
||||
testEncodeError(input, inputType, mimeType, hints);
|
||||
testEncodeCancel(input, inputType, mimeType, hints);
|
||||
testEncodeEmpty(inputType, mimeType, hints);
|
||||
@@ -135,25 +133,25 @@ public abstract class AbstractEncoderTests<E extends Encoder<?>> extends Abstrac
|
||||
*/
|
||||
protected <T> void testEncode(Publisher<? extends T> input, Class<? extends T> inputClass,
|
||||
Consumer<StepVerifier.FirstStep<DataBuffer>> stepConsumer) {
|
||||
|
||||
testEncode(input, ResolvableType.forClass(inputClass), null, null, stepConsumer);
|
||||
testEncode(input, ResolvableType.forClass(inputClass), stepConsumer, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test a standard {@link Encoder#encode encode} scenario.
|
||||
*
|
||||
* @param <T> the output type
|
||||
* @param input the input to be provided to the encoder
|
||||
* @param inputType the input type
|
||||
* @param stepConsumer a consumer to {@linkplain StepVerifier verify} the output
|
||||
* @param mimeType the mime type to use for decoding. May be {@code null}.
|
||||
* @param hints the hints used for decoding. May be {@code null}.
|
||||
* @param stepConsumer a consumer to {@linkplain StepVerifier verify} the output
|
||||
* @param <T> the output type
|
||||
*/
|
||||
protected <T> void testEncode(Publisher<? extends T> input, ResolvableType inputType,
|
||||
@Nullable MimeType mimeType, @Nullable Map<String, Object> hints,
|
||||
Consumer<StepVerifier.FirstStep<DataBuffer>> stepConsumer) {
|
||||
Consumer<StepVerifier.FirstStep<DataBuffer>> stepConsumer,
|
||||
@Nullable MimeType mimeType, @Nullable Map<String, Object> hints) {
|
||||
|
||||
Flux<DataBuffer> result = encoder().encode(input, this.bufferFactory, inputType, mimeType, hints);
|
||||
Flux<DataBuffer> result = encoder().encode(input, this.bufferFactory, inputType,
|
||||
mimeType, hints);
|
||||
StepVerifier.FirstStep<DataBuffer> step = StepVerifier.create(result);
|
||||
stepConsumer.accept(step);
|
||||
}
|
||||
|
||||
+13
-14
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -49,7 +49,6 @@ import org.springframework.core.io.buffer.NettyDataBufferFactory;
|
||||
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.junit.jupiter.api.Named.named;
|
||||
import static org.junit.jupiter.params.provider.Arguments.arguments;
|
||||
|
||||
/**
|
||||
@@ -162,20 +161,20 @@ public abstract class AbstractDataBufferAllocatingTests {
|
||||
@SuppressWarnings("deprecation") // PooledByteBufAllocator no longer supports tinyCacheSize.
|
||||
public static Stream<Arguments> dataBufferFactories() {
|
||||
return Stream.of(
|
||||
arguments(named("NettyDataBufferFactory - UnpooledByteBufAllocator - preferDirect = true",
|
||||
new NettyDataBufferFactory(new UnpooledByteBufAllocator(true)))),
|
||||
arguments(named("NettyDataBufferFactory - UnpooledByteBufAllocator - preferDirect = false",
|
||||
new NettyDataBufferFactory(new UnpooledByteBufAllocator(false)))),
|
||||
arguments("NettyDataBufferFactory - UnpooledByteBufAllocator - preferDirect = true",
|
||||
new NettyDataBufferFactory(new UnpooledByteBufAllocator(true))),
|
||||
arguments("NettyDataBufferFactory - UnpooledByteBufAllocator - preferDirect = false",
|
||||
new NettyDataBufferFactory(new UnpooledByteBufAllocator(false))),
|
||||
// 1) Disable caching for reliable leak detection, see https://github.com/netty/netty/issues/5275
|
||||
// 2) maxOrder is 4 (vs default 11) but can be increased if necessary
|
||||
arguments(named("NettyDataBufferFactory - PooledByteBufAllocator - preferDirect = true",
|
||||
new NettyDataBufferFactory(new PooledByteBufAllocator(true, 1, 1, 4096, 4, 0, 0, 0, true)))),
|
||||
arguments(named("NettyDataBufferFactory - PooledByteBufAllocator - preferDirect = false",
|
||||
new NettyDataBufferFactory(new PooledByteBufAllocator(false, 1, 1, 4096, 4, 0, 0, 0, true)))),
|
||||
arguments(named("DefaultDataBufferFactory - preferDirect = true",
|
||||
new DefaultDataBufferFactory(true))),
|
||||
arguments(named("DefaultDataBufferFactory - preferDirect = false",
|
||||
new DefaultDataBufferFactory(false)))
|
||||
arguments("NettyDataBufferFactory - PooledByteBufAllocator - preferDirect = true",
|
||||
new NettyDataBufferFactory(new PooledByteBufAllocator(true, 1, 1, 4096, 4, 0, 0, 0, true))),
|
||||
arguments("NettyDataBufferFactory - PooledByteBufAllocator - preferDirect = false",
|
||||
new NettyDataBufferFactory(new PooledByteBufAllocator(false, 1, 1, 4096, 4, 0, 0, 0, true))),
|
||||
arguments("DefaultDataBufferFactory - preferDirect = true",
|
||||
new DefaultDataBufferFactory(true)),
|
||||
arguments("DefaultDataBufferFactory - preferDirect = false",
|
||||
new DefaultDataBufferFactory(false))
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -22,8 +22,8 @@ import org.springframework.core.convert.TypeDescriptor;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* A method resolver attempts to locate a method and returns a command executor that can be
|
||||
* used to invoke that method. The command executor will be cached, but if it 'goes stale'
|
||||
* A method resolver attempts locate a method and returns a command executor that can be
|
||||
* used to invoke that method. The command executor will be cached but if it 'goes stale'
|
||||
* the resolvers will be called again.
|
||||
*
|
||||
* @author Andy Clement
|
||||
|
||||
+3
-12
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -27,11 +27,10 @@ import java.text.MessageFormat;
|
||||
* <p>When a message is formatted, it will have this kind of form, capturing the prefix
|
||||
* and the error kind:
|
||||
*
|
||||
* <pre class="code">EL1005E: Type cannot be found 'String'</pre>
|
||||
* <pre class="code">EL1004E: Type cannot be found 'String'</pre>
|
||||
*
|
||||
* @author Andy Clement
|
||||
* @author Juergen Hoeller
|
||||
* @author Sam Brannen
|
||||
* @since 3.0
|
||||
*/
|
||||
public enum SpelMessage {
|
||||
@@ -256,15 +255,7 @@ public enum SpelMessage {
|
||||
|
||||
/** @since 4.3.17 */
|
||||
FLAWED_PATTERN(Kind.ERROR, 1073,
|
||||
"Failed to efficiently evaluate pattern ''{0}'': consider redesigning it"),
|
||||
|
||||
/** @since 5.3.17 */
|
||||
EXCEPTION_COMPILING_EXPRESSION(Kind.ERROR, 1074,
|
||||
"An exception occurred while compiling an expression"),
|
||||
|
||||
/** @since 5.3.17 */
|
||||
MAX_ARRAY_ELEMENTS_THRESHOLD_EXCEEDED(Kind.ERROR, 1075,
|
||||
"Array declares too many elements, exceeding the threshold of ''{0}''");
|
||||
"Failed to efficiently evaluate pattern ''{0}'': consider redesigning it");
|
||||
|
||||
|
||||
private final Kind kind;
|
||||
|
||||
+2
-22
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -53,18 +53,10 @@ import org.springframework.util.Assert;
|
||||
*
|
||||
* @author Andy Clement
|
||||
* @author Juergen Hoeller
|
||||
* @author Sam Brannen
|
||||
* @since 3.0
|
||||
*/
|
||||
public class ConstructorReference extends SpelNodeImpl {
|
||||
|
||||
/**
|
||||
* Maximum number of elements permitted in an array declaration, applying
|
||||
* to one-dimensional as well as multi-dimensional arrays.
|
||||
* @since 5.3.17
|
||||
*/
|
||||
private static final int MAX_ARRAY_ELEMENTS = 256 * 1024; // 256K
|
||||
|
||||
private final boolean isArrayConstructor;
|
||||
|
||||
@Nullable
|
||||
@@ -267,19 +259,14 @@ public class ConstructorReference extends SpelNodeImpl {
|
||||
// Shortcut for 1-dimensional
|
||||
TypedValue o = this.dimensions[0].getTypedValue(state);
|
||||
int arraySize = ExpressionUtils.toInt(typeConverter, o);
|
||||
checkNumElements(arraySize);
|
||||
newArray = Array.newInstance(componentType, arraySize);
|
||||
}
|
||||
else {
|
||||
// Multi-dimensional - hold onto your hat!
|
||||
int[] dims = new int[this.dimensions.length];
|
||||
long numElements = 1;
|
||||
for (int d = 0; d < this.dimensions.length; d++) {
|
||||
TypedValue o = this.dimensions[d].getTypedValue(state);
|
||||
int arraySize = ExpressionUtils.toInt(typeConverter, o);
|
||||
dims[d] = arraySize;
|
||||
numElements *= arraySize;
|
||||
checkNumElements(numElements);
|
||||
dims[d] = ExpressionUtils.toInt(typeConverter, o);
|
||||
}
|
||||
newArray = Array.newInstance(componentType, dims);
|
||||
}
|
||||
@@ -340,13 +327,6 @@ public class ConstructorReference extends SpelNodeImpl {
|
||||
return new TypedValue(newArray);
|
||||
}
|
||||
|
||||
private void checkNumElements(long numElements) {
|
||||
if (numElements >= MAX_ARRAY_ELEMENTS) {
|
||||
throw new SpelEvaluationException(getStartPosition(),
|
||||
SpelMessage.MAX_ARRAY_ELEMENTS_THRESHOLD_EXCEEDED, MAX_ARRAY_ELEMENTS);
|
||||
}
|
||||
}
|
||||
|
||||
private void populateReferenceTypeArray(ExpressionState state, Object newArray, TypeConverter typeConverter,
|
||||
InlineList initializer, Class<?> componentType) {
|
||||
|
||||
|
||||
+2
-1
@@ -200,7 +200,8 @@ public class MethodReference extends SpelNodeImpl {
|
||||
EvaluationContext evaluationContext) throws SpelEvaluationException {
|
||||
|
||||
AccessException accessException = null;
|
||||
for (MethodResolver methodResolver : evaluationContext.getMethodResolvers()) {
|
||||
List<MethodResolver> methodResolvers = evaluationContext.getMethodResolvers();
|
||||
for (MethodResolver methodResolver : methodResolvers) {
|
||||
try {
|
||||
MethodExecutor methodExecutor = methodResolver.resolve(
|
||||
evaluationContext, targetObject, this.name, argumentTypes);
|
||||
|
||||
+2
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -110,8 +110,7 @@ public final class SpelCompiler implements Opcodes {
|
||||
return ReflectionUtils.accessibleConstructor(clazz).newInstance();
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
throw new IllegalStateException("Failed to instantiate CompiledExpression for expression: " +
|
||||
expression.toStringAST(), ex);
|
||||
throw new IllegalStateException("Failed to instantiate CompiledExpression", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+9
-27
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -44,7 +44,6 @@ import org.springframework.util.Assert;
|
||||
*
|
||||
* @author Andy Clement
|
||||
* @author Juergen Hoeller
|
||||
* @author Sam Brannen
|
||||
* @since 3.0
|
||||
*/
|
||||
public class SpelExpression implements Expression {
|
||||
@@ -523,34 +522,17 @@ public class SpelExpression implements Expression {
|
||||
// Compiled by another thread before this thread got into the sync block
|
||||
return true;
|
||||
}
|
||||
try {
|
||||
SpelCompiler compiler = SpelCompiler.getCompiler(this.configuration.getCompilerClassLoader());
|
||||
compiledAst = compiler.compile(this.ast);
|
||||
if (compiledAst != null) {
|
||||
// Successfully compiled
|
||||
this.compiledAst = compiledAst;
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
// Failed to compile
|
||||
this.failedAttempts.incrementAndGet();
|
||||
return false;
|
||||
}
|
||||
SpelCompiler compiler = SpelCompiler.getCompiler(this.configuration.getCompilerClassLoader());
|
||||
compiledAst = compiler.compile(this.ast);
|
||||
if (compiledAst != null) {
|
||||
// Successfully compiled
|
||||
this.compiledAst = compiledAst;
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex) {
|
||||
else {
|
||||
// Failed to compile
|
||||
this.failedAttempts.incrementAndGet();
|
||||
|
||||
// If running in mixed mode, revert to interpreted
|
||||
if (this.configuration.getCompilerMode() == SpelCompilerMode.MIXED) {
|
||||
this.compiledAst = null;
|
||||
this.interpretedCount.set(0);
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
// Running in SpelCompilerMode.immediate mode - propagate exception to caller
|
||||
throw new SpelEvaluationException(ex, SpelMessage.EXCEPTION_COMPILING_EXPRESSION);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1211
-1229
File diff suppressed because it is too large
Load Diff
+67
-63
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -41,17 +41,16 @@ import static org.assertj.core.api.Assertions.within;
|
||||
/**
|
||||
* Test the examples specified in the documentation.
|
||||
*
|
||||
* <p>NOTE: any outgoing changes from this file upon synchronizing with the repo may indicate that
|
||||
* NOTE: any outgoing changes from this file upon synchronizing with the repo may indicate that
|
||||
* you need to update the documentation too !
|
||||
*
|
||||
* @author Andy Clement
|
||||
*/
|
||||
@SuppressWarnings("rawtypes")
|
||||
class SpelDocumentationTests extends AbstractExpressionTests {
|
||||
public class SpelDocumentationTests extends AbstractExpressionTests {
|
||||
|
||||
static Inventor tesla;
|
||||
|
||||
static Inventor pupin;
|
||||
static Inventor tesla ;
|
||||
static Inventor pupin ;
|
||||
|
||||
static {
|
||||
GregorianCalendar c = new GregorianCalendar();
|
||||
@@ -66,24 +65,53 @@ class SpelDocumentationTests extends AbstractExpressionTests {
|
||||
pupin.setPlaceOfBirth(new PlaceOfBirth("Idvor"));
|
||||
|
||||
}
|
||||
static class IEEE {
|
||||
private String name;
|
||||
|
||||
|
||||
public Inventor[] Members = new Inventor[1];
|
||||
public List Members2 = new ArrayList();
|
||||
public Map<String,Object> officers = new HashMap<>();
|
||||
|
||||
public List<Map<String, Object>> reverse = new ArrayList<>();
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
IEEE() {
|
||||
officers.put("president",pupin);
|
||||
List linv = new ArrayList();
|
||||
linv.add(tesla);
|
||||
officers.put("advisors",linv);
|
||||
Members2.add(tesla);
|
||||
Members2.add(pupin);
|
||||
|
||||
reverse.add(officers);
|
||||
}
|
||||
|
||||
public boolean isMember(String name) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public String getName() { return name; }
|
||||
public void setName(String n) { this.name = n; }
|
||||
}
|
||||
|
||||
@Test
|
||||
void methodInvocation() {
|
||||
public void testMethodInvocation() {
|
||||
evaluate("'Hello World'.concat('!')","Hello World!",String.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void beanPropertyAccess() {
|
||||
public void testBeanPropertyAccess() {
|
||||
evaluate("new String('Hello World'.bytes)","Hello World",String.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void arrayLengthAccess() {
|
||||
public void testArrayLengthAccess() {
|
||||
evaluate("'Hello World'.bytes.length",11,Integer.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void rootObject() throws Exception {
|
||||
public void testRootObject() throws Exception {
|
||||
GregorianCalendar c = new GregorianCalendar();
|
||||
c.set(1856, 7, 9);
|
||||
|
||||
@@ -101,7 +129,7 @@ class SpelDocumentationTests extends AbstractExpressionTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
void equalityCheck() throws Exception {
|
||||
public void testEqualityCheck() throws Exception {
|
||||
ExpressionParser parser = new SpelExpressionParser();
|
||||
|
||||
StandardEvaluationContext context = new StandardEvaluationContext();
|
||||
@@ -115,13 +143,13 @@ class SpelDocumentationTests extends AbstractExpressionTests {
|
||||
// Section 7.4.1
|
||||
|
||||
@Test
|
||||
void xmlBasedConfig() {
|
||||
public void testXMLBasedConfig() {
|
||||
evaluate("(T(java.lang.Math).random() * 100.0 )>0",true,Boolean.class);
|
||||
}
|
||||
|
||||
// Section 7.5
|
||||
@Test
|
||||
void literals() throws Exception {
|
||||
public void testLiterals() throws Exception {
|
||||
ExpressionParser parser = new SpelExpressionParser();
|
||||
|
||||
String helloWorld = (String) parser.parseExpression("'Hello World'").getValue(); // evals to "Hello World"
|
||||
@@ -141,7 +169,7 @@ class SpelDocumentationTests extends AbstractExpressionTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
void propertyAccess() throws Exception {
|
||||
public void testPropertyAccess() throws Exception {
|
||||
EvaluationContext context = TestScenarioCreator.getTestEvaluationContext();
|
||||
int year = (Integer) parser.parseExpression("Birthdate.Year + 1900").getValue(context); // 1856
|
||||
assertThat(year).isEqualTo(1856);
|
||||
@@ -151,12 +179,12 @@ class SpelDocumentationTests extends AbstractExpressionTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
void propertyNavigation() throws Exception {
|
||||
public void testPropertyNavigation() throws Exception {
|
||||
ExpressionParser parser = new SpelExpressionParser();
|
||||
|
||||
// Inventions Array
|
||||
StandardEvaluationContext teslaContext = TestScenarioCreator.getTestEvaluationContext();
|
||||
// teslaContext.setRootObject(tesla);
|
||||
// teslaContext.setRootObject(tesla);
|
||||
|
||||
// evaluates to "Induction motor"
|
||||
String invention = parser.parseExpression("inventions[3]").getValue(teslaContext, String.class);
|
||||
@@ -178,8 +206,9 @@ class SpelDocumentationTests extends AbstractExpressionTests {
|
||||
assertThat(invention).isEqualTo("Wireless communication");
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
void dictionaryAccess() throws Exception {
|
||||
public void testDictionaryAccess() throws Exception {
|
||||
StandardEvaluationContext societyContext = new StandardEvaluationContext();
|
||||
societyContext.setRootObject(new IEEE());
|
||||
// Officer's Dictionary
|
||||
@@ -204,7 +233,7 @@ class SpelDocumentationTests extends AbstractExpressionTests {
|
||||
// 7.5.3
|
||||
|
||||
@Test
|
||||
void methodInvocation2() throws Exception {
|
||||
public void testMethodInvocation2() throws Exception {
|
||||
// string literal, evaluates to "bc"
|
||||
String c = parser.parseExpression("'abc'.substring(1, 3)").getValue(String.class);
|
||||
assertThat(c).isEqualTo("bc");
|
||||
@@ -219,7 +248,7 @@ class SpelDocumentationTests extends AbstractExpressionTests {
|
||||
// 7.5.4.1
|
||||
|
||||
@Test
|
||||
void relationalOperators() throws Exception {
|
||||
public void testRelationalOperators() throws Exception {
|
||||
boolean result = parser.parseExpression("2 == 2").getValue(Boolean.class);
|
||||
assertThat(result).isTrue();
|
||||
// evaluates to false
|
||||
@@ -232,7 +261,7 @@ class SpelDocumentationTests extends AbstractExpressionTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
void otherOperators() throws Exception {
|
||||
public void testOtherOperators() throws Exception {
|
||||
// evaluates to false
|
||||
boolean falseValue = parser.parseExpression("'xyz' instanceof T(int)").getValue(Boolean.class);
|
||||
assertThat(falseValue).isFalse();
|
||||
@@ -249,7 +278,7 @@ class SpelDocumentationTests extends AbstractExpressionTests {
|
||||
// 7.5.4.2
|
||||
|
||||
@Test
|
||||
void logicalOperators() throws Exception {
|
||||
public void testLogicalOperators() throws Exception {
|
||||
|
||||
StandardEvaluationContext societyContext = new StandardEvaluationContext();
|
||||
societyContext.setRootObject(new IEEE());
|
||||
@@ -290,7 +319,7 @@ class SpelDocumentationTests extends AbstractExpressionTests {
|
||||
// 7.5.4.3
|
||||
|
||||
@Test
|
||||
void numericalOperators() throws Exception {
|
||||
public void testNumericalOperators() throws Exception {
|
||||
// Addition
|
||||
int two = parser.parseExpression("1 + 1").getValue(Integer.class); // 2
|
||||
assertThat(two).isEqualTo(2);
|
||||
@@ -334,7 +363,7 @@ class SpelDocumentationTests extends AbstractExpressionTests {
|
||||
// 7.5.5
|
||||
|
||||
@Test
|
||||
void assignment() throws Exception {
|
||||
public void testAssignment() throws Exception {
|
||||
Inventor inventor = new Inventor();
|
||||
StandardEvaluationContext inventorContext = new StandardEvaluationContext();
|
||||
inventorContext.setRootObject(inventor);
|
||||
@@ -352,7 +381,7 @@ class SpelDocumentationTests extends AbstractExpressionTests {
|
||||
// 7.5.6
|
||||
|
||||
@Test
|
||||
void types() throws Exception {
|
||||
public void testTypes() throws Exception {
|
||||
Class<?> dateClass = parser.parseExpression("T(java.util.Date)").getValue(Class.class);
|
||||
assertThat(dateClass).isEqualTo(Date.class);
|
||||
boolean trueValue = parser.parseExpression("T(java.math.RoundingMode).CEILING < T(java.math.RoundingMode).FLOOR").getValue(Boolean.class);
|
||||
@@ -362,7 +391,7 @@ class SpelDocumentationTests extends AbstractExpressionTests {
|
||||
// 7.5.7
|
||||
|
||||
@Test
|
||||
void constructors() throws Exception {
|
||||
public void testConstructors() throws Exception {
|
||||
StandardEvaluationContext societyContext = new StandardEvaluationContext();
|
||||
societyContext.setRootObject(new IEEE());
|
||||
Inventor einstein =
|
||||
@@ -375,7 +404,7 @@ class SpelDocumentationTests extends AbstractExpressionTests {
|
||||
// 7.5.8
|
||||
|
||||
@Test
|
||||
void variables() throws Exception {
|
||||
public void testVariables() throws Exception {
|
||||
Inventor tesla = new Inventor("Nikola Tesla", "Serbian");
|
||||
StandardEvaluationContext context = new StandardEvaluationContext();
|
||||
context.setVariable("newName", "Mike Tesla");
|
||||
@@ -387,9 +416,9 @@ class SpelDocumentationTests extends AbstractExpressionTests {
|
||||
assertThat(tesla.getFoo()).isEqualTo("Mike Tesla");
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
void specialVariables() throws Exception {
|
||||
@Test
|
||||
public void testSpecialVariables() throws Exception {
|
||||
// create an array of integers
|
||||
List<Integer> primes = Arrays.asList(2, 3, 5, 7, 11, 13, 17);
|
||||
|
||||
@@ -406,7 +435,7 @@ class SpelDocumentationTests extends AbstractExpressionTests {
|
||||
// 7.5.9
|
||||
|
||||
@Test
|
||||
void functions() throws Exception {
|
||||
public void testFunctions() throws Exception {
|
||||
ExpressionParser parser = new SpelExpressionParser();
|
||||
StandardEvaluationContext context = new StandardEvaluationContext();
|
||||
context.registerFunction("reverseString", StringUtils.class.getDeclaredMethod("reverseString", String.class));
|
||||
@@ -418,7 +447,7 @@ class SpelDocumentationTests extends AbstractExpressionTests {
|
||||
// 7.5.10
|
||||
|
||||
@Test
|
||||
void ternary() throws Exception {
|
||||
public void testTernary() throws Exception {
|
||||
String falseString = parser.parseExpression("false ? 'trueExp' : 'falseExp'").getValue(String.class);
|
||||
assertThat(falseString).isEqualTo("falseExp");
|
||||
|
||||
@@ -439,9 +468,9 @@ class SpelDocumentationTests extends AbstractExpressionTests {
|
||||
|
||||
// 7.5.11
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
void selection() throws Exception {
|
||||
@Test
|
||||
public void testSelection() throws Exception {
|
||||
StandardEvaluationContext societyContext = new StandardEvaluationContext();
|
||||
societyContext.setRootObject(new IEEE());
|
||||
List<Inventor> list = (List<Inventor>) parser.parseExpression("Members2.?[nationality == 'Serbian']").getValue(societyContext);
|
||||
@@ -452,7 +481,7 @@ class SpelDocumentationTests extends AbstractExpressionTests {
|
||||
// 7.5.12
|
||||
|
||||
@Test
|
||||
void templating() throws Exception {
|
||||
public void testTemplating() throws Exception {
|
||||
String randomPhrase =
|
||||
parser.parseExpression("random number is ${T(java.lang.Math).random()}", new TemplatedParserContext()).getValue(String.class);
|
||||
assertThat(randomPhrase.startsWith("random number")).isTrue();
|
||||
@@ -476,39 +505,14 @@ class SpelDocumentationTests extends AbstractExpressionTests {
|
||||
}
|
||||
}
|
||||
|
||||
static class IEEE {
|
||||
private String name;
|
||||
|
||||
public Inventor[] Members = new Inventor[1];
|
||||
public List Members2 = new ArrayList();
|
||||
public Map<String,Object> officers = new HashMap<>();
|
||||
|
||||
public List<Map<String, Object>> reverse = new ArrayList<>();
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
IEEE() {
|
||||
officers.put("president",pupin);
|
||||
List linv = new ArrayList();
|
||||
linv.add(tesla);
|
||||
officers.put("advisors",linv);
|
||||
Members2.add(tesla);
|
||||
Members2.add(pupin);
|
||||
|
||||
reverse.add(officers);
|
||||
}
|
||||
|
||||
public boolean isMember(String name) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public String getName() { return name; }
|
||||
public void setName(String n) { this.name = n; }
|
||||
}
|
||||
|
||||
static class StringUtils {
|
||||
|
||||
public static String reverseString(String input) {
|
||||
return new StringBuilder(input).reverse().toString();
|
||||
StringBuilder backwards = new StringBuilder();
|
||||
for (int i = 0; i < input.length(); i++) {
|
||||
backwards.append(input.charAt(input.length() - 1 - i));
|
||||
}
|
||||
return backwards.toString();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -30,7 +30,7 @@ import org.springframework.expression.spel.testresources.PlaceOfBirth;
|
||||
* <li>The root context object is an Inventor instance {@link Inventor}
|
||||
* </ul>
|
||||
*/
|
||||
class TestScenarioCreator {
|
||||
public class TestScenarioCreator {
|
||||
|
||||
public static StandardEvaluationContext getTestEvaluationContext() {
|
||||
StandardEvaluationContext testContext = new StandardEvaluationContext();
|
||||
|
||||
-39
@@ -76,21 +76,6 @@ class SpelCompilerTests {
|
||||
assertThat(expression.getValue(context)).asInstanceOf(BOOLEAN).isTrue();
|
||||
}
|
||||
|
||||
@Test // gh-28043
|
||||
void changingRegisteredVariableTypeDoesNotResultInFailureInMixedMode() {
|
||||
SpelParserConfiguration config = new SpelParserConfiguration(SpelCompilerMode.MIXED, null);
|
||||
SpelExpressionParser parser = new SpelExpressionParser(config);
|
||||
Expression sharedExpression = parser.parseExpression("#bean.value");
|
||||
StandardEvaluationContext context = new StandardEvaluationContext();
|
||||
|
||||
Object[] beans = new Object[] {new Bean1(), new Bean2(), new Bean3(), new Bean4()};
|
||||
|
||||
IntStream.rangeClosed(1, 1_000_000).parallel().forEach(count -> {
|
||||
context.setVariable("bean", beans[count % 4]);
|
||||
assertThat(sharedExpression.getValue(context)).asString().startsWith("1");
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
static class OrderedComponent implements Ordered {
|
||||
|
||||
@@ -136,28 +121,4 @@ class SpelCompilerTests {
|
||||
boolean hasSomeProperty();
|
||||
}
|
||||
|
||||
public static class Bean1 {
|
||||
public String getValue() {
|
||||
return "11";
|
||||
}
|
||||
}
|
||||
|
||||
public static class Bean2 {
|
||||
public Integer getValue() {
|
||||
return 111;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Bean3 {
|
||||
public Float getValue() {
|
||||
return 1.23f;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Bean4 {
|
||||
public Character getValue() {
|
||||
return '1';
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -341,6 +341,12 @@ public class BeanPropertyRowMapper<T> implements RowMapper<T> {
|
||||
"Unable to map column '" + column + "' to property '" + pd.getName() + "'", ex);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// No PropertyDescriptor found
|
||||
if (rowNumber == 0 && logger.isDebugEnabled()) {
|
||||
logger.debug("No property found for column '" + column + "' mapped to field '" + field + "'");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (populatedProperties != null && !populatedProperties.equals(this.mappedProperties)) {
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -320,7 +320,7 @@ public class ReactorNettyTcpClient<P> implements TcpOperations<P> {
|
||||
TcpConnection<P> connection = new ReactorNettyTcpConnection<>(inbound, outbound, codec, completionSink);
|
||||
scheduler.schedule(() -> this.connectionHandler.afterConnected(connection));
|
||||
|
||||
inbound.withConnection(conn -> conn.addHandlerFirst(new StompMessageDecoder<>(codec)));
|
||||
inbound.withConnection(conn -> conn.addHandler(new StompMessageDecoder<>(codec)));
|
||||
|
||||
inbound.receiveObject()
|
||||
.cast(Message.class)
|
||||
|
||||
+1
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -419,7 +419,6 @@ public class OpenEntityManagerInViewTests {
|
||||
private final CountDownLatch latch = new CountDownLatch(1);
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public void execute(Runnable task, long startTimeout) {
|
||||
Runnable decoratedTask = () -> {
|
||||
try {
|
||||
|
||||
+10
-31
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -32,7 +32,7 @@ import org.springframework.util.Assert;
|
||||
*/
|
||||
public class MockClientHttpResponse extends MockHttpInputMessage implements ClientHttpResponse {
|
||||
|
||||
private final int statusCode;
|
||||
private final HttpStatus status;
|
||||
|
||||
|
||||
/**
|
||||
@@ -41,17 +41,7 @@ public class MockClientHttpResponse extends MockHttpInputMessage implements Clie
|
||||
public MockClientHttpResponse(byte[] body, HttpStatus statusCode) {
|
||||
super(body);
|
||||
Assert.notNull(statusCode, "HttpStatus is required");
|
||||
this.statusCode = statusCode.value();
|
||||
}
|
||||
|
||||
/**
|
||||
* Variant of {@link #MockClientHttpResponse(byte[], HttpStatus)} with a
|
||||
* custom HTTP status code.
|
||||
* @since 5.3.17
|
||||
*/
|
||||
public MockClientHttpResponse(byte[] body, int statusCode) {
|
||||
super(body);
|
||||
this.statusCode = statusCode;
|
||||
this.status = statusCode;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -60,34 +50,23 @@ public class MockClientHttpResponse extends MockHttpInputMessage implements Clie
|
||||
public MockClientHttpResponse(InputStream body, HttpStatus statusCode) {
|
||||
super(body);
|
||||
Assert.notNull(statusCode, "HttpStatus is required");
|
||||
this.statusCode = statusCode.value();
|
||||
}
|
||||
|
||||
/**
|
||||
* Variant of {@link #MockClientHttpResponse(InputStream, HttpStatus)} with a
|
||||
* custom HTTP status code.
|
||||
* @since 5.3.17
|
||||
*/
|
||||
public MockClientHttpResponse(InputStream body, int statusCode) {
|
||||
super(body);
|
||||
this.statusCode = statusCode;
|
||||
this.status = statusCode;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public HttpStatus getStatusCode() {
|
||||
return HttpStatus.valueOf(this.statusCode);
|
||||
public HttpStatus getStatusCode() throws IOException {
|
||||
return this.status;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRawStatusCode() {
|
||||
return this.statusCode;
|
||||
public int getRawStatusCode() throws IOException {
|
||||
return this.status.value();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getStatusText() {
|
||||
HttpStatus status = HttpStatus.resolve(this.statusCode);
|
||||
return (status != null ? status.getReasonPhrase() : "");
|
||||
public String getStatusText() throws IOException {
|
||||
return this.status.getReasonPhrase();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+12
-33
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -17,12 +17,16 @@
|
||||
package org.springframework.test.context.event;
|
||||
|
||||
import org.springframework.test.context.TestContext;
|
||||
import org.springframework.test.context.TestExecutionListener;
|
||||
import org.springframework.test.context.support.AbstractTestExecutionListener;
|
||||
|
||||
/**
|
||||
* {@code TestExecutionListener} that publishes test execution events to the
|
||||
* {@link org.springframework.test.context.TestExecutionListener TestExecutionListener}
|
||||
* that publishes test execution events to the
|
||||
* {@link org.springframework.context.ApplicationContext ApplicationContext}
|
||||
* for the currently executing test.
|
||||
* for the currently executing test. Events are only published if the
|
||||
* {@code ApplicationContext} {@linkplain TestContext#hasApplicationContext()
|
||||
* has already been loaded}.
|
||||
*
|
||||
* <h3>Supported Events</h3>
|
||||
* <ul>
|
||||
@@ -37,36 +41,11 @@ import org.springframework.test.context.support.AbstractTestExecutionListener;
|
||||
*
|
||||
* <p>These events may be consumed for various reasons, such as resetting <em>mock</em>
|
||||
* beans or tracing test execution. One advantage of consuming test events rather
|
||||
* than implementing a custom {@link org.springframework.test.context.TestExecutionListener
|
||||
* TestExecutionListener} is that test events may be consumed by any Spring bean
|
||||
* registered in the test {@code ApplicationContext}, and such beans may benefit
|
||||
* directly from dependency injection and other features of the {@code ApplicationContext}.
|
||||
* In contrast, a {@code TestExecutionListener} is not a bean in the {@code ApplicationContext}.
|
||||
*
|
||||
* <p>Note that the {@code EventPublishingTestExecutionListener} is registered by
|
||||
* default; however, it only publishes events if the {@code ApplicationContext}
|
||||
* {@linkplain TestContext#hasApplicationContext() has already been loaded}. This
|
||||
* prevents the {@code ApplicationContext} from being loaded unnecessarily or too
|
||||
* early. Consequently, a {@code BeforeTestClassEvent} will not be published until
|
||||
* after the {@code ApplicationContext} has been loaded by another
|
||||
* {@code TestExecutionListener}. For example, with the default set of
|
||||
* {@code TestExecutionListeners} registered, a {@code BeforeTestClassEvent} will
|
||||
* not be published for the first test class that uses a particular test
|
||||
* {@code ApplicationContext}, but a {@code BeforeTestClassEvent} will be published
|
||||
* for any subsequent test class in the same test suite that uses the same test
|
||||
* {@code ApplicationContext} since the context will already have been loaded
|
||||
* when subsequent test classes run (as long as the context has not been removed
|
||||
* from the {@link org.springframework.test.context.cache.ContextCache ContextCache}
|
||||
* via {@link org.springframework.test.annotation.DirtiesContext @DirtiesContext}
|
||||
* or the max-size eviction policy). If you wish to ensure that a
|
||||
* {@code BeforeTestClassEvent} is published for every test class, you need to
|
||||
* register a {@code TestExecutionListener} that loads the {@code ApplicationContext}
|
||||
* in the {@link org.springframework.test.context.TestExecutionListener#beforeTestClass
|
||||
* beforeTestClass} callback, and that {@code TestExecutionListener} must be registered
|
||||
* before the {@code EventPublishingTestExecutionListener}. Similarly, if
|
||||
* {@code @DirtiesContext} is used to remove the {@code ApplicationContext} from
|
||||
* the context cache after the last test method in a given test class, the
|
||||
* {@code AfterTestClassEvent} will not be published for that test class.
|
||||
* than implementing a custom {@link TestExecutionListener} is that test events
|
||||
* may be consumed by any Spring bean registered in the test {@code ApplicationContext},
|
||||
* and such beans may benefit directly from dependency injection and other features
|
||||
* of the {@code ApplicationContext}. In contrast, a {@link TestExecutionListener}
|
||||
* is not a bean in the {@code ApplicationContext}.
|
||||
*
|
||||
* <h3>Exception Handling</h3>
|
||||
* <p>By default, if a test event listener throws an exception while consuming
|
||||
|
||||
+1
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -49,8 +49,6 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||
* <p>The {@code EventPublishingTestExecutionListener} must be registered in order
|
||||
* for this annotation to have an effect — for example, via
|
||||
* {@link org.springframework.test.context.TestExecutionListeners @TestExecutionListeners}.
|
||||
* Note, however, that the {@code EventPublishingTestExecutionListener} is registered
|
||||
* by default.
|
||||
*
|
||||
* @author Frank Scheffler
|
||||
* @author Sam Brannen
|
||||
|
||||
+1
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -49,8 +49,6 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||
* <p>The {@code EventPublishingTestExecutionListener} must be registered in order
|
||||
* for this annotation to have an effect — for example, via
|
||||
* {@link org.springframework.test.context.TestExecutionListeners @TestExecutionListeners}.
|
||||
* Note, however, that the {@code EventPublishingTestExecutionListener} is registered
|
||||
* by default.
|
||||
*
|
||||
* @author Frank Scheffler
|
||||
* @author Sam Brannen
|
||||
|
||||
+1
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -49,8 +49,6 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||
* <p>The {@code EventPublishingTestExecutionListener} must be registered in order
|
||||
* for this annotation to have an effect — for example, via
|
||||
* {@link org.springframework.test.context.TestExecutionListeners @TestExecutionListeners}.
|
||||
* Note, however, that the {@code EventPublishingTestExecutionListener} is registered
|
||||
* by default.
|
||||
*
|
||||
* @author Frank Scheffler
|
||||
* @author Sam Brannen
|
||||
|
||||
+1
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -49,8 +49,6 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||
* <p>The {@code EventPublishingTestExecutionListener} must be registered in order
|
||||
* for this annotation to have an effect — for example, via
|
||||
* {@link org.springframework.test.context.TestExecutionListeners @TestExecutionListeners}.
|
||||
* Note, however, that the {@code EventPublishingTestExecutionListener} is registered
|
||||
* by default.
|
||||
*
|
||||
* @author Frank Scheffler
|
||||
* @author Sam Brannen
|
||||
|
||||
+1
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -49,8 +49,6 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||
* <p>The {@code EventPublishingTestExecutionListener} must be registered in order
|
||||
* for this annotation to have an effect — for example, via
|
||||
* {@link org.springframework.test.context.TestExecutionListeners @TestExecutionListeners}.
|
||||
* Note, however, that the {@code EventPublishingTestExecutionListener} is registered
|
||||
* by default.
|
||||
*
|
||||
* @author Frank Scheffler
|
||||
* @author Sam Brannen
|
||||
|
||||
+1
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -49,8 +49,6 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||
* <p>The {@code EventPublishingTestExecutionListener} must be registered in order
|
||||
* for this annotation to have an effect — for example, via
|
||||
* {@link org.springframework.test.context.TestExecutionListeners @TestExecutionListeners}.
|
||||
* Note, however, that the {@code EventPublishingTestExecutionListener} is registered
|
||||
* by default.
|
||||
*
|
||||
* @author Frank Scheffler
|
||||
* @author Sam Brannen
|
||||
|
||||
+1
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -49,8 +49,6 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||
* <p>The {@code EventPublishingTestExecutionListener} must be registered in order
|
||||
* for this annotation to have an effect — for example, via
|
||||
* {@link org.springframework.test.context.TestExecutionListeners @TestExecutionListeners}.
|
||||
* Note, however, that the {@code EventPublishingTestExecutionListener} is registered
|
||||
* by default.
|
||||
*
|
||||
* @author Frank Scheffler
|
||||
* @author Sam Brannen
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
/**
|
||||
* Test execution event annotations for the <em>Spring TestContext Framework</em>.
|
||||
* Test event annotations for the <em>Spring TestContext Framework</em>.
|
||||
*/
|
||||
package org.springframework.test.context.event.annotation;
|
||||
|
||||
+1
-12
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -50,23 +50,12 @@ import org.springframework.core.annotation.AliasFor;
|
||||
* public {@literal @}interface DisabledOnMac {}
|
||||
* </pre>
|
||||
*
|
||||
* <p>Please note that {@code @DisabledOnMac} is meant only as an example of what
|
||||
* is possible. If you have that exact use case, please use the built-in
|
||||
* {@link org.junit.jupiter.api.condition.DisabledOnOs @DisabledOnOs(MAC)} support
|
||||
* in JUnit Jupiter.
|
||||
*
|
||||
* <p>Since JUnit 5.7, JUnit Jupiter also has a condition annotation named
|
||||
* {@link org.junit.jupiter.api.condition.DisabledIf @DisabledIf}. Thus, if you
|
||||
* wish to use Spring's {@code @DisabledIf} support make sure you import the
|
||||
* annotation type from the correct package.
|
||||
*
|
||||
* @author Sam Brannen
|
||||
* @author Tadaya Tsuyukubo
|
||||
* @since 5.0
|
||||
* @see SpringExtension
|
||||
* @see EnabledIf
|
||||
* @see org.junit.jupiter.api.Disabled
|
||||
* @see org.junit.jupiter.api.condition.DisabledIf
|
||||
*/
|
||||
@Target({ElementType.TYPE, ElementType.METHOD})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
|
||||
+1
-12
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -50,22 +50,11 @@ import org.springframework.core.annotation.AliasFor;
|
||||
* public {@literal @}interface EnabledOnMac {}
|
||||
* </pre>
|
||||
*
|
||||
* <p>Please note that {@code @EnabledOnMac} is meant only as an example of what
|
||||
* is possible. If you have that exact use case, please use the built-in
|
||||
* {@link org.junit.jupiter.api.condition.EnabledOnOs @EnabledOnOs(MAC)} support
|
||||
* in JUnit Jupiter.
|
||||
*
|
||||
* <p>Since JUnit 5.7, JUnit Jupiter also has a condition annotation named
|
||||
* {@link org.junit.jupiter.api.condition.EnabledIf @EnabledIf}. Thus, if you
|
||||
* wish to use Spring's {@code @EnabledIf} support make sure you import the
|
||||
* annotation type from the correct package.
|
||||
*
|
||||
* @author Sam Brannen
|
||||
* @since 5.0
|
||||
* @see SpringExtension
|
||||
* @see DisabledIf
|
||||
* @see org.junit.jupiter.api.Disabled
|
||||
* @see org.junit.jupiter.api.condition.EnabledIf
|
||||
*/
|
||||
@Target({ElementType.TYPE, ElementType.METHOD})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
|
||||
+11
-14
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -17,6 +17,7 @@
|
||||
package org.springframework.test.web.client.response;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URI;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
@@ -39,7 +40,7 @@ import org.springframework.util.Assert;
|
||||
*/
|
||||
public class DefaultResponseCreator implements ResponseCreator {
|
||||
|
||||
private final int statusCode;
|
||||
private HttpStatus statusCode;
|
||||
|
||||
private byte[] content = new byte[0];
|
||||
|
||||
@@ -55,15 +56,6 @@ public class DefaultResponseCreator implements ResponseCreator {
|
||||
*/
|
||||
protected DefaultResponseCreator(HttpStatus statusCode) {
|
||||
Assert.notNull(statusCode, "HttpStatus must not be null");
|
||||
this.statusCode = statusCode.value();
|
||||
}
|
||||
|
||||
/**
|
||||
* Protected constructor.
|
||||
* Use static factory methods in {@link MockRestResponseCreators}.
|
||||
* @since 5.3.17
|
||||
*/
|
||||
protected DefaultResponseCreator(int statusCode) {
|
||||
this.statusCode = statusCode;
|
||||
}
|
||||
|
||||
@@ -119,9 +111,14 @@ public class DefaultResponseCreator implements ResponseCreator {
|
||||
|
||||
@Override
|
||||
public ClientHttpResponse createResponse(@Nullable ClientHttpRequest request) throws IOException {
|
||||
MockClientHttpResponse response = (this.contentResource != null ?
|
||||
new MockClientHttpResponse(this.contentResource.getInputStream(), this.statusCode) :
|
||||
new MockClientHttpResponse(this.content, this.statusCode));
|
||||
MockClientHttpResponse response;
|
||||
if (this.contentResource != null) {
|
||||
InputStream stream = this.contentResource.getInputStream();
|
||||
response = new MockClientHttpResponse(stream, this.statusCode);
|
||||
}
|
||||
else {
|
||||
response = new MockClientHttpResponse(this.content, this.statusCode);
|
||||
}
|
||||
response.getHeaders().putAll(this.headers);
|
||||
return response;
|
||||
}
|
||||
|
||||
+1
-10
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -117,15 +117,6 @@ public abstract class MockRestResponseCreators {
|
||||
return new DefaultResponseCreator(status);
|
||||
}
|
||||
|
||||
/**
|
||||
* Variant of {@link #withStatus(HttpStatus)} for a custom HTTP status code.
|
||||
* @param status the response status
|
||||
* @since 5.3.17
|
||||
*/
|
||||
public static DefaultResponseCreator withRawStatus(int status) {
|
||||
return new DefaultResponseCreator(status);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@code ResponseCreator} with an internal application {@code IOException}.
|
||||
* <p>For example, one could use this to simulate a {@code SocketTimeoutException}.
|
||||
|
||||
+13
-17
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -19,9 +19,9 @@ package org.springframework.mock.http.server.reactive;
|
||||
import java.util.Arrays;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.assertj.core.api.ThrowableAssert.ThrowingCallable;
|
||||
import org.junit.jupiter.api.Named;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.function.Executable;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
||||
@@ -31,8 +31,6 @@ import org.springframework.http.HttpMethod;
|
||||
import org.springframework.web.util.UriComponentsBuilder;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
|
||||
import static org.junit.jupiter.api.Named.named;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link MockServerHttpRequest}.
|
||||
@@ -65,23 +63,21 @@ class MockServerHttpRequestTests {
|
||||
assertThat(request.getURI().toString()).isEqualTo("/foo%20bar?a=b&name%20A=value%20A1&name%20A=value%20A2&name%20B=value%20B1");
|
||||
}
|
||||
|
||||
@ParameterizedTest(name = "[{index}] {0}")
|
||||
@ParameterizedTest
|
||||
@MethodSource
|
||||
void httpMethodNotNullOrEmpty(ThrowingCallable callable) {
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(callable)
|
||||
.withMessageContaining("HTTP method is required.");
|
||||
void httpMethodNotNullOrEmpty(Executable executable) {
|
||||
Exception ex = Assertions.assertThrows(IllegalArgumentException.class, executable);
|
||||
assertThat(ex.getMessage()).contains("HTTP method is required.");
|
||||
}
|
||||
|
||||
static Stream<Named<ThrowingCallable>> httpMethodNotNullOrEmpty() {
|
||||
static Stream<Executable> httpMethodNotNullOrEmpty() {
|
||||
String uriTemplate = "/foo bar?a=b";
|
||||
return Stream.of(
|
||||
named("null HttpMethod, URI", () -> MockServerHttpRequest.method(null, UriComponentsBuilder.fromUriString(uriTemplate).build("")).build()),
|
||||
named("null HttpMethod, uriTemplate", () -> MockServerHttpRequest.method((HttpMethod) null, uriTemplate).build()),
|
||||
named("null String, uriTemplate", () -> MockServerHttpRequest.method((String) null, uriTemplate).build()),
|
||||
named("empty String, uriTemplate", () -> MockServerHttpRequest.method("", uriTemplate).build()),
|
||||
named("blank String, uriTemplate", () -> MockServerHttpRequest.method(" ", uriTemplate).build())
|
||||
() -> MockServerHttpRequest.method(null, UriComponentsBuilder.fromUriString(uriTemplate).build("")).build(),
|
||||
() -> MockServerHttpRequest.method((HttpMethod) null, uriTemplate).build(),
|
||||
() -> MockServerHttpRequest.method((String) null, uriTemplate).build(),
|
||||
() -> MockServerHttpRequest.method("", uriTemplate).build(),
|
||||
() -> MockServerHttpRequest.method(" ", uriTemplate).build()
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -40,7 +40,6 @@ import org.springframework.test.context.web.WebTestContextBootstrapper;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
|
||||
import static org.junit.jupiter.api.Named.named;
|
||||
import static org.junit.jupiter.params.provider.Arguments.arguments;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.springframework.test.context.BootstrapUtils.resolveTestContextBootstrapper;
|
||||
@@ -105,9 +104,9 @@ class BootstrapUtilsTests {
|
||||
/**
|
||||
* @since 5.3
|
||||
*/
|
||||
@ParameterizedTest(name = "[{index}] {0}")
|
||||
@ParameterizedTest(name = "{0}")
|
||||
@MethodSource
|
||||
void resolveTestContextBootstrapperInEnclosingClassHierarchy(Class<?> testClass, Class<?> expectedBootstrapper) {
|
||||
void resolveTestContextBootstrapperInEnclosingClassHierarchy(String name, Class<?> testClass, Class<?> expectedBootstrapper) {
|
||||
assertBootstrapper(testClass, expectedBootstrapper);
|
||||
}
|
||||
|
||||
@@ -130,7 +129,7 @@ class BootstrapUtilsTests {
|
||||
}
|
||||
|
||||
private static Arguments args(Class<?> testClass, Class<? extends TestContextBootstrapper> expectedBootstrapper) {
|
||||
return arguments(named(testClass.getSimpleName(), testClass), expectedBootstrapper);
|
||||
return arguments(testClass.getSimpleName(), testClass, expectedBootstrapper);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
-237
@@ -1,237 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://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.springframework.test.context.event;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.MethodOrderer.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.TestMethodOrder;
|
||||
import org.junit.platform.testkit.engine.EngineTestKit;
|
||||
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.annotation.DirtiesContext.MethodMode;
|
||||
import org.springframework.test.context.TestPropertySource;
|
||||
import org.springframework.test.context.event.annotation.AfterTestClass;
|
||||
import org.springframework.test.context.event.annotation.AfterTestExecution;
|
||||
import org.springframework.test.context.event.annotation.AfterTestMethod;
|
||||
import org.springframework.test.context.event.annotation.BeforeTestClass;
|
||||
import org.springframework.test.context.event.annotation.BeforeTestExecution;
|
||||
import org.springframework.test.context.event.annotation.BeforeTestMethod;
|
||||
import org.springframework.test.context.event.annotation.PrepareTestInstance;
|
||||
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.junit.platform.engine.discovery.DiscoverySelectors.selectClass;
|
||||
|
||||
/**
|
||||
* Tests for the {@link EventPublishingTestExecutionListener} which verify
|
||||
* behavior for test context events when {@link DirtiesContext @DirtiesContext}
|
||||
* is used.
|
||||
*
|
||||
* @author Sam Brannen
|
||||
* @since 5.3.17
|
||||
* @see https://github.com/spring-projects/spring-framework/issues/27757
|
||||
*/
|
||||
class DirtiesContextEventPublishingTests {
|
||||
|
||||
private static final List<Class<? extends TestContextEvent>> events = new ArrayList<>();
|
||||
|
||||
|
||||
@BeforeEach
|
||||
@AfterEach
|
||||
void resetEvents() {
|
||||
events.clear();
|
||||
}
|
||||
|
||||
@Test
|
||||
void classLevelDirtiesContext() {
|
||||
EngineTestKit.engine("junit-jupiter")//
|
||||
.selectors(selectClass(ClassLevelDirtiesContextTestCase.class))//
|
||||
.execute()//
|
||||
.testEvents()//
|
||||
.assertStatistics(stats -> stats.started(1).succeeded(1).failed(0));
|
||||
|
||||
assertThat(events).containsExactly(//
|
||||
// BeforeTestClassEvent.class -- always missing for 1st test class by default
|
||||
PrepareTestInstanceEvent.class, //
|
||||
BeforeTestMethodEvent.class, //
|
||||
BeforeTestExecutionEvent.class, //
|
||||
AfterTestExecutionEvent.class, //
|
||||
AfterTestMethodEvent.class, //
|
||||
AfterTestClassEvent.class //
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
void methodLevelAfterMethodDirtiesContext() {
|
||||
EngineTestKit.engine("junit-jupiter")//
|
||||
.selectors(selectClass(MethodLevelAfterMethodDirtiesContextTestCase.class))//
|
||||
.execute()//
|
||||
.testEvents()//
|
||||
.assertStatistics(stats -> stats.started(1).succeeded(1).failed(0));
|
||||
|
||||
assertThat(events).containsExactly(//
|
||||
// BeforeTestClassEvent.class -- always missing for 1st test class by default
|
||||
PrepareTestInstanceEvent.class, //
|
||||
BeforeTestMethodEvent.class, //
|
||||
BeforeTestExecutionEvent.class, //
|
||||
AfterTestExecutionEvent.class, //
|
||||
AfterTestMethodEvent.class //
|
||||
// AfterTestClassEvent.class -- missing b/c of @DirtiestContext "after method" at the method level
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
void methodLevelAfterMethodDirtiesContextWithSubsequentTestMethod() {
|
||||
EngineTestKit.engine("junit-jupiter")//
|
||||
.selectors(selectClass(MethodLevelAfterMethodDirtiesContextWithSubsequentTestMethodTestCase.class))//
|
||||
.execute()//
|
||||
.testEvents()//
|
||||
.assertStatistics(stats -> stats.started(2).succeeded(2).failed(0));
|
||||
|
||||
assertThat(events).containsExactly(//
|
||||
// BeforeTestClassEvent.class -- always missing for 1st test class by default
|
||||
// test1()
|
||||
PrepareTestInstanceEvent.class, //
|
||||
BeforeTestMethodEvent.class, //
|
||||
BeforeTestExecutionEvent.class, //
|
||||
AfterTestExecutionEvent.class, //
|
||||
AfterTestMethodEvent.class, //
|
||||
// test2()
|
||||
PrepareTestInstanceEvent.class, //
|
||||
BeforeTestMethodEvent.class, //
|
||||
BeforeTestExecutionEvent.class, //
|
||||
AfterTestExecutionEvent.class, //
|
||||
AfterTestMethodEvent.class, //
|
||||
AfterTestClassEvent.class // b/c @DirtiestContext is not applied for test2()
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
void methodLevelBeforeMethodDirtiesContext() {
|
||||
EngineTestKit.engine("junit-jupiter")//
|
||||
.selectors(selectClass(MethodLevelBeforeMethodDirtiesContextTestCase.class))//
|
||||
.execute()//
|
||||
.testEvents()//
|
||||
.assertStatistics(stats -> stats.started(1).succeeded(1).failed(0));
|
||||
|
||||
assertThat(events).containsExactly(//
|
||||
// BeforeTestClassEvent.class -- always missing for 1st test class by default
|
||||
PrepareTestInstanceEvent.class, //
|
||||
BeforeTestMethodEvent.class, //
|
||||
BeforeTestExecutionEvent.class, //
|
||||
AfterTestExecutionEvent.class, //
|
||||
AfterTestMethodEvent.class, //
|
||||
AfterTestClassEvent.class // b/c @DirtiestContext happens "before method" at the method level
|
||||
);
|
||||
}
|
||||
|
||||
@SpringJUnitConfig(Config.class)
|
||||
// add unique property to get a unique ApplicationContext
|
||||
@TestPropertySource(properties = "DirtiesContextEventPublishingTests.key = class-level")
|
||||
@DirtiesContext
|
||||
static class ClassLevelDirtiesContextTestCase {
|
||||
|
||||
@Test
|
||||
void test() {
|
||||
}
|
||||
}
|
||||
|
||||
@SpringJUnitConfig(Config.class)
|
||||
// add unique property to get a unique ApplicationContext
|
||||
@TestPropertySource(properties = "DirtiesContextEventPublishingTests.key = method-level-after-method")
|
||||
static class MethodLevelAfterMethodDirtiesContextTestCase {
|
||||
|
||||
@Test
|
||||
@DirtiesContext
|
||||
void test1() {
|
||||
}
|
||||
}
|
||||
|
||||
@SpringJUnitConfig(Config.class)
|
||||
// add unique property to get a unique ApplicationContext
|
||||
@TestPropertySource(properties = "DirtiesContextEventPublishingTests.key = method-level-after-method-with-subsequent-test-method")
|
||||
@TestMethodOrder(DisplayName.class)
|
||||
static class MethodLevelAfterMethodDirtiesContextWithSubsequentTestMethodTestCase {
|
||||
|
||||
@Test
|
||||
@DirtiesContext
|
||||
void test1() {
|
||||
}
|
||||
|
||||
@Test
|
||||
void test2() {
|
||||
}
|
||||
}
|
||||
|
||||
@SpringJUnitConfig(Config.class)
|
||||
// add unique property to get a unique ApplicationContext
|
||||
@TestPropertySource(properties = "DirtiesContextEventPublishingTests.key = method-level-before-method")
|
||||
static class MethodLevelBeforeMethodDirtiesContextTestCase {
|
||||
|
||||
@Test
|
||||
@DirtiesContext(methodMode = MethodMode.BEFORE_METHOD)
|
||||
void test() {
|
||||
}
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class Config {
|
||||
|
||||
@BeforeTestClass
|
||||
public void beforeTestClass(BeforeTestClassEvent e) {
|
||||
events.add(e.getClass());
|
||||
}
|
||||
|
||||
@PrepareTestInstance
|
||||
public void prepareTestInstance(PrepareTestInstanceEvent e) {
|
||||
events.add(e.getClass());
|
||||
}
|
||||
|
||||
@BeforeTestMethod
|
||||
public void beforeTestMethod(BeforeTestMethodEvent e) {
|
||||
events.add(e.getClass());
|
||||
}
|
||||
|
||||
@BeforeTestExecution
|
||||
public void beforeTestExecution(BeforeTestExecutionEvent e) {
|
||||
events.add(e.getClass());
|
||||
}
|
||||
|
||||
@AfterTestExecution
|
||||
public void afterTestExecution(AfterTestExecutionEvent e) {
|
||||
events.add(e.getClass());
|
||||
}
|
||||
|
||||
@AfterTestMethod
|
||||
public void afterTestMethod(AfterTestMethodEvent e) {
|
||||
events.add(e.getClass());
|
||||
}
|
||||
|
||||
@AfterTestClass
|
||||
public void afterTestClass(AfterTestClassEvent e) {
|
||||
events.add(e.getClass());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
-190
@@ -1,190 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://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.springframework.test.context.event;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.platform.testkit.engine.EngineTestKit;
|
||||
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.test.context.TestContext;
|
||||
import org.springframework.test.context.TestExecutionListener;
|
||||
import org.springframework.test.context.TestExecutionListeners;
|
||||
import org.springframework.test.context.TestExecutionListeners.MergeMode;
|
||||
import org.springframework.test.context.event.annotation.AfterTestClass;
|
||||
import org.springframework.test.context.event.annotation.AfterTestExecution;
|
||||
import org.springframework.test.context.event.annotation.AfterTestMethod;
|
||||
import org.springframework.test.context.event.annotation.BeforeTestClass;
|
||||
import org.springframework.test.context.event.annotation.BeforeTestExecution;
|
||||
import org.springframework.test.context.event.annotation.BeforeTestMethod;
|
||||
import org.springframework.test.context.event.annotation.PrepareTestInstance;
|
||||
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.junit.platform.engine.discovery.DiscoverySelectors.selectClass;
|
||||
|
||||
/**
|
||||
* Tests for the {@link EventPublishingTestExecutionListener} which verify that
|
||||
* a {@link BeforeTestClassEvent} can be eagerly published; whereas, such an
|
||||
* event is not published by default for the first run of a test class for a
|
||||
* specific {@code ApplicationContext}.
|
||||
*
|
||||
* @author Sam Brannen
|
||||
* @since 5.3.17
|
||||
* @see https://github.com/spring-projects/spring-framework/issues/27757
|
||||
*/
|
||||
class EagerTestExecutionEventPublishingTests {
|
||||
|
||||
private static final List<Class<? extends TestContextEvent>> events = new ArrayList<>();
|
||||
|
||||
|
||||
@BeforeEach
|
||||
@AfterEach
|
||||
void resetEvents() {
|
||||
events.clear();
|
||||
}
|
||||
|
||||
@Test
|
||||
void beforeTestClassEventIsNotPublishedByDefaultForFirstTestClass() {
|
||||
EngineTestKit.engine("junit-jupiter")//
|
||||
.selectors(selectClass(LazyTestCase1.class), selectClass(LazyTestCase2.class))//
|
||||
.execute()//
|
||||
.testEvents()//
|
||||
.assertStatistics(stats -> stats.started(2).succeeded(2).failed(0));
|
||||
|
||||
assertThat(events).containsExactly(//
|
||||
// 1st test class
|
||||
// BeforeTestClassEvent.class -- missing for 1st test class
|
||||
PrepareTestInstanceEvent.class, //
|
||||
BeforeTestMethodEvent.class, //
|
||||
BeforeTestExecutionEvent.class, //
|
||||
AfterTestExecutionEvent.class, //
|
||||
AfterTestMethodEvent.class, //
|
||||
AfterTestClassEvent.class, //
|
||||
// 2nd test class
|
||||
BeforeTestClassEvent.class, //
|
||||
PrepareTestInstanceEvent.class, //
|
||||
BeforeTestMethodEvent.class, //
|
||||
BeforeTestExecutionEvent.class, //
|
||||
AfterTestExecutionEvent.class, //
|
||||
AfterTestMethodEvent.class, //
|
||||
AfterTestClassEvent.class//
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
void beforeTestClassEventIsPublishedForAllTestClassesIfCustomListenerEagerlyLoadsContext() {
|
||||
EngineTestKit.engine("junit-jupiter")//
|
||||
.selectors(selectClass(EagerTestCase1.class), selectClass(EagerTestCase2.class))//
|
||||
.execute()//
|
||||
.testEvents()//
|
||||
.assertStatistics(stats -> stats.started(2).succeeded(2).failed(0));
|
||||
|
||||
assertThat(events).containsExactly(//
|
||||
// 1st test class
|
||||
BeforeTestClassEvent.class, //
|
||||
PrepareTestInstanceEvent.class, //
|
||||
BeforeTestMethodEvent.class, //
|
||||
BeforeTestExecutionEvent.class, //
|
||||
AfterTestExecutionEvent.class, //
|
||||
AfterTestMethodEvent.class, //
|
||||
AfterTestClassEvent.class, //
|
||||
// 2nd test class
|
||||
BeforeTestClassEvent.class, //
|
||||
PrepareTestInstanceEvent.class, //
|
||||
BeforeTestMethodEvent.class, //
|
||||
BeforeTestExecutionEvent.class, //
|
||||
AfterTestExecutionEvent.class, //
|
||||
AfterTestMethodEvent.class, //
|
||||
AfterTestClassEvent.class//
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@SpringJUnitConfig(Config.class)
|
||||
static class LazyTestCase1 {
|
||||
|
||||
@Test
|
||||
void test() {
|
||||
}
|
||||
}
|
||||
|
||||
static class LazyTestCase2 extends LazyTestCase1 {
|
||||
}
|
||||
|
||||
@TestExecutionListeners(listeners = EagerLoadingTestExecutionListener.class, mergeMode = MergeMode.MERGE_WITH_DEFAULTS)
|
||||
static class EagerTestCase1 extends LazyTestCase1 {
|
||||
}
|
||||
|
||||
static class EagerTestCase2 extends EagerTestCase1 {
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class Config {
|
||||
|
||||
@BeforeTestClass
|
||||
public void beforeTestClass(BeforeTestClassEvent e) {
|
||||
events.add(e.getClass());
|
||||
}
|
||||
|
||||
@PrepareTestInstance
|
||||
public void prepareTestInstance(PrepareTestInstanceEvent e) {
|
||||
events.add(e.getClass());
|
||||
}
|
||||
|
||||
@BeforeTestMethod
|
||||
public void beforeTestMethod(BeforeTestMethodEvent e) {
|
||||
events.add(e.getClass());
|
||||
}
|
||||
|
||||
@BeforeTestExecution
|
||||
public void beforeTestExecution(BeforeTestExecutionEvent e) {
|
||||
events.add(e.getClass());
|
||||
}
|
||||
|
||||
@AfterTestExecution
|
||||
public void afterTestExecution(AfterTestExecutionEvent e) {
|
||||
events.add(e.getClass());
|
||||
}
|
||||
|
||||
@AfterTestMethod
|
||||
public void afterTestMethod(AfterTestMethodEvent e) {
|
||||
events.add(e.getClass());
|
||||
}
|
||||
|
||||
@AfterTestClass
|
||||
public void afterTestClass(AfterTestClassEvent e) {
|
||||
events.add(e.getClass());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Order(0)
|
||||
static class EagerLoadingTestExecutionListener implements TestExecutionListener {
|
||||
|
||||
@Override
|
||||
public void beforeTestClass(TestContext testContext) {
|
||||
testContext.getApplicationContext();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+17
-18
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -27,10 +27,10 @@ import org.junit.jupiter.params.provider.MethodSource;
|
||||
import org.springframework.core.annotation.AnnotationUtils;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.ContextLoader;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.junit.jupiter.api.Named.named;
|
||||
import static org.junit.jupiter.params.provider.Arguments.arguments;
|
||||
|
||||
/**
|
||||
@@ -53,11 +53,13 @@ class GenericXmlContextLoaderResourceLocationsTests {
|
||||
|
||||
@ParameterizedTest(name = "[{index}] {0}")
|
||||
@MethodSource("contextConfigurationLocationsData")
|
||||
void assertContextConfigurationLocations(Class<?> testClass, String[] expectedLocations) throws Exception {
|
||||
ContextConfiguration contextConfig = testClass.getAnnotation(ContextConfiguration.class);
|
||||
ContextLoader contextLoader = new GenericXmlContextLoader();
|
||||
String[] configuredLocations = (String[]) AnnotationUtils.getValue(contextConfig);
|
||||
String[] processedLocations = contextLoader.processLocations(testClass, configuredLocations);
|
||||
void assertContextConfigurationLocations(String testClassName, String[] expectedLocations) throws Exception {
|
||||
Class<?> testClass = ClassUtils.forName(getClass().getName() + "$" + testClassName, getClass().getClassLoader());
|
||||
|
||||
final ContextConfiguration contextConfig = testClass.getAnnotation(ContextConfiguration.class);
|
||||
final ContextLoader contextLoader = new GenericXmlContextLoader();
|
||||
final String[] configuredLocations = (String[]) AnnotationUtils.getValue(contextConfig);
|
||||
final String[] processedLocations = contextLoader.processLocations(testClass, configuredLocations);
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("----------------------------------------------------------------------");
|
||||
@@ -71,32 +73,29 @@ class GenericXmlContextLoaderResourceLocationsTests {
|
||||
|
||||
static Stream<Arguments> contextConfigurationLocationsData() {
|
||||
return Stream.of(
|
||||
args(ClasspathNonExistentDefaultLocationsTestCase.class, array()),
|
||||
arguments(ClasspathNonExistentDefaultLocationsTestCase.class.getSimpleName(), array()),
|
||||
|
||||
args(ClasspathExistentDefaultLocationsTestCase.class, array(
|
||||
arguments(ClasspathExistentDefaultLocationsTestCase.class.getSimpleName(), array(
|
||||
"classpath:org/springframework/test/context/support/GenericXmlContextLoaderResourceLocationsTests$ClasspathExistentDefaultLocationsTestCase-context.xml")),
|
||||
|
||||
args(ImplicitClasspathLocationsTestCase.class,
|
||||
arguments(ImplicitClasspathLocationsTestCase.class.getSimpleName(),
|
||||
array("classpath:/org/springframework/test/context/support/context1.xml",
|
||||
"classpath:/org/springframework/test/context/support/context2.xml")),
|
||||
|
||||
args(ExplicitClasspathLocationsTestCase.class, array("classpath:context.xml")),
|
||||
arguments(ExplicitClasspathLocationsTestCase.class.getSimpleName(), array("classpath:context.xml")),
|
||||
|
||||
args(ExplicitFileLocationsTestCase.class, array("file:/testing/directory/context.xml")),
|
||||
arguments(ExplicitFileLocationsTestCase.class.getSimpleName(),
|
||||
array("file:/testing/directory/context.xml")),
|
||||
|
||||
args(ExplicitUrlLocationsTestCase.class, array("https://example.com/context.xml")),
|
||||
arguments(ExplicitUrlLocationsTestCase.class.getSimpleName(), array("https://example.com/context.xml")),
|
||||
|
||||
args(ExplicitMixedPathTypesLocationsTestCase.class,
|
||||
arguments(ExplicitMixedPathTypesLocationsTestCase.class.getSimpleName(),
|
||||
array("classpath:/org/springframework/test/context/support/context1.xml", "classpath:context2.xml",
|
||||
"classpath:/context3.xml", "file:/testing/directory/context.xml",
|
||||
"https://example.com/context.xml"))
|
||||
);
|
||||
}
|
||||
|
||||
private static Arguments args(Class<?> testClass, String[] expectedLocations) {
|
||||
return arguments(named(testClass.getSimpleName(), testClass), expectedLocations);
|
||||
}
|
||||
|
||||
private static String[] array(String... elements) {
|
||||
return elements;
|
||||
}
|
||||
|
||||
+1
-10
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -128,15 +128,6 @@ class ResponseCreatorsTests {
|
||||
assertThat(StreamUtils.copyToByteArray(response.getBody()).length).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
void withCustomStatus() throws Exception {
|
||||
DefaultResponseCreator responseCreator = MockRestResponseCreators.withRawStatus(454);
|
||||
MockClientHttpResponse response = (MockClientHttpResponse) responseCreator.createResponse(null);
|
||||
|
||||
assertThat(response.getRawStatusCode()).isEqualTo(454);
|
||||
assertThat(response.getStatusText()).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
void withException() {
|
||||
ResponseCreator responseCreator = MockRestResponseCreators.withException(new SocketTimeoutException());
|
||||
|
||||
+33
-72
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -37,57 +37,17 @@ import org.springframework.transaction.TransactionDefinition;
|
||||
* <a href="https://docs.spring.io/spring-framework/docs/current/reference/html/data-access.html#transaction">Transaction Management</a>
|
||||
* section of the reference manual.
|
||||
*
|
||||
* <p>This annotation is generally directly comparable to Spring's
|
||||
* <p>This annotation type is generally directly comparable to Spring's
|
||||
* {@link org.springframework.transaction.interceptor.RuleBasedTransactionAttribute}
|
||||
* class, and in fact {@link AnnotationTransactionAttributeSource} will directly
|
||||
* convert this annotation's attributes to properties in {@code RuleBasedTransactionAttribute},
|
||||
* so that Spring's transaction support code does not have to know about annotations.
|
||||
* convert the data to the latter class, so that Spring's transaction support code
|
||||
* does not have to know about annotations. If no custom rollback rules apply,
|
||||
* the transaction will roll back on {@link RuntimeException} and {@link Error}
|
||||
* but not on checked exceptions.
|
||||
*
|
||||
* <h3>Attribute Semantics</h3>
|
||||
*
|
||||
* <p>If no custom rollback rules are configured in this annotation, the transaction
|
||||
* will roll back on {@link RuntimeException} and {@link Error} but not on checked
|
||||
* exceptions.
|
||||
*
|
||||
* <p>Rollback rules determine if a transaction should be rolled back when a given
|
||||
* exception is thrown, and the rules are based on patterns. A pattern can be a
|
||||
* fully qualified class name or a substring of a fully qualified class name for
|
||||
* an exception type (which must be a subclass of {@code Throwable}), with no
|
||||
* wildcard support at present. For example, a value of
|
||||
* {@code "javax.servlet.ServletException"} or {@code "ServletException"} will
|
||||
* match {@code javax.servlet.ServletException} and its subclasses.
|
||||
*
|
||||
* <p>Rollback rules may be configured via {@link #rollbackFor}/{@link #noRollbackFor}
|
||||
* and {@link #rollbackForClassName}/{@link #noRollbackForClassName}, which allow
|
||||
* patterns to be specified as {@link Class} references or {@linkplain String
|
||||
* strings}, respectively. When an exception type is specified as a class reference
|
||||
* its fully qualified name will be used as the pattern. Consequently,
|
||||
* {@code @Transactional(rollbackFor = example.CustomException.class)} is equivalent
|
||||
* to {@code @Transactional(rollbackForClassName = "example.CustomException")}.
|
||||
*
|
||||
* <p><strong>WARNING:</strong> You must carefully consider how specific the pattern
|
||||
* is and whether to include package information (which isn't mandatory). For example,
|
||||
* {@code "Exception"} will match nearly anything and will probably hide other
|
||||
* rules. {@code "java.lang.Exception"} would be correct if {@code "Exception"}
|
||||
* were meant to define a rule for all checked exceptions. With more unique
|
||||
* exception names such as {@code "BaseBusinessException"} there is likely no
|
||||
* need to use the fully qualified class name for the exception pattern. Furthermore,
|
||||
* rollback rules may result in unintentional matches for similarly named exceptions
|
||||
* and nested classes. This is due to the fact that a thrown exception is considered
|
||||
* to be a match for a given rollback rule if the name of thrown exception contains
|
||||
* the exception pattern configured for the rollback rule. For example, given a
|
||||
* rule configured to match on {@code com.example.CustomException}, that rule
|
||||
* would match against an exception named
|
||||
* {@code com.example.CustomExceptionV2} (an exception in the same package as
|
||||
* {@code CustomException} but with an additional suffix) or an exception named
|
||||
* {@code com.example.CustomException$AnotherException}
|
||||
* (an exception declared as a nested class in {@code CustomException}).
|
||||
*
|
||||
* <p>For specific information about the semantics of other attributes in this
|
||||
* annotation, consult the {@link org.springframework.transaction.TransactionDefinition}
|
||||
* and {@link org.springframework.transaction.interceptor.TransactionAttribute} javadocs.
|
||||
*
|
||||
* <h3>Transaction Management</h3>
|
||||
* <p>For specific information about the semantics of this annotation's attributes,
|
||||
* consult the {@link org.springframework.transaction.TransactionDefinition} and
|
||||
* {@link org.springframework.transaction.interceptor.TransactionAttribute} javadocs.
|
||||
*
|
||||
* <p>This annotation commonly works with thread-bound transactions managed by a
|
||||
* {@link org.springframework.transaction.PlatformTransactionManager}, exposing a
|
||||
@@ -207,33 +167,37 @@ public @interface Transactional {
|
||||
boolean readOnly() default false;
|
||||
|
||||
/**
|
||||
* Defines zero (0) or more exception {@linkplain Class classes}, which must be
|
||||
* Defines zero (0) or more exception {@link Class classes}, which must be
|
||||
* subclasses of {@link Throwable}, indicating which exception types must cause
|
||||
* a transaction rollback.
|
||||
* <p>By default, a transaction will be rolled back on {@link RuntimeException}
|
||||
* <p>By default, a transaction will be rolling back on {@link RuntimeException}
|
||||
* and {@link Error} but not on checked exceptions (business exceptions). See
|
||||
* {@link org.springframework.transaction.interceptor.DefaultTransactionAttribute#rollbackOn(Throwable)}
|
||||
* for a detailed explanation.
|
||||
* <p>This is the preferred way to construct a rollback rule (in contrast to
|
||||
* {@link #rollbackForClassName}), matching the exception type, its subclasses,
|
||||
* and its nested classes. See the {@linkplain Transactional class-level javadocs}
|
||||
* for further details on rollback rule semantics and warnings regarding possible
|
||||
* unintentional matches.
|
||||
* {@link #rollbackForClassName}), matching the exception class and its subclasses.
|
||||
* <p>Similar to {@link org.springframework.transaction.interceptor.RollbackRuleAttribute#RollbackRuleAttribute(Class clazz)}.
|
||||
* @see #rollbackForClassName
|
||||
* @see org.springframework.transaction.interceptor.RollbackRuleAttribute#RollbackRuleAttribute(Class)
|
||||
* @see org.springframework.transaction.interceptor.DefaultTransactionAttribute#rollbackOn(Throwable)
|
||||
*/
|
||||
Class<? extends Throwable>[] rollbackFor() default {};
|
||||
|
||||
/**
|
||||
* Defines zero (0) or more exception name patterns (for exceptions which must be a
|
||||
* Defines zero (0) or more exception names (for exceptions which must be a
|
||||
* subclass of {@link Throwable}), indicating which exception types must cause
|
||||
* a transaction rollback.
|
||||
* <p>See the {@linkplain Transactional class-level javadocs} for further details
|
||||
* on rollback rule semantics, patterns, and warnings regarding possible
|
||||
* unintentional matches.
|
||||
* <p>This can be a substring of a fully qualified class name, with no wildcard
|
||||
* support at present. For example, a value of {@code "ServletException"} would
|
||||
* match {@code javax.servlet.ServletException} and its subclasses.
|
||||
* <p><b>NB:</b> Consider carefully how specific the pattern is and whether
|
||||
* to include package information (which isn't mandatory). For example,
|
||||
* {@code "Exception"} will match nearly anything and will probably hide other
|
||||
* rules. {@code "java.lang.Exception"} would be correct if {@code "Exception"}
|
||||
* were meant to define a rule for all checked exceptions. With more unusual
|
||||
* {@link Exception} names such as {@code "BaseBusinessException"} there is no
|
||||
* need to use a FQN.
|
||||
* <p>Similar to {@link org.springframework.transaction.interceptor.RollbackRuleAttribute#RollbackRuleAttribute(String exceptionName)}.
|
||||
* @see #rollbackFor
|
||||
* @see org.springframework.transaction.interceptor.RollbackRuleAttribute#RollbackRuleAttribute(String)
|
||||
* @see org.springframework.transaction.interceptor.DefaultTransactionAttribute#rollbackOn(Throwable)
|
||||
*/
|
||||
String[] rollbackForClassName() default {};
|
||||
@@ -242,26 +206,23 @@ public @interface Transactional {
|
||||
* Defines zero (0) or more exception {@link Class Classes}, which must be
|
||||
* subclasses of {@link Throwable}, indicating which exception types must
|
||||
* <b>not</b> cause a transaction rollback.
|
||||
* <p>This is the preferred way to construct a rollback rule (in contrast to
|
||||
* {@link #noRollbackForClassName}), matching the exception type, its subclasses,
|
||||
* and its nested classes. See the {@linkplain Transactional class-level javadocs}
|
||||
* for further details on rollback rule semantics and warnings regarding possible
|
||||
* unintentional matches.
|
||||
* <p>This is the preferred way to construct a rollback rule (in contrast
|
||||
* to {@link #noRollbackForClassName}), matching the exception class and
|
||||
* its subclasses.
|
||||
* <p>Similar to {@link org.springframework.transaction.interceptor.NoRollbackRuleAttribute#NoRollbackRuleAttribute(Class clazz)}.
|
||||
* @see #noRollbackForClassName
|
||||
* @see org.springframework.transaction.interceptor.NoRollbackRuleAttribute#NoRollbackRuleAttribute(Class)
|
||||
* @see org.springframework.transaction.interceptor.DefaultTransactionAttribute#rollbackOn(Throwable)
|
||||
*/
|
||||
Class<? extends Throwable>[] noRollbackFor() default {};
|
||||
|
||||
/**
|
||||
* Defines zero (0) or more exception name patterns (for exceptions which must be a
|
||||
* Defines zero (0) or more exception names (for exceptions which must be a
|
||||
* subclass of {@link Throwable}) indicating which exception types must <b>not</b>
|
||||
* cause a transaction rollback.
|
||||
* <p>See the {@linkplain Transactional class-level javadocs} for further details
|
||||
* on rollback rule semantics, patterns, and warnings regarding possible
|
||||
* unintentional matches.
|
||||
* <p>See the description of {@link #rollbackForClassName} for further
|
||||
* information on how the specified names are treated.
|
||||
* <p>Similar to {@link org.springframework.transaction.interceptor.NoRollbackRuleAttribute#NoRollbackRuleAttribute(String exceptionName)}.
|
||||
* @see #noRollbackFor
|
||||
* @see org.springframework.transaction.interceptor.NoRollbackRuleAttribute#NoRollbackRuleAttribute(String)
|
||||
* @see org.springframework.transaction.interceptor.DefaultTransactionAttribute#rollbackOn(Throwable)
|
||||
*/
|
||||
String[] noRollbackForClassName() default {};
|
||||
|
||||
+9
-16
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -21,7 +21,6 @@ package org.springframework.transaction.interceptor;
|
||||
* to the {@code RollbackRuleAttribute} superclass.
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @author Sam Brannen
|
||||
* @since 09.04.2003
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
@@ -29,28 +28,22 @@ public class NoRollbackRuleAttribute extends RollbackRuleAttribute {
|
||||
|
||||
/**
|
||||
* Create a new instance of the {@code NoRollbackRuleAttribute} class
|
||||
* for the given {@code exceptionType}.
|
||||
* @param exceptionType exception type; must be {@link Throwable} or a subclass
|
||||
* of {@code Throwable}
|
||||
* @throws IllegalArgumentException if the supplied {@code exceptionType} is
|
||||
* not a {@code Throwable} type or is {@code null}
|
||||
* for the supplied {@link Throwable} class.
|
||||
* @param clazz the {@code Throwable} class
|
||||
* @see RollbackRuleAttribute#RollbackRuleAttribute(Class)
|
||||
*/
|
||||
public NoRollbackRuleAttribute(Class<?> exceptionType) {
|
||||
super(exceptionType);
|
||||
public NoRollbackRuleAttribute(Class<?> clazz) {
|
||||
super(clazz);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new instance of the {@code NoRollbackRuleAttribute} class
|
||||
* for the supplied {@code exceptionPattern}.
|
||||
* @param exceptionPattern the exception name pattern; can also be a fully
|
||||
* package-qualified class name
|
||||
* @throws IllegalArgumentException if the supplied {@code exceptionPattern}
|
||||
* is {@code null} or empty
|
||||
* for the supplied {@code exceptionName}.
|
||||
* @param exceptionName the exception name pattern
|
||||
* @see RollbackRuleAttribute#RollbackRuleAttribute(String)
|
||||
*/
|
||||
public NoRollbackRuleAttribute(String exceptionPattern) {
|
||||
super(exceptionPattern);
|
||||
public NoRollbackRuleAttribute(String exceptionName) {
|
||||
super(exceptionName);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+46
-73
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -22,29 +22,13 @@ import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Rule determining whether or not a given exception should cause a rollback.
|
||||
* Rule determining whether or not a given exception (and any subclasses)
|
||||
* should cause a rollback.
|
||||
*
|
||||
* <p>Multiple such rules can be applied to determine whether a transaction
|
||||
* should commit or rollback after an exception has been thrown.
|
||||
*
|
||||
* <p>Each rule is based on an exception pattern which can be a fully qualified
|
||||
* class name or a substring of a fully qualified class name for an exception
|
||||
* type (which must be a subclass of {@code Throwable}), with no wildcard support
|
||||
* at present. For example, a value of {@code "javax.servlet.ServletException"}
|
||||
* or {@code "ServletException"} would match {@code javax.servlet.ServletException}
|
||||
* and its subclasses.
|
||||
*
|
||||
* <p>An exception pattern can be specified as a {@link Class} reference or a
|
||||
* {@link String} in {@link #RollbackRuleAttribute(Class)} and
|
||||
* {@link #RollbackRuleAttribute(String)}, respectively. When an exception type
|
||||
* is specified as a class reference its fully qualified name will be used as the
|
||||
* pattern. See the javadocs for
|
||||
* {@link org.springframework.transaction.annotation.Transactional @Transactional}
|
||||
* for further details on rollback rule semantics, patterns, and warnings regarding
|
||||
* possible unintentional matches.
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @author Sam Brannen
|
||||
* @since 09.04.2003
|
||||
* @see NoRollbackRuleAttribute
|
||||
*/
|
||||
@@ -52,7 +36,7 @@ import org.springframework.util.Assert;
|
||||
public class RollbackRuleAttribute implements Serializable{
|
||||
|
||||
/**
|
||||
* The {@linkplain RollbackRuleAttribute rollback rule} for
|
||||
* The {@link RollbackRuleAttribute rollback rule} for
|
||||
* {@link RuntimeException RuntimeExceptions}.
|
||||
*/
|
||||
public static final RollbackRuleAttribute ROLLBACK_ON_RUNTIME_EXCEPTIONS =
|
||||
@@ -64,90 +48,79 @@ public class RollbackRuleAttribute implements Serializable{
|
||||
* This way does multiple string comparisons, but how often do we decide
|
||||
* whether to roll back a transaction following an exception?
|
||||
*/
|
||||
private final String exceptionPattern;
|
||||
private final String exceptionName;
|
||||
|
||||
|
||||
/**
|
||||
* Create a new instance of the {@code RollbackRuleAttribute} class
|
||||
* for the given {@code exceptionType}.
|
||||
* Create a new instance of the {@code RollbackRuleAttribute} class.
|
||||
* <p>This is the preferred way to construct a rollback rule that matches
|
||||
* the supplied exception type, its subclasses, and its nested classes.
|
||||
* <p>See the javadocs for
|
||||
* {@link org.springframework.transaction.annotation.Transactional @Transactional}
|
||||
* for further details on rollback rule semantics, patterns, and warnings regarding
|
||||
* possible unintentional matches.
|
||||
* @param exceptionType exception type; must be {@link Throwable} or a subclass
|
||||
* the supplied {@link Exception} class, its subclasses, and its nested classes.
|
||||
* @param clazz throwable class; must be {@link Throwable} or a subclass
|
||||
* of {@code Throwable}
|
||||
* @throws IllegalArgumentException if the supplied {@code exceptionType} is
|
||||
* @throws IllegalArgumentException if the supplied {@code clazz} is
|
||||
* not a {@code Throwable} type or is {@code null}
|
||||
*/
|
||||
public RollbackRuleAttribute(Class<?> exceptionType) {
|
||||
Assert.notNull(exceptionType, "'exceptionType' cannot be null");
|
||||
if (!Throwable.class.isAssignableFrom(exceptionType)) {
|
||||
public RollbackRuleAttribute(Class<?> clazz) {
|
||||
Assert.notNull(clazz, "'clazz' cannot be null");
|
||||
if (!Throwable.class.isAssignableFrom(clazz)) {
|
||||
throw new IllegalArgumentException(
|
||||
"Cannot construct rollback rule from [" + exceptionType.getName() + "]: it's not a Throwable");
|
||||
"Cannot construct rollback rule from [" + clazz.getName() + "]: it's not a Throwable");
|
||||
}
|
||||
this.exceptionPattern = exceptionType.getName();
|
||||
this.exceptionName = clazz.getName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new instance of the {@code RollbackRuleAttribute} class
|
||||
* for the given {@code exceptionPattern}.
|
||||
* <p>See the javadocs for
|
||||
* {@link org.springframework.transaction.annotation.Transactional @Transactional}
|
||||
* for further details on rollback rule semantics, patterns, and warnings regarding
|
||||
* possible unintentional matches.
|
||||
* @param exceptionPattern the exception name pattern; can also be a fully
|
||||
* for the given {@code exceptionName}.
|
||||
* <p>This can be a substring, with no wildcard support at present. A value
|
||||
* of "ServletException" would match
|
||||
* {@code javax.servlet.ServletException} and subclasses, for example.
|
||||
* <p><b>NB:</b> Consider carefully how specific the pattern is, and
|
||||
* whether to include package information (which is not mandatory). For
|
||||
* example, "Exception" will match nearly anything, and will probably hide
|
||||
* other rules. "java.lang.Exception" would be correct if "Exception" was
|
||||
* meant to define a rule for all checked exceptions. With more unusual
|
||||
* exception names such as "BaseBusinessException" there's no need to use a
|
||||
* fully package-qualified name.
|
||||
* @param exceptionName the exception name pattern; can also be a fully
|
||||
* package-qualified class name
|
||||
* @throws IllegalArgumentException if the supplied {@code exceptionPattern}
|
||||
* is {@code null} or empty
|
||||
* @throws IllegalArgumentException if the supplied
|
||||
* {@code exceptionName} is {@code null} or empty
|
||||
*/
|
||||
public RollbackRuleAttribute(String exceptionPattern) {
|
||||
Assert.hasText(exceptionPattern, "'exceptionPattern' cannot be null or empty");
|
||||
this.exceptionPattern = exceptionPattern;
|
||||
public RollbackRuleAttribute(String exceptionName) {
|
||||
Assert.hasText(exceptionName, "'exceptionName' cannot be null or empty");
|
||||
this.exceptionName = exceptionName;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the configured exception name pattern that this rule uses for matching.
|
||||
* @see #getDepth(Throwable)
|
||||
* Return the pattern for the exception name.
|
||||
*/
|
||||
public String getExceptionName() {
|
||||
return this.exceptionPattern;
|
||||
return this.exceptionName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the depth of the superclass matching, with the following semantics.
|
||||
* <ul>
|
||||
* <li>{@code -1} means this rule does not match the supplied {@code exception}.</li>
|
||||
* <li>{@code 0} means this rule matches the supplied {@code exception} directly.</li>
|
||||
* <li>Any other positive value means this rule matches the supplied {@code exception}
|
||||
* within the superclass hierarchy, where the value is the number of levels in the
|
||||
* class hierarchy between the supplied {@code exception} and the exception against
|
||||
* which this rule matches directly.</li>
|
||||
* </ul>
|
||||
* <p>When comparing roll back rules that match against a given exception, a rule
|
||||
* with a lower matching depth wins. For example, a direct match ({@code depth == 0})
|
||||
* wins over a match in the superclass hierarchy ({@code depth > 0}).
|
||||
* <p>A match against a nested exception type or similarly named exception type
|
||||
* will return a depth signifying a match at the corresponding level in the
|
||||
* class hierarchy as if there had been a direct match.
|
||||
* Return the depth of the superclass matching.
|
||||
* <p>{@code 0} means {@code ex} matches exactly. Returns
|
||||
* {@code -1} if there is no match. Otherwise, returns depth with the
|
||||
* lowest depth winning.
|
||||
*/
|
||||
public int getDepth(Throwable exception) {
|
||||
return getDepth(exception.getClass(), 0);
|
||||
public int getDepth(Throwable ex) {
|
||||
return getDepth(ex.getClass(), 0);
|
||||
}
|
||||
|
||||
|
||||
private int getDepth(Class<?> exceptionType, int depth) {
|
||||
if (exceptionType.getName().contains(this.exceptionPattern)) {
|
||||
private int getDepth(Class<?> exceptionClass, int depth) {
|
||||
if (exceptionClass.getName().contains(this.exceptionName)) {
|
||||
// Found it!
|
||||
return depth;
|
||||
}
|
||||
// If we've gone as far as we can go and haven't found it...
|
||||
if (exceptionType == Throwable.class) {
|
||||
if (exceptionClass == Throwable.class) {
|
||||
return -1;
|
||||
}
|
||||
return getDepth(exceptionType.getSuperclass(), depth + 1);
|
||||
return getDepth(exceptionClass.getSuperclass(), depth + 1);
|
||||
}
|
||||
|
||||
|
||||
@@ -160,17 +133,17 @@ public class RollbackRuleAttribute implements Serializable{
|
||||
return false;
|
||||
}
|
||||
RollbackRuleAttribute rhs = (RollbackRuleAttribute) other;
|
||||
return this.exceptionPattern.equals(rhs.exceptionPattern);
|
||||
return this.exceptionName.equals(rhs.exceptionName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return this.exceptionPattern.hashCode();
|
||||
return this.exceptionName.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "RollbackRuleAttribute with pattern [" + this.exceptionPattern + "]";
|
||||
return "RollbackRuleAttribute with pattern [" + this.exceptionName + "]";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+1
-7
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -25,13 +25,7 @@ import org.springframework.core.NestedRuntimeException;
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
class MyRuntimeException extends NestedRuntimeException {
|
||||
|
||||
public MyRuntimeException() {
|
||||
super("");
|
||||
}
|
||||
|
||||
public MyRuntimeException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
-160
@@ -1,160 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://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.springframework.transaction.interceptor;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.FatalBeanException;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
|
||||
|
||||
/**
|
||||
* Unit tests for the {@link RollbackRuleAttribute} class.
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @author Rick Evans
|
||||
* @author Chris Beams
|
||||
* @author Sam Brannen
|
||||
* @since 09.04.2003
|
||||
*/
|
||||
class RollbackRuleAttributeTests {
|
||||
|
||||
@Nested
|
||||
class ExceptionPatternTests {
|
||||
|
||||
@Test
|
||||
void constructorPreconditions() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new RollbackRuleAttribute((String) null));
|
||||
}
|
||||
|
||||
@Test
|
||||
void notFound() {
|
||||
RollbackRuleAttribute rr = new RollbackRuleAttribute(IOException.class.getName());
|
||||
assertThat(rr.getDepth(new MyRuntimeException())).isEqualTo(-1);
|
||||
}
|
||||
|
||||
@Test
|
||||
void alwaysFoundForThrowable() {
|
||||
RollbackRuleAttribute rr = new RollbackRuleAttribute(Throwable.class.getName());
|
||||
assertThat(rr.getDepth(new MyRuntimeException())).isGreaterThan(0);
|
||||
assertThat(rr.getDepth(new IOException())).isGreaterThan(0);
|
||||
assertThat(rr.getDepth(new FatalBeanException(null, null))).isGreaterThan(0);
|
||||
assertThat(rr.getDepth(new RuntimeException())).isGreaterThan(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
void foundImmediatelyWhenDirectMatch() {
|
||||
RollbackRuleAttribute rr = new RollbackRuleAttribute(Exception.class.getName());
|
||||
assertThat(rr.getDepth(new Exception())).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
void foundImmediatelyWhenExceptionThrownIsNestedTypeOfRegisteredException() {
|
||||
RollbackRuleAttribute rr = new RollbackRuleAttribute(EnclosingException.class.getName());
|
||||
assertThat(rr.getDepth(new EnclosingException.NestedException())).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
void foundImmediatelyWhenNameOfExceptionThrownStartsWithNameOfRegisteredException() {
|
||||
RollbackRuleAttribute rr = new RollbackRuleAttribute(MyException.class.getName());
|
||||
assertThat(rr.getDepth(new MyException2())).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
void foundInSuperclassHierarchy() {
|
||||
RollbackRuleAttribute rr = new RollbackRuleAttribute(Exception.class.getName());
|
||||
// Exception -> RuntimeException -> NestedRuntimeException -> MyRuntimeException
|
||||
assertThat(rr.getDepth(new MyRuntimeException())).isEqualTo(3);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Nested
|
||||
class ExceptionTypeTests {
|
||||
|
||||
@Test
|
||||
void constructorPreconditions() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new RollbackRuleAttribute(Object.class));
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new RollbackRuleAttribute((Class<?>) null));
|
||||
}
|
||||
|
||||
@Test
|
||||
void notFound() {
|
||||
RollbackRuleAttribute rr = new RollbackRuleAttribute(IOException.class);
|
||||
assertThat(rr.getDepth(new MyRuntimeException())).isEqualTo(-1);
|
||||
}
|
||||
|
||||
@Test
|
||||
void alwaysFoundForThrowable() {
|
||||
RollbackRuleAttribute rr = new RollbackRuleAttribute(Throwable.class);
|
||||
assertThat(rr.getDepth(new MyRuntimeException())).isGreaterThan(0);
|
||||
assertThat(rr.getDepth(new IOException())).isGreaterThan(0);
|
||||
assertThat(rr.getDepth(new FatalBeanException(null, null))).isGreaterThan(0);
|
||||
assertThat(rr.getDepth(new RuntimeException())).isGreaterThan(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
void foundImmediatelyWhenDirectMatch() {
|
||||
RollbackRuleAttribute rr = new RollbackRuleAttribute(Exception.class);
|
||||
assertThat(rr.getDepth(new Exception())).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
void foundImmediatelyWhenExceptionThrownIsNestedTypeOfRegisteredException() {
|
||||
RollbackRuleAttribute rr = new RollbackRuleAttribute(EnclosingException.class);
|
||||
assertThat(rr.getDepth(new EnclosingException.NestedException())).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
void foundImmediatelyWhenNameOfExceptionThrownStartsWithNameOfRegisteredException() {
|
||||
RollbackRuleAttribute rr = new RollbackRuleAttribute(MyException.class);
|
||||
assertThat(rr.getDepth(new MyException2())).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
void foundInSuperclassHierarchy() {
|
||||
RollbackRuleAttribute rr = new RollbackRuleAttribute(Exception.class);
|
||||
// Exception -> RuntimeException -> NestedRuntimeException -> MyRuntimeException
|
||||
assertThat(rr.getDepth(new MyRuntimeException())).isEqualTo(3);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
static class EnclosingException extends RuntimeException {
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
static class NestedException extends RuntimeException {
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
static class MyException extends RuntimeException {
|
||||
}
|
||||
|
||||
// Name intentionally starts with MyException (including package) but does
|
||||
// NOT extend MyException.
|
||||
@SuppressWarnings("serial")
|
||||
static class MyException2 extends RuntimeException {
|
||||
}
|
||||
|
||||
}
|
||||
+103
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://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.springframework.transaction.interceptor;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.FatalBeanException;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
|
||||
|
||||
/**
|
||||
* Unit tests for the {@link RollbackRuleAttribute} class.
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @author Rick Evans
|
||||
* @author Chris Beams
|
||||
* @author Sam Brannen
|
||||
* @since 09.04.2003
|
||||
*/
|
||||
class RollbackRuleTests {
|
||||
|
||||
@Test
|
||||
void foundImmediatelyWithString() {
|
||||
RollbackRuleAttribute rr = new RollbackRuleAttribute(Exception.class.getName());
|
||||
assertThat(rr.getDepth(new Exception())).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
void foundImmediatelyWithClass() {
|
||||
RollbackRuleAttribute rr = new RollbackRuleAttribute(Exception.class);
|
||||
assertThat(rr.getDepth(new Exception())).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
void notFound() {
|
||||
RollbackRuleAttribute rr = new RollbackRuleAttribute(java.io.IOException.class.getName());
|
||||
assertThat(rr.getDepth(new MyRuntimeException(""))).isEqualTo(-1);
|
||||
}
|
||||
|
||||
@Test
|
||||
void ancestry() {
|
||||
RollbackRuleAttribute rr = new RollbackRuleAttribute(Exception.class.getName());
|
||||
// Exception -> Runtime -> NestedRuntime -> MyRuntimeException
|
||||
assertThat(rr.getDepth(new MyRuntimeException(""))).isEqualTo(3);
|
||||
}
|
||||
|
||||
@Test
|
||||
void alwaysTrueForThrowable() {
|
||||
RollbackRuleAttribute rr = new RollbackRuleAttribute(Throwable.class.getName());
|
||||
assertThat(rr.getDepth(new MyRuntimeException(""))).isGreaterThan(0);
|
||||
assertThat(rr.getDepth(new IOException())).isGreaterThan(0);
|
||||
assertThat(rr.getDepth(new FatalBeanException(null, null))).isGreaterThan(0);
|
||||
assertThat(rr.getDepth(new RuntimeException())).isGreaterThan(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
void ctorArgMustBeAThrowableClassWithNonThrowableType() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new RollbackRuleAttribute(Object.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void ctorArgMustBeAThrowableClassWithNullThrowableType() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new RollbackRuleAttribute((Class<?>) null));
|
||||
}
|
||||
|
||||
@Test
|
||||
void ctorArgExceptionStringNameVersionWithNull() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new RollbackRuleAttribute((String) null));
|
||||
}
|
||||
|
||||
@Test
|
||||
void foundEnclosedExceptionWithEnclosingException() {
|
||||
RollbackRuleAttribute rr = new RollbackRuleAttribute(EnclosingException.class);
|
||||
assertThat(rr.getDepth(new EnclosingException.EnclosedException())).isEqualTo(0);
|
||||
}
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
static class EnclosingException extends RuntimeException {
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
static class EnclosedException extends RuntimeException {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+16
-16
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -35,13 +35,13 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
* @author Chris Beams
|
||||
* @since 09.04.2003
|
||||
*/
|
||||
class RuleBasedTransactionAttributeTests {
|
||||
public class RuleBasedTransactionAttributeTests {
|
||||
|
||||
@Test
|
||||
void defaultRule() {
|
||||
public void testDefaultRule() {
|
||||
RuleBasedTransactionAttribute rta = new RuleBasedTransactionAttribute();
|
||||
assertThat(rta.rollbackOn(new RuntimeException())).isTrue();
|
||||
assertThat(rta.rollbackOn(new MyRuntimeException())).isTrue();
|
||||
assertThat(rta.rollbackOn(new MyRuntimeException(""))).isTrue();
|
||||
assertThat(rta.rollbackOn(new Exception())).isFalse();
|
||||
assertThat(rta.rollbackOn(new IOException())).isFalse();
|
||||
}
|
||||
@@ -50,20 +50,20 @@ class RuleBasedTransactionAttributeTests {
|
||||
* Test one checked exception that should roll back.
|
||||
*/
|
||||
@Test
|
||||
void ruleForRollbackOnChecked() {
|
||||
public void testRuleForRollbackOnChecked() {
|
||||
List<RollbackRuleAttribute> list = new ArrayList<>();
|
||||
list.add(new RollbackRuleAttribute(IOException.class.getName()));
|
||||
RuleBasedTransactionAttribute rta = new RuleBasedTransactionAttribute(TransactionDefinition.PROPAGATION_REQUIRED, list);
|
||||
|
||||
assertThat(rta.rollbackOn(new RuntimeException())).isTrue();
|
||||
assertThat(rta.rollbackOn(new MyRuntimeException())).isTrue();
|
||||
assertThat(rta.rollbackOn(new MyRuntimeException(""))).isTrue();
|
||||
assertThat(rta.rollbackOn(new Exception())).isFalse();
|
||||
// Check that default behaviour is overridden
|
||||
assertThat(rta.rollbackOn(new IOException())).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void ruleForCommitOnUnchecked() {
|
||||
public void testRuleForCommitOnUnchecked() {
|
||||
List<RollbackRuleAttribute> list = new ArrayList<>();
|
||||
list.add(new NoRollbackRuleAttribute(MyRuntimeException.class.getName()));
|
||||
list.add(new RollbackRuleAttribute(IOException.class.getName()));
|
||||
@@ -71,14 +71,14 @@ class RuleBasedTransactionAttributeTests {
|
||||
|
||||
assertThat(rta.rollbackOn(new RuntimeException())).isTrue();
|
||||
// Check default behaviour is overridden
|
||||
assertThat(rta.rollbackOn(new MyRuntimeException())).isFalse();
|
||||
assertThat(rta.rollbackOn(new MyRuntimeException(""))).isFalse();
|
||||
assertThat(rta.rollbackOn(new Exception())).isFalse();
|
||||
// Check that default behaviour is overridden
|
||||
assertThat(rta.rollbackOn(new IOException())).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void ruleForSelectiveRollbackOnCheckedWithString() {
|
||||
public void testRuleForSelectiveRollbackOnCheckedWithString() {
|
||||
List<RollbackRuleAttribute> l = new ArrayList<>();
|
||||
l.add(new RollbackRuleAttribute(java.rmi.RemoteException.class.getName()));
|
||||
RuleBasedTransactionAttribute rta = new RuleBasedTransactionAttribute(TransactionDefinition.PROPAGATION_REQUIRED, l);
|
||||
@@ -86,7 +86,7 @@ class RuleBasedTransactionAttributeTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
void ruleForSelectiveRollbackOnCheckedWithClass() {
|
||||
public void testRuleForSelectiveRollbackOnCheckedWithClass() {
|
||||
List<RollbackRuleAttribute> l = Collections.singletonList(new RollbackRuleAttribute(RemoteException.class));
|
||||
RuleBasedTransactionAttribute rta = new RuleBasedTransactionAttribute(TransactionDefinition.PROPAGATION_REQUIRED, l);
|
||||
doTestRuleForSelectiveRollbackOnChecked(rta);
|
||||
@@ -105,7 +105,7 @@ class RuleBasedTransactionAttributeTests {
|
||||
* when Exception prompts a rollback.
|
||||
*/
|
||||
@Test
|
||||
void ruleForCommitOnSubclassOfChecked() {
|
||||
public void testRuleForCommitOnSubclassOfChecked() {
|
||||
List<RollbackRuleAttribute> list = new ArrayList<>();
|
||||
// Note that it's important to ensure that we have this as
|
||||
// a FQN: otherwise it will match everything!
|
||||
@@ -120,20 +120,20 @@ class RuleBasedTransactionAttributeTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
void rollbackNever() {
|
||||
public void testRollbackNever() {
|
||||
List<RollbackRuleAttribute> list = new ArrayList<>();
|
||||
list.add(new NoRollbackRuleAttribute("Throwable"));
|
||||
RuleBasedTransactionAttribute rta = new RuleBasedTransactionAttribute(TransactionDefinition.PROPAGATION_REQUIRED, list);
|
||||
|
||||
assertThat(rta.rollbackOn(new Throwable())).isFalse();
|
||||
assertThat(rta.rollbackOn(new RuntimeException())).isFalse();
|
||||
assertThat(rta.rollbackOn(new MyRuntimeException())).isFalse();
|
||||
assertThat(rta.rollbackOn(new MyRuntimeException(""))).isFalse();
|
||||
assertThat(rta.rollbackOn(new Exception())).isFalse();
|
||||
assertThat(rta.rollbackOn(new IOException())).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
void toStringMatchesEditor() {
|
||||
public void testToStringMatchesEditor() {
|
||||
List<RollbackRuleAttribute> list = new ArrayList<>();
|
||||
list.add(new NoRollbackRuleAttribute("Throwable"));
|
||||
RuleBasedTransactionAttribute rta = new RuleBasedTransactionAttribute(TransactionDefinition.PROPAGATION_REQUIRED, list);
|
||||
@@ -144,7 +144,7 @@ class RuleBasedTransactionAttributeTests {
|
||||
|
||||
assertThat(rta.rollbackOn(new Throwable())).isFalse();
|
||||
assertThat(rta.rollbackOn(new RuntimeException())).isFalse();
|
||||
assertThat(rta.rollbackOn(new MyRuntimeException())).isFalse();
|
||||
assertThat(rta.rollbackOn(new MyRuntimeException(""))).isFalse();
|
||||
assertThat(rta.rollbackOn(new Exception())).isFalse();
|
||||
assertThat(rta.rollbackOn(new IOException())).isFalse();
|
||||
}
|
||||
@@ -153,7 +153,7 @@ class RuleBasedTransactionAttributeTests {
|
||||
* See <a href="https://forum.springframework.org/showthread.php?t=41350">this forum post</a>.
|
||||
*/
|
||||
@Test
|
||||
void conflictingRulesToDetermineExactContract() {
|
||||
public void testConflictingRulesToDetermineExactContract() {
|
||||
List<RollbackRuleAttribute> list = new ArrayList<>();
|
||||
list.add(new NoRollbackRuleAttribute(MyBusinessWarningException.class));
|
||||
list.add(new RollbackRuleAttribute(MyBusinessException.class));
|
||||
|
||||
+43
-31
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.springframework.transaction.interceptor;
|
||||
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
@@ -26,65 +27,72 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
|
||||
|
||||
/**
|
||||
* Tests to check conversion from String to TransactionAttribute using
|
||||
* a {@link TransactionAttributeEditor}.
|
||||
* Tests to check conversion from String to TransactionAttribute.
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @author Juergen Hoeller
|
||||
* @author Chris Beams
|
||||
* @since 26.04.2003
|
||||
*/
|
||||
class TransactionAttributeEditorTests {
|
||||
|
||||
private final TransactionAttributeEditor pe = new TransactionAttributeEditor();
|
||||
|
||||
public class TransactionAttributeEditorTests {
|
||||
|
||||
@Test
|
||||
void nullText() {
|
||||
public void testNull() {
|
||||
TransactionAttributeEditor pe = new TransactionAttributeEditor();
|
||||
pe.setAsText(null);
|
||||
assertThat(pe.getValue()).isNull();
|
||||
TransactionAttribute ta = (TransactionAttribute) pe.getValue();
|
||||
assertThat(ta == null).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void emptyString() {
|
||||
public void testEmptyString() {
|
||||
TransactionAttributeEditor pe = new TransactionAttributeEditor();
|
||||
pe.setAsText("");
|
||||
assertThat(pe.getValue()).isNull();
|
||||
TransactionAttribute ta = (TransactionAttribute) pe.getValue();
|
||||
assertThat(ta == null).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void validPropagationCodeOnly() {
|
||||
public void testValidPropagationCodeOnly() {
|
||||
TransactionAttributeEditor pe = new TransactionAttributeEditor();
|
||||
pe.setAsText("PROPAGATION_REQUIRED");
|
||||
TransactionAttribute ta = (TransactionAttribute) pe.getValue();
|
||||
assertThat(ta).isNotNull();
|
||||
assertThat(ta.getPropagationBehavior()).isEqualTo(TransactionDefinition.PROPAGATION_REQUIRED);
|
||||
assertThat(ta.getIsolationLevel()).isEqualTo(TransactionDefinition.ISOLATION_DEFAULT);
|
||||
assertThat(ta.isReadOnly()).isFalse();
|
||||
assertThat(ta != null).isTrue();
|
||||
assertThat(ta.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRED).isTrue();
|
||||
assertThat(ta.getIsolationLevel() == TransactionDefinition.ISOLATION_DEFAULT).isTrue();
|
||||
boolean condition = !ta.isReadOnly();
|
||||
assertThat(condition).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void invalidPropagationCodeOnly() {
|
||||
public void testInvalidPropagationCodeOnly() {
|
||||
TransactionAttributeEditor pe = new TransactionAttributeEditor();
|
||||
// should have failed with bogus propagation code
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> pe.setAsText("XXPROPAGATION_REQUIRED"));
|
||||
assertThatIllegalArgumentException().isThrownBy(() ->
|
||||
pe.setAsText("XXPROPAGATION_REQUIRED"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void validPropagationCodeAndIsolationCode() {
|
||||
public void testValidPropagationCodeAndIsolationCode() {
|
||||
TransactionAttributeEditor pe = new TransactionAttributeEditor();
|
||||
pe.setAsText("PROPAGATION_REQUIRED, ISOLATION_READ_UNCOMMITTED");
|
||||
TransactionAttribute ta = (TransactionAttribute) pe.getValue();
|
||||
assertThat(ta).isNotNull();
|
||||
assertThat(ta.getPropagationBehavior()).isEqualTo(TransactionDefinition.PROPAGATION_REQUIRED);
|
||||
assertThat(ta.getIsolationLevel()).isEqualTo(TransactionDefinition.ISOLATION_READ_UNCOMMITTED);
|
||||
assertThat(ta != null).isTrue();
|
||||
assertThat(ta.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRED).isTrue();
|
||||
assertThat(ta.getIsolationLevel() == TransactionDefinition.ISOLATION_READ_UNCOMMITTED).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void validPropagationAndIsolationCodesAndInvalidRollbackRule() {
|
||||
public void testValidPropagationAndIsolationCodesAndInvalidRollbackRule() {
|
||||
TransactionAttributeEditor pe = new TransactionAttributeEditor();
|
||||
// should fail with bogus rollback rule
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> pe.setAsText("PROPAGATION_REQUIRED,ISOLATION_READ_UNCOMMITTED,XXX"));
|
||||
assertThatIllegalArgumentException().isThrownBy(() ->
|
||||
pe.setAsText("PROPAGATION_REQUIRED,ISOLATION_READ_UNCOMMITTED,XXX"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void validPropagationCodeAndIsolationCodeAndRollbackRules1() {
|
||||
public void testValidPropagationCodeAndIsolationCodeAndRollbackRules1() {
|
||||
TransactionAttributeEditor pe = new TransactionAttributeEditor();
|
||||
pe.setAsText("PROPAGATION_MANDATORY,ISOLATION_REPEATABLE_READ,timeout_10,-IOException,+MyRuntimeException");
|
||||
TransactionAttribute ta = (TransactionAttribute) pe.getValue();
|
||||
assertThat(ta).isNotNull();
|
||||
@@ -96,11 +104,13 @@ class TransactionAttributeEditorTests {
|
||||
assertThat(ta.rollbackOn(new Exception())).isFalse();
|
||||
// Check for our bizarre customized rollback rules
|
||||
assertThat(ta.rollbackOn(new IOException())).isTrue();
|
||||
assertThat(ta.rollbackOn(new MyRuntimeException())).isFalse();
|
||||
boolean condition = !ta.rollbackOn(new MyRuntimeException(""));
|
||||
assertThat(condition).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void validPropagationCodeAndIsolationCodeAndRollbackRules2() {
|
||||
public void testValidPropagationCodeAndIsolationCodeAndRollbackRules2() {
|
||||
TransactionAttributeEditor pe = new TransactionAttributeEditor();
|
||||
pe.setAsText("+IOException,readOnly,ISOLATION_READ_COMMITTED,-MyRuntimeException,PROPAGATION_SUPPORTS");
|
||||
TransactionAttribute ta = (TransactionAttribute) pe.getValue();
|
||||
assertThat(ta).isNotNull();
|
||||
@@ -112,17 +122,18 @@ class TransactionAttributeEditorTests {
|
||||
assertThat(ta.rollbackOn(new Exception())).isFalse();
|
||||
// Check for our bizarre customized rollback rules
|
||||
assertThat(ta.rollbackOn(new IOException())).isFalse();
|
||||
assertThat(ta.rollbackOn(new MyRuntimeException())).isTrue();
|
||||
assertThat(ta.rollbackOn(new MyRuntimeException(""))).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void defaultTransactionAttributeToString() {
|
||||
public void testDefaultTransactionAttributeToString() {
|
||||
DefaultTransactionAttribute source = new DefaultTransactionAttribute();
|
||||
source.setPropagationBehavior(TransactionDefinition.PROPAGATION_SUPPORTS);
|
||||
source.setIsolationLevel(TransactionDefinition.ISOLATION_REPEATABLE_READ);
|
||||
source.setTimeout(10);
|
||||
source.setReadOnly(true);
|
||||
|
||||
TransactionAttributeEditor pe = new TransactionAttributeEditor();
|
||||
pe.setAsText(source.toString());
|
||||
TransactionAttribute ta = (TransactionAttribute) pe.getValue();
|
||||
assertThat(source).isEqualTo(ta);
|
||||
@@ -140,7 +151,7 @@ class TransactionAttributeEditorTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
void ruleBasedTransactionAttributeToString() {
|
||||
public void testRuleBasedTransactionAttributeToString() {
|
||||
RuleBasedTransactionAttribute source = new RuleBasedTransactionAttribute();
|
||||
source.setPropagationBehavior(TransactionDefinition.PROPAGATION_SUPPORTS);
|
||||
source.setIsolationLevel(TransactionDefinition.ISOLATION_REPEATABLE_READ);
|
||||
@@ -149,6 +160,7 @@ class TransactionAttributeEditorTests {
|
||||
source.getRollbackRules().add(new RollbackRuleAttribute("IllegalArgumentException"));
|
||||
source.getRollbackRules().add(new NoRollbackRuleAttribute("IllegalStateException"));
|
||||
|
||||
TransactionAttributeEditor pe = new TransactionAttributeEditor();
|
||||
pe.setAsText(source.toString());
|
||||
TransactionAttribute ta = (TransactionAttribute) pe.getValue();
|
||||
assertThat(source).isEqualTo(ta);
|
||||
|
||||
+5
-9
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -196,26 +196,22 @@ public abstract class AbstractJackson2Encoder extends Jackson2CodecSupport imple
|
||||
public DataBuffer encodeValue(Object value, DataBufferFactory bufferFactory,
|
||||
ResolvableType valueType, @Nullable MimeType mimeType, @Nullable Map<String, Object> hints) {
|
||||
|
||||
ObjectMapper mapper = selectObjectMapper(valueType, mimeType);
|
||||
if (mapper == null) {
|
||||
throw new IllegalStateException("No ObjectMapper for " + valueType);
|
||||
}
|
||||
Class<?> jsonView = null;
|
||||
FilterProvider filters = null;
|
||||
if (value instanceof MappingJacksonValue) {
|
||||
MappingJacksonValue container = (MappingJacksonValue) value;
|
||||
value = container.getValue();
|
||||
valueType = ResolvableType.forInstance(value);
|
||||
jsonView = container.getSerializationView();
|
||||
filters = container.getFilters();
|
||||
}
|
||||
|
||||
ObjectMapper mapper = selectObjectMapper(valueType, mimeType);
|
||||
if (mapper == null) {
|
||||
throw new IllegalStateException("No ObjectMapper for " + valueType);
|
||||
}
|
||||
|
||||
ObjectWriter writer = createObjectWriter(mapper, valueType, mimeType, jsonView, hints);
|
||||
if (filters != null) {
|
||||
writer = writer.with(filters);
|
||||
}
|
||||
|
||||
ByteArrayBuilder byteBuilder = new ByteArrayBuilder(writer.getFactory()._getBufferRecycler());
|
||||
try {
|
||||
JsonEncoding encoding = getJsonEncoding(mimeType);
|
||||
|
||||
@@ -559,9 +559,9 @@ public class AsyncRestTemplate extends org.springframework.http.client.support.I
|
||||
}
|
||||
|
||||
private void handleResponseError(HttpMethod method, URI url, ClientHttpResponse response) throws IOException {
|
||||
if (logger.isDebugEnabled()) {
|
||||
if (logger.isWarnEnabled()) {
|
||||
try {
|
||||
logger.debug("Async " + method.name() + " request for \"" + url + "\" resulted in " +
|
||||
logger.warn("Async " + method.name() + " request for \"" + url + "\" resulted in " +
|
||||
response.getRawStatusCode() + " (" + response.getStatusText() + "); invoking error handler");
|
||||
}
|
||||
catch (IOException ex) {
|
||||
|
||||
+7
-9
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -37,7 +37,6 @@ import okhttp3.mockwebserver.RecordedRequest;
|
||||
import okio.Buffer;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Named;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
@@ -55,7 +54,6 @@ import org.springframework.lang.NonNull;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.fail;
|
||||
import static org.junit.jupiter.api.Named.named;
|
||||
|
||||
/**
|
||||
* @author Arjen Poutsma
|
||||
@@ -204,22 +202,22 @@ public class ClientHttpConnectorTests {
|
||||
@Target(ElementType.METHOD)
|
||||
// Do not auto-close arguments since HttpComponentsClientHttpConnector implements
|
||||
// AutoCloseable and is shared between parameterized test invocations.
|
||||
@ParameterizedTest(name = "{0}", autoCloseArguments = false)
|
||||
@ParameterizedTest(autoCloseArguments = false)
|
||||
@MethodSource("org.springframework.http.client.reactive.ClientHttpConnectorTests#connectors")
|
||||
public @interface ParameterizedConnectorTest {
|
||||
}
|
||||
|
||||
static List<Named<ClientHttpConnector>> connectors() {
|
||||
static List<ClientHttpConnector> connectors() {
|
||||
return Arrays.asList(
|
||||
named("Reactor Netty", new ReactorClientHttpConnector()),
|
||||
named("Jetty", new JettyClientHttpConnector()),
|
||||
named("HttpComponents", new HttpComponentsClientHttpConnector())
|
||||
new ReactorClientHttpConnector(),
|
||||
new JettyClientHttpConnector(),
|
||||
new HttpComponentsClientHttpConnector()
|
||||
);
|
||||
}
|
||||
|
||||
static List<Arguments> methodsWithConnectors() {
|
||||
List<Arguments> result = new ArrayList<>();
|
||||
for (Named<ClientHttpConnector> connector : connectors()) {
|
||||
for (ClientHttpConnector connector : connectors()) {
|
||||
for (HttpMethod method : HttpMethod.values()) {
|
||||
result.add(Arguments.of(connector, method));
|
||||
}
|
||||
|
||||
+9
-9
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -58,7 +58,7 @@ class ServerSentEventHttpMessageWriterTests extends AbstractDataBufferAllocating
|
||||
|
||||
|
||||
@ParameterizedDataBufferAllocatingTest
|
||||
void canWrite(DataBufferFactory bufferFactory) {
|
||||
void canWrite(String displayName, DataBufferFactory bufferFactory) {
|
||||
super.bufferFactory = bufferFactory;
|
||||
|
||||
assertThat(this.messageWriter.canWrite(forClass(Object.class), null)).isTrue();
|
||||
@@ -73,7 +73,7 @@ class ServerSentEventHttpMessageWriterTests extends AbstractDataBufferAllocating
|
||||
}
|
||||
|
||||
@ParameterizedDataBufferAllocatingTest
|
||||
void writeServerSentEvent(DataBufferFactory bufferFactory) {
|
||||
void writeServerSentEvent(String displayName, DataBufferFactory bufferFactory) {
|
||||
super.bufferFactory = bufferFactory;
|
||||
|
||||
ServerSentEvent<?> event = ServerSentEvent.builder().data("bar").id("c42").event("foo")
|
||||
@@ -91,7 +91,7 @@ class ServerSentEventHttpMessageWriterTests extends AbstractDataBufferAllocating
|
||||
}
|
||||
|
||||
@ParameterizedDataBufferAllocatingTest
|
||||
void writeString(DataBufferFactory bufferFactory) {
|
||||
void writeString(String displayName, DataBufferFactory bufferFactory) {
|
||||
super.bufferFactory = bufferFactory;
|
||||
|
||||
MockServerHttpResponse outputMessage = new MockServerHttpResponse(super.bufferFactory);
|
||||
@@ -106,7 +106,7 @@ class ServerSentEventHttpMessageWriterTests extends AbstractDataBufferAllocating
|
||||
}
|
||||
|
||||
@ParameterizedDataBufferAllocatingTest
|
||||
void writeMultiLineString(DataBufferFactory bufferFactory) {
|
||||
void writeMultiLineString(String displayName, DataBufferFactory bufferFactory) {
|
||||
super.bufferFactory = bufferFactory;
|
||||
|
||||
MockServerHttpResponse outputMessage = new MockServerHttpResponse(super.bufferFactory);
|
||||
@@ -121,7 +121,7 @@ class ServerSentEventHttpMessageWriterTests extends AbstractDataBufferAllocating
|
||||
}
|
||||
|
||||
@ParameterizedDataBufferAllocatingTest // SPR-16516
|
||||
void writeStringWithCustomCharset(DataBufferFactory bufferFactory) {
|
||||
void writeStringWithCustomCharset(String displayName, DataBufferFactory bufferFactory) {
|
||||
super.bufferFactory = bufferFactory;
|
||||
|
||||
MockServerHttpResponse outputMessage = new MockServerHttpResponse(super.bufferFactory);
|
||||
@@ -142,7 +142,7 @@ class ServerSentEventHttpMessageWriterTests extends AbstractDataBufferAllocating
|
||||
}
|
||||
|
||||
@ParameterizedDataBufferAllocatingTest
|
||||
void writePojo(DataBufferFactory bufferFactory) {
|
||||
void writePojo(String displayName, DataBufferFactory bufferFactory) {
|
||||
super.bufferFactory = bufferFactory;
|
||||
|
||||
MockServerHttpResponse outputMessage = new MockServerHttpResponse(super.bufferFactory);
|
||||
@@ -161,7 +161,7 @@ class ServerSentEventHttpMessageWriterTests extends AbstractDataBufferAllocating
|
||||
}
|
||||
|
||||
@ParameterizedDataBufferAllocatingTest // SPR-14899
|
||||
void writePojoWithPrettyPrint(DataBufferFactory bufferFactory) {
|
||||
void writePojoWithPrettyPrint(String displayName, DataBufferFactory bufferFactory) {
|
||||
super.bufferFactory = bufferFactory;
|
||||
|
||||
ObjectMapper mapper = Jackson2ObjectMapperBuilder.json().indentOutput(true).build();
|
||||
@@ -187,7 +187,7 @@ class ServerSentEventHttpMessageWriterTests extends AbstractDataBufferAllocating
|
||||
}
|
||||
|
||||
@ParameterizedDataBufferAllocatingTest // SPR-16516, SPR-16539
|
||||
void writePojoWithCustomEncoding(DataBufferFactory bufferFactory) {
|
||||
void writePojoWithCustomEncoding(String displayName, DataBufferFactory bufferFactory) {
|
||||
super.bufferFactory = bufferFactory;
|
||||
|
||||
MockServerHttpResponse outputMessage = new MockServerHttpResponse(super.bufferFactory);
|
||||
|
||||
+25
-46
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -95,12 +95,12 @@ public class Jackson2JsonEncoderTests extends AbstractEncoderTests<Jackson2JsonE
|
||||
new Pojo("foofoo", "barbar"),
|
||||
new Pojo("foofoofoo", "barbarbar"));
|
||||
|
||||
testEncodeAll(input, ResolvableType.forClass(Pojo.class), APPLICATION_STREAM_JSON, null, step -> step
|
||||
testEncodeAll(input, ResolvableType.forClass(Pojo.class), step -> step
|
||||
.consumeNextWith(expectString("{\"foo\":\"foo\",\"bar\":\"bar\"}\n"))
|
||||
.consumeNextWith(expectString("{\"foo\":\"foofoo\",\"bar\":\"barbar\"}\n"))
|
||||
.consumeNextWith(expectString("{\"foo\":\"foofoofoo\",\"bar\":\"barbarbar\"}\n"))
|
||||
.verifyComplete()
|
||||
);
|
||||
.verifyComplete(),
|
||||
APPLICATION_STREAM_JSON, null);
|
||||
}
|
||||
|
||||
@Test // SPR-15866
|
||||
@@ -168,15 +168,15 @@ public class Jackson2JsonEncoderTests extends AbstractEncoderTests<Jackson2JsonE
|
||||
new Pojo("foofoofoo", "barbarbar")
|
||||
);
|
||||
|
||||
testEncode(input, ResolvableType.forClass(Pojo.class), barMediaType, null, step -> step
|
||||
testEncode(input, ResolvableType.forClass(Pojo.class), step -> step
|
||||
.consumeNextWith(expectString("{\"foo\":\"foo\",\"bar\":\"bar\"}\n")
|
||||
.andThen(DataBufferUtils::release))
|
||||
.consumeNextWith(expectString("{\"foo\":\"foofoo\",\"bar\":\"barbar\"}\n")
|
||||
.andThen(DataBufferUtils::release))
|
||||
.consumeNextWith(expectString("{\"foo\":\"foofoofoo\",\"bar\":\"barbarbar\"}\n")
|
||||
.andThen(DataBufferUtils::release))
|
||||
.verifyComplete()
|
||||
);
|
||||
.verifyComplete(),
|
||||
barMediaType, null);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -190,10 +190,11 @@ public class Jackson2JsonEncoderTests extends AbstractEncoderTests<Jackson2JsonE
|
||||
ResolvableType type = ResolvableType.forClass(JacksonViewBean.class);
|
||||
Map<String, Object> hints = singletonMap(JSON_VIEW_HINT, MyJacksonView1.class);
|
||||
|
||||
testEncode(input, type, null, hints, step -> step
|
||||
.consumeNextWith(expectString("{\"withView1\":\"with\"}").andThen(DataBufferUtils::release))
|
||||
.verifyComplete()
|
||||
);
|
||||
testEncode(input, type, step -> step
|
||||
.consumeNextWith(expectString("{\"withView1\":\"with\"}")
|
||||
.andThen(DataBufferUtils::release))
|
||||
.verifyComplete(),
|
||||
null, hints);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -207,10 +208,11 @@ public class Jackson2JsonEncoderTests extends AbstractEncoderTests<Jackson2JsonE
|
||||
ResolvableType type = ResolvableType.forClass(JacksonViewBean.class);
|
||||
Map<String, Object> hints = singletonMap(JSON_VIEW_HINT, MyJacksonView3.class);
|
||||
|
||||
testEncode(input, type, null, hints, step -> step
|
||||
.consumeNextWith(expectString("{\"withoutView\":\"without\"}").andThen(DataBufferUtils::release))
|
||||
.verifyComplete()
|
||||
);
|
||||
testEncode(input, type, step -> step
|
||||
.consumeNextWith(expectString("{\"withoutView\":\"without\"}")
|
||||
.andThen(DataBufferUtils::release))
|
||||
.verifyComplete(),
|
||||
null, hints);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -225,33 +227,11 @@ public class Jackson2JsonEncoderTests extends AbstractEncoderTests<Jackson2JsonE
|
||||
|
||||
ResolvableType type = ResolvableType.forClass(MappingJacksonValue.class);
|
||||
|
||||
testEncode(Mono.just(jacksonValue), type, null, Collections.emptyMap(), step -> step
|
||||
.consumeNextWith(expectString("{\"withView1\":\"with\"}").andThen(DataBufferUtils::release))
|
||||
.verifyComplete()
|
||||
);
|
||||
}
|
||||
|
||||
@Test // gh-28045
|
||||
public void jacksonValueUnwrappedBeforeObjectMapperSelection() {
|
||||
|
||||
JacksonViewBean bean = new JacksonViewBean();
|
||||
bean.setWithView1("with");
|
||||
bean.setWithView2("with");
|
||||
bean.setWithoutView("without");
|
||||
|
||||
MappingJacksonValue jacksonValue = new MappingJacksonValue(bean);
|
||||
jacksonValue.setSerializationView(MyJacksonView1.class);
|
||||
|
||||
ResolvableType type = ResolvableType.forClass(MappingJacksonValue.class);
|
||||
|
||||
MediaType halMediaType = MediaType.parseMediaType("application/hal+json");
|
||||
ObjectMapper mapper = new ObjectMapper().configure(SerializationFeature.INDENT_OUTPUT, true);
|
||||
this.encoder.registerObjectMappersForType(JacksonViewBean.class, map -> map.put(halMediaType, mapper));
|
||||
|
||||
testEncode(Mono.just(jacksonValue), type, halMediaType, Collections.emptyMap(), step -> step
|
||||
.consumeNextWith(expectString("{\n \"withView1\" : \"with\"\n}").andThen(DataBufferUtils::release))
|
||||
.verifyComplete()
|
||||
);
|
||||
testEncode(Mono.just(jacksonValue), type, step -> step
|
||||
.consumeNextWith(expectString("{\"withView1\":\"with\"}")
|
||||
.andThen(DataBufferUtils::release))
|
||||
.verifyComplete(),
|
||||
null, Collections.emptyMap());
|
||||
}
|
||||
|
||||
@Test // gh-22771
|
||||
@@ -272,12 +252,11 @@ public class Jackson2JsonEncoderTests extends AbstractEncoderTests<Jackson2JsonE
|
||||
@Test
|
||||
public void encodeAscii() {
|
||||
Mono<Object> input = Mono.just(new Pojo("foo", "bar"));
|
||||
MimeType mimeType = new MimeType("application", "json", StandardCharsets.US_ASCII);
|
||||
|
||||
testEncode(input, ResolvableType.forClass(Pojo.class), mimeType, null, step -> step
|
||||
testEncode(input, ResolvableType.forClass(Pojo.class), step -> step
|
||||
.consumeNextWith(expectString("{\"foo\":\"foo\",\"bar\":\"bar\"}"))
|
||||
.verifyComplete()
|
||||
);
|
||||
.verifyComplete(),
|
||||
new MimeType("application", "json", StandardCharsets.US_ASCII), null);
|
||||
}
|
||||
|
||||
|
||||
|
||||
+8
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -108,13 +108,17 @@ public class Jackson2SmileEncoderTests extends AbstractEncoderTests<Jackson2Smil
|
||||
}
|
||||
|
||||
@Test
|
||||
public void encodeError() {
|
||||
public void encodeError() throws Exception {
|
||||
Mono<Pojo> input = Mono.error(new InputException());
|
||||
testEncode(input, Pojo.class, step -> step.expectError(InputException.class).verify());
|
||||
|
||||
testEncode(input, Pojo.class, step -> step
|
||||
.expectError(InputException.class)
|
||||
.verify());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void encodeAsStream() {
|
||||
public void encodeAsStream() throws Exception {
|
||||
Pojo pojo1 = new Pojo("foo", "bar");
|
||||
Pojo pojo2 = new Pojo("foofoo", "barbar");
|
||||
Pojo pojo3 = new Pojo("foofoofoo", "barbarbar");
|
||||
|
||||
+26
-25
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -55,7 +55,6 @@ import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
import static java.util.Collections.emptyMap;
|
||||
import static java.util.Collections.singletonMap;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.junit.jupiter.api.Named.named;
|
||||
import static org.junit.jupiter.params.provider.Arguments.arguments;
|
||||
import static org.springframework.core.ResolvableType.forClass;
|
||||
import static org.springframework.core.io.buffer.DataBufferUtils.release;
|
||||
@@ -63,7 +62,7 @@ import static org.springframework.core.io.buffer.DataBufferUtils.release;
|
||||
/**
|
||||
* @author Arjen Poutsma
|
||||
*/
|
||||
class DefaultPartHttpMessageReaderTests {
|
||||
public class DefaultPartHttpMessageReaderTests {
|
||||
|
||||
private static final String LOREM_IPSUM = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer iaculis metus id vestibulum nullam.";
|
||||
|
||||
@@ -74,12 +73,12 @@ class DefaultPartHttpMessageReaderTests {
|
||||
private static final DataBufferFactory bufferFactory = new NettyDataBufferFactory(new PooledByteBufAllocator());
|
||||
|
||||
@ParameterizedDefaultPartHttpMessageReaderTest
|
||||
void canRead(DefaultPartHttpMessageReader reader) {
|
||||
public void canRead(String displayName, DefaultPartHttpMessageReader reader) {
|
||||
assertThat(reader.canRead(forClass(Part.class), MediaType.MULTIPART_FORM_DATA)).isTrue();
|
||||
}
|
||||
|
||||
@ParameterizedDefaultPartHttpMessageReaderTest
|
||||
void simple(DefaultPartHttpMessageReader reader) throws InterruptedException {
|
||||
public void simple(String displayName, DefaultPartHttpMessageReader reader) throws InterruptedException {
|
||||
MockServerHttpRequest request = createRequest(
|
||||
new ClassPathResource("simple.multipart", getClass()), "simple-boundary");
|
||||
|
||||
@@ -97,7 +96,7 @@ class DefaultPartHttpMessageReaderTests {
|
||||
}
|
||||
|
||||
@ParameterizedDefaultPartHttpMessageReaderTest
|
||||
void noHeaders(DefaultPartHttpMessageReader reader) {
|
||||
public void noHeaders(String displayName, DefaultPartHttpMessageReader reader) {
|
||||
MockServerHttpRequest request = createRequest(
|
||||
new ClassPathResource("no-header.multipart", getClass()), "boundary");
|
||||
Flux<Part> result = reader.read(forClass(Part.class), request, emptyMap());
|
||||
@@ -111,7 +110,7 @@ class DefaultPartHttpMessageReaderTests {
|
||||
}
|
||||
|
||||
@ParameterizedDefaultPartHttpMessageReaderTest
|
||||
void noEndBoundary(DefaultPartHttpMessageReader reader) {
|
||||
public void noEndBoundary(String displayName, DefaultPartHttpMessageReader reader) {
|
||||
MockServerHttpRequest request = createRequest(
|
||||
new ClassPathResource("no-end-boundary.multipart", getClass()), "boundary");
|
||||
|
||||
@@ -123,7 +122,7 @@ class DefaultPartHttpMessageReaderTests {
|
||||
}
|
||||
|
||||
@ParameterizedDefaultPartHttpMessageReaderTest
|
||||
void garbage(DefaultPartHttpMessageReader reader) {
|
||||
public void garbage(String displayName, DefaultPartHttpMessageReader reader) {
|
||||
MockServerHttpRequest request = createRequest(
|
||||
new ClassPathResource("garbage-1.multipart", getClass()), "boundary");
|
||||
|
||||
@@ -135,7 +134,7 @@ class DefaultPartHttpMessageReaderTests {
|
||||
}
|
||||
|
||||
@ParameterizedDefaultPartHttpMessageReaderTest
|
||||
void noEndHeader(DefaultPartHttpMessageReader reader) {
|
||||
public void noEndHeader(String displayName, DefaultPartHttpMessageReader reader) {
|
||||
MockServerHttpRequest request = createRequest(
|
||||
new ClassPathResource("no-end-header.multipart", getClass()), "boundary");
|
||||
Flux<Part> result = reader.read(forClass(Part.class), request, emptyMap());
|
||||
@@ -146,7 +145,7 @@ class DefaultPartHttpMessageReaderTests {
|
||||
}
|
||||
|
||||
@ParameterizedDefaultPartHttpMessageReaderTest
|
||||
void noEndBody(DefaultPartHttpMessageReader reader) {
|
||||
public void noEndBody(String displayName, DefaultPartHttpMessageReader reader) {
|
||||
MockServerHttpRequest request = createRequest(
|
||||
new ClassPathResource("no-end-body.multipart", getClass()), "boundary");
|
||||
Flux<Part> result = reader.read(forClass(Part.class), request, emptyMap());
|
||||
@@ -157,7 +156,7 @@ class DefaultPartHttpMessageReaderTests {
|
||||
}
|
||||
|
||||
@ParameterizedDefaultPartHttpMessageReaderTest
|
||||
void cancelPart(DefaultPartHttpMessageReader reader) {
|
||||
public void cancelPart(String displayName, DefaultPartHttpMessageReader reader) {
|
||||
MockServerHttpRequest request = createRequest(
|
||||
new ClassPathResource("simple.multipart", getClass()), "simple-boundary");
|
||||
Flux<Part> result = reader.read(forClass(Part.class), request, emptyMap());
|
||||
@@ -169,7 +168,7 @@ class DefaultPartHttpMessageReaderTests {
|
||||
}
|
||||
|
||||
@ParameterizedDefaultPartHttpMessageReaderTest
|
||||
void cancelBody(DefaultPartHttpMessageReader reader) throws Exception {
|
||||
public void cancelBody(String displayName, DefaultPartHttpMessageReader reader) throws Exception {
|
||||
MockServerHttpRequest request = createRequest(
|
||||
new ClassPathResource("simple.multipart", getClass()), "simple-boundary");
|
||||
Flux<Part> result = reader.read(forClass(Part.class), request, emptyMap());
|
||||
@@ -186,7 +185,7 @@ class DefaultPartHttpMessageReaderTests {
|
||||
}
|
||||
|
||||
@ParameterizedDefaultPartHttpMessageReaderTest
|
||||
void cancelBodyThenPart(DefaultPartHttpMessageReader reader) {
|
||||
public void cancelBodyThenPart(String displayName, DefaultPartHttpMessageReader reader) {
|
||||
MockServerHttpRequest request = createRequest(
|
||||
new ClassPathResource("simple.multipart", getClass()), "simple-boundary");
|
||||
Flux<Part> result = reader.read(forClass(Part.class), request, emptyMap());
|
||||
@@ -198,25 +197,25 @@ class DefaultPartHttpMessageReaderTests {
|
||||
}
|
||||
|
||||
@ParameterizedDefaultPartHttpMessageReaderTest
|
||||
void firefox(DefaultPartHttpMessageReader reader) throws InterruptedException {
|
||||
public void firefox(String displayName, DefaultPartHttpMessageReader reader) throws InterruptedException {
|
||||
testBrowser(reader, new ClassPathResource("firefox.multipart", getClass()),
|
||||
"---------------------------18399284482060392383840973206");
|
||||
}
|
||||
|
||||
@ParameterizedDefaultPartHttpMessageReaderTest
|
||||
void chrome(DefaultPartHttpMessageReader reader) throws InterruptedException {
|
||||
public void chrome(String displayName, DefaultPartHttpMessageReader reader) throws InterruptedException {
|
||||
testBrowser(reader, new ClassPathResource("chrome.multipart", getClass()),
|
||||
"----WebKitFormBoundaryEveBLvRT65n21fwU");
|
||||
}
|
||||
|
||||
@ParameterizedDefaultPartHttpMessageReaderTest
|
||||
void safari(DefaultPartHttpMessageReader reader) throws InterruptedException {
|
||||
public void safari(String displayName, DefaultPartHttpMessageReader reader) throws InterruptedException {
|
||||
testBrowser(reader, new ClassPathResource("safari.multipart", getClass()),
|
||||
"----WebKitFormBoundaryG8fJ50opQOML0oGD");
|
||||
}
|
||||
|
||||
@Test
|
||||
void tooManyParts() throws InterruptedException {
|
||||
public void tooManyParts() throws InterruptedException {
|
||||
MockServerHttpRequest request = createRequest(
|
||||
new ClassPathResource("simple.multipart", getClass()), "simple-boundary");
|
||||
|
||||
@@ -236,7 +235,7 @@ class DefaultPartHttpMessageReaderTests {
|
||||
}
|
||||
|
||||
@ParameterizedDefaultPartHttpMessageReaderTest
|
||||
void quotedBoundary(DefaultPartHttpMessageReader reader) throws InterruptedException {
|
||||
public void quotedBoundary(String displayName, DefaultPartHttpMessageReader reader) throws InterruptedException {
|
||||
MockServerHttpRequest request = createRequest(
|
||||
new ClassPathResource("simple.multipart", getClass()), "\"simple-boundary\"");
|
||||
|
||||
@@ -254,7 +253,7 @@ class DefaultPartHttpMessageReaderTests {
|
||||
}
|
||||
|
||||
@ParameterizedDefaultPartHttpMessageReaderTest
|
||||
void utf8Headers(DefaultPartHttpMessageReader reader) throws InterruptedException {
|
||||
public void utf8Headers(String displayName, DefaultPartHttpMessageReader reader) throws InterruptedException {
|
||||
MockServerHttpRequest request = createRequest(
|
||||
new ClassPathResource("utf8.multipart", getClass()), "\"simple-boundary\"");
|
||||
|
||||
@@ -273,7 +272,7 @@ class DefaultPartHttpMessageReaderTests {
|
||||
|
||||
// gh-27612
|
||||
@Test
|
||||
void exceedHeaderLimit() throws InterruptedException {
|
||||
public void exceedHeaderLimit() throws InterruptedException {
|
||||
Flux<DataBuffer> body = DataBufferUtils
|
||||
.readByteChannel((new ClassPathResource("files.multipart", getClass()))::readableChannel, bufferFactory, 282);
|
||||
|
||||
@@ -411,10 +410,10 @@ class DefaultPartHttpMessageReaderTests {
|
||||
@Target(ElementType.METHOD)
|
||||
@ParameterizedTest(name = "[{index}] {0}")
|
||||
@MethodSource("org.springframework.http.codec.multipart.DefaultPartHttpMessageReaderTests#messageReaders()")
|
||||
@interface ParameterizedDefaultPartHttpMessageReaderTest {
|
||||
public @interface ParameterizedDefaultPartHttpMessageReaderTest {
|
||||
}
|
||||
|
||||
static Stream<Arguments> messageReaders() {
|
||||
public static Stream<Arguments> messageReaders() {
|
||||
DefaultPartHttpMessageReader streaming = new DefaultPartHttpMessageReader();
|
||||
streaming.setStreaming(true);
|
||||
|
||||
@@ -427,9 +426,11 @@ class DefaultPartHttpMessageReaderTests {
|
||||
onDisk.setMaxInMemorySize(100);
|
||||
|
||||
return Stream.of(
|
||||
arguments(named("streaming", streaming)),
|
||||
arguments(named("in-memory", inMemory)),
|
||||
arguments(named("on-disk", onDisk)));
|
||||
arguments("streaming", streaming),
|
||||
arguments("in-memory", inMemory),
|
||||
arguments("on-disk", onDisk)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
+10
-9
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -71,8 +71,8 @@ public class Jaxb2XmlEncoderTests extends AbstractEncoderTests<Jaxb2XmlEncoder>
|
||||
Mono<Pojo> input = Mono.just(new Pojo("foofoo", "barbar"));
|
||||
|
||||
testEncode(input, Pojo.class, step -> step
|
||||
.consumeNextWith(expectXml(
|
||||
"<?xml version='1.0' encoding='UTF-8' standalone='yes'?>" +
|
||||
.consumeNextWith(
|
||||
expectXml("<?xml version='1.0' encoding='UTF-8' standalone='yes'?>" +
|
||||
"<pojo><bar>barbar</bar><foo>foofoo</foo></pojo>"))
|
||||
.verifyComplete());
|
||||
}
|
||||
@@ -80,7 +80,10 @@ public class Jaxb2XmlEncoderTests extends AbstractEncoderTests<Jaxb2XmlEncoder>
|
||||
@Test
|
||||
public void encodeError() {
|
||||
Flux<Pojo> input = Flux.error(RuntimeException::new);
|
||||
testEncode(input, Pojo.class, step -> step.expectError(RuntimeException.class).verify());
|
||||
|
||||
testEncode(input, Pojo.class, step -> step
|
||||
.expectError(RuntimeException.class)
|
||||
.verify());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -88,11 +91,9 @@ public class Jaxb2XmlEncoderTests extends AbstractEncoderTests<Jaxb2XmlEncoder>
|
||||
Mono<Container> input = Mono.just(new Container());
|
||||
|
||||
testEncode(input, Pojo.class, step -> step
|
||||
.consumeNextWith(expectXml(
|
||||
"<?xml version='1.0' encoding='UTF-8' standalone='yes'?>" +
|
||||
"<container>" +
|
||||
"<foo><name>name1</name></foo><bar><title>title1</title></bar>" +
|
||||
"</container>"))
|
||||
.consumeNextWith(
|
||||
expectXml("<?xml version='1.0' encoding='UTF-8' standalone='yes'?>" +
|
||||
"<container><foo><name>name1</name></foo><bar><title>title1</title></bar></container>"))
|
||||
.verifyComplete());
|
||||
}
|
||||
|
||||
|
||||
+16
-17
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -39,7 +39,6 @@ import org.springframework.util.MultiValueMap;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
import static org.junit.jupiter.api.Named.named;
|
||||
import static org.junit.jupiter.params.provider.Arguments.arguments;
|
||||
|
||||
/**
|
||||
@@ -51,24 +50,24 @@ import static org.junit.jupiter.params.provider.Arguments.arguments;
|
||||
class HeadersAdaptersTests {
|
||||
|
||||
@ParameterizedHeadersTest
|
||||
void getWithUnknownHeaderShouldReturnNull(MultiValueMap<String, String> headers) {
|
||||
void getWithUnknownHeaderShouldReturnNull(String displayName, MultiValueMap<String, String> headers) {
|
||||
assertThat(headers.get("Unknown")).isNull();
|
||||
}
|
||||
|
||||
@ParameterizedHeadersTest
|
||||
void getFirstWithUnknownHeaderShouldReturnNull(MultiValueMap<String, String> headers) {
|
||||
void getFirstWithUnknownHeaderShouldReturnNull(String displayName, MultiValueMap<String, String> headers) {
|
||||
assertThat(headers.getFirst("Unknown")).isNull();
|
||||
}
|
||||
|
||||
@ParameterizedHeadersTest
|
||||
void sizeWithMultipleValuesForHeaderShouldCountHeaders(MultiValueMap<String, String> headers) {
|
||||
void sizeWithMultipleValuesForHeaderShouldCountHeaders(String displayName, MultiValueMap<String, String> headers) {
|
||||
headers.add("TestHeader", "first");
|
||||
headers.add("TestHeader", "second");
|
||||
assertThat(headers.size()).isEqualTo(1);
|
||||
}
|
||||
|
||||
@ParameterizedHeadersTest
|
||||
void keySetShouldNotDuplicateHeaderNames(MultiValueMap<String, String> headers) {
|
||||
void keySetShouldNotDuplicateHeaderNames(String displayName, MultiValueMap<String, String> headers) {
|
||||
headers.add("TestHeader", "first");
|
||||
headers.add("OtherHeader", "test");
|
||||
headers.add("TestHeader", "second");
|
||||
@@ -76,13 +75,13 @@ class HeadersAdaptersTests {
|
||||
}
|
||||
|
||||
@ParameterizedHeadersTest
|
||||
void containsKeyShouldBeCaseInsensitive(MultiValueMap<String, String> headers) {
|
||||
void containsKeyShouldBeCaseInsensitive(String displayName, MultiValueMap<String, String> headers) {
|
||||
headers.add("TestHeader", "first");
|
||||
assertThat(headers.containsKey("testheader")).isTrue();
|
||||
}
|
||||
|
||||
@ParameterizedHeadersTest
|
||||
void addShouldKeepOrdering(MultiValueMap<String, String> headers) {
|
||||
void addShouldKeepOrdering(String displayName, MultiValueMap<String, String> headers) {
|
||||
headers.add("TestHeader", "first");
|
||||
headers.add("TestHeader", "second");
|
||||
assertThat(headers.getFirst("TestHeader")).isEqualTo("first");
|
||||
@@ -90,7 +89,7 @@ class HeadersAdaptersTests {
|
||||
}
|
||||
|
||||
@ParameterizedHeadersTest
|
||||
void putShouldOverrideExisting(MultiValueMap<String, String> headers) {
|
||||
void putShouldOverrideExisting(String displayName, MultiValueMap<String, String> headers) {
|
||||
headers.add("TestHeader", "first");
|
||||
headers.put("TestHeader", Arrays.asList("override"));
|
||||
assertThat(headers.getFirst("TestHeader")).isEqualTo("override");
|
||||
@@ -98,7 +97,7 @@ class HeadersAdaptersTests {
|
||||
}
|
||||
|
||||
@ParameterizedHeadersTest
|
||||
void nullValuesShouldNotFail(MultiValueMap<String, String> headers) {
|
||||
void nullValuesShouldNotFail(String displayName, MultiValueMap<String, String> headers) {
|
||||
headers.add("TestHeader", null);
|
||||
assertThat(headers.getFirst("TestHeader")).isNull();
|
||||
headers.set("TestHeader", null);
|
||||
@@ -106,7 +105,7 @@ class HeadersAdaptersTests {
|
||||
}
|
||||
|
||||
@ParameterizedHeadersTest
|
||||
void shouldReflectChangesOnKeyset(MultiValueMap<String, String> headers) {
|
||||
void shouldReflectChangesOnKeyset(String displayName, MultiValueMap<String, String> headers) {
|
||||
headers.add("TestHeader", "first");
|
||||
assertThat(headers.keySet()).hasSize(1);
|
||||
headers.keySet().removeIf("TestHeader"::equals);
|
||||
@@ -114,7 +113,7 @@ class HeadersAdaptersTests {
|
||||
}
|
||||
|
||||
@ParameterizedHeadersTest
|
||||
void shouldFailIfHeaderRemovedFromKeyset(MultiValueMap<String, String> headers) {
|
||||
void shouldFailIfHeaderRemovedFromKeyset(String displayName, MultiValueMap<String, String> headers) {
|
||||
headers.add("TestHeader", "first");
|
||||
assertThat(headers.keySet()).hasSize(1);
|
||||
Iterator<String> names = headers.keySet().iterator();
|
||||
@@ -133,11 +132,11 @@ class HeadersAdaptersTests {
|
||||
|
||||
static Stream<Arguments> headers() {
|
||||
return Stream.of(
|
||||
arguments(named("Map", CollectionUtils.toMultiValueMap(new LinkedCaseInsensitiveMap<>(8, Locale.ENGLISH)))),
|
||||
arguments(named("Netty", new NettyHeadersAdapter(new DefaultHttpHeaders()))),
|
||||
arguments(named("Tomcat", new TomcatHeadersAdapter(new MimeHeaders()))),
|
||||
arguments(named("Undertow", new UndertowHeadersAdapter(new HeaderMap()))),
|
||||
arguments(named("Jetty", new JettyHeadersAdapter(new HttpFields())))
|
||||
arguments("Map", CollectionUtils.toMultiValueMap(new LinkedCaseInsensitiveMap<>(8, Locale.ENGLISH))),
|
||||
arguments("Netty", new NettyHeadersAdapter(new DefaultHttpHeaders())),
|
||||
arguments("Tomcat", new TomcatHeadersAdapter(new MimeHeaders())),
|
||||
arguments("Undertow", new UndertowHeadersAdapter(new HeaderMap())),
|
||||
arguments("Jetty", new JettyHeadersAdapter(new HttpFields()))
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
+21
-32
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,11 +16,8 @@
|
||||
|
||||
package org.springframework.web.client;
|
||||
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
||||
import org.springframework.http.HttpHeaders;
|
||||
@@ -30,8 +27,6 @@ import org.springframework.http.client.ClientHttpResponse;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
import static org.junit.jupiter.api.Named.named;
|
||||
import static org.junit.jupiter.params.provider.Arguments.arguments;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.springframework.http.HttpStatus.BAD_GATEWAY;
|
||||
@@ -70,7 +65,7 @@ class DefaultResponseErrorHandlerHttpStatusTests {
|
||||
assertThat(this.handler.hasError(this.response)).isTrue();
|
||||
}
|
||||
|
||||
@ParameterizedTest(name = "[{index}] error: {0}, exception: {1}")
|
||||
@ParameterizedTest(name = "[{index}] error: [{0}], exception: [{1}]")
|
||||
@DisplayName("handleError() throws an exception")
|
||||
@MethodSource("errorCodes")
|
||||
void handleErrorException(HttpStatus httpStatus, Class<? extends Throwable> expectedExceptionClass) throws Exception {
|
||||
@@ -83,33 +78,27 @@ class DefaultResponseErrorHandlerHttpStatusTests {
|
||||
assertThatExceptionOfType(expectedExceptionClass).isThrownBy(() -> this.handler.handleError(this.response));
|
||||
}
|
||||
|
||||
static Stream<Arguments> errorCodes() {
|
||||
return Stream.of(
|
||||
static Object[][] errorCodes() {
|
||||
return new Object[][]{
|
||||
// 4xx
|
||||
args(BAD_REQUEST, HttpClientErrorException.BadRequest.class),
|
||||
args(UNAUTHORIZED, HttpClientErrorException.Unauthorized.class),
|
||||
args(FORBIDDEN, HttpClientErrorException.Forbidden.class),
|
||||
args(NOT_FOUND, HttpClientErrorException.NotFound.class),
|
||||
args(METHOD_NOT_ALLOWED, HttpClientErrorException.MethodNotAllowed.class),
|
||||
args(NOT_ACCEPTABLE, HttpClientErrorException.NotAcceptable.class),
|
||||
args(CONFLICT, HttpClientErrorException.Conflict.class),
|
||||
args(TOO_MANY_REQUESTS, HttpClientErrorException.TooManyRequests.class),
|
||||
args(UNPROCESSABLE_ENTITY, HttpClientErrorException.UnprocessableEntity.class),
|
||||
args(I_AM_A_TEAPOT, HttpClientErrorException.class),
|
||||
{BAD_REQUEST, HttpClientErrorException.BadRequest.class},
|
||||
{UNAUTHORIZED, HttpClientErrorException.Unauthorized.class},
|
||||
{FORBIDDEN, HttpClientErrorException.Forbidden.class},
|
||||
{NOT_FOUND, HttpClientErrorException.NotFound.class},
|
||||
{METHOD_NOT_ALLOWED, HttpClientErrorException.MethodNotAllowed.class},
|
||||
{NOT_ACCEPTABLE, HttpClientErrorException.NotAcceptable.class},
|
||||
{CONFLICT, HttpClientErrorException.Conflict.class},
|
||||
{TOO_MANY_REQUESTS, HttpClientErrorException.TooManyRequests.class},
|
||||
{UNPROCESSABLE_ENTITY, HttpClientErrorException.UnprocessableEntity.class},
|
||||
{I_AM_A_TEAPOT, HttpClientErrorException.class},
|
||||
// 5xx
|
||||
args(INTERNAL_SERVER_ERROR, HttpServerErrorException.InternalServerError.class),
|
||||
args(NOT_IMPLEMENTED, HttpServerErrorException.NotImplemented.class),
|
||||
args(BAD_GATEWAY, HttpServerErrorException.BadGateway.class),
|
||||
args(SERVICE_UNAVAILABLE, HttpServerErrorException.ServiceUnavailable.class),
|
||||
args(GATEWAY_TIMEOUT, HttpServerErrorException.GatewayTimeout.class),
|
||||
args(HTTP_VERSION_NOT_SUPPORTED, HttpServerErrorException.class)
|
||||
);
|
||||
}
|
||||
|
||||
private static Arguments args(HttpStatus httpStatus, Class<? extends Throwable> exceptionType) {
|
||||
return arguments(
|
||||
named(String.valueOf(httpStatus.value()), httpStatus),
|
||||
named(exceptionType.getSimpleName(), exceptionType));
|
||||
{INTERNAL_SERVER_ERROR, HttpServerErrorException.InternalServerError.class},
|
||||
{NOT_IMPLEMENTED, HttpServerErrorException.NotImplemented.class},
|
||||
{BAD_GATEWAY, HttpServerErrorException.BadGateway.class},
|
||||
{SERVICE_UNAVAILABLE, HttpServerErrorException.ServiceUnavailable.class},
|
||||
{GATEWAY_TIMEOUT, HttpServerErrorException.GatewayTimeout.class},
|
||||
{HTTP_VERSION_NOT_SUPPORTED, HttpServerErrorException.class}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+6
-8
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -31,7 +31,6 @@ import java.util.stream.Stream;
|
||||
import com.fasterxml.jackson.annotation.JsonTypeInfo;
|
||||
import com.fasterxml.jackson.annotation.JsonTypeName;
|
||||
import com.fasterxml.jackson.annotation.JsonView;
|
||||
import org.junit.jupiter.api.Named;
|
||||
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||
import org.junit.jupiter.api.extension.TestExecutionExceptionHandler;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
@@ -59,7 +58,6 @@ import org.springframework.util.MultiValueMap;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
import static org.junit.jupiter.api.Assumptions.assumeFalse;
|
||||
import static org.junit.jupiter.api.Named.named;
|
||||
import static org.springframework.http.HttpMethod.POST;
|
||||
import static org.springframework.http.MediaType.MULTIPART_MIXED;
|
||||
|
||||
@@ -90,12 +88,12 @@ class RestTemplateIntegrationTests extends AbstractMockWebServerTests {
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
static Stream<Named<ClientHttpRequestFactory>> clientHttpRequestFactories() {
|
||||
static Stream<ClientHttpRequestFactory> clientHttpRequestFactories() {
|
||||
return Stream.of(
|
||||
named("JDK", new SimpleClientHttpRequestFactory()),
|
||||
named("HttpComponents", new HttpComponentsClientHttpRequestFactory()),
|
||||
named("Netty", new org.springframework.http.client.Netty4ClientHttpRequestFactory()),
|
||||
named("OkHttp", new OkHttp3ClientHttpRequestFactory())
|
||||
new SimpleClientHttpRequestFactory(),
|
||||
new HttpComponentsClientHttpRequestFactory(),
|
||||
new org.springframework.http.client.Netty4ClientHttpRequestFactory(),
|
||||
new OkHttp3ClientHttpRequestFactory()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
+33
-33
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -23,7 +23,6 @@ import java.lang.annotation.Target;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.junit.jupiter.api.Named;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
@@ -35,7 +34,6 @@ import org.springframework.web.util.UrlPathHelper;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
|
||||
import static org.junit.jupiter.api.Named.named;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link UrlBasedCorsConfigurationSource}.
|
||||
@@ -44,35 +42,62 @@ import static org.junit.jupiter.api.Named.named;
|
||||
*/
|
||||
class UrlBasedCorsConfigurationSourceTests {
|
||||
|
||||
private final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.METHOD)
|
||||
@ParameterizedTest
|
||||
@MethodSource("pathPatternsArguments")
|
||||
@interface PathPatternsParameterizedTest {
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static Stream<Function<String, MockHttpServletRequest>> pathPatternsArguments() {
|
||||
return Stream.of(
|
||||
requestUri -> {
|
||||
MockHttpServletRequest request = new MockHttpServletRequest("GET", requestUri);
|
||||
ServletRequestPathUtils.parseAndCache(request);
|
||||
return request;
|
||||
},
|
||||
requestUri -> {
|
||||
MockHttpServletRequest request = new MockHttpServletRequest("GET", requestUri);
|
||||
UrlPathHelper.defaultInstance.getLookupPathForRequest(request);
|
||||
return request;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@PathPatternsParameterizedTest
|
||||
void empty(Function<String, MockHttpServletRequest> requestFactory) {
|
||||
CorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
|
||||
assertThat(source.getCorsConfiguration(requestFactory.apply("/bar/test.html"))).isNull();
|
||||
}
|
||||
|
||||
@PathPatternsParameterizedTest
|
||||
void registerAndMatch(Function<String, MockHttpServletRequest> requestFactory) {
|
||||
CorsConfiguration config = new CorsConfiguration();
|
||||
source.registerCorsConfiguration("/bar/**", config);
|
||||
UrlBasedCorsConfigurationSource configSource = new UrlBasedCorsConfigurationSource();
|
||||
configSource.registerCorsConfiguration("/bar/**", config);
|
||||
|
||||
MockHttpServletRequest request = requestFactory.apply("/foo/test.html");
|
||||
assertThat(source.getCorsConfiguration(request)).isNull();
|
||||
assertThat(configSource.getCorsConfiguration(request)).isNull();
|
||||
|
||||
request = requestFactory.apply("/bar/test.html");
|
||||
assertThat(source.getCorsConfiguration(request)).isEqualTo(config);
|
||||
assertThat(configSource.getCorsConfiguration(request)).isEqualTo(config);
|
||||
}
|
||||
|
||||
@Test
|
||||
void unmodifiableConfigurationsMap() {
|
||||
assertThatExceptionOfType(UnsupportedOperationException.class)
|
||||
.isThrownBy(() -> source.getCorsConfigurations().put("/**", new CorsConfiguration()));
|
||||
.isThrownBy(() -> {
|
||||
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
|
||||
source.getCorsConfigurations().put("/**", new CorsConfiguration());
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void allowInitLookupPath() {
|
||||
CorsConfiguration config = new CorsConfiguration();
|
||||
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
|
||||
source.registerCorsConfiguration("/**", config);
|
||||
|
||||
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/foo");
|
||||
@@ -83,29 +108,4 @@ class UrlBasedCorsConfigurationSourceTests {
|
||||
source.setAllowInitLookupPath(false);
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> source.getCorsConfiguration(request));
|
||||
}
|
||||
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.METHOD)
|
||||
@ParameterizedTest(name = "[{index}] {0}")
|
||||
@MethodSource("pathPatternsArguments")
|
||||
private @interface PathPatternsParameterizedTest {
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static Stream<Named<Function<String, MockHttpServletRequest>>> pathPatternsArguments() {
|
||||
return Stream.of(
|
||||
named("ServletRequestPathUtils", requestUri -> {
|
||||
MockHttpServletRequest request = new MockHttpServletRequest("GET", requestUri);
|
||||
ServletRequestPathUtils.parseAndCache(request);
|
||||
return request;
|
||||
}),
|
||||
named("UrlPathHelper", requestUri -> {
|
||||
MockHttpServletRequest request = new MockHttpServletRequest("GET", requestUri);
|
||||
UrlPathHelper.defaultInstance.getLookupPathForRequest(request);
|
||||
return request;
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+14
-12
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -65,23 +65,25 @@ class KotlinSerializationJsonEncoderTests : AbstractEncoderTests<KotlinSerializa
|
||||
Pojo("foofoo", "barbar"),
|
||||
Pojo("foofoofoo", "barbarbar")
|
||||
)
|
||||
testEncode(input, Pojo::class.java, { step: FirstStep<DataBuffer?> -> step
|
||||
.consumeNextWith(expectString("[" +
|
||||
"{\"foo\":\"foo\",\"bar\":\"bar\"}," +
|
||||
"{\"foo\":\"foofoo\",\"bar\":\"barbar\"}," +
|
||||
"{\"foo\":\"foofoofoo\",\"bar\":\"barbarbar\"}]")
|
||||
.andThen { dataBuffer: DataBuffer? -> DataBufferUtils.release(dataBuffer) })
|
||||
.verifyComplete()
|
||||
testEncode(input, Pojo::class.java, { step: FirstStep<DataBuffer?> ->
|
||||
step
|
||||
.consumeNextWith(expectString("[" +
|
||||
"{\"foo\":\"foo\",\"bar\":\"bar\"}," +
|
||||
"{\"foo\":\"foofoo\",\"bar\":\"barbar\"}," +
|
||||
"{\"foo\":\"foofoofoo\",\"bar\":\"barbarbar\"}]")
|
||||
.andThen { dataBuffer: DataBuffer? -> DataBufferUtils.release(dataBuffer) })
|
||||
.verifyComplete()
|
||||
})
|
||||
}
|
||||
|
||||
@Test
|
||||
fun encodeMono() {
|
||||
val input = Mono.just(Pojo("foo", "bar"))
|
||||
testEncode(input, Pojo::class.java, { step: FirstStep<DataBuffer?> -> step
|
||||
.consumeNextWith(expectString("{\"foo\":\"foo\",\"bar\":\"bar\"}")
|
||||
.andThen { dataBuffer: DataBuffer? -> DataBufferUtils.release(dataBuffer) })
|
||||
.verifyComplete()
|
||||
testEncode(input, Pojo::class.java, { step: FirstStep<DataBuffer?> ->
|
||||
step
|
||||
.consumeNextWith(expectString("{\"foo\":\"foo\",\"bar\":\"bar\"}")
|
||||
.andThen { dataBuffer: DataBuffer? -> DataBufferUtils.release(dataBuffer) })
|
||||
.verifyComplete()
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
+6
-9
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -26,7 +26,6 @@ import java.util.stream.Stream;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Named;
|
||||
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||
import org.junit.jupiter.api.extension.TestExecutionExceptionHandler;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
@@ -37,8 +36,6 @@ import org.springframework.http.server.reactive.HttpHandler;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.client.HttpServerErrorException;
|
||||
|
||||
import static org.junit.jupiter.api.Named.named;
|
||||
|
||||
public abstract class AbstractHttpHandlerIntegrationTests {
|
||||
|
||||
/**
|
||||
@@ -124,12 +121,12 @@ public abstract class AbstractHttpHandlerIntegrationTests {
|
||||
public @interface ParameterizedHttpServerTest {
|
||||
}
|
||||
|
||||
static Stream<Named<HttpServer>> httpServers() {
|
||||
static Stream<HttpServer> httpServers() {
|
||||
return Stream.of(
|
||||
named("Jetty", new JettyHttpServer()),
|
||||
named("Reactor Netty", new ReactorHttpServer()),
|
||||
named("Tomcat", new TomcatHttpServer()),
|
||||
named("Undertow", new UndertowHttpServer())
|
||||
new JettyHttpServer(),
|
||||
new ReactorHttpServer(),
|
||||
new TomcatHttpServer(),
|
||||
new UndertowHttpServer()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
+1
-3
@@ -21,7 +21,6 @@ import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.reactivestreams.Publisher;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.core.KotlinDetector;
|
||||
@@ -131,8 +130,7 @@ public abstract class AbstractMessageWriterResultHandler extends HandlerResultHa
|
||||
if (adapter != null) {
|
||||
publisher = adapter.toPublisher(body);
|
||||
boolean isUnwrapped = KotlinDetector.isSuspendingFunction(bodyParameter.getMethod()) &&
|
||||
!COROUTINES_FLOW_CLASS_NAME.equals(bodyType.toClass().getName()) &&
|
||||
!Flux.class.equals(bodyType.toClass());
|
||||
!COROUTINES_FLOW_CLASS_NAME.equals(bodyType.toClass().getName());
|
||||
ResolvableType genericType = isUnwrapped ? bodyType : bodyType.getGeneric();
|
||||
elementType = getElementType(adapter, genericType);
|
||||
actualElementType = elementType;
|
||||
|
||||
+8
-8
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -45,7 +45,7 @@ import org.springframework.web.util.UriUtils;
|
||||
* values from the model or with URI variables from the current request.
|
||||
*
|
||||
* <p>By default {@link HttpStatus#SEE_OTHER} is used but alternate status codes
|
||||
* may be supplied via constructor or setters arguments.
|
||||
* may be via constructor or setters arguments.
|
||||
*
|
||||
* @author Sebastien Deleuze
|
||||
* @author Rossen Stoyanchev
|
||||
@@ -74,7 +74,7 @@ public class RedirectView extends AbstractUrlBasedView {
|
||||
|
||||
/**
|
||||
* Create a new {@code RedirectView} with the given redirect URL.
|
||||
* <p>Status code {@link HttpStatus#SEE_OTHER} is used by default.
|
||||
* Status code {@link HttpStatus#SEE_OTHER} is used by default.
|
||||
*/
|
||||
public RedirectView(String redirectUrl) {
|
||||
super(redirectUrl);
|
||||
@@ -109,9 +109,9 @@ public class RedirectView extends AbstractUrlBasedView {
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether to interpret a given redirect URL that starts with a slash ("/")
|
||||
* as relative to the current context path ({@code true}, the default) or
|
||||
* relative to the web server root ({@code false}).
|
||||
* Whether to interpret a given redirect URLs that starts with a slash ("/")
|
||||
* as relative to the current context path ({@code true}, the default) or to
|
||||
* the web server root ({@code false}).
|
||||
*/
|
||||
public void setContextRelative(boolean contextRelative) {
|
||||
this.contextRelative = contextRelative;
|
||||
@@ -141,7 +141,7 @@ public class RedirectView extends AbstractUrlBasedView {
|
||||
|
||||
/**
|
||||
* Configure one or more hosts associated with the application.
|
||||
* <p>All other hosts will be considered external hosts.
|
||||
* All other hosts will be considered external hosts.
|
||||
* <p>In effect this provides a way turn off encoding for URLs that
|
||||
* have a host and that host is not listed as a known host.
|
||||
* <p>If not set (the default) all redirect URLs are encoded.
|
||||
@@ -301,7 +301,7 @@ public class RedirectView extends AbstractUrlBasedView {
|
||||
* property is configured and the target URL has a host that does not match.
|
||||
* @param targetUrl the target redirect URL
|
||||
* @return {@code true} the target URL has a remote host, {@code false} if it
|
||||
* the URL does not have a host or the "host" property is not configured
|
||||
* the URL does not have a host or the "host" property is not configured.
|
||||
*/
|
||||
protected boolean isRemoteHost(String targetUrl) {
|
||||
if (ObjectUtils.isEmpty(this.hosts)) {
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -34,7 +34,7 @@ import org.springframework.ui.Model;
|
||||
* Or controllers may return model attribute(s) and rely on a default view name
|
||||
* being selected based on the request path.
|
||||
*
|
||||
* <p>{@code Rendering} can be used to combine a view name with model attributes,
|
||||
* <p>{@link Rendering} can be used to combine a view name with model attributes,
|
||||
* set the HTTP status or headers, and for other more advanced options around
|
||||
* redirect scenarios.
|
||||
*
|
||||
|
||||
+10
-10
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -96,7 +96,7 @@ class WebClientDataBufferAllocatingTests extends AbstractDataBufferAllocatingTes
|
||||
|
||||
|
||||
@ParameterizedDataBufferAllocatingTest
|
||||
void bodyToMonoVoid(DataBufferFactory bufferFactory) {
|
||||
void bodyToMonoVoid(String displayName, DataBufferFactory bufferFactory) {
|
||||
setUp(bufferFactory);
|
||||
|
||||
this.server.enqueue(new MockResponse()
|
||||
@@ -114,7 +114,7 @@ class WebClientDataBufferAllocatingTests extends AbstractDataBufferAllocatingTes
|
||||
}
|
||||
|
||||
@ParameterizedDataBufferAllocatingTest // SPR-17482
|
||||
void bodyToMonoVoidWithoutContentType(DataBufferFactory bufferFactory) {
|
||||
void bodyToMonoVoidWithoutContentType(String displayName, DataBufferFactory bufferFactory) {
|
||||
setUp(bufferFactory);
|
||||
|
||||
this.server.enqueue(new MockResponse()
|
||||
@@ -131,7 +131,7 @@ class WebClientDataBufferAllocatingTests extends AbstractDataBufferAllocatingTes
|
||||
}
|
||||
|
||||
@ParameterizedDataBufferAllocatingTest
|
||||
void onStatusWithBodyNotConsumed(DataBufferFactory bufferFactory) {
|
||||
void onStatusWithBodyNotConsumed(String displayName, DataBufferFactory bufferFactory) {
|
||||
setUp(bufferFactory);
|
||||
|
||||
RuntimeException ex = new RuntimeException("response error");
|
||||
@@ -139,7 +139,7 @@ class WebClientDataBufferAllocatingTests extends AbstractDataBufferAllocatingTes
|
||||
}
|
||||
|
||||
@ParameterizedDataBufferAllocatingTest
|
||||
void onStatusWithBodyConsumed(DataBufferFactory bufferFactory) {
|
||||
void onStatusWithBodyConsumed(String displayName, DataBufferFactory bufferFactory) {
|
||||
setUp(bufferFactory);
|
||||
|
||||
RuntimeException ex = new RuntimeException("response error");
|
||||
@@ -147,7 +147,7 @@ class WebClientDataBufferAllocatingTests extends AbstractDataBufferAllocatingTes
|
||||
}
|
||||
|
||||
@ParameterizedDataBufferAllocatingTest // SPR-17473
|
||||
void onStatusWithMonoErrorAndBodyNotConsumed(DataBufferFactory bufferFactory) {
|
||||
void onStatusWithMonoErrorAndBodyNotConsumed(String displayName, DataBufferFactory bufferFactory) {
|
||||
setUp(bufferFactory);
|
||||
|
||||
RuntimeException ex = new RuntimeException("response error");
|
||||
@@ -155,7 +155,7 @@ class WebClientDataBufferAllocatingTests extends AbstractDataBufferAllocatingTes
|
||||
}
|
||||
|
||||
@ParameterizedDataBufferAllocatingTest
|
||||
void onStatusWithMonoErrorAndBodyConsumed(DataBufferFactory bufferFactory) {
|
||||
void onStatusWithMonoErrorAndBodyConsumed(String displayName, DataBufferFactory bufferFactory) {
|
||||
setUp(bufferFactory);
|
||||
|
||||
RuntimeException ex = new RuntimeException("response error");
|
||||
@@ -163,7 +163,7 @@ class WebClientDataBufferAllocatingTests extends AbstractDataBufferAllocatingTes
|
||||
}
|
||||
|
||||
@ParameterizedDataBufferAllocatingTest // gh-23230
|
||||
void onStatusWithImmediateErrorAndBodyNotConsumed(DataBufferFactory bufferFactory) {
|
||||
void onStatusWithImmediateErrorAndBodyNotConsumed(String displayName, DataBufferFactory bufferFactory) {
|
||||
setUp(bufferFactory);
|
||||
|
||||
RuntimeException ex = new RuntimeException("response error");
|
||||
@@ -173,7 +173,7 @@ class WebClientDataBufferAllocatingTests extends AbstractDataBufferAllocatingTes
|
||||
}
|
||||
|
||||
@ParameterizedDataBufferAllocatingTest
|
||||
void releaseBody(DataBufferFactory bufferFactory) {
|
||||
void releaseBody(String displayName, DataBufferFactory bufferFactory) {
|
||||
setUp(bufferFactory);
|
||||
|
||||
this.server.enqueue(new MockResponse()
|
||||
@@ -190,7 +190,7 @@ class WebClientDataBufferAllocatingTests extends AbstractDataBufferAllocatingTes
|
||||
}
|
||||
|
||||
@ParameterizedDataBufferAllocatingTest
|
||||
void exchangeToBodilessEntity(DataBufferFactory bufferFactory) {
|
||||
void exchangeToBodilessEntity(String displayName, DataBufferFactory bufferFactory) {
|
||||
setUp(bufferFactory);
|
||||
|
||||
this.server.enqueue(new MockResponse()
|
||||
|
||||
+5
-6
@@ -43,7 +43,6 @@ import okhttp3.mockwebserver.MockResponse;
|
||||
import okhttp3.mockwebserver.MockWebServer;
|
||||
import okhttp3.mockwebserver.RecordedRequest;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Named;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
@@ -90,16 +89,16 @@ class WebClientIntegrationTests {
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.METHOD)
|
||||
@ParameterizedTest(name = "[{index}] {0}")
|
||||
@ParameterizedTest(name = "[{index}] {displayName} [{0}]")
|
||||
@MethodSource("arguments")
|
||||
@interface ParameterizedWebClientTest {
|
||||
}
|
||||
|
||||
static Stream<Named<ClientHttpConnector>> arguments() {
|
||||
static Stream<ClientHttpConnector> arguments() {
|
||||
return Stream.of(
|
||||
Named.named("Reactor Netty", new ReactorClientHttpConnector()),
|
||||
Named.named("Jetty", new JettyClientHttpConnector()),
|
||||
Named.named("HttpComponents", new HttpComponentsClientHttpConnector())
|
||||
new ReactorClientHttpConnector(),
|
||||
new JettyClientHttpConnector(),
|
||||
new HttpComponentsClientHttpConnector()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
+26
-35
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -21,11 +21,9 @@ import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
import java.time.Duration;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
@@ -58,7 +56,6 @@ import org.springframework.web.testfixture.http.server.reactive.bootstrap.Undert
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.junit.jupiter.api.Assumptions.assumeTrue;
|
||||
import static org.junit.jupiter.api.Named.named;
|
||||
import static org.springframework.http.MediaType.TEXT_EVENT_STREAM;
|
||||
|
||||
/**
|
||||
@@ -67,6 +64,31 @@ import static org.springframework.http.MediaType.TEXT_EVENT_STREAM;
|
||||
*/
|
||||
class SseIntegrationTests extends AbstractHttpHandlerIntegrationTests {
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.METHOD)
|
||||
@ParameterizedTest(name = "[{index}] server [{0}], webClient [{1}]")
|
||||
@MethodSource("arguments")
|
||||
protected @interface ParameterizedSseTest {
|
||||
}
|
||||
|
||||
static Object[][] arguments() {
|
||||
return new Object[][] {
|
||||
{new JettyHttpServer(), new ReactorClientHttpConnector()},
|
||||
{new JettyHttpServer(), new JettyClientHttpConnector()},
|
||||
{new JettyHttpServer(), new HttpComponentsClientHttpConnector()},
|
||||
{new ReactorHttpServer(), new ReactorClientHttpConnector()},
|
||||
{new ReactorHttpServer(), new JettyClientHttpConnector()},
|
||||
{new ReactorHttpServer(), new HttpComponentsClientHttpConnector()},
|
||||
{new TomcatHttpServer(), new ReactorClientHttpConnector()},
|
||||
{new TomcatHttpServer(), new JettyClientHttpConnector()},
|
||||
{new TomcatHttpServer(), new HttpComponentsClientHttpConnector()},
|
||||
{new UndertowHttpServer(), new ReactorClientHttpConnector()},
|
||||
{new UndertowHttpServer(), new JettyClientHttpConnector()},
|
||||
{new UndertowHttpServer(), new HttpComponentsClientHttpConnector()}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
private AnnotationConfigApplicationContext wac;
|
||||
|
||||
private WebClient webClient;
|
||||
@@ -290,35 +312,4 @@ class SseIntegrationTests extends AbstractHttpHandlerIntegrationTests {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.METHOD)
|
||||
@ParameterizedTest(name = "[{index}] server = {0}, webClient = {1}")
|
||||
@MethodSource("arguments")
|
||||
private @interface ParameterizedSseTest {
|
||||
}
|
||||
|
||||
static Stream<Arguments> arguments() {
|
||||
return Stream.of(
|
||||
args(new JettyHttpServer(), new ReactorClientHttpConnector()),
|
||||
args(new JettyHttpServer(), new JettyClientHttpConnector()),
|
||||
args(new JettyHttpServer(), new HttpComponentsClientHttpConnector()),
|
||||
args(new ReactorHttpServer(), new ReactorClientHttpConnector()),
|
||||
args(new ReactorHttpServer(), new JettyClientHttpConnector()),
|
||||
args(new ReactorHttpServer(), new HttpComponentsClientHttpConnector()),
|
||||
args(new TomcatHttpServer(), new ReactorClientHttpConnector()),
|
||||
args(new TomcatHttpServer(), new JettyClientHttpConnector()),
|
||||
args(new TomcatHttpServer(), new HttpComponentsClientHttpConnector()),
|
||||
args(new UndertowHttpServer(), new ReactorClientHttpConnector()),
|
||||
args(new UndertowHttpServer(), new JettyClientHttpConnector()),
|
||||
args(new UndertowHttpServer(), new HttpComponentsClientHttpConnector())
|
||||
);
|
||||
}
|
||||
|
||||
private static Arguments args(HttpServer httpServer, ClientHttpConnector connector) {
|
||||
return Arguments.of(
|
||||
named(httpServer.getClass().getSimpleName(), httpServer),
|
||||
named(connector.getClass().getSimpleName(), connector));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
-40
@@ -36,8 +36,6 @@ import org.springframework.web.bind.annotation.RestController
|
||||
import org.springframework.web.client.HttpServerErrorException
|
||||
import org.springframework.web.reactive.config.EnableWebFlux
|
||||
import org.springframework.web.testfixture.http.server.reactive.bootstrap.HttpServer
|
||||
import reactor.core.publisher.Flux
|
||||
import java.time.Duration
|
||||
|
||||
class CoroutinesIntegrationTests : AbstractRequestMappingIntegrationTests() {
|
||||
|
||||
@@ -112,25 +110,6 @@ class CoroutinesIntegrationTests : AbstractRequestMappingIntegrationTests() {
|
||||
}
|
||||
}
|
||||
|
||||
@ParameterizedHttpServerTest
|
||||
fun `Suspending handler method returning ResponseEntity of Flux `(httpServer: HttpServer) {
|
||||
startServer(httpServer)
|
||||
|
||||
val entity = performGet<String>("/entity-flux", HttpHeaders.EMPTY, String::class.java)
|
||||
assertThat(entity.statusCode).isEqualTo(HttpStatus.OK)
|
||||
assertThat(entity.body).isEqualTo("01234")
|
||||
}
|
||||
|
||||
@ParameterizedHttpServerTest
|
||||
fun `Suspending handler method returning ResponseEntity of Flow`(httpServer: HttpServer) {
|
||||
startServer(httpServer)
|
||||
|
||||
val entity = performGet<String>("/entity-flow", HttpHeaders.EMPTY, String::class.java)
|
||||
assertThat(entity.statusCode).isEqualTo(HttpStatus.OK)
|
||||
assertThat(entity.body).isEqualTo("foobar")
|
||||
}
|
||||
|
||||
|
||||
@Configuration
|
||||
@EnableWebFlux
|
||||
@ComponentScan(resourcePattern = "**/CoroutinesIntegrationTests*")
|
||||
@@ -188,25 +167,6 @@ class CoroutinesIntegrationTests : AbstractRequestMappingIntegrationTests() {
|
||||
throw IllegalStateException()
|
||||
}
|
||||
|
||||
@GetMapping("/entity-flux")
|
||||
suspend fun entityFlux() : ResponseEntity<Flux<String>> {
|
||||
val strings = Flux.interval(Duration.ofMillis(100)).take(5)
|
||||
.map { l -> l.toString() }
|
||||
delay(1)
|
||||
return ResponseEntity.ok().body(strings)
|
||||
}
|
||||
|
||||
@GetMapping("/entity-flow")
|
||||
suspend fun entityFlow() : ResponseEntity<Flow<String>> {
|
||||
val strings = flow {
|
||||
emit("foo")
|
||||
delay(1)
|
||||
emit("bar")
|
||||
delay(1)
|
||||
}
|
||||
return ResponseEntity.ok().body(strings)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
+12
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,7 +16,9 @@
|
||||
|
||||
package org.springframework.web.servlet.handler;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
@@ -30,7 +32,6 @@ import org.springframework.web.servlet.HandlerInterceptor;
|
||||
import org.springframework.web.testfixture.servlet.MockHttpServletRequest;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.junit.jupiter.params.provider.Arguments.arguments;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
@@ -43,12 +44,19 @@ class HandlerMappingTests {
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static Stream<Arguments> pathPatternsArguments() {
|
||||
return PathPatternsTestUtils.requestArguments().map(function -> arguments(function, new TestHandlerMapping()));
|
||||
List<Function<String, MockHttpServletRequest>> factories =
|
||||
PathPatternsTestUtils.requestArguments().collect(Collectors.toList());
|
||||
return Stream.of(
|
||||
Arguments.arguments(new TestHandlerMapping(), factories.get(0)),
|
||||
Arguments.arguments(new TestHandlerMapping(), factories.get(1))
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@PathPatternsParameterizedTest
|
||||
void orderedInterceptors(Function<String, MockHttpServletRequest> requestFactory, TestHandlerMapping mapping) throws Exception {
|
||||
void orderedInterceptors(
|
||||
TestHandlerMapping mapping, Function<String, MockHttpServletRequest> requestFactory)
|
||||
throws Exception {
|
||||
|
||||
MappedInterceptor i1 = new MappedInterceptor(new String[] {"/**"}, mock(HandlerInterceptor.class));
|
||||
HandlerInterceptor i2 = mock(HandlerInterceptor.class);
|
||||
|
||||
+2
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -24,7 +24,6 @@ import java.util.stream.Stream;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.junit.jupiter.api.Named;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.util.PathMatcher;
|
||||
@@ -48,7 +47,7 @@ class MappedInterceptorTests {
|
||||
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static Stream<Named<Function<String, MockHttpServletRequest>>> pathPatternsArguments() {
|
||||
private static Stream<Function<String, MockHttpServletRequest>> pathPatternsArguments() {
|
||||
return PathPatternsTestUtils.requestArguments();
|
||||
}
|
||||
|
||||
|
||||
+3
-6
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -21,9 +21,6 @@ import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
||||
/**
|
||||
* Annotation for tests parameterized to use either
|
||||
* {@link org.springframework.web.util.pattern.PathPatternParser} or
|
||||
@@ -36,7 +33,7 @@ import org.junit.jupiter.params.provider.MethodSource;
|
||||
@Target(ElementType.METHOD)
|
||||
// Do not auto-close arguments since ConfigurableWebApplicationContext implements
|
||||
// AutoCloseable and is shared between parameterized test invocations.
|
||||
@ParameterizedTest(name = "[{index}] {0}", autoCloseArguments = false)
|
||||
@MethodSource("pathPatternsArguments")
|
||||
@org.junit.jupiter.params.ParameterizedTest(autoCloseArguments = false)
|
||||
@org.junit.jupiter.params.provider.MethodSource("pathPatternsArguments")
|
||||
public @interface PathPatternsParameterizedTest {
|
||||
}
|
||||
|
||||
+7
-11
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -20,15 +20,11 @@ import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.junit.jupiter.api.Named;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.web.testfixture.servlet.MockHttpServletRequest;
|
||||
import org.springframework.web.util.ServletRequestPathUtils;
|
||||
import org.springframework.web.util.UrlPathHelper;
|
||||
|
||||
import static org.junit.jupiter.api.Named.named;
|
||||
|
||||
/**
|
||||
* Utility methods to help with parameterized tests for URL pattern matching
|
||||
* via pre-parsed {@code PathPattern}s or String pattern matching with
|
||||
@@ -39,22 +35,22 @@ import static org.junit.jupiter.api.Named.named;
|
||||
*/
|
||||
public abstract class PathPatternsTestUtils {
|
||||
|
||||
public static Stream<Named<Function<String, MockHttpServletRequest>>> requestArguments() {
|
||||
public static Stream<Function<String, MockHttpServletRequest>> requestArguments() {
|
||||
return requestArguments(null);
|
||||
}
|
||||
|
||||
public static Stream<Named<Function<String, MockHttpServletRequest>>> requestArguments(@Nullable String contextPath) {
|
||||
public static Stream<Function<String, MockHttpServletRequest>> requestArguments(@Nullable String contextPath) {
|
||||
return Stream.of(
|
||||
named("ServletRequestPathUtils", path -> {
|
||||
path -> {
|
||||
MockHttpServletRequest request = createRequest("GET", contextPath, path);
|
||||
ServletRequestPathUtils.parseAndCache(request);
|
||||
return request;
|
||||
}),
|
||||
named("UrlPathHelper", path -> {
|
||||
},
|
||||
path -> {
|
||||
MockHttpServletRequest request = createRequest("GET", contextPath, path);
|
||||
UrlPathHelper.defaultInstance.resolveAndCacheLookupPath(request);
|
||||
return request;
|
||||
})
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
+2
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -19,7 +19,6 @@ package org.springframework.web.servlet.mvc;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.junit.jupiter.api.Named;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.ui.ModelMap;
|
||||
@@ -43,7 +42,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
class UrlFilenameViewControllerTests {
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static Stream<Named<Function<String, MockHttpServletRequest>>> pathPatternsArguments() {
|
||||
private static Stream<Function<String, MockHttpServletRequest>> pathPatternsArguments() {
|
||||
return PathPatternsTestUtils.requestArguments();
|
||||
}
|
||||
|
||||
|
||||
+2
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -20,7 +20,6 @@ import java.util.Properties;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.junit.jupiter.api.Named;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.web.servlet.handler.PathPatternsParameterizedTest;
|
||||
@@ -47,7 +46,7 @@ class WebContentInterceptorTests {
|
||||
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static Stream<Named<Function<String, MockHttpServletRequest>>> pathPatternsArguments() {
|
||||
private static Stream<Function<String, MockHttpServletRequest>> pathPatternsArguments() {
|
||||
return PathPatternsTestUtils.requestArguments();
|
||||
}
|
||||
|
||||
|
||||
+21
-30
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -19,10 +19,8 @@ package org.springframework.web.servlet.mvc.method.annotation;
|
||||
import java.lang.reflect.Method;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
||||
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
|
||||
@@ -51,8 +49,6 @@ import org.springframework.web.testfixture.servlet.MockHttpServletRequest;
|
||||
import org.springframework.web.testfixture.servlet.MockHttpServletResponse;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.junit.jupiter.api.Named.named;
|
||||
import static org.junit.jupiter.params.provider.Arguments.arguments;
|
||||
|
||||
/**
|
||||
* Test various scenarios for detecting method-level and method parameter annotations depending
|
||||
@@ -64,39 +60,34 @@ import static org.junit.jupiter.params.provider.Arguments.arguments;
|
||||
*/
|
||||
class HandlerMethodAnnotationDetectionTests {
|
||||
|
||||
static Stream<Arguments> handlerTypes() {
|
||||
return Stream.of(
|
||||
args(SimpleController.class, true), // CGLIB proxy
|
||||
args(SimpleController.class, false),
|
||||
static Object[][] handlerTypes() {
|
||||
return new Object[][] {
|
||||
{ SimpleController.class, true }, // CGLIB proxy
|
||||
{ SimpleController.class, false },
|
||||
|
||||
args(AbstractClassController.class, true), // CGLIB proxy
|
||||
args(AbstractClassController.class, false),
|
||||
{ AbstractClassController.class, true }, // CGLIB proxy
|
||||
{ AbstractClassController.class, false },
|
||||
|
||||
args(ParameterizedAbstractClassController.class, true), // CGLIB proxy
|
||||
args(ParameterizedAbstractClassController.class, false),
|
||||
{ ParameterizedAbstractClassController.class, true }, // CGLIB proxy
|
||||
{ ParameterizedAbstractClassController.class, false },
|
||||
|
||||
args(ParameterizedSubclassOverridesDefaultMappings.class, true), // CGLIB proxy
|
||||
args(ParameterizedSubclassOverridesDefaultMappings.class, false),
|
||||
{ ParameterizedSubclassOverridesDefaultMappings.class, true }, // CGLIB proxy
|
||||
{ ParameterizedSubclassOverridesDefaultMappings.class, false },
|
||||
|
||||
// TODO [SPR-9517] Enable ParameterizedSubclassDoesNotOverrideConcreteImplementationsFromGenericAbstractSuperclass test cases
|
||||
// args(ParameterizedSubclassDoesNotOverrideConcreteImplementationsFromGenericAbstractSuperclass.class, true), // CGLIB proxy
|
||||
// args(ParameterizedSubclassDoesNotOverrideConcreteImplementationsFromGenericAbstractSuperclass.class, false),
|
||||
// { ParameterizedSubclassDoesNotOverrideConcreteImplementationsFromGenericAbstractSuperclass.class, true }, // CGLIB proxy
|
||||
// { ParameterizedSubclassDoesNotOverrideConcreteImplementationsFromGenericAbstractSuperclass.class, false },
|
||||
|
||||
args(InterfaceController.class, true), // JDK dynamic proxy
|
||||
args(InterfaceController.class, false),
|
||||
{ InterfaceController.class, true }, // JDK dynamic proxy
|
||||
{ InterfaceController.class, false },
|
||||
|
||||
args(ParameterizedInterfaceController.class, false), // no AOP
|
||||
{ ParameterizedInterfaceController.class, false }, // no AOP
|
||||
|
||||
args(SupportClassController.class, true), // CGLIB proxy
|
||||
args(SupportClassController.class, false)
|
||||
);
|
||||
{ SupportClassController.class, true }, // CGLIB proxy
|
||||
{ SupportClassController.class, false }
|
||||
};
|
||||
}
|
||||
|
||||
private static Arguments args(Class<?> controllerType, boolean useAutoProxy) {
|
||||
return arguments(named(controllerType.getSimpleName(), controllerType), useAutoProxy);
|
||||
}
|
||||
|
||||
|
||||
private RequestMappingHandlerMapping handlerMapping;
|
||||
|
||||
private RequestMappingHandlerAdapter handlerAdapter;
|
||||
@@ -125,9 +116,9 @@ class HandlerMethodAnnotationDetectionTests {
|
||||
}
|
||||
|
||||
|
||||
@ParameterizedTest(name = "[{index}] controller = {0}, auto-proxy = {1}")
|
||||
@ParameterizedTest(name = "[{index}] controller [{0}], auto-proxy [{1}]")
|
||||
@MethodSource("handlerTypes")
|
||||
void requestMappingMethod(Class<?> controllerType, boolean useAutoProxy) throws Exception {
|
||||
void testRequestMappingMethod(Class<?> controllerType, boolean useAutoProxy) throws Exception {
|
||||
setUp(controllerType, useAutoProxy);
|
||||
|
||||
String datePattern = "MM:dd:yyyy";
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -136,7 +136,7 @@ public abstract class AbstractHtmlElementTagTests extends AbstractTagTests {
|
||||
}
|
||||
|
||||
protected final void assertBlockTagContains(String output, String desiredContents) {
|
||||
String contents = output.substring(output.indexOf(">") + 1, output.lastIndexOf('<'));
|
||||
String contents = output.substring(output.indexOf(">") + 1, output.lastIndexOf("<"));
|
||||
assertThat(contents.contains(desiredContents)).as("Expected to find '" + desiredContents + "' in the contents of block tag '" + output + "'").isTrue();
|
||||
}
|
||||
|
||||
|
||||
+13
-15
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -19,8 +19,6 @@ package org.springframework.web.servlet.view;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.junit.jupiter.api.Named;
|
||||
|
||||
import org.springframework.web.servlet.handler.PathPatternsParameterizedTest;
|
||||
import org.springframework.web.servlet.handler.PathPatternsTestUtils;
|
||||
import org.springframework.web.testfixture.servlet.MockHttpServletRequest;
|
||||
@@ -40,59 +38,59 @@ public class DefaultRequestToViewNameTranslatorTests {
|
||||
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static Stream<Named<Function<String, MockHttpServletRequest>>> pathPatternsArguments() {
|
||||
private static Stream<Function<String, MockHttpServletRequest>> pathPatternsArguments() {
|
||||
return PathPatternsTestUtils.requestArguments("/sundays");
|
||||
}
|
||||
|
||||
|
||||
@PathPatternsParameterizedTest
|
||||
void getViewNameLeavesLeadingSlashIfSoConfigured(Function<String, MockHttpServletRequest> requestFactory) {
|
||||
void testGetViewNameLeavesLeadingSlashIfSoConfigured(Function<String, MockHttpServletRequest> requestFactory) {
|
||||
MockHttpServletRequest request = requestFactory.apply(VIEW_NAME + "/");
|
||||
this.translator.setStripLeadingSlash(false);
|
||||
assertViewName(request, "/" + VIEW_NAME);
|
||||
}
|
||||
|
||||
@PathPatternsParameterizedTest
|
||||
void getViewNameLeavesTrailingSlashIfSoConfigured(Function<String, MockHttpServletRequest> requestFactory) {
|
||||
void testGetViewNameLeavesTrailingSlashIfSoConfigured(Function<String, MockHttpServletRequest> requestFactory) {
|
||||
MockHttpServletRequest request = requestFactory.apply(VIEW_NAME + "/");
|
||||
this.translator.setStripTrailingSlash(false);
|
||||
assertViewName(request, VIEW_NAME + "/");
|
||||
}
|
||||
|
||||
@PathPatternsParameterizedTest
|
||||
void getViewNameLeavesExtensionIfSoConfigured(Function<String, MockHttpServletRequest> requestFactory) {
|
||||
void testGetViewNameLeavesExtensionIfSoConfigured(Function<String, MockHttpServletRequest> requestFactory) {
|
||||
MockHttpServletRequest request = requestFactory.apply(VIEW_NAME + EXTENSION);
|
||||
this.translator.setStripExtension(false);
|
||||
assertViewName(request, VIEW_NAME + EXTENSION);
|
||||
}
|
||||
|
||||
@PathPatternsParameterizedTest
|
||||
void getViewNameWithDefaultConfiguration(Function<String, MockHttpServletRequest> requestFactory) {
|
||||
void testGetViewNameWithDefaultConfiguration(Function<String, MockHttpServletRequest> requestFactory) {
|
||||
MockHttpServletRequest request = requestFactory.apply(VIEW_NAME + EXTENSION);
|
||||
assertViewName(request, VIEW_NAME);
|
||||
}
|
||||
|
||||
@PathPatternsParameterizedTest
|
||||
void getViewNameWithCustomSeparator(Function<String, MockHttpServletRequest> requestFactory) {
|
||||
void testGetViewNameWithCustomSeparator(Function<String, MockHttpServletRequest> requestFactory) {
|
||||
MockHttpServletRequest request = requestFactory.apply(VIEW_NAME + "/fiona" + EXTENSION);
|
||||
this.translator.setSeparator("_");
|
||||
assertViewName(request, VIEW_NAME + "_fiona");
|
||||
}
|
||||
|
||||
@PathPatternsParameterizedTest
|
||||
void getViewNameWithNoExtension(Function<String, MockHttpServletRequest> requestFactory) {
|
||||
void testGetViewNameWithNoExtension(Function<String, MockHttpServletRequest> requestFactory) {
|
||||
MockHttpServletRequest request = requestFactory.apply(VIEW_NAME);
|
||||
assertViewName(request, VIEW_NAME);
|
||||
}
|
||||
|
||||
@PathPatternsParameterizedTest
|
||||
void getViewNameWithSemicolonContent(Function<String, MockHttpServletRequest> requestFactory) {
|
||||
void testGetViewNameWithSemicolonContent(Function<String, MockHttpServletRequest> requestFactory) {
|
||||
MockHttpServletRequest request = requestFactory.apply(VIEW_NAME + ";a=A;b=B");
|
||||
assertViewName(request, VIEW_NAME);
|
||||
}
|
||||
|
||||
@PathPatternsParameterizedTest
|
||||
void getViewNameWithPrefix(Function<String, MockHttpServletRequest> requestFactory) {
|
||||
void testGetViewNameWithPrefix(Function<String, MockHttpServletRequest> requestFactory) {
|
||||
final String prefix = "fiona_";
|
||||
MockHttpServletRequest request = requestFactory.apply(VIEW_NAME);
|
||||
this.translator.setPrefix(prefix);
|
||||
@@ -100,14 +98,14 @@ public class DefaultRequestToViewNameTranslatorTests {
|
||||
}
|
||||
|
||||
@PathPatternsParameterizedTest
|
||||
void getViewNameWithNullPrefix(Function<String, MockHttpServletRequest> requestFactory) {
|
||||
void testGetViewNameWithNullPrefix(Function<String, MockHttpServletRequest> requestFactory) {
|
||||
MockHttpServletRequest request = requestFactory.apply(VIEW_NAME);
|
||||
this.translator.setPrefix(null);
|
||||
assertViewName(request, VIEW_NAME);
|
||||
}
|
||||
|
||||
@PathPatternsParameterizedTest
|
||||
void getViewNameWithSuffix(Function<String, MockHttpServletRequest> requestFactory) {
|
||||
void testGetViewNameWithSuffix(Function<String, MockHttpServletRequest> requestFactory) {
|
||||
final String suffix = ".fiona";
|
||||
MockHttpServletRequest request = requestFactory.apply(VIEW_NAME);
|
||||
this.translator.setSuffix(suffix);
|
||||
@@ -115,7 +113,7 @@ public class DefaultRequestToViewNameTranslatorTests {
|
||||
}
|
||||
|
||||
@PathPatternsParameterizedTest
|
||||
void getViewNameWithNullSuffix(Function<String, MockHttpServletRequest> requestFactory) {
|
||||
void testGetViewNameWithNullSuffix(Function<String, MockHttpServletRequest> requestFactory) {
|
||||
MockHttpServletRequest request = requestFactory.apply(VIEW_NAME);
|
||||
this.translator.setSuffix(null);
|
||||
assertViewName(request, VIEW_NAME);
|
||||
|
||||
+5
-6
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -46,7 +46,6 @@ import org.springframework.web.socket.server.standard.TomcatRequestUpgradeStrate
|
||||
import org.springframework.web.socket.server.standard.UndertowRequestUpgradeStrategy;
|
||||
import org.springframework.web.socket.server.support.DefaultHandshakeHandler;
|
||||
|
||||
import static org.junit.jupiter.api.Named.named;
|
||||
import static org.junit.jupiter.params.provider.Arguments.arguments;
|
||||
|
||||
/**
|
||||
@@ -67,15 +66,15 @@ public abstract class AbstractWebSocketIntegrationTests {
|
||||
|
||||
static Stream<Arguments> argumentsFactory() {
|
||||
return Stream.of(
|
||||
arguments(named("Jetty", new JettyWebSocketTestServer()), named("Jetty", new JettyWebSocketClient())),
|
||||
arguments(named("Tomcat", new TomcatWebSocketTestServer()), named("Standard", new StandardWebSocketClient())),
|
||||
arguments(named("Undertow", new UndertowTestServer()), named("Standard", new StandardWebSocketClient())));
|
||||
arguments(new JettyWebSocketTestServer(), new JettyWebSocketClient()),
|
||||
arguments(new TomcatWebSocketTestServer(), new StandardWebSocketClient()),
|
||||
arguments(new UndertowTestServer(), new StandardWebSocketClient()));
|
||||
}
|
||||
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.METHOD)
|
||||
@ParameterizedTest(name = "[{index}] server = {0}, client = {1}")
|
||||
@ParameterizedTest(name = "[{index}] server [{0}], client [{1}]")
|
||||
@MethodSource("argumentsFactory")
|
||||
protected @interface ParameterizedWebSocketTest {
|
||||
}
|
||||
|
||||
@@ -104,7 +104,6 @@
|
||||
<suppress files="ExtractingResponseErrorHandlerTests" checks="MutableException" />
|
||||
<suppress files="ServletAnnotationControllerHandlerMethodTests" checks="InterfaceIsType" />
|
||||
<suppress files="src[\\/]test[\\/]java[\\/]org[\\/]springframework[\\/]web[\\/]servlet[\\/]resource[\\/]GzipSupport" checks="IllegalImport" id="bannedJUnitJupiterImports" />
|
||||
<suppress files="src[\\/]test[\\/]java[\\/]org[\\/]springframework[\\/]web[\\/]servlet[\\/]handler[\\/]PathPatterns.+" checks="IllegalImport" id="bannedJUnitJupiterImports" />
|
||||
|
||||
<!-- spring-websocket -->
|
||||
<suppress files="web[\\/]socket[\\/]CloseStatus" checks="JavadocStyle" />
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user