up
This commit is contained in:
@@ -482,4 +482,46 @@ public class ConstantResolverTest {
|
||||
assertThat(result).contains("OrderEvents.B2");
|
||||
assertThat(result).contains("OrderEvents.DEF");
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldResolveEnumValueOfWithConstantString(@TempDir Path tempDir) throws IOException {
|
||||
Path dir = tempDir.resolve("com/example");
|
||||
Files.createDirectories(dir);
|
||||
Files.writeString(dir.resolve("OrderEvent.java"),
|
||||
"package com.example;\n" +
|
||||
"public enum OrderEvent { RECEIVED, SHIPPED }\n");
|
||||
Files.writeString(dir.resolve("Caller.java"),
|
||||
"package com.example;\n" +
|
||||
"public class Caller {\n" +
|
||||
" public void call() {\n" +
|
||||
" OrderEvent e1 = OrderEvent.valueOf(\"RECEIVED\");\n" +
|
||||
" OrderEvent e2 = OrderEvent.valueOf(getEventString());\n" +
|
||||
" }\n" +
|
||||
" private String getEventString() {\n" +
|
||||
" return \"SHIPPED\";\n" +
|
||||
" }\n" +
|
||||
"}");
|
||||
|
||||
CodebaseContext context = new CodebaseContext();
|
||||
context.scan(tempDir);
|
||||
|
||||
TypeDeclaration callerTd = context.getTypeDeclaration("com.example.Caller");
|
||||
MethodDeclaration callMethod = callerTd.getMethods()[0];
|
||||
|
||||
VariableDeclarationStatement vds1 = (VariableDeclarationStatement) callMethod.getBody().statements().get(0);
|
||||
VariableDeclarationFragment fragment1 = (VariableDeclarationFragment) vds1.fragments().get(0);
|
||||
MethodInvocation mi1 = (MethodInvocation) fragment1.getInitializer();
|
||||
|
||||
VariableDeclarationStatement vds2 = (VariableDeclarationStatement) callMethod.getBody().statements().get(1);
|
||||
VariableDeclarationFragment fragment2 = (VariableDeclarationFragment) vds2.fragments().get(0);
|
||||
MethodInvocation mi2 = (MethodInvocation) fragment2.getInitializer();
|
||||
|
||||
ConstantResolver resolver = new ConstantResolver();
|
||||
|
||||
String result1 = resolver.resolve(mi1, context);
|
||||
assertThat(result1).isEqualTo("com.example.OrderEvent.RECEIVED");
|
||||
|
||||
String result2 = resolver.resolve(mi2, context);
|
||||
assertThat(result2).isEqualTo("com.example.OrderEvent.SHIPPED");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -102,6 +102,7 @@ class HeuristicCallGraphEngineExtendedTest {
|
||||
java.nio.file.Files.writeString(tempDir.resolve("OrderConfig.java"), source);
|
||||
|
||||
CodebaseContext context = new CodebaseContext();
|
||||
context.setResolveBindings(true);
|
||||
context.scan(tempDir);
|
||||
|
||||
HeuristicCallGraphEngine engine = new HeuristicCallGraphEngine(context);
|
||||
|
||||
@@ -954,4 +954,42 @@ class HeuristicCallGraphEngineGetterTest {
|
||||
assertThat(chains.get(0).getTriggerPoint().getPolymorphicEvents())
|
||||
.containsExactlyInAnyOrder("SMEvent.PAY_RECEIVED");
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldResolveGetterOnInterProceduralClassInstanceCreation() throws IOException {
|
||||
String source = """
|
||||
package com.example;
|
||||
public class OrderController {
|
||||
private OrderService service;
|
||||
public void handle() {
|
||||
service.process(new DomainEvent("PAYLOAD_ID"));
|
||||
}
|
||||
}
|
||||
|
||||
class DomainEvent {
|
||||
private String id;
|
||||
public DomainEvent(String id) { this.id = id; }
|
||||
public String getEvent() { return "INLINE_EVENT"; }
|
||||
}
|
||||
|
||||
class OrderService {
|
||||
public void process(DomainEvent event) {
|
||||
sendEvent(event.getEvent());
|
||||
}
|
||||
public void sendEvent(String ev) {}
|
||||
}
|
||||
""";
|
||||
Path tempDir = Files.createTempDirectory("callgraph_interproc_cic");
|
||||
Files.writeString(tempDir.resolve("OrderConfig.java"), source);
|
||||
CodebaseContext context = new CodebaseContext();
|
||||
context.scan(tempDir);
|
||||
HeuristicCallGraphEngine builder = new HeuristicCallGraphEngine(context);
|
||||
|
||||
EntryPoint entryPoint = EntryPoint.builder().className("com.example.OrderController").methodName("handle").build();
|
||||
TriggerPoint trigger = TriggerPoint.builder().className("com.example.OrderService").methodName("sendEvent").event("ev").build();
|
||||
List<CallChain> chains = builder.findChains(List.of(entryPoint), List.of(trigger));
|
||||
|
||||
assertThat(chains).hasSize(1);
|
||||
assertThat(chains.get(0).getTriggerPoint().getPolymorphicEvents()).containsExactlyInAnyOrder("INLINE_EVENT");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -468,7 +468,7 @@ class HeuristicCallGraphEngineTypeTest {
|
||||
CallChain chain = chains.get(0);
|
||||
assertThat(chain.getTriggerPoint().getEvent()).isEqualTo("mapToEnum(str)");
|
||||
assertThat(chain.getTriggerPoint().getPolymorphicEvents())
|
||||
.containsExactly("<SYMBOLIC: MyEvents.*>");
|
||||
.containsExactly("<SYMBOLIC: com.example.MyEvents.*>");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -92,4 +92,153 @@ class PolymorphicDispatchCallGraphTest {
|
||||
"com.example.TransportOrderService.processOrderEvent"
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldFilterPolymorphicDispatchContextually(@TempDir Path tempDir) throws IOException {
|
||||
String source = """
|
||||
package com.example;
|
||||
|
||||
public class LogisticsController {
|
||||
private LogisticsService service;
|
||||
|
||||
public void handle(String event) {
|
||||
service.process(event);
|
||||
}
|
||||
}
|
||||
|
||||
abstract class AbstractOrderService {
|
||||
public void process(String event) {
|
||||
String resolved = assertSupportedOrderEvent(event);
|
||||
sendEvent(resolved);
|
||||
}
|
||||
|
||||
protected abstract String assertSupportedOrderEvent(String event);
|
||||
|
||||
public void sendEvent(String ev) {}
|
||||
}
|
||||
|
||||
class LogisticsService extends AbstractOrderService {
|
||||
@Override
|
||||
protected String assertSupportedOrderEvent(String event) {
|
||||
return LogisticsEvent.valueOf(event).name();
|
||||
}
|
||||
}
|
||||
|
||||
class ComputerStoreService extends AbstractOrderService {
|
||||
@Override
|
||||
protected String assertSupportedOrderEvent(String event) {
|
||||
return ComputerEvent.valueOf(event).name();
|
||||
}
|
||||
}
|
||||
|
||||
enum LogisticsEvent { DELIVERED, RETURNED }
|
||||
enum ComputerEvent { SHIPPED, REFUNDED }
|
||||
""";
|
||||
Files.writeString(tempDir.resolve("OrderConfig.java"), source);
|
||||
|
||||
CodebaseContext context = new CodebaseContext();
|
||||
context.setResolveBindings(true);
|
||||
context.scan(tempDir);
|
||||
|
||||
HeuristicCallGraphEngine builder = new HeuristicCallGraphEngine(context);
|
||||
|
||||
EntryPoint entryPoint = EntryPoint.builder()
|
||||
.className("com.example.LogisticsController")
|
||||
.methodName("handle")
|
||||
.build();
|
||||
|
||||
TriggerPoint trigger = TriggerPoint.builder()
|
||||
.className("com.example.AbstractOrderService")
|
||||
.methodName("sendEvent")
|
||||
.event("ev")
|
||||
.build();
|
||||
|
||||
List<CallChain> chains = builder.findChains(List.of(entryPoint), List.of(trigger));
|
||||
|
||||
assertThat(chains).hasSize(1);
|
||||
assertThat(chains.get(0).getTriggerPoint().getPolymorphicEvents())
|
||||
.containsExactlyInAnyOrder("LogisticsEvent.DELIVERED", "LogisticsEvent.RETURNED");
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldResolveMapBasedDynamicDispatch(@TempDir Path tempDir) throws IOException {
|
||||
String source = """
|
||||
package com.example;
|
||||
import java.util.Map;
|
||||
import java.util.HashMap;
|
||||
|
||||
public class DispatcherController {
|
||||
private Map<String, AbstractService> serviceMap = new HashMap<>();
|
||||
|
||||
public DispatcherController(LogisticsService logistics, ComputerStoreService computerStore) {
|
||||
serviceMap.put("LOGISTICS", logistics);
|
||||
serviceMap.put("COMPUTER", computerStore);
|
||||
}
|
||||
|
||||
public void handle(String machineType, String event) {
|
||||
serviceMap.get(machineType).process(event);
|
||||
}
|
||||
}
|
||||
|
||||
abstract class AbstractService {
|
||||
public void process(String event) {
|
||||
String resolved = assertSupportedEvent(event);
|
||||
sendEvent(resolved);
|
||||
}
|
||||
protected abstract String assertSupportedEvent(String event);
|
||||
public void sendEvent(String ev) {}
|
||||
}
|
||||
|
||||
class LogisticsService extends AbstractService {
|
||||
@Override
|
||||
protected String assertSupportedEvent(String event) {
|
||||
return LogisticsEvent.valueOf(event).name();
|
||||
}
|
||||
}
|
||||
|
||||
class ComputerStoreService extends AbstractService {
|
||||
@Override
|
||||
protected String assertSupportedEvent(String event) {
|
||||
return ComputerEvent.valueOf(event).name();
|
||||
}
|
||||
}
|
||||
|
||||
enum LogisticsEvent { DELIVERED, RETURNED }
|
||||
enum ComputerEvent { SHIPPED, REFUNDED }
|
||||
""";
|
||||
Files.writeString(tempDir.resolve("DispatchConfig.java"), source);
|
||||
|
||||
CodebaseContext context = new CodebaseContext();
|
||||
context.setResolveBindings(true);
|
||||
context.scan(tempDir);
|
||||
|
||||
HeuristicCallGraphEngine builder = new HeuristicCallGraphEngine(context);
|
||||
|
||||
EntryPoint entryPoint = EntryPoint.builder()
|
||||
.className("com.example.DispatcherController")
|
||||
.methodName("handle")
|
||||
.build();
|
||||
|
||||
TriggerPoint trigger = TriggerPoint.builder()
|
||||
.className("com.example.AbstractService")
|
||||
.methodName("sendEvent")
|
||||
.event("ev")
|
||||
.build();
|
||||
|
||||
List<CallChain> chains = builder.findChains(List.of(entryPoint), List.of(trigger));
|
||||
|
||||
assertThat(chains).hasSize(2);
|
||||
|
||||
CallChain chainLogistics = chains.stream()
|
||||
.filter(c -> "machineType == \"LOGISTICS\"".equals(c.getTriggerPoint().getConstraint()))
|
||||
.findFirst().orElseThrow();
|
||||
assertThat(chainLogistics.getTriggerPoint().getPolymorphicEvents())
|
||||
.containsExactlyInAnyOrder("LogisticsEvent.DELIVERED", "LogisticsEvent.RETURNED");
|
||||
|
||||
CallChain chainComputer = chains.stream()
|
||||
.filter(c -> "machineType == \"COMPUTER\"".equals(c.getTriggerPoint().getConstraint()))
|
||||
.findFirst().orElseThrow();
|
||||
assertThat(chainComputer.getTriggerPoint().getPolymorphicEvents())
|
||||
.containsExactlyInAnyOrder("ComputerEvent.SHIPPED", "ComputerEvent.REFUNDED");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -282,7 +282,7 @@
|
||||
},
|
||||
"methodChain" : [ "click.kamil.web.RabbitOrderListener.handleCustomTransition", "click.kamil.service.StateMachineServiceImpl.sendCustomMessage" ],
|
||||
"triggerPoint" : {
|
||||
"event" : "OrderEvent.PROCESS",
|
||||
"event" : "new CustomStateMachineMessage<>(OrderEvent.PROCESS,\"My Rabbit Custom Payload: \" + payload)",
|
||||
"className" : "click.kamil.service.StateMachineServiceImpl",
|
||||
"methodName" : "sendCustomMessage",
|
||||
"sourceFile" : "service/src/main/java/click/kamil/service/StateMachineServiceImpl.java",
|
||||
@@ -290,16 +290,12 @@
|
||||
"stateMachineId" : null,
|
||||
"sourceState" : null,
|
||||
"lineNumber" : 78,
|
||||
"polymorphicEvents" : [ "OrderEvent.PROCESS" ],
|
||||
"polymorphicEvents" : [ ],
|
||||
"external" : false,
|
||||
"constraint" : null
|
||||
},
|
||||
"contextMachineId" : null,
|
||||
"matchedTransitions" : [ {
|
||||
"sourceState" : "OrderState.NEW",
|
||||
"targetState" : "OrderState.PROCESSING",
|
||||
"event" : "OrderEvent.PROCESS"
|
||||
} ]
|
||||
"matchedTransitions" : null
|
||||
}, {
|
||||
"entryPoint" : {
|
||||
"type" : "JMS",
|
||||
|
||||
Reference in New Issue
Block a user