inhertiance

This commit is contained in:
2026-06-17 21:22:03 +02:00
parent 566a814671
commit 0c9e8de310
20 changed files with 324 additions and 8016 deletions

View File

@@ -0,0 +1,90 @@
package click.kamil.springstatemachineexporter.analysis;
import click.kamil.springstatemachineexporter.analysis.model.CallChain;
import click.kamil.springstatemachineexporter.analysis.model.EntryPoint;
import click.kamil.springstatemachineexporter.analysis.model.TriggerPoint;
import click.kamil.springstatemachineexporter.analysis.resolver.ConstantResolver;
import click.kamil.springstatemachineexporter.analysis.service.CallGraphBuilder;
import click.kamil.springstatemachineexporter.analysis.service.GenericEventDetector;
import click.kamil.springstatemachineexporter.analysis.service.SpringMvcDetector;
import click.kamil.springstatemachineexporter.ast.common.CodebaseContext;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.TypeDeclaration;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
public class InheritedEventDetectionTest {
@Test
void testInheritedMessageBuilderEvent(@TempDir Path tempDir) throws IOException {
Path srcDir = tempDir.resolve("src/main/java/com/example");
Files.createDirectories(srcDir);
// 1. Abstract Base Controller with protected method using MessageBuilder
Files.writeString(srcDir.resolve("BaseController.java"),
"package com.example;\n" +
"import org.springframework.messaging.support.MessageBuilder;\n" +
"import org.springframework.statemachine.StateMachine;\n" +
"public abstract class BaseController {\n" +
" protected StateMachine<String, String> stateMachine;\n" +
" \n" +
" protected void send(String event) {\n" +
" stateMachine.sendEvent(MessageBuilder.withPayload(event).build());\n" +
" }\n" +
"}");
// 2. Child Controller calling super.send()
Files.writeString(srcDir.resolve("ChildController.java"),
"package com.example;\n" +
"import org.springframework.web.bind.annotation.*;\n" +
"@RestController\n" +
"public class ChildController extends BaseController {\n" +
" \n" +
" @GetMapping(\"/trigger\")\n" +
" public void trigger() {\n" +
" super.send(\"MY_EVENT\");\n" +
" }\n" +
"}");
CodebaseContext context = new CodebaseContext();
context.scan(tempDir);
// Detect Entry Points
SpringMvcDetector mvcDetector = new SpringMvcDetector(context, new ConstantResolver());
TypeDeclaration childTd = context.getTypeDeclaration("com.example.ChildController");
CompilationUnit childCu = (CompilationUnit) childTd.getRoot();
List<EntryPoint> entryPoints = mvcDetector.detect(childCu);
assertThat(entryPoints).hasSize(1);
EntryPoint ep = entryPoints.get(0);
// Detect Trigger Points
GenericEventDetector eventDetector = new GenericEventDetector(context, new ConstantResolver(), List.of());
TypeDeclaration baseTd = context.getTypeDeclaration("com.example.BaseController");
CompilationUnit baseCu = (CompilationUnit) baseTd.getRoot();
List<TriggerPoint> triggers = eventDetector.detect(baseCu);
assertThat(triggers).describedAs("Should detect sendEvent in BaseController").hasSize(1);
TriggerPoint tp = triggers.get(0);
assertThat(tp.getEvent()).isEqualTo("event");
// Build Call Chains
CallGraphBuilder callGraphBuilder = new CallGraphBuilder(context);
List<CallChain> chains = callGraphBuilder.findChains(entryPoints, triggers);
assertThat(chains).describedAs("Should link ChildController.trigger to BaseController.send").hasSize(1);
CallChain chain = chains.get(0);
assertThat(chain.getMethodChain()).containsExactly(
"com.example.ChildController.trigger",
"com.example.BaseController.send"
);
assertThat(chain.getTriggerPoint().getEvent()).isEqualTo("MY_EVENT");
}
}