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 b6f2dd17f Remove the old matrix test suite framework
b6f2dd17f is described below

commit b6f2dd17f259cfae2aea70e939732f4e2b86dd95
Author: Andreas Veithen-Knowles <[email protected]>
AuthorDate: Sun Mar 29 09:02:56 2026 +0100

    Remove the old matrix test suite framework
---
 testing/matrix-testsuite/migration.md              | 523 ---------------------
 .../axiom/testutils/suite/MatrixTestCase.java      |  57 ---
 .../testutils/suite/MatrixTestSuiteBuilder.java    |  60 ---
 3 files changed, 640 deletions(-)

diff --git a/testing/matrix-testsuite/migration.md 
b/testing/matrix-testsuite/migration.md
deleted file mode 100644
index 709adb107..000000000
--- a/testing/matrix-testsuite/migration.md
+++ /dev/null
@@ -1,523 +0,0 @@
-<!--
-  ~ Licensed to the Apache Software Foundation (ASF) under one
-  ~ or more contributor license agreements. See the NOTICE file
-  ~ distributed with this work for additional information
-  ~ regarding copyright ownership. The ASF licenses this file
-  ~ to you 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
-  ~
-  ~ http://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.
-  -->
-
-# Migration guide: MatrixTestSuiteBuilder → MatrixTestNode
-
-This document describes how to migrate a test suite from the old
-`MatrixTestSuiteBuilder` / `MatrixTestCase` pattern (JUnit 3) to the new
-`MatrixTestNode` pattern (JUnit 5 + Guice).
-
-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. After migration, these are split into a test case
-  class (e.g. `StAXPivotTransformerTestCase`) and a suite class (e.g.
-  `StAXPivotTransformerTest`). They typically don't need `InjectorNode`
-  at all; fan-out nodes with `MatrixTest` leaves are sufficient. See
-  `StAXPivotTransformerTest` / `StAXPivotTransformerTestCase` 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
-
-The module being migrated must depend on:
-
-```xml
-<dependency>
-    <groupId>org.junit.jupiter</groupId>
-    <artifactId>junit-jupiter</artifactId>
-</dependency>
-<dependency>
-    <groupId>com.google.inject</groupId>
-    <artifactId>guice</artifactId>
-</dependency>
-```
-
-These are already declared in the root POM's `<dependencyManagement>`.
-
-## Step-by-step migration
-
-### 1. Update the test case base class
-
-The domain-specific base class (e.g. `SAAJTestCase`) currently:
-
-- Extends `MatrixTestCase`
-- Accepts all dimension values and implementation objects via constructor
-  parameters
-- Calls `addTestParameter(name, value)` in the constructor
-
-**Change it to:**
-
-- Extend `junit.framework.TestCase` directly
-- Declare dependencies as `@Inject` fields (using `com.google.inject.Inject`)
-- Remove the constructor entirely (or make it no-arg)
-- Remove all `addTestParameter()` calls
-
-**Before:**
-
-```java
-public abstract class SAAJTestCase extends MatrixTestCase {
-    protected final SAAJImplementation saajImplementation;
-    protected final SOAPSpec spec;
-
-    public SAAJTestCase(SAAJImplementation saajImplementation, SOAPSpec spec) {
-        this.saajImplementation = saajImplementation;
-        this.spec = spec;
-        addTestParameter("spec", spec.getName());
-    }
-
-    protected final MessageFactory newMessageFactory() throws SOAPException {
-        return 
spec.getAdapter(FactorySelector.class).newMessageFactory(saajImplementation);
-    }
-}
-```
-
-**After:**
-
-```java
-public abstract class SAAJTestCase extends TestCase {
-    @Inject protected SAAJImplementation saajImplementation;
-    @Inject protected SOAPSpec spec;
-
-    protected final MessageFactory newMessageFactory() throws SOAPException {
-        return 
spec.getAdapter(FactorySelector.class).newMessageFactory(saajImplementation);
-    }
-}
-```
-
-### 2. Update each test case class
-
-Each test case class currently accepts constructor parameters and forwards them
-to the base class.
-
-**Remove the constructor.** The `runTest()` method stays unchanged. Any imports
-of the implementation class and dimension types that were only used in the
-constructor can be removed.
-
-**Before:**
-
-```java
-public class TestAddChildElementReification extends SAAJTestCase {
-    public TestAddChildElementReification(SAAJImplementation 
saajImplementation, SOAPSpec spec) {
-        super(saajImplementation, spec);
-    }
-
-    @Override
-    protected void runTest() throws Throwable {
-        // ... test logic unchanged ...
-    }
-}
-```
-
-**After:**
-
-```java
-public class TestAddChildElementReification extends SAAJTestCase {
-    @Override
-    protected void runTest() throws Throwable {
-        // ... test logic unchanged ...
-    }
-}
-```
-
-### 3. Replace the suite builder with a suite factory
-
-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
-`MatrixTestNode`. The factory method:
-
-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.
-   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.
-
-Use `FanOutNode` for each dimension, supplying:
-- an `ImmutableList<T>` of values (e.g. from `Multiton.getInstances()`),
-- a `Binding<T>` lambda that configures the Guice binding for each value,
-- a `ParameterBinding<? super T>` lambda that registers test parameters for
-  display and filtering,
-- a single `MatrixTestNode` child; use `ParentNode` to group multiple children.
-
-**Before:**
-
-```java
-public class SAAJTestSuiteBuilder extends MatrixTestSuiteBuilder {
-    private final SAAJImplementation saajImplementation;
-
-    public SAAJTestSuiteBuilder(SAAJMetaFactory metaFactory) {
-        saajImplementation = new SAAJImplementation(metaFactory);
-    }
-
-    @Override
-    protected void addTests() {
-        addTests(SOAPSpec.SOAP11);
-        addTests(SOAPSpec.SOAP12);
-    }
-
-    private void addTests(SOAPSpec spec) {
-        addTest(new TestAddChildElementReification(saajImplementation, spec));
-        addTest(new TestGetOwnerDocument(saajImplementation, spec));
-        // ...
-    }
-}
-```
-
-**After:**
-
-```java
-public class SAAJTestSuite {
-    public static MatrixTestNode create(SAAJMetaFactory metaFactory) {
-        return new InjectorNode(
-                binder ->
-                        binder.bind(SAAJImplementation.class)
-                                .toInstance(new 
SAAJImplementation(metaFactory)),
-                new FanOutNode<>(
-                        Multiton.getInstances(SOAPSpec.class),
-                        Binding.singleton(Key.get(SOAPSpec.class)),
-                        (params, value) -> params.addTestParameter("spec", 
value.getName()),
-                        new ParentNode(
-                                new 
MatrixTest(TestAddChildElementReification.class),
-                                new MatrixTest(TestGetOwnerDocument.class))));
-    }
-}
-```
-
-Key differences:
-
-- Test classes are registered **once** as `MatrixTest` instances, passed as
-  children to the appropriate fan-out node at construction time, rather than 
once
-  per dimension combination.
-- Dimension values are listed via `Multiton.getInstances()` (or an explicit 
list)
-  in the fan-out node, not iterated manually.
-- No constructor arguments are passed to test classes.
-
-### 4. Replace the consumer test class
-
-The old consumer class uses JUnit 3's `static suite()` method.
-
-**Replace it** with a JUnit 5 class that has a `@TestFactory` method returning
-`Stream<DynamicNode>`. By convention, the method should be called `tests`.
-
-**Before:**
-
-```java
-public class SAAJRITest extends TestCase {
-    public static TestSuite suite() throws Exception {
-        return new SAAJTestSuiteBuilder(new SAAJMetaFactoryImpl()).build();
-    }
-}
-```
-
-**After:**
-
-```java
-public class SAAJRITest {
-    @TestFactory
-    public Stream<DynamicNode> tests() {
-        return SAAJTestSuite.create(new SAAJMetaFactoryImpl())
-                .toDynamicNodes();
-    }
-}
-```
-
-### 5. Migrate exclusions
-
-If the old consumer called `exclude()` on the builder, convert those calls to
-`MatrixTestFilters.builder().add(...)` entries.
-
-**Before:**
-
-```java
-SAAJTestSuiteBuilder builder = new SAAJTestSuiteBuilder(factory);
-builder.exclude(TestGetOwnerDocument.class, "(spec=soap12)");
-builder.exclude(TestSomething.class);
-builder.exclude("(parser=StAX)");
-return builder.build();
-```
-
-**After:**
-
-```java
-MatrixTestFilters excludes = MatrixTestFilters.builder()
-        .add(TestGetOwnerDocument.class, "(spec=soap12)")
-        .add(TestSomething.class)
-        .add("(parser=StAX)")
-        .build();
-return MyTestSuite.create(factory).toDynamicNodes(excludes);
-```
-
-The filter syntax and semantics are identical.
-
-### 6. Update dependencies in pom.xml
-
-Add `junit-jupiter` and `guice` to the module's `<dependencies>`. If the module
-uses `Multiton.getInstances()`, also add a dependency on the `multiton` module.
-
-Remove any dependency on `junit:junit` if no code in the module still uses 
JUnit 3
-or 4 APIs directly. (Note: test case classes still extend
-`junit.framework.TestCase`, which comes from `junit:junit` transitively through
-`matrix-testsuite`.)
-
-### 7. Delete the old builder class
-
-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.
-However, the result must be **two** classes:
-
-- A **test case class** (e.g. `StAXPivotTransformerTestCase`) that extends
-  `TestCase` and contains the test logic. Name it with a `*TestCase` suffix
-  (not `*Test`) so that Maven Surefire does not try to run it directly as a
-  JUnit 3/4 test.
-- A **suite class** (e.g. `StAXPivotTransformerTest`) with a `@TestFactory`
-  method that builds the fan-out tree and returns `Stream<DynamicNode>`. Name
-  it with a `*Test` suffix so that Maven Surefire discovers and runs it.
-
-Steps:
-
-1. Rename the class to a `*TestCase` suffix. Change it to extend `TestCase`
-   directly and declare dimension values as `@Inject` fields instead of
-   constructor parameters.
-2. Remove the constructor and all `addTestParameter()` calls.
-3. Remove the `static suite()` method.
-4. Create a new suite class with a `*Test` suffix. Add a `@TestFactory`
-   **instance** method called `tests` that builds the fan-out tree and calls
-   `toDynamicNodes()` on the root node.
-   No `InjectorNode` is needed unless you have additional bindings beyond the
-   dimension values.
-
-Note: the `@TestFactory` method **must not be static** — JUnit 5 requires it
-to be an instance method.
-
-**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** (`StAXPivotTransformerTestCase.java` — test logic):
-
-```java
-public class StAXPivotTransformerTestCase extends TestCase {
-    @Inject private XSLTImplementation xsltImplementation;
-    @Inject private XMLSample sample;
-
-    @Override
-    protected void runTest() throws Throwable {
-        // ... test logic unchanged ...
-    }
-}
-```
-
-**After** (`StAXPivotTransformerTest.java` — JUnit 5 suite):
-
-```java
-public class StAXPivotTransformerTest {
-    @TestFactory
-    public Stream<DynamicNode> tests() {
-        return new FanOutNode<>(
-                        Multiton.getInstances(XSLTImplementation.class),
-                        Binding.singleton(Key.get(XSLTImplementation.class)),
-                        (params, value) -> params.addTestParameter("xslt", 
value.getName()),
-                        new FanOutNode<>(
-                                Multiton.getInstances(XMLSample.class),
-                                Binding.singleton(Key.get(XMLSample.class)),
-                                (params, value) ->
-                                        params.addTestParameter("sample", 
value.getName()),
-                                new 
MatrixTest(StAXPivotTransformerTestCase.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 by filtering the
-`ImmutableList` of values passed to the `FanOutNode` (e.g.
-`.stream().filter(...).collect(ImmutableList.toImmutableList())`).
-
-## Tips and lessons learned
-
-### Injecting primitive types
-
-Guice can inject primitive types such as `boolean` directly — there is no need
-to use the boxed wrapper type. On the binding side, use the boxed type
-(`Boolean.class`) since `boolean.class` is not a valid Guice key:
-
-```java
-Binding.singleton(Key.get(Boolean.class, Names.named("deep")))
-```
-
-Or, if you need to write the binding manually:
-
-```java
-binder.bind(Boolean.class)
-        .annotatedWith(Names.named("deep"))
-        .toInstance(value);
-```
-
-On the injection side, a primitive field works fine:
-
-```java
-@Inject @Named("deep") private boolean deep;
-```
-
-### Use `@Named` to disambiguate primitive bindings
-
-When a test case (or its fan-out tree) involves more than one dimension of the
-same primitive type, Guice cannot distinguish the bindings by type alone. Use
-`@Named` (from `com.google.inject.name.Named`) on both the `@Inject` field and
-the corresponding `FanOutNode` binding (via `Names.named(...)`) to 
disambiguate.
-This also applies when a single primitive dimension exists — the annotation
-makes the binding self-documenting and avoids conflicts if another dimension of
-the same type is added later.
-
-See the `dom-testsuite` module for an example with two boolean dimensions
-(`"deep"` and `"newChildHasSiblings"`).
-
-### Constructor injection as an alternative to field injection
-
-The examples above use `@Inject` on fields, but in some cases it is necessary
-or more convenient to use **constructor injection** instead. This is the case
-when the base test case class stores dependencies in `final` fields set by
-the constructor. Converting those fields to non-final `@Inject` fields would
-require changing how the class and its subclasses are structured, which may
-not be desirable.
-
-With constructor injection, the existing constructor chain is preserved: 
subclass
-constructors receive dependencies as parameters and pass them up via 
`super(…)`.
-To make this work with Guice, simply add `@Inject` to the subclass constructor
-(there is no need to annotate the base class constructor). Guice will then 
inject
-the parameters when creating the test instance.
-
-**Base test case class** (no `@Inject` needed here — constructor stays as-is):
-
-```java
-public abstract class WritableBlobTestCase extends TestCase {
-    private final WritableBlobFactory<?> factory;
-    private final State initialState;
-
-    public WritableBlobTestCase(WritableBlobFactory<?> factory, State 
initialState) {
-        this.factory = factory;
-        this.initialState = initialState;
-    }
-    // ...
-}
-```
-
-**Simple subclass** — add `@Inject` to the constructor:
-
-```java
-public class TestAvailable extends WritableBlobTestCase {
-    @Inject
-    public TestAvailable(WritableBlobFactory<?> factory) {
-        super(factory, State.NEW);
-    }
-    // ...
-}
-```
-
-**Subclass with `@Named` parameter** — use `@Named` on the constructor
-parameter just as you would on a field:
-
-```java
-public class TestMarkReset extends SizeSensitiveWritableBlobTestCase {
-    @Inject
-    public TestMarkReset(WritableBlobFactory<?> factory, @Named("size") int 
size) {
-        super(factory, State.NEW, size);
-    }
-    // ...
-}
-```
-
-See the `blob` module (`WritableBlobTestCase` hierarchy) for a complete
-example.
-
-## Checklist
-
-### Reusable API test suites
-
-- [ ] Base test case class: extends `TestCase`, uses `@Inject` fields, no
-      constructor
-- [ ] 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; 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
-- [ ] Old builder class deleted
-- [ ] Tests pass: `mvn clean test -pl <module> -am`
-
-### Self-contained test suites
-
-- [ ] Test case class: renamed to `*TestCase` suffix, extends `TestCase`, uses
-      `@Inject` fields, no constructor, `static suite()` removed
-- [ ] Suite class: named with `*Test` suffix, has `@TestFactory` instance
-      method `tests()` 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`
diff --git 
a/testing/matrix-testsuite/src/main/java/org/apache/axiom/testutils/suite/MatrixTestCase.java
 
b/testing/matrix-testsuite/src/main/java/org/apache/axiom/testutils/suite/MatrixTestCase.java
deleted file mode 100644
index 6ca34cb00..000000000
--- 
a/testing/matrix-testsuite/src/main/java/org/apache/axiom/testutils/suite/MatrixTestCase.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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
- *
- * http://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.apache.axiom.testutils.suite;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import junit.framework.TestCase;
-
-/** A test case that can be executed multiple times with different parameters. 
*/
-public abstract class MatrixTestCase extends TestCase implements 
TestParameterTarget {
-    private final Map<String, String> parameters = new HashMap<>();
-
-    public MatrixTestCase() {
-        setName(getClass().getName());
-    }
-
-    @Override
-    public final void addTestParameter(String name, String value) {
-        setName(getName() + " [" + name + "=" + value + "]");
-        parameters.put(name, value);
-    }
-
-    @Override
-    public final void addTestParameter(String name, boolean value) {
-        addTestParameter(name, String.valueOf(value));
-    }
-
-    @Override
-    public final void addTestParameter(String name, int value) {
-        addTestParameter(name, String.valueOf(value));
-    }
-
-    public final Map<String, String> getTestParameters() {
-        return parameters;
-    }
-
-    // Force subclasses to override the runTest method:
-    @Override
-    protected abstract void runTest() throws Throwable;
-}
diff --git 
a/testing/matrix-testsuite/src/main/java/org/apache/axiom/testutils/suite/MatrixTestSuiteBuilder.java
 
b/testing/matrix-testsuite/src/main/java/org/apache/axiom/testutils/suite/MatrixTestSuiteBuilder.java
deleted file mode 100644
index 4ca84af81..000000000
--- 
a/testing/matrix-testsuite/src/main/java/org/apache/axiom/testutils/suite/MatrixTestSuiteBuilder.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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
- *
- * http://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.apache.axiom.testutils.suite;
-
-import junit.framework.TestSuite;
-
-/**
- * Builds a matrix test suite. This is an abstract class. Subclasses are 
expected to implement the
- * {@link #addTests()} method to generate a set of {@link MatrixTestCase} 
instances. For each type
- * of {@link MatrixTestCase}, the {@link #addTests()} method should add 
instances for all allowed
- * parameter values. The resulting set can then be filtered using LDAP filter 
expressions.
- */
-public abstract class MatrixTestSuiteBuilder {
-    private final MatrixTestFilters.Builder excludesBuilder = 
MatrixTestFilters.builder();
-    private MatrixTestFilters excludes;
-    private TestSuite suite;
-
-    public final void exclude(Class<? extends MatrixTestCase> testClass, 
String filter) {
-        excludesBuilder.add(testClass, filter);
-    }
-
-    public final void exclude(Class<? extends MatrixTestCase> testClass) {
-        excludesBuilder.add(testClass);
-    }
-
-    public final void exclude(String filter) {
-        excludesBuilder.add(filter);
-    }
-
-    protected abstract void addTests();
-
-    public final TestSuite build() {
-        excludes = excludesBuilder.build();
-        suite = new TestSuite();
-        addTests();
-        return suite;
-    }
-
-    protected final void addTest(MatrixTestCase test) {
-        if (!excludes.test(test.getClass(), test.getTestParameters())) {
-            suite.addTest(test);
-        }
-    }
-}

Reply via email to