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 266f7c03b Refactor MatrixTestNode hierarchy: single-child 
fan-out/injector nodes, concrete ParentNode
266f7c03b is described below

commit 266f7c03b5335a3df128d8965e3e6e274efc406e
Author: Andreas Veithen-Knowles <[email protected]>
AuthorDate: Fri Mar 13 22:18:00 2026 +0000

    Refactor MatrixTestNode hierarchy: single-child fan-out/injector nodes, 
concrete ParentNode
    
    AbstractFanOutNode and InjectorNode now extend MatrixTestNode directly and
    hold exactly one child node. ParentNode becomes a final concrete class that
    groups a list of children without injecting anything or adding parameters.
    A varargs constructor is provided for convenience.
    
    All call sites and documentation (README.md, migration.md) updated
    accordingly.
---
 .../apache/axiom/ts/om/cross/CrossOMTestSuite.java |  3 +-
 .../org/apache/axiom/ts/omdom/OMDOMTestSuite.java  |  5 +--
 testing/matrix-testsuite/README.md                 | 29 ++++++++++------
 testing/matrix-testsuite/migration.md              | 15 ++++-----
 .../axiom/testutils/suite/AbstractFanOutNode.java  | 10 +++---
 .../axiom/testutils/suite/DimensionFanOutNode.java | 16 +--------
 .../apache/axiom/testutils/suite/InjectorNode.java | 39 ++++++----------------
 .../axiom/testutils/suite/ParameterFanOutNode.java | 22 ++----------
 .../apache/axiom/testutils/suite/ParentNode.java   | 23 +++++++++----
 .../org/apache/axiom/ts/saaj/SAAJTestSuite.java    |  4 +--
 10 files changed, 67 insertions(+), 99 deletions(-)

diff --git 
a/testing/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/cross/CrossOMTestSuite.java
 
b/testing/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/cross/CrossOMTestSuite.java
index 02f04b07c..3d1b9c094 100644
--- 
a/testing/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/cross/CrossOMTestSuite.java
+++ 
b/testing/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/cross/CrossOMTestSuite.java
@@ -22,6 +22,7 @@ import org.apache.axiom.om.OMMetaFactory;
 import org.apache.axiom.testing.multiton.Multiton;
 import org.apache.axiom.testutils.suite.InjectorNode;
 import org.apache.axiom.testutils.suite.MatrixTest;
+import org.apache.axiom.testutils.suite.ParentNode;
 import org.apache.axiom.testutils.suite.ParameterFanOutNode;
 import org.apache.axiom.ts.xml.XMLSample;
 
@@ -43,7 +44,7 @@ public class CrossOMTestSuite {
                                 .toInstance(altMetaFactory);
                     }
                 },
-                ImmutableList.of(
+                new ParentNode(
                         new MatrixTest(TestAddChild.class),
                         new ParameterFanOutNode<>(
                                 XMLSample.class,
diff --git 
a/testing/axiom-testsuite/src/main/java/org/apache/axiom/ts/omdom/OMDOMTestSuite.java
 
b/testing/axiom-testsuite/src/main/java/org/apache/axiom/ts/omdom/OMDOMTestSuite.java
index 92383a551..3b5c91062 100644
--- 
a/testing/axiom-testsuite/src/main/java/org/apache/axiom/ts/omdom/OMDOMTestSuite.java
+++ 
b/testing/axiom-testsuite/src/main/java/org/apache/axiom/ts/omdom/OMDOMTestSuite.java
@@ -22,6 +22,7 @@ import org.apache.axiom.om.dom.DOMMetaFactory;
 import org.apache.axiom.testing.multiton.Multiton;
 import org.apache.axiom.testutils.suite.InjectorNode;
 import org.apache.axiom.testutils.suite.MatrixTest;
+import org.apache.axiom.testutils.suite.ParentNode;
 import org.apache.axiom.testutils.suite.ParameterFanOutNode;
 import org.apache.axiom.ts.xml.XMLSample;
 
@@ -42,7 +43,7 @@ public class OMDOMTestSuite {
                         bind(DOMMetaFactory.class).toInstance(metaFactory);
                     }
                 },
-                ImmutableList.of(
+                new ParentNode(
                         new MatrixTest(
                                 
org.apache.axiom.ts.omdom.attr.TestGetNamespaceNormalized.class),
                         new MatrixTest(
@@ -53,7 +54,7 @@ public class OMDOMTestSuite {
                                 ImmutableList.of(true, false),
                                 "build",
                                 String::valueOf,
-                                ImmutableList.of(
+                                new ParentNode(
                                         new MatrixTest(
                                                 
org.apache.axiom.ts.omdom.document
                                                         
.TestAppendChildForbidden.class),
diff --git a/testing/matrix-testsuite/README.md 
b/testing/matrix-testsuite/README.md
index 9ef716cec..5e4495ff3 100644
--- a/testing/matrix-testsuite/README.md
+++ b/testing/matrix-testsuite/README.md
@@ -32,7 +32,8 @@ Google Guice dependency injection to produce hierarchical, 
filterable test trees
 
 A test suite is a tree of `MatrixTestNode` instances. Interior nodes are
 **fan-out nodes** that iterate over a list of dimension values, creating one
-`DynamicContainer` per value. Leaf nodes are **`MatrixTest`** instances that
+`DynamicContainer` per value. `ParentNode` groups multiple child nodes into a
+flat sequence. Leaf nodes are **`MatrixTest`** instances that
 instantiate and run a `junit.framework.TestCase` subclass.
 
 ### Guice injector hierarchy
@@ -84,10 +85,10 @@ value, it:
 1. Creates a child Guice injector binding `T` to the value.
 2. Extracts test parameters (via the abstract `extractParameters` method).
 3. Produces a `DynamicContainer` containing the results of recursing into its
-   child nodes.
+   single child node.
 
-Child nodes are supplied at construction time via an 
`ImmutableList<MatrixTestNode>`
-parameter; the resulting instance is immutable.
+Extends `MatrixTestNode` directly and holds exactly one child node. When
+multiple children are needed, wrap them in a `ParentNode`.
 
 Subclasses:
 
@@ -111,15 +112,23 @@ exclusion filters.
 ### `InjectorNode`
 
 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. Accepts an `ImmutableList<Module>` (primary constructor) 
or
-a single `Module` (convenience constructor), together with an
-`ImmutableList<MatrixTestNode>` of child nodes. Provides:
+it through its single child. Can be used at any level of the test tree to 
introduce
+additional bindings. Extends `MatrixTestNode` directly and holds exactly one 
child
+node. When multiple children are needed, wrap them in a `ParentNode`. Accepts 
an
+`ImmutableList<Module>` (primary constructor) or a single `Module` (convenience
+constructor), together with a single `MatrixTestNode` child. Provides:
 
 ```java
 public Stream<DynamicNode> toDynamicNodes(BiPredicate<Class<?>, Map<String, 
String>> excludes)
 ```
 
+### `ParentNode`
+
+A concrete node that groups a list of child nodes without injecting anything or
+adding parameters. The children's dynamic nodes are simply concatenated in 
order.
+Use `ParentNode` whenever a fan-out node or `InjectorNode` needs to hold more
+than one child.
+
 ### `MatrixTestFilters`
 
 Immutable set of exclusion filters. Each filter entry optionally constrains by
@@ -171,7 +180,7 @@ public class MyTestSuite {
                 Multiton.getInstances(SomeDimension.class),
                 "dimension",
                 SomeDimension::getName,
-                ImmutableList.of(
+                new ParentNode(
                         new MatrixTest(TestSomeBehavior.class),
                         new MatrixTest(TestOtherBehavior.class)));
 
@@ -180,7 +189,7 @@ public class MyTestSuite {
             protected void configure() {
                 bind(SomeImplementation.class).toInstance(impl);
             }
-        }, ImmutableList.of(dimensions));
+        }, dimensions);
 
         return suite;
     }
diff --git a/testing/matrix-testsuite/migration.md 
b/testing/matrix-testsuite/migration.md
index 35041b199..24a3e6592 100644
--- a/testing/matrix-testsuite/migration.md
+++ b/testing/matrix-testsuite/migration.md
@@ -157,8 +157,8 @@ 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,
-   or a single `MatrixTestNode` directly (convenience constructor).
+   The child node is a single `MatrixTestNode`; use `ParentNode` when you need
+   to group multiple children.
 2. Creates fan-out nodes for each dimension.
 3. Adds `MatrixTest` leaf nodes as children of the fan-out nodes at 
construction
    time.
@@ -167,9 +167,8 @@ Use `ParameterFanOutNode` for types that don't implement 
`Dimension` (supplying
 parameter name and a function to extract the display value); the value is bound
 with `@Named(parameterName)`, so injection sites must use
 `@Inject @Named("...")`. Use `DimensionFanOutNode` for types that implement
-`Dimension` (plain unannotated binding). Both fan-out nodes also accept a 
single
-`MatrixTestNode` child directly (convenience constructor) instead of an
-`ImmutableList<MatrixTestNode>`.
+`Dimension` (plain unannotated binding). Both fan-out node types accept a 
single
+`MatrixTestNode` child; use `ParentNode` to group multiple children.
 
 **Before:**
 
@@ -213,9 +212,9 @@ public class SAAJTestSuite {
                         Multiton.getInstances(SOAPSpec.class),
                         "spec",
                         SOAPSpec::getName,
-                        ImmutableList.of(
+                        new ParentNode(
                                 new 
MatrixTest(TestAddChildElementReification.class),
-                                new MatrixTest(TestGetOwnerDocument.class))));
+                                new MatrixTest(TestGetOwnerDocument.class)))));
     }
 }
 ```
@@ -418,7 +417,7 @@ example by filtering the list of instances passed to the 
fan-out node.
 - [ ] All test case classes: constructor removed, `runTest()` unchanged
 - [ ] Suite factory class: creates `InjectorNode` with Guice module, builds
       immutable fan-out tree with `MatrixTest` leaves supplied at construction
-      time
+      time; uses `ParentNode` to group multiple children
 - [ ] Consumer test class: uses `@TestFactory` returning `Stream<DynamicNode>`
 - [ ] Exclusions: converted to `MatrixTestFilters.builder()` calls
 - [ ] `pom.xml`: `junit-jupiter`, `guice`, and (if needed) `multiton` added
diff --git 
a/testing/matrix-testsuite/src/main/java/org/apache/axiom/testutils/suite/AbstractFanOutNode.java
 
b/testing/matrix-testsuite/src/main/java/org/apache/axiom/testutils/suite/AbstractFanOutNode.java
index 2784580fc..f20d8b44b 100644
--- 
a/testing/matrix-testsuite/src/main/java/org/apache/axiom/testutils/suite/AbstractFanOutNode.java
+++ 
b/testing/matrix-testsuite/src/main/java/org/apache/axiom/testutils/suite/AbstractFanOutNode.java
@@ -53,15 +53,15 @@ import com.google.inject.Module;
  *
  * @param <T> the value type
  */
-public abstract class AbstractFanOutNode<T> extends ParentNode {
+public abstract class AbstractFanOutNode<T> extends MatrixTestNode {
     protected final Class<T> type;
     private final ImmutableList<T> values;
+    private final MatrixTestNode child;
 
-    protected AbstractFanOutNode(
-            Class<T> type, ImmutableList<T> values, 
ImmutableList<MatrixTestNode> children) {
-        super(children);
+    protected AbstractFanOutNode(Class<T> type, ImmutableList<T> values, 
MatrixTestNode child) {
         this.type = type;
         this.values = values;
+        this.child = child;
     }
 
     /**
@@ -106,7 +106,7 @@ public abstract class AbstractFanOutNode<T> extends 
ParentNode {
                                             .collect(Collectors.joining(", "));
                             return DynamicContainer.dynamicContainer(
                                     displayName,
-                                    childDynamicNodes(childInjector, params, 
excludes));
+                                    child.toDynamicNodes(childInjector, 
params, excludes));
                         });
     }
 }
diff --git 
a/testing/matrix-testsuite/src/main/java/org/apache/axiom/testutils/suite/DimensionFanOutNode.java
 
b/testing/matrix-testsuite/src/main/java/org/apache/axiom/testutils/suite/DimensionFanOutNode.java
index a5a3f4fe6..1cecbda3a 100644
--- 
a/testing/matrix-testsuite/src/main/java/org/apache/axiom/testutils/suite/DimensionFanOutNode.java
+++ 
b/testing/matrix-testsuite/src/main/java/org/apache/axiom/testutils/suite/DimensionFanOutNode.java
@@ -33,23 +33,9 @@ import com.google.common.collect.ImmutableList;
  * @param <D> the dimension type
  */
 public class DimensionFanOutNode<D extends Dimension> extends 
AbstractFanOutNode<D> {
-    public DimensionFanOutNode(
-            Class<D> dimensionType,
-            ImmutableList<D> dimensions,
-            ImmutableList<MatrixTestNode> children) {
-        super(dimensionType, dimensions, children);
-    }
-
-    /**
-     * Convenience constructor for the case of a single child.
-     *
-     * @param dimensionType the dimension type
-     * @param dimensions the dimension values to fan out over
-     * @param child the single child node
-     */
     public DimensionFanOutNode(
             Class<D> dimensionType, ImmutableList<D> dimensions, 
MatrixTestNode child) {
-        this(dimensionType, dimensions, ImmutableList.of(child));
+        super(dimensionType, dimensions, child);
     }
 
     @Override
diff --git 
a/testing/matrix-testsuite/src/main/java/org/apache/axiom/testutils/suite/InjectorNode.java
 
b/testing/matrix-testsuite/src/main/java/org/apache/axiom/testutils/suite/InjectorNode.java
index aa398676b..aa19e0cae 100644
--- 
a/testing/matrix-testsuite/src/main/java/org/apache/axiom/testutils/suite/InjectorNode.java
+++ 
b/testing/matrix-testsuite/src/main/java/org/apache/axiom/testutils/suite/InjectorNode.java
@@ -30,54 +30,35 @@ import com.google.inject.Module;
 
 /**
  * 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.
+ * single child. Can be used at any level of the test tree to introduce 
additional bindings.
  *
  * <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 InjectorNode extends ParentNode {
+public class InjectorNode extends MatrixTestNode {
     private final ImmutableList<Module> modules;
+    private final MatrixTestNode child;
 
     /**
-     * Creates a new node with the given list of modules and child nodes.
+     * Creates a new node with the given list of modules and a single child 
node.
      *
      * @param modules the Guice modules to install when creating the child 
injector
-     * @param children the child nodes of this node
+     * @param child the child node of this node
      */
-    public InjectorNode(ImmutableList<Module> modules, 
ImmutableList<MatrixTestNode> children) {
-        super(children);
+    public InjectorNode(ImmutableList<Module> modules, MatrixTestNode child) {
         this.modules = modules;
+        this.child = child;
     }
 
     /**
      * Convenience constructor for the common case of a single module.
      *
      * @param module the Guice module to install when creating the child 
injector
-     * @param children the child nodes of this node
-     */
-    public InjectorNode(Module module, ImmutableList<MatrixTestNode> children) 
{
-        this(ImmutableList.of(module), children);
-    }
-
-    /**
-     * Convenience constructor for the case of a single child.
-     *
-     * @param modules the Guice modules to install when creating the child 
injector
-     * @param child the single child node of this node
-     */
-    public InjectorNode(ImmutableList<Module> modules, MatrixTestNode child) {
-        this(modules, ImmutableList.of(child));
-    }
-
-    /**
-     * Convenience constructor for the case of a single module and a single 
child.
-     *
-     * @param module the Guice module to install when creating the child 
injector
-     * @param child the single child node of this node
+     * @param child the child node of this node
      */
     public InjectorNode(Module module, MatrixTestNode child) {
-        this(ImmutableList.of(module), ImmutableList.of(child));
+        this(ImmutableList.of(module), child);
     }
 
     @Override
@@ -85,7 +66,7 @@ public class InjectorNode extends ParentNode {
             Injector parentInjector,
             Map<String, String> inheritedParameters,
             BiPredicate<Class<?>, Map<String, String>> excludes) {
-        return childDynamicNodes(
+        return child.toDynamicNodes(
                 parentInjector.createChildInjector(modules), 
inheritedParameters, excludes);
     }
 }
diff --git 
a/testing/matrix-testsuite/src/main/java/org/apache/axiom/testutils/suite/ParameterFanOutNode.java
 
b/testing/matrix-testsuite/src/main/java/org/apache/axiom/testutils/suite/ParameterFanOutNode.java
index 8dcb5cbeb..a0c0d6127 100644
--- 
a/testing/matrix-testsuite/src/main/java/org/apache/axiom/testutils/suite/ParameterFanOutNode.java
+++ 
b/testing/matrix-testsuite/src/main/java/org/apache/axiom/testutils/suite/ParameterFanOutNode.java
@@ -42,30 +42,12 @@ public class ParameterFanOutNode<T> extends 
AbstractFanOutNode<T> {
             ImmutableList<T> values,
             String parameterName,
             Function<T, String> parameterValueFunction,
-            ImmutableList<MatrixTestNode> children) {
-        super(type, values, children);
+            MatrixTestNode child) {
+        super(type, values, child);
         this.parameterName = parameterName;
         this.parameterValueFunction = parameterValueFunction;
     }
 
-    /**
-     * Convenience constructor for the case of a single child.
-     *
-     * @param type the value type
-     * @param values the values to fan out over
-     * @param parameterName the parameter name
-     * @param parameterValueFunction maps each value to its parameter value 
string
-     * @param child the single child node
-     */
-    public ParameterFanOutNode(
-            Class<T> type,
-            ImmutableList<T> values,
-            String parameterName,
-            Function<T, String> parameterValueFunction,
-            MatrixTestNode child) {
-        this(type, values, parameterName, parameterValueFunction, 
ImmutableList.of(child));
-    }
-
     @Override
     protected Module createBindingModule(T value) {
         return new AbstractModule() {
diff --git 
a/testing/matrix-testsuite/src/main/java/org/apache/axiom/testutils/suite/ParentNode.java
 
b/testing/matrix-testsuite/src/main/java/org/apache/axiom/testutils/suite/ParentNode.java
index 0fbb1451c..a70793df7 100644
--- 
a/testing/matrix-testsuite/src/main/java/org/apache/axiom/testutils/suite/ParentNode.java
+++ 
b/testing/matrix-testsuite/src/main/java/org/apache/axiom/testutils/suite/ParentNode.java
@@ -28,22 +28,31 @@ import com.google.common.collect.ImmutableList;
 import com.google.inject.Injector;
 
 /**
- * A {@link MatrixTestNode} that holds an immutable, ordered list of child 
nodes.
+ * A {@link MatrixTestNode} that groups an immutable, ordered list of child 
nodes without injecting
+ * anything or adding parameters. The child nodes' dynamic nodes are simply 
concatenated.
  *
  * <p>Children are supplied at construction time; instances are immutable 
after creation.
  */
-public abstract class ParentNode extends MatrixTestNode {
+public final class ParentNode extends MatrixTestNode {
     private final ImmutableList<MatrixTestNode> children;
 
-    protected ParentNode(ImmutableList<MatrixTestNode> children) {
+    public ParentNode(ImmutableList<MatrixTestNode> children) {
         this.children = children;
     }
 
-    protected final Stream<DynamicNode> childDynamicNodes(
-            Injector injector,
-            Map<String, String> parameters,
+    public ParentNode(MatrixTestNode... children) {
+        this(ImmutableList.copyOf(children));
+    }
+
+    @Override
+    Stream<DynamicNode> toDynamicNodes(
+            Injector parentInjector,
+            Map<String, String> inheritedParameters,
             BiPredicate<Class<?>, Map<String, String>> excludes) {
         return children.stream()
-                .flatMap(child -> child.toDynamicNodes(injector, parameters, 
excludes));
+                .flatMap(
+                        child ->
+                                child.toDynamicNodes(
+                                        parentInjector, inheritedParameters, 
excludes));
     }
 }
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 6b39abc3f..b2f7e6567 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
@@ -23,6 +23,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.InjectorNode;
+import org.apache.axiom.testutils.suite.ParentNode;
 import org.apache.axiom.testutils.suite.ParameterFanOutNode;
 import org.apache.axiom.ts.saaj.body.TestAddChildElementReification;
 import org.apache.axiom.ts.saaj.element.TestAddChildElementLocalName;
@@ -32,7 +33,6 @@ import org.apache.axiom.ts.saaj.element.TestSetParentElement;
 import org.apache.axiom.ts.saaj.header.TestExamineMustUnderstandHeaderElements;
 import org.apache.axiom.ts.soap.SOAPSpec;
 
-import com.google.common.collect.ImmutableList;
 import com.google.inject.AbstractModule;
 
 public class SAAJTestSuite {
@@ -50,7 +50,7 @@ public class SAAJTestSuite {
                         Multiton.getInstances(SOAPSpec.class),
                         "spec",
                         SOAPSpec::getName,
-                        ImmutableList.of(
+                        new ParentNode(
                                 new 
MatrixTest(TestAddChildElementReification.class),
                                 new 
MatrixTest(TestExamineMustUnderstandHeaderElements.class),
                                 new 
MatrixTest(TestAddChildElementLocalName.class),

Reply via email to