Background
#268 codified: if a test is data-driven, use @ObjectSource.
#273 adds a companion annotation, @TableSource, for dense primitive matrices — same Jackson pipeline, same name-based parameter binding, CSV-like density. Together they form the data-driven family:
@ObjectSource — nested / heterogeneous / single-case data
@TableSource — dense primitive matrices (state machines, combinatorial tables)
An automated audit of all 145 test files found 72 convertible and 49 not (Graph/HBase fixtures, contract suites, Spring/E2E, mocks).
Scope limited to Kotlin
@ObjectSource/@TableSource both use kotlin.reflect.full.memberFunctions to map YAML keys to parameter names, and the project does not compile Java with -parameters, so Java parameter names are erased to arg0, arg1, … at runtime.
This issue therefore tracks 33 Kotlin files only. The remaining 39 Java files (core-java 34, codec-java 5) wait for a separate infrastructure PR that extends the annotations to Java (enable -parameters and add Java-reflection fallback).
Prerequisite
Phases
Each phase is one PR (<500 LOC diff target). Tick files off as they land.
Phase 1 — Kotlin already-parameterized (5)
Migrate existing @CsvSource / @MethodSource to @TableSource (or @ObjectSource for non-tabular shapes). The density stays CSV-like and test bodies can drop string-parsing helpers (toBooleanFlexible, toStateValue, toEventType, toEventSequence, handleSpecialValue) once a Jackson module is registered for the domain types.
Alongside this phase, register Jackson deserializers for State, StateValue, EventType, and any other domain types touched by the migrated tests. This is what enables the helper removal above.
Phase 2 — core module non-parameterized (17)
Serialization, mutation builder, mapper, payload tests. Currently multi-@Test with similar assertion shape; convert to a single @ObjectSource (nested payloads) or @TableSource (primitive matrix) method per group.
Phase 3 — engine + server stragglers (11)
Engine non-fixture tests and the one remaining server unit. Four Kotest Spec files under v2/engine/v3/query/ are included — migrating them also removes Kotest from that subdirectory.
Guidance: @ObjectSource vs @TableSource
| Shape |
Use |
| Heterogeneous / nested payloads, single scenario, shared fields |
@ObjectSource |
| Dense primitive matrix (≥ ~5 columns), state machines, combinatorial tables |
@TableSource |
| Cases must be generated at runtime (combinatorics, config-derived) |
@ParameterizedTest + @MethodSource (escape hatch) |
Acceptance
Out of scope (separate issues)
- 39 Java files (core-java 34, codec-java 5). Requires extending
@ObjectSource/@TableSource to support Java reflection (enable -parameters project-wide and add a Java-reflection fallback in ObjectSourceExtension). Follow-up issue after that PR lands.
- The 49 non-convertible files (Graph/HBase fixtures, contract suites, Spring/E2E). Separate pattern TBD.
- Kotest removal from fixture-heavy engine Spec files (separate track).
- AssertJ removal from server tests (separate track).
*Spec.kt → *Test.kt renaming (separate cleanup).
- Rename of
ObjectSourceExtension now that it handles both sources (separate PR).
Background
#268 codified: if a test is data-driven, use
@ObjectSource.#273 adds a companion annotation,
@TableSource, for dense primitive matrices — same Jackson pipeline, same name-based parameter binding, CSV-like density. Together they form the data-driven family:@ObjectSource— nested / heterogeneous / single-case data@TableSource— dense primitive matrices (state machines, combinatorial tables)An automated audit of all 145 test files found 72 convertible and 49 not (Graph/HBase fixtures, contract suites, Spring/E2E, mocks).
Scope limited to Kotlin
@ObjectSource/@TableSourceboth usekotlin.reflect.full.memberFunctionsto map YAML keys to parameter names, and the project does not compile Java with-parameters, so Java parameter names are erased toarg0,arg1, … at runtime.This issue therefore tracks 33 Kotlin files only. The remaining 39 Java files (core-java 34, codec-java 5) wait for a separate infrastructure PR that extends the annotations to Java (enable
-parametersand add Java-reflection fallback).Prerequisite
@ObjectSourceas the data-driven test rule in TESTING.md #268 —@ObjectSourcerule declared inTESTING.md@TableSourcefor dense test matrices #273 —@TableSourceadded (blocks Phase 1)Phases
Each phase is one PR (<500 LOC diff target). Tick files off as they land.
Phase 1 — Kotlin already-parameterized (5)
Migrate existing
@CsvSource/@MethodSourceto@TableSource(or@ObjectSourcefor non-tabular shapes). The density stays CSV-like and test bodies can drop string-parsing helpers (toBooleanFlexible,toStateValue,toEventType,toEventSequence,handleSpecialValue) once a Jackson module is registered for the domain types.core/src/test/kotlin/.../state/ComplexTransitionTest.kt(@MethodSource→@TableSourceor@ObjectSource)core/src/test/kotlin/.../state/ProcessingOrderTest.kt(@CsvSource41 × 14 →@TableSource)core/src/test/kotlin/.../state/SingleTransitionTest.kt(@CsvSource41 × 32 →@TableSource)core/src/test/kotlin/.../test/state/CombinatoricsTest.kt(@CsvSource→@TableSourceor@MethodSourceif cases are computed)server/src/test/kotlin/.../filter/ReadOnlyRequestFilterTest.kt(@MethodSource— may stay if cases are computed from endpoint sets)Alongside this phase, register Jackson deserializers for
State,StateValue,EventType, and any other domain types touched by the migrated tests. This is what enables the helper removal above.Phase 2 —
coremodule non-parameterized (17)Serialization, mutation builder, mapper, payload tests. Currently multi-
@Testwith similar assertion shape; convert to a single@ObjectSource(nested payloads) or@TableSource(primitive matrix) method per group.core/.../KotlinCoreJvmRuntimeTest.ktcore/bulkload/V2MultiEdgeBulkLoadTest.ktcore/edge/mapper/EdgeCacheRecordMapperTest.ktcore/edge/mutation/EdgeMutationBuilderTest.kt(31 tests)core/edge/mutation/EdgeMutationStrategyTest.kt(15 tests)core/metadata/AliasSerializationTest.ktcore/metadata/DatabaseSerializationTest.ktcore/metadata/DatastoreSerializationTest.ktcore/metadata/TableSerializationTest.ktcore/metadata/common/EdgeSchemaSerializationTest.ktcore/payload/EdgeBulkMutationRequestTest.ktcore/v2/metadata/V2AliasSerializationTest.ktcore/v2/metadata/V2LabelSerializationTest.ktcore/v2/metadata/V2ServiceSerializationTest.ktcore/v2/metadata/V2StorageSerializationTest.ktcore/test/ApiTestExtensionsTest.ktcore/test/json/PrettyObjectWriterTest.kt(18 tests)Phase 3 —
engine+serverstragglers (11)Engine non-fixture tests and the one remaining server unit. Four Kotest Spec files under
v2/engine/v3/query/are included — migrating them also removes Kotest from that subdirectory.engine/core/time/TimestampUtilTest.ktengine/experiments/reactor/RetryBehaviorExperimentTest.ktengine/util/ReactorExtensionsTest.ktengine/v2/engine/compat/DefaultHBaseClusterTest.ktengine/v2/engine/v3/V2BackedMessageBindingTest.ktengine/v2/engine/v3/V2BackedTableBindingTest.kt(18 tests)engine/v2/engine/v3/query/ActionbaseQueryExecutorAggregatorSpec.kt(Kotest)engine/v2/engine/v3/query/ActionbaseQueryExecutorPostProcessJsonObjectSpec.kt(Kotest)engine/v2/engine/v3/query/ActionbaseQueryExecutorPostProcessSplitExplodeSpec.kt(Kotest)engine/v2/engine/v3/query/ActionbaseQueryParserSpec.kt(Kotest)server/api/graph/v3/metadata/MetadataStatusTest.ktGuidance:
@ObjectSourcevs@TableSource@ObjectSource@TableSource@ParameterizedTest+@MethodSource(escape hatch)Acceptance
rg "@CsvSource|@ValueSource" core engine server(Kotlin-only paths) returns 0./gradlew testgreenbefore: N / after: Nin each PR body)toBooleanFlexible,toStateValue,toEventType,toEventSequence,handleSpecialValue) removed when no longer referencedOut of scope (separate issues)
@ObjectSource/@TableSourceto support Java reflection (enable-parametersproject-wide and add a Java-reflection fallback inObjectSourceExtension). Follow-up issue after that PR lands.*Spec.kt→*Test.ktrenaming (separate cleanup).ObjectSourceExtensionnow that it handles both sources (separate PR).