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


The following commit(s) were added to refs/heads/master by this push:
     new b0493fa3a Update migration guide to cover self-contained test suites
b0493fa3a is described below

commit b0493fa3a875107234bbafe4ae1aa547790e6276
Author: Andreas Veithen-Knowles <[email protected]>
AuthorDate: Sat Mar 7 22:24:24 2026 +0000

    Update migration guide to cover self-contained test suites
---
 testing/matrix-testsuite/migration.md | 156 ++++++++++++++++++++++++++++------
 1 file changed, 132 insertions(+), 24 deletions(-)

diff --git a/testing/matrix-testsuite/migration.md 
b/testing/matrix-testsuite/migration.md
index c677cbcd9..37fb81bb2 100644
--- a/testing/matrix-testsuite/migration.md
+++ b/testing/matrix-testsuite/migration.md
@@ -17,13 +17,26 @@
   ~ under the License.
   -->
 
-# Migration guide: MatrixTestSuiteBuilder → InjectorNode
+# Migration guide: MatrixTestSuiteBuilder → MatrixTestNode
 
 This document describes how to migrate a test suite from the old
 `MatrixTestSuiteBuilder` / `MatrixTestCase` pattern (JUnit 3) to the new
-`InjectorNode` / `MatrixTestNode` pattern (JUnit 5 + Guice).
+`MatrixTestNode` pattern (JUnit 5 + Guice).
 
-For a completed example of this migration, see the `saaj-testsuite` module.
+There are two common shapes:
+
+- **Reusable API test suites** — the test suite is defined in one module and
+  consumed by one or more implementation modules. These use `InjectorNode` at
+  the root to bind implementation-level objects. See the `saaj-testsuite`
+  module for a completed example.
+- **Self-contained test suites** — the test case, suite structure, and consumer
+  live in a single class. These typically don't need `InjectorNode` at all;
+  fan-out nodes with `MatrixTest` leaves are sufficient. See
+  `StAXPivotTransformerTest` in `components/core-streams` for an example.
+
+The step-by-step guide below focuses on reusable API test suites. For
+self-contained suites, see the [simplified 
migration](#simplified-migration-for-self-contained-tests)
+section at the end.
 
 ## Prerequisites
 
@@ -138,14 +151,17 @@ The old `*TestSuiteBuilder` class extends 
`MatrixTestSuiteBuilder` and overrides
 1. Creates an `InjectorNode` with a Guice module that binds
    implementation-level objects. Pass a single `Module` directly (convenience
    constructor) or an `ImmutableList<Module>` when you need multiple modules.
-   Child nodes are supplied via an `ImmutableList<MatrixTestNode>` parameter.
+   Child nodes are supplied via an `ImmutableList<MatrixTestNode>` parameter,
+   or a single `MatrixTestNode` directly (convenience constructor).
 2. Creates fan-out nodes for each dimension.
 3. Adds `MatrixTest` leaf nodes as children of the fan-out nodes at 
construction
    time.
 
 Use `ParameterFanOutNode` for types that don't implement `Dimension` 
(supplying a
 parameter name and a function to extract the display value). Use
-`DimensionFanOutNode` for types that implement `Dimension`.
+`DimensionFanOutNode` for types that implement `Dimension`. Both fan-out nodes
+also accept a single `MatrixTestNode` child directly (convenience constructor)
+instead of an `ImmutableList<MatrixTestNode>`.
 
 **Before:**
 
@@ -176,25 +192,22 @@ public class SAAJTestSuiteBuilder extends 
MatrixTestSuiteBuilder {
 ```java
 public class SAAJTestSuite {
     public static InjectorNode create(SAAJMetaFactory metaFactory) {
-        SAAJImplementation impl = new SAAJImplementation(metaFactory);
-
-        ParameterFanOutNode<SOAPSpec> specs = new ParameterFanOutNode<>(
-                SOAPSpec.class,
-                Multiton.getInstances(SOAPSpec.class),
-                "spec",
-                SOAPSpec::getName,
-                ImmutableList.of(
-                        new MatrixTest(TestAddChildElementReification.class),
-                        new MatrixTest(TestGetOwnerDocument.class)));
-
-        InjectorNode suite = new InjectorNode(new AbstractModule() {
-            @Override
-            protected void configure() {
-                bind(SAAJImplementation.class).toInstance(impl);
-            }
-        }, ImmutableList.of(specs));
-
-        return suite;
+        return new InjectorNode(
+                new AbstractModule() {
+                    @Override
+                    protected void configure() {
+                        bind(SAAJImplementation.class)
+                                .toInstance(new 
SAAJImplementation(metaFactory));
+                    }
+                },
+                new ParameterFanOutNode<>(
+                        SOAPSpec.class,
+                        Multiton.getInstances(SOAPSpec.class),
+                        "spec",
+                        SOAPSpec::getName,
+                        ImmutableList.of(
+                                new 
MatrixTest(TestAddChildElementReification.class),
+                                new MatrixTest(TestGetOwnerDocument.class))));
     }
 }
 ```
@@ -280,8 +293,95 @@ or 4 APIs directly. (Note: test case classes still extend
 The old `*TestSuiteBuilder` class can be deleted once the new `*TestSuite` 
factory
 is in place and all consumers have been updated.
 
+## Simplified migration for self-contained tests
+
+When the test case, suite builder, and consumer are all in a single class (i.e.
+the class extends `MatrixTestCase` and has a `static suite()` method), the
+migration is simpler because there is no separate base class or suite factory:
+
+1. Change the class to extend `TestCase` directly and declare dimension values
+   as `@Inject` fields instead of constructor parameters.
+2. Remove the constructor and all `addTestParameter()` calls.
+3. Replace the `static suite()` method with a `@TestFactory` method that builds
+   the fan-out tree directly and calls `toDynamicNodes()` on the root node.
+   No `InjectorNode` is needed unless you have additional bindings beyond the
+   dimension values.
+
+**Before:**
+
+```java
+public class StAXPivotTransformerTest extends MatrixTestCase {
+    private final XSLTImplementation xsltImplementation;
+    private final XMLSample sample;
+
+    public StAXPivotTransformerTest(
+            XSLTImplementation xsltImplementation, XMLSample sample) {
+        this.xsltImplementation = xsltImplementation;
+        this.sample = sample;
+        addTestParameter("xslt", xsltImplementation.getName());
+        addTestParameter("sample", sample.getName());
+    }
+
+    @Override
+    protected void runTest() throws Throwable {
+        // ... test logic ...
+    }
+
+    public static TestSuite suite() {
+        return new MatrixTestSuiteBuilder() {
+            @Override
+            protected void addTests() {
+                for (XSLTImplementation xsltImplementation :
+                        getInstances(XSLTImplementation.class)) {
+                    for (XMLSample sample : getInstances(XMLSample.class)) {
+                        addTest(new 
StAXPivotTransformerTest(xsltImplementation, sample));
+                    }
+                }
+            }
+        }.build();
+    }
+}
+```
+
+**After:**
+
+```java
+public class StAXPivotTransformerTest extends TestCase {
+    @Inject private XSLTImplementation xsltImplementation;
+    @Inject private XMLSample sample;
+
+    @Override
+    protected void runTest() throws Throwable {
+        // ... test logic unchanged ...
+    }
+
+    @TestFactory
+    public static Stream<DynamicNode> suite() {
+        return new ParameterFanOutNode<>(
+                XSLTImplementation.class,
+                Multiton.getInstances(XSLTImplementation.class),
+                "xslt",
+                XSLTImplementation::getName,
+                new ParameterFanOutNode<>(
+                        XMLSample.class,
+                        Multiton.getInstances(XMLSample.class),
+                        "sample",
+                        XMLSample::getName,
+                        new MatrixTest(StAXPivotTransformerTest.class)))
+                .toDynamicNodes();
+    }
+}
+```
+
+Note that filtering logic (e.g. skipping values based on a condition like
+`xsltImplementation.supportsStAXSource()`) that was previously expressed as
+`if` guards in the `addTests()` loop should be handled differently — for
+example by filtering the list of instances passed to the fan-out node.
+
 ## Checklist
 
+### Reusable API test suites
+
 - [ ] Base test case class: extends `TestCase`, uses `@Inject` fields, no
       constructor
 - [ ] All test case classes: constructor removed, `runTest()` unchanged
@@ -293,3 +393,11 @@ is in place and all consumers have been updated.
 - [ ] `pom.xml`: `junit-jupiter`, `guice`, and (if needed) `multiton` added
 - [ ] Old builder class deleted
 - [ ] Tests pass: `mvn clean test -pl <module> -am`
+
+### Self-contained test suites
+
+- [ ] Test class: extends `TestCase`, uses `@Inject` fields, no constructor
+- [ ] `static suite()` replaced with `@TestFactory` method building fan-out
+      tree and calling `toDynamicNodes()`
+- [ ] `pom.xml`: `junit-jupiter`, `guice`, and (if needed) `multiton` added
+- [ ] Tests pass: `mvn clean test -pl <module> -am`

Reply via email to