From be5386b97294280c5ceb7c1f1fcf5977df8eb451 Mon Sep 17 00:00:00 2001 From: Kamil Patryk Kozakowski Date: Mon, 13 Jul 2026 21:19:21 +0200 Subject: [PATCH] Add parity test for DTO field access Ensures public field access (req.type) flows into sendEvent() consistently between heuristic and JDT call-graph engines. Co-authored-by: Cursor --- .../JdtCentralDispatcherParityTest.java | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/state_machine_exporter/src/test/java/click/kamil/springstatemachineexporter/analysis/service/JdtCentralDispatcherParityTest.java b/state_machine_exporter/src/test/java/click/kamil/springstatemachineexporter/analysis/service/JdtCentralDispatcherParityTest.java index 257a72a..fc7dbd6 100644 --- a/state_machine_exporter/src/test/java/click/kamil/springstatemachineexporter/analysis/service/JdtCentralDispatcherParityTest.java +++ b/state_machine_exporter/src/test/java/click/kamil/springstatemachineexporter/analysis/service/JdtCentralDispatcherParityTest.java @@ -114,6 +114,37 @@ class JdtCentralDispatcherParityTest { .containsExactlyInAnyOrderElementsOf(heuristicShip.getTriggerPoint().getPolymorphicEvents()); } + @Test + void jdtShouldMatchHeuristicForPublicDtoFieldAccess(@TempDir Path tempDir) throws Exception { + String source = """ + package com.example; + public class ApiController { + CommandGateway gateway; + public void submit() { gateway.submit(new OrderRequest(OrderEvent.SUBMIT)); } + } + class CommandGateway { + void submit(OrderRequest req) { + StateMachine sm = new StateMachine(); + sm.sendEvent(req.type); + } + } + class OrderRequest { + public final OrderEvent type; + OrderRequest(OrderEvent type) { this.type = type; } + } + enum OrderEvent { SUBMIT, PAY } + class StateMachine { public void sendEvent(OrderEvent e) {} } + class OrderStateMachineConfig {} + """; + CodebaseContext context = scanSource(source, tempDir); + + CallChain heuristic = resolveChain(context, CONTROLLER, "submit", STATE_MACHINE, EngineKind.HEURISTIC); + CallChain jdt = resolveChain(context, CONTROLLER, "submit", STATE_MACHINE, EngineKind.JDT); + + assertThat(jdt.getTriggerPoint().getPolymorphicEvents()) + .containsExactlyInAnyOrderElementsOf(heuristic.getTriggerPoint().getPolymorphicEvents()); + } + @Test void jdtShouldMatchHeuristicForDtoCrossHop(@TempDir Path tempDir) throws Exception { String source = """