This is an automated email from the ASF dual-hosted git repository. veithen pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/ws-axiom.git
commit 1cfbaa10dd6d1fa42ceae21e17b2a85ade1770f8 Author: Andreas Veithen-Knowles <[email protected]> AuthorDate: Sun Mar 1 11:44:48 2026 +0000 Rename MatrixTestSuite to InjectorNode and add public toDynamicNodes to MatrixTestNode - Add public final toDynamicNodes methods to MatrixTestNode so that any node can be used as an entry point without requiring a wrapper. - Rename MatrixTestSuite to InjectorNode to reflect that it is no longer limited to being the root of the tree. It now creates a child injector from the parent instead of eagerly creating a root injector. - Update SAAJTestSuite, README.md and migration.md accordingly. --- testing/matrix-testsuite/README.md | 15 ++++++----- testing/matrix-testsuite/migration.md | 16 +++++------ .../{MatrixTestSuite.java => InjectorNode.java} | 31 ++++++++++------------ .../axiom/testutils/suite/MatrixTestNode.java | 19 +++++++++++++ .../org/apache/axiom/ts/saaj/SAAJTestSuite.java | 8 +++--- 5 files changed, 53 insertions(+), 36 deletions(-) diff --git a/testing/matrix-testsuite/README.md b/testing/matrix-testsuite/README.md index e0f6a8717..3aa03bcae 100644 --- a/testing/matrix-testsuite/README.md +++ b/testing/matrix-testsuite/README.md @@ -102,10 +102,11 @@ executes it through `TestCase.runBare()` (which runs the full `setUp()` → `runTest()` → `tearDown()` lifecycle). The test is skipped if matched by the exclusion filters. -### `MatrixTestSuite` +### `InjectorNode` -Root of a test suite. Owns the Guice root injector (created from caller-supplied -modules) and a list of top-level `MatrixTestNode` children. Provides: +A node that creates a child Guice injector from the supplied modules and threads +it through its children. Can be used at any level of the test tree to introduce +additional bindings. Provides: ```java public Stream<DynamicNode> toDynamicNodes(BiPredicate<Class<?>, Dictionary<String, String>> excludes) @@ -144,15 +145,15 @@ public class TestSomeBehavior extends MyTestCase { ## Defining a test suite -The test suite author creates a factory method that builds a `MatrixTestSuite`, +The test suite author creates a factory method that builds an `InjectorNode`, adds fan-out nodes for each dimension, and registers test classes as `MatrixTest` leaf nodes: ```java public class MyTestSuite { - public static MatrixTestSuite create(SomeFactory factory) { + public static InjectorNode create(SomeFactory factory) { SomeImplementation impl = new SomeImplementation(factory); - MatrixTestSuite suite = new MatrixTestSuite(new AbstractModule() { + InjectorNode suite = new InjectorNode(new AbstractModule() { @Override protected void configure() { bind(SomeImplementation.class).toInstance(impl); @@ -181,7 +182,7 @@ Consumers create a JUnit 5 test class with a `@TestFactory` method: class MyImplTest { @TestFactory Stream<DynamicNode> tests() { - MatrixTestSuite suite = MyTestSuite.create(new MyFactoryImpl()); + InjectorNode suite = MyTestSuite.create(new MyFactoryImpl()); MatrixTestFilters excludes = MatrixTestFilters.builder() .add(TestSomeBehavior.class, "(dimension=problematicValue)") .build(); diff --git a/testing/matrix-testsuite/migration.md b/testing/matrix-testsuite/migration.md index ab85a4ffb..aba07b44c 100644 --- a/testing/matrix-testsuite/migration.md +++ b/testing/matrix-testsuite/migration.md @@ -17,11 +17,11 @@ ~ under the License. --> -# Migration guide: MatrixTestSuiteBuilder → MatrixTestSuite +# Migration guide: MatrixTestSuiteBuilder → InjectorNode This document describes how to migrate a test suite from the old `MatrixTestSuiteBuilder` / `MatrixTestCase` pattern (JUnit 3) to the new -`MatrixTestSuite` / `MatrixTestNode` pattern (JUnit 5 + Guice). +`InjectorNode` / `MatrixTestNode` pattern (JUnit 5 + Guice). For a completed example of this migration, see the `saaj-testsuite` module. @@ -132,10 +132,10 @@ public class TestAddChildElementReification extends SAAJTestCase { The old `*TestSuiteBuilder` class extends `MatrixTestSuiteBuilder` and overrides `addTests()` to register test instances for each dimension combination. -**Replace it** with a class that has a static factory method returning a -`MatrixTestSuite`. The factory method: +**Replace it** with a class that has a static factory method returning an +`InjectorNode`. The factory method: -1. Creates a `MatrixTestSuite` with a Guice module that binds +1. Creates an `InjectorNode` with a Guice module that binds implementation-level objects. 2. Creates fan-out nodes for each dimension. 3. Adds `MatrixTest` leaf nodes for each test case class. @@ -172,9 +172,9 @@ public class SAAJTestSuiteBuilder extends MatrixTestSuiteBuilder { ```java public class SAAJTestSuite { - public static MatrixTestSuite create(SAAJMetaFactory metaFactory) { + public static InjectorNode create(SAAJMetaFactory metaFactory) { SAAJImplementation impl = new SAAJImplementation(metaFactory); - MatrixTestSuite suite = new MatrixTestSuite(new AbstractModule() { + InjectorNode suite = new InjectorNode(new AbstractModule() { @Override protected void configure() { bind(SAAJImplementation.class).toInstance(impl); @@ -281,7 +281,7 @@ is in place and all consumers have been updated. - [ ] Base test case class: extends `TestCase`, uses `@Inject` fields, no constructor - [ ] All test case classes: constructor removed, `runTest()` unchanged -- [ ] Suite factory class: creates `MatrixTestSuite` with Guice module, builds +- [ ] Suite factory class: creates `InjectorNode` with Guice module, builds fan-out tree with `MatrixTest` leaves - [ ] Consumer test class: uses `@TestFactory` returning `Stream<DynamicNode>` - [ ] Exclusions: converted to `MatrixTestFilters.builder()` calls diff --git a/testing/matrix-testsuite/src/main/java/org/apache/axiom/testutils/suite/MatrixTestSuite.java b/testing/matrix-testsuite/src/main/java/org/apache/axiom/testutils/suite/InjectorNode.java similarity index 59% rename from testing/matrix-testsuite/src/main/java/org/apache/axiom/testutils/suite/MatrixTestSuite.java rename to testing/matrix-testsuite/src/main/java/org/apache/axiom/testutils/suite/InjectorNode.java index 9fe89155f..1ab76123e 100644 --- a/testing/matrix-testsuite/src/main/java/org/apache/axiom/testutils/suite/MatrixTestSuite.java +++ b/testing/matrix-testsuite/src/main/java/org/apache/axiom/testutils/suite/InjectorNode.java @@ -20,45 +20,42 @@ package org.apache.axiom.testutils.suite; import java.util.ArrayList; import java.util.Dictionary; -import java.util.Hashtable; import java.util.List; import java.util.function.BiPredicate; import java.util.stream.Stream; import org.junit.jupiter.api.DynamicNode; -import com.google.inject.Guice; import com.google.inject.Injector; import com.google.inject.Module; /** - * Root of a test suite. Owns the Guice root injector and the tree of {@link MatrixTestNode} - * instances. Provides a {@link #toDynamicNodes(BiPredicate)} method that converts the tree to JUnit - * 5 dynamic nodes, applying the supplied exclusion predicate. + * A node that creates a child Guice injector from the supplied modules and threads it through its + * children. Can be used at any level of the test tree to introduce additional bindings. * - * <p>Exclusion filters are <em>not</em> owned by the suite itself because they are specific to each - * consumer (implementation under test), whereas the suite structure and bindings are defined by the + * <p>Exclusion filters are <em>not</em> owned by this node because they are specific to each + * consumer (implementation under test), whereas the tree structure and bindings are defined by the * test suite author. */ -public class MatrixTestSuite { - private final Injector rootInjector; +public class InjectorNode extends MatrixTestNode { + private final Module[] modules; private final List<MatrixTestNode> children = new ArrayList<>(); - public MatrixTestSuite(Module... modules) { - this.rootInjector = Guice.createInjector(modules); + public InjectorNode(Module... modules) { + this.modules = modules; } public void addChild(MatrixTestNode child) { children.add(child); } - public Stream<DynamicNode> toDynamicNodes( + @Override + Stream<DynamicNode> toDynamicNodes( + Injector parentInjector, + Dictionary<String, String> inheritedParameters, BiPredicate<Class<?>, Dictionary<String, String>> excludes) { + Injector injector = parentInjector.createChildInjector(modules); return children.stream() - .flatMap(child -> child.toDynamicNodes(rootInjector, new Hashtable<>(), excludes)); - } - - public Stream<DynamicNode> toDynamicNodes() { - return toDynamicNodes((testClass, parameters) -> false); + .flatMap(child -> child.toDynamicNodes(injector, inheritedParameters, excludes)); } } diff --git a/testing/matrix-testsuite/src/main/java/org/apache/axiom/testutils/suite/MatrixTestNode.java b/testing/matrix-testsuite/src/main/java/org/apache/axiom/testutils/suite/MatrixTestNode.java index 1e7349d24..c132ad581 100644 --- a/testing/matrix-testsuite/src/main/java/org/apache/axiom/testutils/suite/MatrixTestNode.java +++ b/testing/matrix-testsuite/src/main/java/org/apache/axiom/testutils/suite/MatrixTestNode.java @@ -19,11 +19,13 @@ package org.apache.axiom.testutils.suite; import java.util.Dictionary; +import java.util.Hashtable; import java.util.function.BiPredicate; import java.util.stream.Stream; import org.junit.jupiter.api.DynamicNode; +import com.google.inject.Guice; import com.google.inject.Injector; /** @@ -39,4 +41,21 @@ public abstract class MatrixTestNode { Injector parentInjector, Dictionary<String, String> inheritedParameters, BiPredicate<Class<?>, Dictionary<String, String>> excludes); + + /** + * Converts this node (and its subtree) to JUnit 5 dynamic nodes, applying the supplied + * exclusion predicate. + * + * <p>This allows using a {@code MatrixTestNode} directly without wrapping it in a {@link + * InjectorNode}. + */ + public final Stream<DynamicNode> toDynamicNodes( + BiPredicate<Class<?>, Dictionary<String, String>> excludes) { + return toDynamicNodes(Guice.createInjector(), new Hashtable<>(), excludes); + } + + /** Converts this node (and its subtree) to JUnit 5 dynamic nodes without any exclusions. */ + public final Stream<DynamicNode> toDynamicNodes() { + return toDynamicNodes((testClass, parameters) -> false); + } } diff --git a/testing/saaj-testsuite/src/main/java/org/apache/axiom/ts/saaj/SAAJTestSuite.java b/testing/saaj-testsuite/src/main/java/org/apache/axiom/ts/saaj/SAAJTestSuite.java index 962ea365e..e0b438b0c 100644 --- a/testing/saaj-testsuite/src/main/java/org/apache/axiom/ts/saaj/SAAJTestSuite.java +++ b/testing/saaj-testsuite/src/main/java/org/apache/axiom/ts/saaj/SAAJTestSuite.java @@ -22,7 +22,7 @@ import jakarta.xml.soap.SAAJMetaFactory; import org.apache.axiom.testing.multiton.Multiton; import org.apache.axiom.testutils.suite.MatrixTest; -import org.apache.axiom.testutils.suite.MatrixTestSuite; +import org.apache.axiom.testutils.suite.InjectorNode; import org.apache.axiom.testutils.suite.ParameterFanOutNode; import org.apache.axiom.ts.saaj.body.TestAddChildElementReification; import org.apache.axiom.ts.saaj.element.TestAddChildElementLocalName; @@ -35,10 +35,10 @@ import org.apache.axiom.ts.soap.SOAPSpec; import com.google.inject.AbstractModule; public class SAAJTestSuite { - public static MatrixTestSuite create(SAAJMetaFactory metaFactory) { + public static InjectorNode create(SAAJMetaFactory metaFactory) { SAAJImplementation impl = new SAAJImplementation(metaFactory); - MatrixTestSuite suite = - new MatrixTestSuite( + InjectorNode suite = + new InjectorNode( new AbstractModule() { @Override protected void configure() {
