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 b0d45d3d4 Remove Axiom examples from Guice-based test suite design doc
b0d45d3d4 is described below

commit b0d45d3d4ca0cd075674b704a1cc6a8714ebe4f3
Author: Andreas Veithen-Knowles <[email protected]>
AuthorDate: Sat Feb 28 09:25:12 2026 +0000

    Remove Axiom examples from Guice-based test suite design doc
    
    Focus the proposed new design entirely on the SAAJ test suite by
    removing all Axiom-specific examples (OMTestSuiteBuilder,
    SOAPTestSuiteBuilder, AxiomTestCase, SerializationStrategy, etc.)
    and the multi-dimension injector hierarchy diagrams.
---
 docs/design/test-suite-pattern.md | 202 ++++++--------------------------------
 1 file changed, 32 insertions(+), 170 deletions(-)

diff --git a/docs/design/test-suite-pattern.md 
b/docs/design/test-suite-pattern.md
index eea02d7c0..09c4119e4 100644
--- a/docs/design/test-suite-pattern.md
+++ b/docs/design/test-suite-pattern.md
@@ -24,12 +24,10 @@ Reusable test suites and parameterization
 
 The Axiom project provides reusable API test suites that can be applied to 
different
 implementations of the same API. For example, `saaj-testsuite` defines tests 
for the
-SAAJ API that can be executed against any `SAAJMetaFactory`, and 
`axiom-testsuite`
-defines tests for the Axiom API that can be executed against any 
`OMMetaFactory`.
+SAAJ API that can be executed against any `SAAJMetaFactory`.
 
-Most test suites also execute tests across multiple dimensions. For instance, 
SAAJ and
-SOAP tests run against both SOAP 1.1 and SOAP 1.2, while `OMTestSuiteBuilder` 
multiplies
-tests across XML samples, serialization strategies, builder factories, and 
more.
+Test suites also execute tests across multiple dimensions. For instance, SAAJ 
tests
+run against both SOAP 1.1 and SOAP 1.2.
 
 This document examines the current pattern used to implement these test suites 
and
 evaluates whether JUnit 5's `@TestFactory` mechanism offers a better approach.
@@ -93,17 +91,6 @@ For 6 test cases × 2 SOAP versions = 12 test instances, the 
main files are:
 | `TestExamineMustUnderstandHeaderElements.java` | Test case class |
 | `SAAJRITest.java` | JUnit 3 runner for the reference implementation |
 
-### Usage across the project
-
-The same pattern is used at much larger scale in other modules:
-
-| Module | Builder | `addTest()` calls | Estimated runtime tests |
-|--------|---------|-------------------|------------------------|
-| axiom-testsuite | `OMTestSuiteBuilder` | ~452 | Thousands (combinatorial) |
-| axiom-testsuite | `SOAPTestSuiteBuilder` | ~197 | Hundreds |
-| dom-testsuite | `DOMTestSuiteBuilder` | Many | Hundreds |
-| saaj-testsuite | `SAAJTestSuiteBuilder` | 6 | 12 |
-
 ## Alternative: JUnit 5 @TestFactory + DynamicTest
 
 JUnit 5 provides a built-in mechanism for dynamic test generation that directly
@@ -189,9 +176,9 @@ class SAAJRITests extends SAAJTests {
 
 ## Considerations for migration
 
-### saaj-testsuite (small suite)
+### saaj-testsuite
 
-For the saaj-testsuite specifically, migrating to JUnit 5 `@TestFactory` would:
+For the saaj-testsuite, migrating to JUnit 5 `@TestFactory` would:
 
 *   Collapse 6 test case classes into methods within a single class.
 *   Remove the need for `SAAJTestSuiteBuilder` entirely.
@@ -202,21 +189,6 @@ For the saaj-testsuite specifically, migrating to JUnit 5 
`@TestFactory` would:
 The `SAAJImplementation` class (which uses reflection to access protected 
methods on
 `SAAJMetaFactory`) would be retained as-is.
 
-### Large suites (OMTestSuiteBuilder, SOAPTestSuiteBuilder)
-
-The larger suites present additional considerations:
-
-*   The one-class-per-test pattern, while verbose, keeps each test 
independently
-    navigable and organizes tests by the API area they cover.
-*   The exclusion mechanism (LDAP filters on test parameters) is heavily used 
by
-    consumers to skip known-failing tests for specific implementations. A 
JUnit 5
-    equivalent would need to provide comparable functionality.
-*   The sheer number of test case classes (hundreds) means migration would be a
-    substantial effort.
-*   A phased approach is possible: a JUnit 5 adapter that wraps 
`MatrixTestSuiteBuilder`
-    output into `DynamicTest` instances would allow consuming modules to 
migrate to
-    JUnit 5 runners without rewriting test case classes.
-
 ### Replacement for MatrixTestSuiteBuilder: MatrixTestNode tree with Guice
 
 Since `DynamicContainer` and `DynamicTest` are `final` in JUnit 5, they cannot 
be
@@ -253,23 +225,21 @@ abstract class MatrixTestNode {
 ```java
 /**
  * Mirrors {@link DynamicContainer}. Represents a parameterized grouping level
- * in the test tree (e.g. a SOAP version, a serialization strategy).
+ * in the test tree (e.g. a SOAP version).
  *
  * <p>A {@code MatrixTestContainer} holds a list of {@link Dimension} instances
- * of a given type (e.g. all {@code SOAPSpec} values, or all
- * {@code SerializationStrategy} values). When {@link #toDynamicNodes} is 
called,
- * it produces one {@link DynamicContainer} per dimension instance. For each
- * dimension instance, a <em>child Guice injector</em> is created from the
- * parent injector, binding the dimension type to that specific instance. This
- * child injector is then propagated to all children, forming a hierarchy where
- * each path from root to leaf accumulates all dimension bindings.
+ * of a given type (e.g. all {@code SOAPSpec} values). When
+ * {@link #toDynamicNodes} is called, it produces one {@link DynamicContainer}
+ * per dimension instance. For each dimension instance, a <em>child Guice
+ * injector</em> is created from the parent injector, binding the dimension 
type
+ * to that specific instance. This child injector is then propagated to all
+ * children, forming a hierarchy where each path from root to leaf accumulates
+ * all dimension bindings.
  *
- * <p>Because a {@code Dimension} may contribute multiple test parameters (for
- * example, {@code SerializeToWriter} adds both {@code 
serializationStrategy=Writer}
- * and {@code cache=true}), the test parameters extracted from each dimension
- * determine both the display name and the filter dictionary. The full 
parameter
- * dictionary for any leaf {@code MatrixTest} is the accumulation of
- * parameters from its ancestor {@code MatrixTestContainer} chain.
+ * <p>The test parameters extracted from each dimension determine both the
+ * display name and the filter dictionary. The full parameter dictionary for 
any
+ * leaf {@code MatrixTest} is the accumulation of parameters from its ancestor
+ * {@code MatrixTestContainer} chain.
  *
  * @param <D> the dimension type
  */
@@ -346,7 +316,7 @@ class MatrixTestContainer<D extends Dimension> extends 
MatrixTestNode {
  * also supported. The injector received from the ancestor
  * {@code MatrixTestContainer} chain will have bindings for all dimension
  * types, plus any implementation-level bindings from the root injector
- * (e.g. {@code OMMetaFactory}, {@code SAAJImplementation}).
+ * (e.g. {@code SAAJImplementation}).
  *
  * <p>Once the instance is created, it is executed via {@link 
TestCase#runBare()},
  * which invokes the full {@code setUp()} → {@code runTest()} → {@code 
tearDown()}
@@ -404,24 +374,6 @@ Root Injector
                            → testInstance.runBare()
 ```
 
-For suites with multiple dimensions the nesting deepens:
-
-```
-Root Injector
-  binds: OMMetaFactory → instance
-  │
-  ├─ Child Injector (SOAPSpec → SOAP11)
-  │    │
-  │    ├─ Child Injector (SerializationStrategy → SerializeToWriter)
-  │    │    └─ MatrixTest → injector has {OMMetaFactory, SOAPSpec, 
SerializationStrategy}
-  │    │
-  │    └─ Child Injector (SerializationStrategy → SerializeToOutputStream)
-  │         └─ MatrixTest → injector has {OMMetaFactory, SOAPSpec, 
SerializationStrategy}
-  │
-  └─ Child Injector (SOAPSpec → SOAP12)
-       └─ ...
-```
-
 #### What test case classes look like
 
 Test case classes continue to extend `junit.framework.TestCase` (or a 
domain-specific
@@ -477,40 +429,6 @@ public abstract class SAAJTestCase extends TestCase {
 }
 ```
 
-For the larger axiom-testsuite, intermediate classes follow the same pattern:
-
-```java
-public abstract class AxiomTestCase extends TestCase {
-    @Inject protected OMMetaFactory metaFactory;
-}
-
-public abstract class SOAPTestCase extends AxiomTestCase {
-    @Inject protected SOAPSpec spec;
-    protected SOAPFactory soapFactory;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        soapFactory = 
spec.getAdapter(FactorySelector.class).getFactory(metaFactory);
-    }
-}
-```
-
-Test cases with multiple dimensions simply inject all of them:
-
-```java
-public class TestSerializeWithXSITypeAttribute extends SOAPTestCase {
-    @Inject private SerializationStrategy serializationStrategy;
-
-    @Override
-    protected void runTest() throws Throwable {
-        XML xml = serializationStrategy.serialize(
-                soapFactory.getDefaultSOAPEnvelope().getBody());
-        // ... assertions ...
-    }
-}
-```
-
 Note that the existing `Dimension.addTestParameters()` mechanism is **not** 
used by test
 case classes at all. Parameters are extracted only by `MatrixTestContainer` 
for display
 names and filter matching. Test cases interact with dimensions purely as typed 
objects
@@ -519,23 +437,20 @@ obtained through injection.
 #### How filtering works
 
 Each `MatrixTestContainer` level holds a list of `Dimension` instances (e.g. 
all
-`SOAPSpec` values or all `SerializationStrategy` values). When 
`toDynamicNodes()` is
-called, each container produces one `DynamicContainer` per dimension instance, 
and
-parameters accumulate from the root down:
+`SOAPSpec` values). When `toDynamicNodes()` is called, each container produces 
one
+`DynamicContainer` per dimension instance, and parameters accumulate from the 
root down:
 
 ```
 MatrixTestContainer(SOAPSpec.class, [SOAPSpec.SOAP11, SOAPSpec.SOAP12])
-  MatrixTestContainer(SerializationStrategy.class, [SerializeToWriter, ...])
-    MatrixTest(TestSerializeElement.class)
-    MatrixTest(TestSerializeDocument.class)
-
-→ spec=soap11                                      [child injector binds 
SOAPSpec]
-    → serializationStrategy=Writer, cache=true      [child injector binds 
SerializationStrategy]
-        → TestSerializeElement  (filtered against {spec=soap11, 
serializationStrategy=Writer, cache=true})
-        → TestSerializeDocument (filtered against {spec=soap11, 
serializationStrategy=Writer, cache=true})
+  MatrixTest(TestAddChildElementReification.class)
+  MatrixTest(TestGetOwnerDocument.class)
+
+→ spec=soap11                          [child injector binds SOAPSpec]
+    → TestAddChildElementReification   (filtered against {spec=soap11})
+    → TestGetOwnerDocument             (filtered against {spec=soap11})
   spec=soap12
-    → serializationStrategy=Writer, cache=true
-        → ...
+    → TestAddChildElementReification   (filtered against {spec=soap12})
+    → TestGetOwnerDocument             (filtered against {spec=soap12})
 ```
 
 Consumers apply exclusions and create the root injector:
@@ -562,60 +477,7 @@ class SAAJRITests {
         root.addChild(new MatrixTest(TestGetOwnerDocument.class));
 
         List<Filter> excludes = new ArrayList<>();
-        return root.toDynamicNodes(rootInjector, new Hashtable<>(), excludes);
-    }
-}
-```
-
-For large suites, a builder class constructs the tree:
-
-```java
-class OMTestTreeBuilder {
-    private final OMMetaFactory metaFactory;
-
-    OMTestTreeBuilder(OMMetaFactory metaFactory) {
-        this.metaFactory = metaFactory;
-    }
-
-    Injector createRootInjector() {
-        return Guice.createInjector(new AbstractModule() {
-            @Override
-            protected void configure() {
-                bind(OMMetaFactory.class).toInstance(metaFactory);
-            }
-        });
-    }
-
-    MatrixTestNode build() {
-        // Top-level container groups by SOAPSpec
-        MatrixTestContainer<SOAPSpec> bySpec = new MatrixTestContainer<>(
-                SOAPSpec.class, Multiton.getInstances(SOAPSpec.class));
-
-        // Nested container groups by SerializationStrategy
-        MatrixTestContainer<SerializationStrategy> bySerialization = new 
MatrixTestContainer<>(
-                SerializationStrategy.class,
-                Multiton.getInstances(SerializationStrategy.class));
-        bySerialization.addChild(new 
MatrixTest(TestSerializeWithXSITypeAttribute.class));
-        bySerialization.addChild(new MatrixTest(TestSerializeDocument.class));
-        bySpec.addChild(bySerialization);
-
-        // Tests that only vary by SOAPSpec (no serialization dimension)
-        bySpec.addChild(new MatrixTest(TestGetSOAPVersion.class));
-
-        return bySpec;
-    }
-}
-```
-
-```java
-class OMImplementationTests {
-    @TestFactory
-    Stream<DynamicNode> omTests() {
-        OMTestTreeBuilder builder = new OMTestTreeBuilder(myMetaFactory);
-        Injector rootInjector = builder.createRootInjector();
-        MatrixTestNode root = builder.build();
-        List<Filter> excludes = new ArrayList<>();
-        excludes.add(Filter.forClass(TestSerializeDocument.class, 
"(spec=soap12)"));
+        excludes.add(Filter.forClass(TestGetOwnerDocument.class, 
"(spec=soap12)"));
         return root.toDynamicNodes(rootInjector, new Hashtable<>(), excludes);
     }
 }
@@ -639,6 +501,6 @@ class OMImplementationTests {
     `addTest()` call to manually pass all dimension values to the test 
constructor.
     With Guice, `MatrixTest` only needs the test class; the injector supplies
     everything.
-*   **Test case base classes become simpler.** Intermediate classes like 
`SAAJTestCase`,
-    `SOAPTestCase`, and `AxiomTestCase` no longer need constructor parameters 
or chains
-    of `super(...)` calls — they simply declare `@Inject` fields.
+*   **Test case base classes become simpler.** `SAAJTestCase` no longer needs
+    constructor parameters or chains of `super(...)` calls — it simply declares
+    `@Inject` fields.

Reply via email to