Skip to content

Commit

Permalink
Support conditional processing in TestContext event annotations
Browse files Browse the repository at this point in the history
This commit introduces support for SpEL expressions for conditional
event processing in annotations such as @BeforeTestClass,
@BeforeTestMethod, etc.

This commit also introduces a new getTestContext() method in
TestContextEvent in order to improve the readability of such SpEL
expressions.

See gh-18490
  • Loading branch information
sbrannen committed Mar 2, 2019
1 parent f6d62ed commit e272e2e
Show file tree
Hide file tree
Showing 9 changed files with 147 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,25 @@ public TestContextEvent(TestContext source) {
}

/**
* Get the {@code TestContext} associated with this event.
* Get the {@link TestContext} associated with this event.
* @return the {@code TestContext} associated with this event (never {@code null})
* @see #getTestContext()
*/
@Override
public TestContext getSource() {
public final TestContext getSource() {
return (TestContext) super.getSource();
}

/**
* Alias for {@link #getSource()}.
* <p>This method may be favored over {@code getSource()} to improve readability
* in SpEL expressions for event processing
* {@linkplain org.springframework.context.event.EventListener#condition conditions}.
* @return the {@code TestContext} associated with this event (never {@code null})
* @see #getSource()
*/
public final TestContext getTestContext() {
return getSource();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import java.lang.annotation.Target;

import org.springframework.context.event.EventListener;
import org.springframework.core.annotation.AliasFor;
import org.springframework.test.context.event.AfterTestClassEvent;

import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
Expand All @@ -41,17 +42,29 @@
* {@link org.springframework.test.context.TestExecutionListener#afterTestClass}
* lifecycle.
*
* <p>Event processing can optionally be made {@linkplain #value conditional} via
* a SpEL expression &mdash; for example,
* {@code @AfterTestClass("event.testContext.testClass.name matches '.+IntegrationTests'")}.
*
* <p>The {@code EventPublishingTestExecutionListener} must be registered in order
* for this annotation to have an effect &mdash; for example, via
* {@link org.springframework.test.context.TestExecutionListeners @TestExecutionListeners}.
*
* @author Frank Scheffler
* @author Sam Brannen
* @since 5.2
* @see AfterTestClassEvent
*/
@Documented
@Retention(RUNTIME)
@Target({ METHOD, ANNOTATION_TYPE })
@Documented
@EventListener(AfterTestClassEvent.class)
public @interface AfterTestClass {

/**
* Alias for {@link EventListener#condition}.
*/
@AliasFor(annotation = EventListener.class, attribute = "condition")
String value() default "";

}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import java.lang.annotation.Target;

import org.springframework.context.event.EventListener;
import org.springframework.core.annotation.AliasFor;
import org.springframework.test.context.event.AfterTestExecutionEvent;

import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
Expand All @@ -41,17 +42,29 @@
* {@link org.springframework.test.context.TestExecutionListener#afterTestExecution}
* lifecycle.
*
* <p>Event processing can optionally be made {@linkplain #value conditional} via
* a SpEL expression &mdash; for example,
* {@code @AfterTestExecution("event.testContext.testMethod.name matches 'test.*'")}.
*
* <p>The {@code EventPublishingTestExecutionListener} must be registered in order
* for this annotation to have an effect &mdash; for example, via
* {@link org.springframework.test.context.TestExecutionListeners @TestExecutionListeners}.
*
* @author Frank Scheffler
* @author Sam Brannen
* @since 5.2
* @see AfterTestExecutionEvent
*/
@Documented
@Retention(RUNTIME)
@Target({ METHOD, ANNOTATION_TYPE })
@Documented
@EventListener(AfterTestExecutionEvent.class)
public @interface AfterTestExecution {

/**
* Alias for {@link EventListener#condition}.
*/
@AliasFor(annotation = EventListener.class, attribute = "condition")
String value() default "";

}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import java.lang.annotation.Target;

import org.springframework.context.event.EventListener;
import org.springframework.core.annotation.AliasFor;
import org.springframework.test.context.event.AfterTestMethodEvent;

import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
Expand All @@ -41,17 +42,29 @@
* {@link org.springframework.test.context.TestExecutionListener#afterTestMethod}
* lifecycle.
*
* <p>Event processing can optionally be made {@linkplain #value conditional} via
* a SpEL expression &mdash; for example,
* {@code @AfterTestMethod("event.testContext.testMethod.name matches 'test.*'")}.
*
* <p>The {@code EventPublishingTestExecutionListener} must be registered in order
* for this annotation to have an effect &mdash; for example, via
* {@link org.springframework.test.context.TestExecutionListeners @TestExecutionListeners}.
*
* @author Frank Scheffler
* @author Sam Brannen
* @since 5.2
* @see AfterTestMethodEvent
*/
@Documented
@Retention(RUNTIME)
@Target({ METHOD, ANNOTATION_TYPE })
@Documented
@EventListener(AfterTestMethodEvent.class)
public @interface AfterTestMethod {

/**
* Alias for {@link EventListener#condition}.
*/
@AliasFor(annotation = EventListener.class, attribute = "condition")
String value() default "";

}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import java.lang.annotation.Target;

import org.springframework.context.event.EventListener;
import org.springframework.core.annotation.AliasFor;
import org.springframework.test.context.event.BeforeTestClassEvent;

import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
Expand All @@ -41,17 +42,29 @@
* {@link org.springframework.test.context.TestExecutionListener#beforeTestClass}
* lifecycle.
*
* <p>Event processing can optionally be made {@linkplain #value conditional} via
* a SpEL expression &mdash; for example,
* {@code @BeforeTestClass("event.testContext.testClass.name matches '.+IntegrationTests'")}.
*
* <p>The {@code EventPublishingTestExecutionListener} must be registered in order
* for this annotation to have an effect &mdash; for example, via
* {@link org.springframework.test.context.TestExecutionListeners @TestExecutionListeners}.
*
* @author Frank Scheffler
* @author Sam Brannen
* @since 5.2
* @see BeforeTestClassEvent
*/
@Documented
@Retention(RUNTIME)
@Target({ METHOD, ANNOTATION_TYPE })
@Documented
@EventListener(BeforeTestClassEvent.class)
public @interface BeforeTestClass {

/**
* Alias for {@link EventListener#condition}.
*/
@AliasFor(annotation = EventListener.class, attribute = "condition")
String value() default "";

}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import java.lang.annotation.Target;

import org.springframework.context.event.EventListener;
import org.springframework.core.annotation.AliasFor;
import org.springframework.test.context.event.BeforeTestExecutionEvent;

import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
Expand All @@ -41,17 +42,29 @@
* {@link org.springframework.test.context.TestExecutionListener#beforeTestExecution}
* lifecycle.
*
* <p>Event processing can optionally be made {@linkplain #value conditional} via
* a SpEL expression &mdash; for example,
* {@code @BeforeTestExecution("event.testContext.testMethod.name matches 'test.*'")}.
*
* <p>The {@code EventPublishingTestExecutionListener} must be registered in order
* for this annotation to have an effect &mdash; for example, via
* {@link org.springframework.test.context.TestExecutionListeners @TestExecutionListeners}.
*
* @author Frank Scheffler
* @author Sam Brannen
* @since 5.2
* @see BeforeTestExecutionEvent
*/
@Documented
@Retention(RUNTIME)
@Target({ METHOD, ANNOTATION_TYPE })
@Documented
@EventListener(BeforeTestExecutionEvent.class)
public @interface BeforeTestExecution {

/**
* Alias for {@link EventListener#condition}.
*/
@AliasFor(annotation = EventListener.class, attribute = "condition")
String value() default "";

}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import java.lang.annotation.Target;

import org.springframework.context.event.EventListener;
import org.springframework.core.annotation.AliasFor;
import org.springframework.test.context.event.BeforeTestMethodEvent;

import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
Expand All @@ -41,17 +42,29 @@
* {@link org.springframework.test.context.TestExecutionListener#beforeTestMethod}
* lifecycle.
*
* <p>Event processing can optionally be made {@linkplain #value conditional} via
* a SpEL expression &mdash; for example,
* {@code @BeforeTestMethod("event.testContext.testMethod.name matches 'test.*'")}.
*
* <p>The {@code EventPublishingTestExecutionListener} must be registered in order
* for this annotation to have an effect &mdash; for example, via
* {@link org.springframework.test.context.TestExecutionListeners @TestExecutionListeners}.
*
* @author Frank Scheffler
* @author Sam Brannen
* @since 5.2
* @see BeforeTestMethodEvent
*/
@Documented
@Retention(RUNTIME)
@Target({ METHOD, ANNOTATION_TYPE })
@Documented
@EventListener(BeforeTestMethodEvent.class)
public @interface BeforeTestMethod {

/**
* Alias for {@link EventListener#condition}.
*/
@AliasFor(annotation = EventListener.class, attribute = "condition")
String value() default "";

}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import java.lang.annotation.Target;

import org.springframework.context.event.EventListener;
import org.springframework.core.annotation.AliasFor;
import org.springframework.test.context.event.PrepareTestInstanceEvent;

import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
Expand All @@ -41,17 +42,29 @@
* {@link org.springframework.test.context.TestExecutionListener#prepareTestInstance}
* lifecycle.
*
* <p>Event processing can optionally be made {@linkplain #value conditional} via
* a SpEL expression &mdash; for example,
* {@code @PrepareTestInstance("event.testContext.testClass.name matches '.+IntegrationTests'")}.
*
* <p>The {@code EventPublishingTestExecutionListener} must be registered in order
* for this annotation to have an effect &mdash; for example, via
* {@link org.springframework.test.context.TestExecutionListeners @TestExecutionListeners}.
*
* @author Frank Scheffler
* @author Sam Brannen
* @since 5.2
* @see PrepareTestInstanceEvent
*/
@Documented
@Retention(RUNTIME)
@Target({ METHOD, ANNOTATION_TYPE })
@Documented
@EventListener(PrepareTestInstanceEvent.class)
public @interface PrepareTestInstance {

/**
* Alias for {@link EventListener#condition}.
*/
@AliasFor(annotation = EventListener.class, attribute = "condition")
String value() default "";

}
Loading

0 comments on commit e272e2e

Please sign in to comment.