update number 6

This commit is contained in:
2026-07-05 16:15:52 +02:00
parent 0cb78e5dfd
commit 27005da678
8 changed files with 424 additions and 16 deletions

View File

@@ -168,4 +168,128 @@ class EnterpriseBugsTest {
.build();
assertThat(engine.isRoutedToCorrectMachine(chain2, "com.example.OrderStateMachineConfig", context)).isFalse();
}
@Test
void shouldFindPathsUsingInterfaceImplementationFallback(@TempDir Path tempDir) throws IOException {
String apiSrc = """
package com.example;
public interface OrderApi {
void submit();
}
""";
String controllerSrc = """
package com.example;
public class OrderController implements OrderApi {
private OrderService service;
public void submit() {
service.trigger();
}
}
""";
String serviceSrc = """
package com.example;
public class OrderService {
public void trigger() {}
}
""";
Files.writeString(tempDir.resolve("OrderApi.java"), apiSrc);
Files.writeString(tempDir.resolve("OrderController.java"), controllerSrc);
Files.writeString(tempDir.resolve("OrderService.java"), serviceSrc);
CodebaseContext context = new CodebaseContext();
context.scan(tempDir);
HeuristicCallGraphEngine engine = new HeuristicCallGraphEngine(context);
var graph = engine.buildCallGraph();
CallGraphPathFinder pathFinder = new CallGraphPathFinder(context);
List<List<String>> paths = pathFinder.findAllPaths("com.example.OrderApi.submit", "com.example.OrderService.trigger", graph, new java.util.HashSet<>());
assertThat(paths).hasSize(1);
assertThat(paths.get(0)).containsExactly(
"com.example.OrderApi.submit",
"com.example.OrderController.submit",
"com.example.OrderService.trigger"
);
}
@Test
void shouldNotPolymorphicallyExpandFunctionalInterfaceCalls(@TempDir Path tempDir) throws IOException {
String taskSrc = """
package com.example;
@FunctionalInterface
public interface MyTask {
void run();
}
""";
String spuriousSrc = """
package com.example;
public class SpuriousTask implements MyTask {
private UnrelatedService service;
public void run() {
service.doSomething();
}
}
""";
String unrelatedSrc = """
package com.example;
public class UnrelatedService {
public void doSomething() {}
}
""";
String executorSrc = """
package com.example;
public class ExecutorService {
public void execute(MyTask task) {
task.run();
}
}
""";
String mainSrc = """
package com.example;
public class MainService {
private ExecutorService executor;
public void runJob() {
executor.execute(() -> {});
}
}
""";
Files.writeString(tempDir.resolve("MyTask.java"), taskSrc);
Files.writeString(tempDir.resolve("SpuriousTask.java"), spuriousSrc);
Files.writeString(tempDir.resolve("UnrelatedService.java"), unrelatedSrc);
Files.writeString(tempDir.resolve("ExecutorService.java"), executorSrc);
Files.writeString(tempDir.resolve("MainService.java"), mainSrc);
CodebaseContext context = new CodebaseContext();
context.scan(tempDir);
HeuristicCallGraphEngine engine = new HeuristicCallGraphEngine(context);
var graph = engine.buildCallGraph();
// The execute method calls task.run(). Since MyTask is a functional interface,
// it should NOT resolve task.run() to SpuriousTask.run()
var edges = graph.get("com.example.ExecutorService.execute");
if (edges != null) {
for (var edge : edges) {
assertThat(edge.getTargetMethod()).isNotEqualTo("com.example.SpuriousTask.run");
}
}
}
@Test
void shouldNotTreatValueOfExpressionAsWildcardMatchingAllTransitions() {
click.kamil.springstatemachineexporter.analysis.enricher.matching.StrictFqnMatchingEngine engine =
new click.kamil.springstatemachineexporter.analysis.enricher.matching.StrictFqnMatchingEngine();
click.kamil.springstatemachineexporter.model.Event smEvent =
click.kamil.springstatemachineexporter.model.Event.of("PAY", "com.example.OrderEvents.PAY");
TriggerPoint triggerPoint = TriggerPoint.builder()
.event("OrderEvents.valueOf(someVar)")
.build();
assertThat(engine.matches(smEvent, triggerPoint)).isFalse();
}
}

View File

@@ -182,6 +182,76 @@
} ]
} ],
"callChains" : [ {
"entryPoint" : {
"type" : "REST",
"name" : "POST /api/enterprise/orders/place",
"className" : "click.kamil.examples.enterprise.api.OrderApi",
"methodName" : "placeOrder",
"sourceFile" : "src/main/java/click/kamil/examples/enterprise/api/OrderApi.java",
"metadata" : {
"path" : "/api/enterprise/orders/place",
"verb" : "POST"
},
"parameters" : [ ]
},
"methodChain" : [ "click.kamil.examples.enterprise.api.OrderApi.placeOrder", "click.kamil.examples.enterprise.api.OrderController.placeOrder", "click.kamil.examples.enterprise.service.OrderServiceImpl.place" ],
"triggerPoint" : {
"event" : "PLACE_ORDER",
"className" : "click.kamil.examples.enterprise.service.OrderServiceImpl",
"methodName" : "place",
"sourceFile" : "src/main/java/click/kamil/examples/enterprise/service/OrderServiceImpl.java",
"sourceModule" : null,
"stateMachineId" : null,
"sourceState" : null,
"lineNumber" : 16,
"polymorphicEvents" : [ "PLACE_ORDER" ],
"external" : false,
"constraint" : null
},
"contextMachineId" : null,
"matchedTransitions" : [ {
"sourceState" : "NEW",
"targetState" : "CHECK_AVAILABILITY",
"event" : "PLACE_ORDER"
} ]
}, {
"entryPoint" : {
"type" : "REST",
"name" : "POST /api/enterprise/orders/{id}/cancel",
"className" : "click.kamil.examples.enterprise.api.OrderApi",
"methodName" : "cancelOrder",
"sourceFile" : "src/main/java/click/kamil/examples/enterprise/api/OrderApi.java",
"metadata" : {
"path" : "/api/enterprise/orders/{id}/cancel",
"verb" : "POST"
},
"parameters" : [ {
"name" : "id",
"type" : "String",
"annotations" : [ "PathVariable" ]
} ]
},
"methodChain" : [ "click.kamil.examples.enterprise.api.OrderApi.cancelOrder", "click.kamil.examples.enterprise.api.OrderController.cancelOrder", "click.kamil.examples.enterprise.service.OrderServiceImpl.cancel" ],
"triggerPoint" : {
"event" : "CANCEL_ORDER",
"className" : "click.kamil.examples.enterprise.service.OrderServiceImpl",
"methodName" : "cancel",
"sourceFile" : "src/main/java/click/kamil/examples/enterprise/service/OrderServiceImpl.java",
"sourceModule" : null,
"stateMachineId" : null,
"sourceState" : null,
"lineNumber" : 21,
"polymorphicEvents" : [ "CANCEL_ORDER" ],
"external" : false,
"constraint" : null
},
"contextMachineId" : null,
"matchedTransitions" : [ {
"sourceState" : "PAID",
"targetState" : "CANCELLED",
"event" : "CANCEL_ORDER"
} ]
}, {
"entryPoint" : {
"type" : "REST",
"name" : "POST /api/enterprise/orders/place",

View File

@@ -37,6 +37,39 @@
"parameters" : [ ]
} ],
"callChains" : [ {
"entryPoint" : {
"type" : "REST",
"name" : "POST /api/v2/orders/submit",
"className" : "click.kamil.examples.statemachine.inheritance.api.OrderApi",
"methodName" : "submitOrder",
"sourceFile" : "src/main/java/click/kamil/examples/statemachine/inheritance/api/OrderApi.java",
"metadata" : {
"path" : "/api/v2/orders/submit",
"verb" : "POST"
},
"parameters" : [ ]
},
"methodChain" : [ "click.kamil.examples.statemachine.inheritance.api.OrderApi.submitOrder", "click.kamil.examples.statemachine.inheritance.api.OrderControllerImpl.submitOrder", "click.kamil.examples.statemachine.inheritance.service.ProcessingServiceImpl.doProcess" ],
"triggerPoint" : {
"event" : "INHERITED_SUBMIT",
"className" : "click.kamil.examples.statemachine.inheritance.service.ProcessingServiceImpl",
"methodName" : "doProcess",
"sourceFile" : "src/main/java/click/kamil/examples/statemachine/inheritance/service/ProcessingServiceImpl.java",
"sourceModule" : null,
"stateMachineId" : null,
"sourceState" : null,
"lineNumber" : 15,
"polymorphicEvents" : [ "INHERITED_SUBMIT" ],
"external" : false,
"constraint" : null
},
"contextMachineId" : null,
"matchedTransitions" : [ {
"sourceState" : "START",
"targetState" : "WORKING",
"event" : "INHERITED_SUBMIT"
} ]
}, {
"entryPoint" : {
"type" : "REST",
"name" : "POST /api/v2/orders/submit",

View File

@@ -120,6 +120,80 @@
"targetState" : "BUSY",
"event" : "SUBMIT"
} ]
}, {
"entryPoint" : {
"type" : "REST",
"name" : "POST /maven/orders/submit",
"className" : "click.kamil.maven.api.MavenOrderApi",
"methodName" : "submitOrder",
"sourceFile" : "api-module/src/main/java/click/kamil/maven/api/MavenOrderApi.java",
"metadata" : {
"path" : "/maven/orders/submit",
"verb" : "POST"
},
"parameters" : [ {
"name" : "orderId",
"type" : "String",
"annotations" : [ "RequestBody" ]
} ]
},
"methodChain" : [ "click.kamil.maven.api.MavenOrderApi.submitOrder", "click.kamil.maven.core.MavenOrderStateMachine.OrderController.submitOrder" ],
"triggerPoint" : {
"event" : "SUBMIT",
"className" : "click.kamil.maven.core.MavenOrderStateMachine.OrderController",
"methodName" : "submitOrder",
"sourceFile" : "core-module/src/main/java/click/kamil/maven/core/MavenOrderStateMachine.java",
"sourceModule" : null,
"stateMachineId" : null,
"sourceState" : null,
"lineNumber" : 40,
"polymorphicEvents" : null,
"external" : false,
"constraint" : null
},
"contextMachineId" : null,
"matchedTransitions" : [ {
"sourceState" : "INIT",
"targetState" : "BUSY",
"event" : "SUBMIT"
} ]
}, {
"entryPoint" : {
"type" : "JMS",
"name" : "JMS: order.queue",
"className" : "click.kamil.maven.api.JmsOrderListener",
"methodName" : "onMessage",
"sourceFile" : "api-module/src/main/java/click/kamil/maven/api/JmsOrderListener.java",
"metadata" : {
"protocol" : "JMS",
"destination" : "order.queue"
},
"parameters" : [ {
"name" : "message",
"type" : "String",
"annotations" : [ ]
} ]
},
"methodChain" : [ "click.kamil.maven.api.JmsOrderListener.onMessage", "click.kamil.maven.core.MavenOrderStateMachine.OrderService.onMessage" ],
"triggerPoint" : {
"event" : "ORDER_EVENT",
"className" : "click.kamil.maven.core.MavenOrderStateMachine.OrderService",
"methodName" : "onMessage",
"sourceFile" : "core-module/src/main/java/click/kamil/maven/core/MavenOrderStateMachine.java",
"sourceModule" : null,
"stateMachineId" : null,
"sourceState" : null,
"lineNumber" : 52,
"polymorphicEvents" : [ "ORDER_EVENT" ],
"external" : false,
"constraint" : null
},
"contextMachineId" : null,
"matchedTransitions" : [ {
"sourceState" : "BUSY",
"targetState" : "DONE",
"event" : "ORDER_EVENT"
} ]
} ],
"properties" : {
"default" : { }

View File

@@ -81,6 +81,43 @@
"targetState" : "PROCESSING",
"event" : "SUBMIT"
} ]
}, {
"entryPoint" : {
"type" : "REST",
"name" : "POST /orders/submit",
"className" : "click.kamil.multi.api.OrderApi",
"methodName" : "submitOrder",
"sourceFile" : "api-module/src/main/java/click/kamil/multi/api/OrderApi.java",
"metadata" : {
"path" : "/orders/submit",
"verb" : "POST"
},
"parameters" : [ {
"name" : "orderId",
"type" : "String",
"annotations" : [ "RequestBody" ]
} ]
},
"methodChain" : [ "click.kamil.multi.api.OrderApi.submitOrder", "click.kamil.multi.core.OrderController.submitOrder" ],
"triggerPoint" : {
"event" : "SUBMIT",
"className" : "click.kamil.multi.core.OrderController",
"methodName" : "submitOrder",
"sourceFile" : "core-module/src/main/java/click/kamil/multi/core/OrderController.java",
"sourceModule" : null,
"stateMachineId" : null,
"sourceState" : null,
"lineNumber" : 18,
"polymorphicEvents" : null,
"external" : false,
"constraint" : null
},
"contextMachineId" : null,
"matchedTransitions" : [ {
"sourceState" : "NEW",
"targetState" : "PROCESSING",
"event" : "SUBMIT"
} ]
} ],
"properties" : {
"default" : { }