From 393c998b66abc3ae857864ccdd44f579932c4c5e Mon Sep 17 00:00:00 2001 From: Kamil Patryk Kozakowski Date: Sun, 12 Jul 2026 12:18:03 +0200 Subject: [PATCH] Fix HTML export states, endpoint linking, and dynamic trigger event validation. Co-authored-by: Cursor --- .../TriggerCanonicalizationEnricher.java | 7 +- .../analysis/model/AnalysisResult.java | 1 + .../resolver/MachineEnumCanonicalizer.java | 142 +++++++++++++++++- .../service/AnalysisResultFinalizer.java | 24 ++- .../AnalysisCanonicalFormValidator.java | 14 ++ .../exporter/Dot.java | 4 +- .../exporter/ExportOptions.java | 6 + .../exporter/PlantUml.java | 4 +- .../exporter/Scxml.java | 6 +- .../service/ExportService.java | 2 +- .../TransitionLinkerEnricherTest.java | 29 ++++ .../MachineEnumCanonicalizerTest.java | 44 ++++++ ...portPipelineIdentifierConsistencyTest.java | 39 +++++ .../AnalysisCanonicalFormValidatorTest.java | 51 +++++++ .../exporter/PlantUmlTest.java | 26 ++++ .../ComplexStateMachineConfig.puml | 2 +- .../ComplexStateMachineConfig.scxml.xml | 2 - .../DocumentStateMachineConfiguration.json | 16 +- .../DocumentStateMachineConfiguration.puml | 4 +- ...ocumentStateMachineConfiguration.scxml.xml | 4 - .../F1StateMachineConfiguration.puml | 4 +- .../F1StateMachineConfiguration.scxml.xml | 4 - .../F2StateMachineConfiguration.puml | 4 +- .../F2StateMachineConfiguration.scxml.xml | 4 - .../ForkJoinStateMachineConfig.puml | 4 +- .../ForkJoinStateMachineConfig.scxml.xml | 4 - .../G1StateMachineConfiguration.puml | 4 +- .../G1StateMachineConfiguration.scxml.xml | 4 - .../G2StateMachineConfiguration.puml | 4 +- .../G2StateMachineConfiguration.scxml.xml | 4 - .../KamilEnumStateMachineConfiguration.puml | 6 +- ...milEnumStateMachineConfiguration.scxml.xml | 6 - .../OneStateMachineConfiguration.puml | 4 +- .../OneStateMachineConfiguration.scxml.xml | 4 - .../OrderStateMachineConfiguration.json | 12 +- .../OrderStateMachineConfiguration.puml | 4 +- .../OrderStateMachineConfiguration.scxml.xml | 4 - .../PolymorphicStateMachineConfiguration.puml | 6 +- ...morphicStateMachineConfiguration.scxml.xml | 6 - .../SimpleEnumStateMachineConfiguration.puml | 6 +- ...pleEnumStateMachineConfiguration.scxml.xml | 6 - ...dardDocumentStateMachineConfiguration.puml | 6 +- ...ocumentStateMachineConfiguration.scxml.xml | 6 - ...tandardOrderStateMachineConfiguration.puml | 6 +- ...rdOrderStateMachineConfiguration.scxml.xml | 6 - .../StateMachineConfig.puml | 6 +- .../StateMachineConfig.scxml.xml | 6 - .../ThreeStateMachineConfiguration.puml | 4 +- .../ThreeStateMachineConfiguration.scxml.xml | 4 - .../TwoStateMachineConfiguration.puml | 4 +- .../TwoStateMachineConfiguration.scxml.xml | 4 - .../UserStateMachineConfiguration.json | 12 +- .../UserStateMachineConfiguration.puml | 4 +- .../UserStateMachineConfiguration.scxml.xml | 4 - .../HtmlTransitionLinkConsistencyTest.java | 34 +++++ 55 files changed, 489 insertions(+), 148 deletions(-) diff --git a/state_machine_exporter/src/main/java/click/kamil/springstatemachineexporter/analysis/enricher/TriggerCanonicalizationEnricher.java b/state_machine_exporter/src/main/java/click/kamil/springstatemachineexporter/analysis/enricher/TriggerCanonicalizationEnricher.java index 34e7c97..7dbf74e 100644 --- a/state_machine_exporter/src/main/java/click/kamil/springstatemachineexporter/analysis/enricher/TriggerCanonicalizationEnricher.java +++ b/state_machine_exporter/src/main/java/click/kamil/springstatemachineexporter/analysis/enricher/TriggerCanonicalizationEnricher.java @@ -33,7 +33,8 @@ public class TriggerCanonicalizationEnricher implements AnalysisEnricher { List triggers = result.getMetadata().getTriggers(); List canonicalTriggers = triggers == null ? null : triggers.stream() - .map(trigger -> MachineEnumCanonicalizer.canonicalizeTriggerPoint(trigger, machineTypes)) + .map(trigger -> MachineEnumCanonicalizer.canonicalizeAndExpandTriggerPoint( + trigger, machineTypes, context)) .collect(Collectors.toList()); List callChains = result.getMetadata().getCallChains(); @@ -43,8 +44,8 @@ public class TriggerCanonicalizationEnricher implements AnalysisEnricher { return chain; } return chain.toBuilder() - .triggerPoint(MachineEnumCanonicalizer.canonicalizeTriggerPoint( - chain.getTriggerPoint(), machineTypes)) + .triggerPoint(MachineEnumCanonicalizer.canonicalizeAndExpandTriggerPoint( + chain.getTriggerPoint(), machineTypes, context)) .build(); }) .collect(Collectors.toList()); diff --git a/state_machine_exporter/src/main/java/click/kamil/springstatemachineexporter/analysis/model/AnalysisResult.java b/state_machine_exporter/src/main/java/click/kamil/springstatemachineexporter/analysis/model/AnalysisResult.java index 10544c0..2a77fcf 100644 --- a/state_machine_exporter/src/main/java/click/kamil/springstatemachineexporter/analysis/model/AnalysisResult.java +++ b/state_machine_exporter/src/main/java/click/kamil/springstatemachineexporter/analysis/model/AnalysisResult.java @@ -128,6 +128,7 @@ public class AnalysisResult { } click.kamil.springstatemachineexporter.analysis.service.AnalysisResultFinalizer.applyCanonicalization( this, + null, new StateMachineTypeResolver.MachineTypes(stateTypeFqn, eventTypeFqn)); } diff --git a/state_machine_exporter/src/main/java/click/kamil/springstatemachineexporter/analysis/resolver/MachineEnumCanonicalizer.java b/state_machine_exporter/src/main/java/click/kamil/springstatemachineexporter/analysis/resolver/MachineEnumCanonicalizer.java index 949c7b3..27a26f5 100644 --- a/state_machine_exporter/src/main/java/click/kamil/springstatemachineexporter/analysis/resolver/MachineEnumCanonicalizer.java +++ b/state_machine_exporter/src/main/java/click/kamil/springstatemachineexporter/analysis/resolver/MachineEnumCanonicalizer.java @@ -1,6 +1,7 @@ package click.kamil.springstatemachineexporter.analysis.resolver; import click.kamil.springstatemachineexporter.analysis.model.TriggerPoint; +import click.kamil.springstatemachineexporter.ast.common.CodebaseContext; import click.kamil.springstatemachineexporter.model.Event; import click.kamil.springstatemachineexporter.model.State; import click.kamil.springstatemachineexporter.model.Transition; @@ -91,10 +92,73 @@ public final class MachineEnumCanonicalizer { .build(); } + /** + * Expands {@code } placeholders into concrete package-canonical enum + * constants for the owning machine's event type. Non-matching symbolic entries are dropped. + */ + public static List expandSymbolicPolymorphicEvents( + List polymorphicEvents, + String machineEventTypeFqn, + CodebaseContext context) { + if (polymorphicEvents == null || polymorphicEvents.isEmpty()) { + return polymorphicEvents; + } + if (machineEventTypeFqn == null || machineEventTypeFqn.isBlank()) { + return polymorphicEvents; + } + + List expanded = new ArrayList<>(); + for (String pe : polymorphicEvents) { + if (pe == null) { + continue; + } + if (pe.startsWith("")) { + String symbolicType = pe.substring(" enumValues = context.getEnumValues(stripGenerics(machineEventTypeFqn)); + if (enumValues != null) { + for (String value : enumValues) { + String parsed = value; + if (parsed.contains(".")) { + parsed = parsed.substring(parsed.lastIndexOf('.') + 1); + } + expanded.add(stripGenerics(machineEventTypeFqn) + "." + parsed); + } + } + } + continue; + } + expanded.add(pe); + } + return expanded; + } + + public static TriggerPoint canonicalizeAndExpandTriggerPoint( + TriggerPoint trigger, + StateMachineTypeResolver.MachineTypes machineTypes, + CodebaseContext context) { + TriggerPoint canonical = canonicalizeTriggerPoint(trigger, machineTypes); + if (canonical == null || machineTypes == null || machineTypes.eventTypeFqn() == null) { + return canonical; + } + List expanded = expandSymbolicPolymorphicEvents( + canonical.getPolymorphicEvents(), machineTypes.eventTypeFqn(), context); + if (expanded == canonical.getPolymorphicEvents()) { + return canonical; + } + return canonical.toBuilder().polymorphicEvents(expanded).build(); + } + public static String qualifyEventIdentifier(String event, String eventTypeFqn) { if (event == null || eventTypeFqn == null || event.isEmpty()) { return event; } + if (isDynamicTriggerExpression(event)) { + return denormalizeCorruptedDynamicEvent(event); + } if (event.startsWith(" canonicalizeStates(List states, String stateTypeFqn) { @@ -257,6 +392,9 @@ public final class MachineEnumCanonicalizer { if (value == null || value.isBlank() || enumTypeFqn == null || enumTypeFqn.isBlank()) { return value; } + if (isDynamicTriggerExpression(value)) { + return denormalizeCorruptedDynamicEvent(value); + } value = resolvePlaceholder(value); if (value == null || value.isBlank()) { return value; diff --git a/state_machine_exporter/src/main/java/click/kamil/springstatemachineexporter/analysis/service/AnalysisResultFinalizer.java b/state_machine_exporter/src/main/java/click/kamil/springstatemachineexporter/analysis/service/AnalysisResultFinalizer.java index 98eb9fd..99e1653 100644 --- a/state_machine_exporter/src/main/java/click/kamil/springstatemachineexporter/analysis/service/AnalysisResultFinalizer.java +++ b/state_machine_exporter/src/main/java/click/kamil/springstatemachineexporter/analysis/service/AnalysisResultFinalizer.java @@ -43,7 +43,7 @@ public final class AnalysisResultFinalizer { } persistMachineTypes(result, machineTypes); - applyCanonicalization(result, machineTypes); + applyCanonicalizationFields(result, context, machineTypes); if (context != null) { AnalysisCanonicalFormValidator.enforce(result, context); @@ -66,17 +66,25 @@ public final class AnalysisResultFinalizer { public static void applyCanonicalization( AnalysisResult result, StateMachineTypeResolver.MachineTypes machineTypes) { + applyCanonicalization(result, null, machineTypes); + } + + public static void applyCanonicalization( + AnalysisResult result, + CodebaseContext context, + StateMachineTypeResolver.MachineTypes machineTypes) { if (result == null || machineTypes == null) { return; } if (machineTypes.stateTypeFqn() == null && machineTypes.eventTypeFqn() == null) { return; } - applyCanonicalizationFields(result, machineTypes); + applyCanonicalizationFields(result, context, machineTypes); } private static void applyCanonicalizationFields( AnalysisResult result, + CodebaseContext context, StateMachineTypeResolver.MachineTypes machineTypes) { MachineEnumCanonicalizer.canonicalizeTransitions(result.getTransitions(), machineTypes); @@ -91,8 +99,8 @@ public final class AnalysisResultFinalizer { if (result.getMetadata() != null) { CodebaseMetadata metadata = result.getMetadata(); - List triggers = canonicalizeTriggers(metadata.getTriggers(), machineTypes); - List callChains = canonicalizeCallChains(metadata.getCallChains(), machineTypes); + List triggers = canonicalizeTriggers(metadata.getTriggers(), context, machineTypes); + List callChains = canonicalizeCallChains(metadata.getCallChains(), context, machineTypes); result.setMetadata(CodebaseMetadata.builder() .triggers(triggers) .entryPoints(metadata.getEntryPoints()) @@ -104,17 +112,20 @@ public final class AnalysisResultFinalizer { private static List canonicalizeTriggers( List triggers, + CodebaseContext context, StateMachineTypeResolver.MachineTypes machineTypes) { if (triggers == null) { return null; } return triggers.stream() - .map(trigger -> MachineEnumCanonicalizer.canonicalizeTriggerPoint(trigger, machineTypes)) + .map(trigger -> MachineEnumCanonicalizer.canonicalizeAndExpandTriggerPoint( + trigger, machineTypes, context)) .collect(Collectors.toList()); } private static List canonicalizeCallChains( List callChains, + CodebaseContext context, StateMachineTypeResolver.MachineTypes machineTypes) { if (callChains == null) { return null; @@ -123,7 +134,8 @@ public final class AnalysisResultFinalizer { .map(chain -> { TriggerPoint trigger = chain.getTriggerPoint() == null ? null - : MachineEnumCanonicalizer.canonicalizeTriggerPoint(chain.getTriggerPoint(), machineTypes); + : MachineEnumCanonicalizer.canonicalizeAndExpandTriggerPoint( + chain.getTriggerPoint(), machineTypes, context); List matched = canonicalizeMatchedTransitions( chain.getMatchedTransitions(), machineTypes); return chain.toBuilder() diff --git a/state_machine_exporter/src/main/java/click/kamil/springstatemachineexporter/analysis/validation/AnalysisCanonicalFormValidator.java b/state_machine_exporter/src/main/java/click/kamil/springstatemachineexporter/analysis/validation/AnalysisCanonicalFormValidator.java index a4fc677..fd58498 100644 --- a/state_machine_exporter/src/main/java/click/kamil/springstatemachineexporter/analysis/validation/AnalysisCanonicalFormValidator.java +++ b/state_machine_exporter/src/main/java/click/kamil/springstatemachineexporter/analysis/validation/AnalysisCanonicalFormValidator.java @@ -185,6 +185,7 @@ public final class AnalysisCanonicalFormValidator { String stateTypeFqn = preferTypeFqn(trigger.getStateTypeFqn(), machineTypes.stateTypeFqn()); requireCanonical(prefix + ".event", trigger.getEvent(), eventTypeFqn, violations); + validateTriggerEventForm(prefix + ".event", trigger.getEvent(), violations); requireCanonical(prefix + ".sourceState", trigger.getSourceState(), stateTypeFqn, violations); if (trigger.getPolymorphicEvents() != null) { @@ -215,6 +216,7 @@ public final class AnalysisCanonicalFormValidator { String eventTypeFqn = preferTypeFqn(trigger.getEventTypeFqn(), machineTypes.eventTypeFqn()); String stateTypeFqn = preferTypeFqn(trigger.getStateTypeFqn(), machineTypes.stateTypeFqn()); requireCanonical(triggerPrefix + ".event", trigger.getEvent(), eventTypeFqn, violations); + validateTriggerEventForm(triggerPrefix + ".event", trigger.getEvent(), violations); requireCanonical(triggerPrefix + ".sourceState", trigger.getSourceState(), stateTypeFqn, violations); if (trigger.getPolymorphicEvents() != null) { for (int j = 0; j < trigger.getPolymorphicEvents().size(); j++) { @@ -258,4 +260,16 @@ public final class AnalysisCanonicalFormValidator { violations.add(new Violation(path, value, expected)); } } + + private static void validateTriggerEventForm(String path, String event, List violations) { + if (event == null || event.isBlank()) { + return; + } + if (MachineEnumCanonicalizer.hasCorruptedPackageDynamicEvent(event)) { + violations.add(new Violation( + path, + event, + MachineEnumCanonicalizer.denormalizeCorruptedDynamicEvent(event))); + } + } } diff --git a/state_machine_exporter/src/main/java/click/kamil/springstatemachineexporter/exporter/Dot.java b/state_machine_exporter/src/main/java/click/kamil/springstatemachineexporter/exporter/Dot.java index 1b4a3bb..a06899b 100644 --- a/state_machine_exporter/src/main/java/click/kamil/springstatemachineexporter/exporter/Dot.java +++ b/state_machine_exporter/src/main/java/click/kamil/springstatemachineexporter/exporter/Dot.java @@ -63,10 +63,10 @@ public class Dot implements StateMachineExporter { // Start/End nodes sb.append(" _start [shape=circle, label=\"\", fillcolor=black, width=0.1];\n"); for (String start : startStates) { - sb.append(" _start -> ").append(simplify(start)).append(";\n"); + sb.append(" _start -> ").append(simplify(options.formatStateLabel(start))).append(";\n"); } for (String end : endStates) { - sb.append(" ").append(simplify(end)).append(" [fillcolor=lightgray];\n"); + sb.append(" ").append(simplify(options.formatStateLabel(end))).append(" [fillcolor=lightgray];\n"); } // Transitions diff --git a/state_machine_exporter/src/main/java/click/kamil/springstatemachineexporter/exporter/ExportOptions.java b/state_machine_exporter/src/main/java/click/kamil/springstatemachineexporter/exporter/ExportOptions.java index 7813517..7eb4313 100644 --- a/state_machine_exporter/src/main/java/click/kamil/springstatemachineexporter/exporter/ExportOptions.java +++ b/state_machine_exporter/src/main/java/click/kamil/springstatemachineexporter/exporter/ExportOptions.java @@ -30,6 +30,12 @@ public class ExportOptions { return format(event.rawName(), event.fullIdentifier(), eventFormat); } + /** Formats a bare state label (e.g. start/end state string) using the same rules as {@link #formatState}. */ + public String formatStateLabel(String label) { + if (label == null) return null; + return format(label, label, stateFormat); + } + private String format(String raw, String fqn, EnumFormat format) { if (fqn == null) return raw; switch (format) { diff --git a/state_machine_exporter/src/main/java/click/kamil/springstatemachineexporter/exporter/PlantUml.java b/state_machine_exporter/src/main/java/click/kamil/springstatemachineexporter/exporter/PlantUml.java index 634cfc7..dde0afb 100644 --- a/state_machine_exporter/src/main/java/click/kamil/springstatemachineexporter/exporter/PlantUml.java +++ b/state_machine_exporter/src/main/java/click/kamil/springstatemachineexporter/exporter/PlantUml.java @@ -55,7 +55,7 @@ public class PlantUml implements StateMachineExporter { sb.append("\n"); for (String start : startStates) { - sb.append("[*] --> ").append(simplify(start)).append("\n"); + sb.append("[*] --> ").append(simplify(options.formatStateLabel(start))).append("\n"); } sb.append("\n"); @@ -143,7 +143,7 @@ public class PlantUml implements StateMachineExporter { sb.append("\n"); for (String end : endStates) { - sb.append(simplify(end)).append(" --> [*]\n"); + sb.append(simplify(options.formatStateLabel(end))).append(" --> [*]\n"); } sb.append("@enduml\n"); diff --git a/state_machine_exporter/src/main/java/click/kamil/springstatemachineexporter/exporter/Scxml.java b/state_machine_exporter/src/main/java/click/kamil/springstatemachineexporter/exporter/Scxml.java index 947242f..5d0d1f9 100644 --- a/state_machine_exporter/src/main/java/click/kamil/springstatemachineexporter/exporter/Scxml.java +++ b/state_machine_exporter/src/main/java/click/kamil/springstatemachineexporter/exporter/Scxml.java @@ -26,7 +26,7 @@ public class Scxml implements StateMachineExporter { StringBuilder sb = new StringBuilder(); sb.append("\n"); sb.append("\n"); Set allStates = new java.util.LinkedHashSet<>(); @@ -34,8 +34,8 @@ public class Scxml implements StateMachineExporter { t.getSourceStates().forEach(s -> allStates.add(options.formatState(s))); t.getTargetStates().forEach(s -> allStates.add(options.formatState(s))); } - allStates.addAll(startStates); - allStates.addAll(endStates); + startStates.forEach(s -> allStates.add(options.formatStateLabel(s))); + endStates.forEach(s -> allStates.add(options.formatStateLabel(s))); for (String state : allStates) { sb.append(" \n"); diff --git a/state_machine_exporter/src/main/java/click/kamil/springstatemachineexporter/service/ExportService.java b/state_machine_exporter/src/main/java/click/kamil/springstatemachineexporter/service/ExportService.java index 7b67b7c..6edac43 100644 --- a/state_machine_exporter/src/main/java/click/kamil/springstatemachineexporter/service/ExportService.java +++ b/state_machine_exporter/src/main/java/click/kamil/springstatemachineexporter/service/ExportService.java @@ -193,7 +193,7 @@ public class ExportService { result.getStateTypeFqn(), result.getEventTypeFqn(), context); - AnalysisResultFinalizer.applyCanonicalization(result, machineTypes); + AnalysisResultFinalizer.applyCanonicalization(result, context, machineTypes); enrichmentService.relinkAfterPropertyResolution(result, context, null); AnalysisResultFinalizer.finalizeResult(result, context, machineTypes); diff --git a/state_machine_exporter/src/test/java/click/kamil/springstatemachineexporter/analysis/enricher/TransitionLinkerEnricherTest.java b/state_machine_exporter/src/test/java/click/kamil/springstatemachineexporter/analysis/enricher/TransitionLinkerEnricherTest.java index f6287b3..83c8341 100644 --- a/state_machine_exporter/src/test/java/click/kamil/springstatemachineexporter/analysis/enricher/TransitionLinkerEnricherTest.java +++ b/state_machine_exporter/src/test/java/click/kamil/springstatemachineexporter/analysis/enricher/TransitionLinkerEnricherTest.java @@ -42,6 +42,35 @@ class TransitionLinkerEnricherTest { assertThat(result.getMetadata().getCallChains().get(0).getMatchedTransitions()).hasSize(1); } + @Test + void shouldLinkWhenSymbolicPolymorphicEventsExpandToMachineEnumConstants() { + Transition payT = new Transition(); + payT.setSourceStates(List.of( + State.of("OrderState.NEW", "com.example.order.OrderState.NEW"))); + payT.setTargetStates(List.of( + State.of("OrderState.PAID", "com.example.order.OrderState.PAID"))); + payT.setEvent(Event.of("OrderEvent.PAY", "com.example.order.OrderEvent.PAY")); + + CallChain chain = CallChain.builder() + .triggerPoint(TriggerPoint.builder() + .event("eventString") + .polymorphicEvents(List.of("com.example.order.OrderEvent.PAY")) + .constraint("\"ORDER\".equalsIgnoreCase(machineType)") + .build()) + .build(); + + AnalysisResult result = AnalysisResult.builder() + .name("com.example.config.OrderStateMachineConfiguration") + .eventTypeFqn("com.example.order.OrderEvent") + .transitions(List.of(payT)) + .metadata(CodebaseMetadata.builder().callChains(List.of(chain)).build()) + .build(); + + enricher.enrich(result, null, null); + + assertThat(result.getMetadata().getCallChains().get(0).getMatchedTransitions()).hasSize(1); + } + @Test void shouldRespectDispatcherBranchConstraintForMachineDomain() { Transition payT = new Transition(); diff --git a/state_machine_exporter/src/test/java/click/kamil/springstatemachineexporter/analysis/resolver/MachineEnumCanonicalizerTest.java b/state_machine_exporter/src/test/java/click/kamil/springstatemachineexporter/analysis/resolver/MachineEnumCanonicalizerTest.java index 28576a4..30ba795 100644 --- a/state_machine_exporter/src/test/java/click/kamil/springstatemachineexporter/analysis/resolver/MachineEnumCanonicalizerTest.java +++ b/state_machine_exporter/src/test/java/click/kamil/springstatemachineexporter/analysis/resolver/MachineEnumCanonicalizerTest.java @@ -167,6 +167,50 @@ class MachineEnumCanonicalizerTest { assertThat(canonical.rawName()).isEqualTo("OrderState.NEW"); } + @Test + void shouldNotPackageCanonicalizeDynamicValueOfTriggerExpression() { + String dynamic = "MyEvent.valueOf(event)"; + assertThat(MachineEnumCanonicalizer.classifyTriggerEvent(dynamic)) + .isEqualTo(MachineEnumCanonicalizer.TriggerEventKind.DYNAMIC_EXPRESSION); + assertThat(MachineEnumCanonicalizer.canonicalizeLabel( + dynamic, "com.abcd.aaa.MyEvent")) + .isEqualTo("MyEvent.valueOf(event)"); + } + + @Test + void shouldDenormalizeCorruptedPackageValueOfTriggerExpression() { + String corrupted = "com.abcd.aaa.MyEvent.valueOf(event)"; + assertThat(MachineEnumCanonicalizer.denormalizeCorruptedDynamicEvent(corrupted)) + .isEqualTo("MyEvent.valueOf(event)"); + assertThat(MachineEnumCanonicalizer.hasCorruptedPackageDynamicEvent(corrupted)).isTrue(); + } + + @Test + void shouldClassifyConcreteEnumTriggerEvents() { + assertThat(MachineEnumCanonicalizer.classifyTriggerEvent("com.example.order.OrderEvent.PAY")) + .isEqualTo(MachineEnumCanonicalizer.TriggerEventKind.CANONICAL_ENUM); + assertThat(MachineEnumCanonicalizer.classifyTriggerEvent("event.getType()")) + .isEqualTo(MachineEnumCanonicalizer.TriggerEventKind.DYNAMIC_EXPRESSION); + assertThat(MachineEnumCanonicalizer.classifyTriggerEvent("")) + .isEqualTo(MachineEnumCanonicalizer.TriggerEventKind.SYMBOLIC); + } + + @Test + void shouldExpandSymbolicPolymorphicEventsForMatchingMachineType(@TempDir Path tempDir) throws IOException { + writeSampleConfig(tempDir); + + CodebaseContext context = new CodebaseContext(); + context.scan(tempDir); + + List expanded = MachineEnumCanonicalizer.expandSymbolicPolymorphicEvents( + List.of("", ""), + "com.example.order.OrderEvent", + context); + + assertThat(expanded).containsExactly( + "com.example.order.OrderEvent.PAY"); + } + @Test void shouldDedupeStatesByCanonicalFullIdentifier(@TempDir Path tempDir) throws IOException { writeSampleConfig(tempDir); diff --git a/state_machine_exporter/src/test/java/click/kamil/springstatemachineexporter/analysis/service/ExportPipelineIdentifierConsistencyTest.java b/state_machine_exporter/src/test/java/click/kamil/springstatemachineexporter/analysis/service/ExportPipelineIdentifierConsistencyTest.java index 845f766..0d9e614 100644 --- a/state_machine_exporter/src/test/java/click/kamil/springstatemachineexporter/analysis/service/ExportPipelineIdentifierConsistencyTest.java +++ b/state_machine_exporter/src/test/java/click/kamil/springstatemachineexporter/analysis/service/ExportPipelineIdentifierConsistencyTest.java @@ -105,10 +105,49 @@ class ExportPipelineIdentifierConsistencyTest { } AnalysisResult result = new JsonImportService().importAnalysisResult(json); assertNoMixedEnumIdentifiers(result); + assertTriggerEventForms(result); } } } + static void assertTriggerEventForms(AnalysisResult result) { + if (result.getMetadata() == null) { + return; + } + if (result.getMetadata().getTriggers() != null) { + for (TriggerPoint trigger : result.getMetadata().getTriggers()) { + assertTriggerEventForm(trigger.getEvent()); + } + } + if (result.getMetadata().getCallChains() != null) { + for (CallChain chain : result.getMetadata().getCallChains()) { + if (chain.getTriggerPoint() != null) { + assertTriggerEventForm(chain.getTriggerPoint().getEvent()); + } + } + } + } + + private static void assertTriggerEventForm(String event) { + if (event == null || event.isBlank()) { + return; + } + MachineEnumCanonicalizer.TriggerEventKind kind = MachineEnumCanonicalizer.classifyTriggerEvent(event); + assertThat(kind) + .as("triggerPoint.event must be canonical enum, dynamic expression, symbolic, or lifecycle: %s", event) + .isIn( + MachineEnumCanonicalizer.TriggerEventKind.CANONICAL_ENUM, + MachineEnumCanonicalizer.TriggerEventKind.DYNAMIC_EXPRESSION, + MachineEnumCanonicalizer.TriggerEventKind.SYMBOLIC, + MachineEnumCanonicalizer.TriggerEventKind.LIFECYCLE); + assertThat(MachineEnumCanonicalizer.hasCorruptedPackageDynamicEvent(event)) + .as("dynamic trigger event must not be package-prefixed: %s", event) + .isFalse(); + if (kind == MachineEnumCanonicalizer.TriggerEventKind.CANONICAL_ENUM) { + assertThat(event).contains(".").doesNotContain("("); + } + } + @Test void propertyResolutionShouldCanonicalizeCallChainTriggersBeforeRelink(@TempDir Path tempDir) throws Exception { writeSampleProject(tempDir); diff --git a/state_machine_exporter/src/test/java/click/kamil/springstatemachineexporter/analysis/validation/AnalysisCanonicalFormValidatorTest.java b/state_machine_exporter/src/test/java/click/kamil/springstatemachineexporter/analysis/validation/AnalysisCanonicalFormValidatorTest.java index 6464cdd..8fa06fe 100644 --- a/state_machine_exporter/src/test/java/click/kamil/springstatemachineexporter/analysis/validation/AnalysisCanonicalFormValidatorTest.java +++ b/state_machine_exporter/src/test/java/click/kamil/springstatemachineexporter/analysis/validation/AnalysisCanonicalFormValidatorTest.java @@ -120,6 +120,57 @@ class AnalysisCanonicalFormValidatorTest { .anyMatch(path -> path.contains("matchedTransitions[0].sourceState")); } + @Test + void shouldFailWhenTriggerEventHasCorruptedPackageValueOfForm() { + AnalysisResult result = AnalysisResult.builder() + .name("com.example.config.OrderStateMachineConfiguration") + .stateTypeFqn("com.example.order.OrderState") + .eventTypeFqn("com.example.order.OrderEvent") + .metadata(CodebaseMetadata.builder() + .triggers(List.of(TriggerPoint.builder() + .event("com.example.order.OrderEvent.valueOf(eventString)") + .className("com.example.web.OrderController") + .methodName("dispatch") + .sourceFile("OrderController.java") + .build())) + .build()) + .build(); + + List violations = + AnalysisCanonicalFormValidator.validateWithMachineTypes( + result, + new click.kamil.springstatemachineexporter.analysis.resolver.StateMachineTypeResolver.MachineTypes( + "com.example.order.OrderState", "com.example.order.OrderEvent")); + + assertThat(violations) + .extracting(AnalysisCanonicalFormValidator.Violation::path) + .contains("metadata.triggers[0].event"); + } + + @Test + void shouldAllowDynamicDispatcherExpressionWithoutPackagePrefix() { + AnalysisResult result = AnalysisResult.builder() + .name("com.example.config.OrderStateMachineConfiguration") + .stateTypeFqn("com.example.order.OrderState") + .eventTypeFqn("com.example.order.OrderEvent") + .metadata(CodebaseMetadata.builder() + .triggers(List.of(TriggerPoint.builder() + .event("OrderEvent.valueOf(eventString.toUpperCase())") + .className("com.example.web.OrderController") + .methodName("dispatch") + .sourceFile("OrderController.java") + .polymorphicEvents(List.of("com.example.order.OrderEvent.PAY")) + .build())) + .build()) + .build(); + + assertThat(AnalysisCanonicalFormValidator.validateWithMachineTypes( + result, + new click.kamil.springstatemachineexporter.analysis.resolver.StateMachineTypeResolver.MachineTypes( + "com.example.order.OrderState", "com.example.order.OrderEvent"))) + .noneMatch(v -> v.path().contains(".event")); + } + @Test void shouldSkipValidationForStringStateMachines(@TempDir Path tempDir) throws IOException { Path configPkg = tempDir.resolve("com/example/config"); diff --git a/state_machine_exporter/src/test/java/click/kamil/springstatemachineexporter/exporter/PlantUmlTest.java b/state_machine_exporter/src/test/java/click/kamil/springstatemachineexporter/exporter/PlantUmlTest.java index 67dbf41..a34662d 100644 --- a/state_machine_exporter/src/test/java/click/kamil/springstatemachineexporter/exporter/PlantUmlTest.java +++ b/state_machine_exporter/src/test/java/click/kamil/springstatemachineexporter/exporter/PlantUmlTest.java @@ -52,4 +52,30 @@ class PlantUmlTest { assertThat(result).contains("[list.size() < 5]"); assertThat(result).contains("new int[]{1, 2}"); } + + @Test + void shouldFormatPackageCanonicalStartAndEndStatesLikeTransitionNodes() { + PlantUml plantUml = new PlantUml(); + ExportOptions options = ExportOptions.builder().build(); + + State stateA = State.of("State.A", "com.abcd.aaa.State.A"); + State stateB = State.of("State.B", "com.abcd.aaa.State.B"); + + Transition t = new Transition(); + t.setType(TransitionType.EXTERNAL); + t.setSourceStates(List.of(stateA)); + t.setTargetStates(List.of(stateB)); + + String result = plantUml.export( + "TestMachine", + List.of(t), + Set.of("com.abcd.aaa.State.A"), + Set.of("com.abcd.aaa.State.B"), + options); + + assertThat(result).contains("[*] --> State.A"); + assertThat(result).contains("State.B --> [*]"); + assertThat(result).doesNotContain("com.abcd.aaa.State.A"); + assertThat(result).doesNotContain("abcd.aaa.State.A"); + } } diff --git a/state_machine_exporter/src/test/resources/golden/ComplexStateMachineConfig/ComplexStateMachineConfig.puml b/state_machine_exporter/src/test/resources/golden/ComplexStateMachineConfig/ComplexStateMachineConfig.puml index 7572bd8..65692f3 100644 --- a/state_machine_exporter/src/test/resources/golden/ComplexStateMachineConfig/ComplexStateMachineConfig.puml +++ b/state_machine_exporter/src/test/resources/golden/ComplexStateMachineConfig/ComplexStateMachineConfig.puml @@ -21,7 +21,7 @@ skinparam ArrowThickness 1 skinparam dpi 110 skinparam svgLinkTarget _self -[*] --> ComplexStateMachineConfig.States.STATE1 +[*] --> States.STATE1 state States.STATE16 <> state States.STATE17 <> diff --git a/state_machine_exporter/src/test/resources/golden/ComplexStateMachineConfig/ComplexStateMachineConfig.scxml.xml b/state_machine_exporter/src/test/resources/golden/ComplexStateMachineConfig/ComplexStateMachineConfig.scxml.xml index c70ed20..166eefe 100644 --- a/state_machine_exporter/src/test/resources/golden/ComplexStateMachineConfig/ComplexStateMachineConfig.scxml.xml +++ b/state_machine_exporter/src/test/resources/golden/ComplexStateMachineConfig/ComplexStateMachineConfig.scxml.xml @@ -124,7 +124,5 @@ - - diff --git a/state_machine_exporter/src/test/resources/golden/DocumentStateMachineConfiguration/DocumentStateMachineConfiguration.json b/state_machine_exporter/src/test/resources/golden/DocumentStateMachineConfiguration/DocumentStateMachineConfiguration.json index 2636286..e568f9a 100644 --- a/state_machine_exporter/src/test/resources/golden/DocumentStateMachineConfiguration/DocumentStateMachineConfiguration.json +++ b/state_machine_exporter/src/test/resources/golden/DocumentStateMachineConfiguration/DocumentStateMachineConfiguration.json @@ -181,13 +181,25 @@ "stateMachineId" : null, "sourceState" : null, "lineNumber" : 87, - "polymorphicEvents" : [ "", "", "" ], + "polymorphicEvents" : [ "click.kamil.enterprise.machines.document.DocumentEvent.SUBMIT", "click.kamil.enterprise.machines.document.DocumentEvent.APPROVE", "click.kamil.enterprise.machines.document.DocumentEvent.REJECT" ], "external" : true, "constraint" : "!(\"ORDER\".equalsIgnoreCase(machineType)) && \"DOCUMENT\".equalsIgnoreCase(machineType)", "ambiguous" : false }, "contextMachineId" : null, - "matchedTransitions" : null + "matchedTransitions" : [ { + "sourceState" : "click.kamil.enterprise.machines.document.DocumentState.DRAFT", + "targetState" : "click.kamil.enterprise.machines.document.DocumentState.IN_REVIEW", + "event" : "click.kamil.enterprise.machines.document.DocumentEvent.SUBMIT" + }, { + "sourceState" : "click.kamil.enterprise.machines.document.DocumentState.IN_REVIEW", + "targetState" : "click.kamil.enterprise.machines.document.DocumentState.APPROVED", + "event" : "click.kamil.enterprise.machines.document.DocumentEvent.APPROVE" + }, { + "sourceState" : "click.kamil.enterprise.machines.document.DocumentState.IN_REVIEW", + "targetState" : "click.kamil.enterprise.machines.document.DocumentState.DRAFT", + "event" : "click.kamil.enterprise.machines.document.DocumentEvent.REJECT" + } ] } ], "properties" : { "default" : { } diff --git a/state_machine_exporter/src/test/resources/golden/DocumentStateMachineConfiguration/DocumentStateMachineConfiguration.puml b/state_machine_exporter/src/test/resources/golden/DocumentStateMachineConfiguration/DocumentStateMachineConfiguration.puml index 4172381..f93ba9d 100644 --- a/state_machine_exporter/src/test/resources/golden/DocumentStateMachineConfiguration/DocumentStateMachineConfiguration.puml +++ b/state_machine_exporter/src/test/resources/golden/DocumentStateMachineConfiguration/DocumentStateMachineConfiguration.puml @@ -21,13 +21,13 @@ skinparam ArrowThickness 1 skinparam dpi 110 skinparam svgLinkTarget _self -[*] --> click.kamil.enterprise.machines.document.DocumentState.DRAFT +[*] --> DocumentState.DRAFT DocumentState.DRAFT -[#1E90FF,bold]-> DocumentState.IN_REVIEW <> : DocumentEvent.SUBMIT DocumentState.IN_REVIEW -[#1E90FF,bold]-> DocumentState.APPROVED <> : DocumentEvent.APPROVE DocumentState.IN_REVIEW -[#1E90FF,bold]-> DocumentState.DRAFT <> : DocumentEvent.REJECT -click.kamil.enterprise.machines.document.DocumentState.APPROVED --> [*] +DocumentState.APPROVED --> [*] @enduml diff --git a/state_machine_exporter/src/test/resources/golden/DocumentStateMachineConfiguration/DocumentStateMachineConfiguration.scxml.xml b/state_machine_exporter/src/test/resources/golden/DocumentStateMachineConfiguration/DocumentStateMachineConfiguration.scxml.xml index 38fb03a..c71ad83 100644 --- a/state_machine_exporter/src/test/resources/golden/DocumentStateMachineConfiguration/DocumentStateMachineConfiguration.scxml.xml +++ b/state_machine_exporter/src/test/resources/golden/DocumentStateMachineConfiguration/DocumentStateMachineConfiguration.scxml.xml @@ -9,9 +9,5 @@ - - - - diff --git a/state_machine_exporter/src/test/resources/golden/F1StateMachineConfiguration/F1StateMachineConfiguration.puml b/state_machine_exporter/src/test/resources/golden/F1StateMachineConfiguration/F1StateMachineConfiguration.puml index b845aee..dcb4963 100644 --- a/state_machine_exporter/src/test/resources/golden/F1StateMachineConfiguration/F1StateMachineConfiguration.puml +++ b/state_machine_exporter/src/test/resources/golden/F1StateMachineConfiguration/F1StateMachineConfiguration.puml @@ -21,7 +21,7 @@ skinparam ArrowThickness 1 skinparam dpi 110 skinparam svgLinkTarget _self -[*] --> click.kamil.examples.statemachine.inheritanceextrafunctionsstate3.States.STATE1 +[*] --> States.STATE1 state States.STATEY <> state States.STATE16 <> @@ -89,6 +89,6 @@ States.STATE_EXTRA_1 -[#1E90FF,bold]-> States.STATE_EXTRA_3 <> : Event States.STATE_EXTRA_1 -[#1E90FF,bold]-> States.CANCEL <> : Events.EVENT_CANCEL_2 States.STATE_EXTRA_2 -[#1E90FF,bold]-> States.CANCEL <> : Events.EVENT_CANCEL_2 -click.kamil.examples.statemachine.inheritanceextrafunctionsstate3.States.STATEZ --> [*] +States.STATEZ --> [*] @enduml diff --git a/state_machine_exporter/src/test/resources/golden/F1StateMachineConfiguration/F1StateMachineConfiguration.scxml.xml b/state_machine_exporter/src/test/resources/golden/F1StateMachineConfiguration/F1StateMachineConfiguration.scxml.xml index 83a22a2..2b81fe0 100644 --- a/state_machine_exporter/src/test/resources/golden/F1StateMachineConfiguration/F1StateMachineConfiguration.scxml.xml +++ b/state_machine_exporter/src/test/resources/golden/F1StateMachineConfiguration/F1StateMachineConfiguration.scxml.xml @@ -160,9 +160,5 @@ - - - - diff --git a/state_machine_exporter/src/test/resources/golden/F2StateMachineConfiguration/F2StateMachineConfiguration.puml b/state_machine_exporter/src/test/resources/golden/F2StateMachineConfiguration/F2StateMachineConfiguration.puml index f0f0a02..071a9cc 100644 --- a/state_machine_exporter/src/test/resources/golden/F2StateMachineConfiguration/F2StateMachineConfiguration.puml +++ b/state_machine_exporter/src/test/resources/golden/F2StateMachineConfiguration/F2StateMachineConfiguration.puml @@ -21,7 +21,7 @@ skinparam ArrowThickness 1 skinparam dpi 110 skinparam svgLinkTarget _self -[*] --> click.kamil.examples.statemachine.inheritanceextrafunctionsstate3.States.STATE1 +[*] --> States.STATE1 state States.STATEY <> state States.STATE16 <> @@ -90,6 +90,6 @@ States.STATE_EXTRA_1_1 -[#1E90FF,bold]-> States.CANCEL <> : Events.EVE States.STATE_EXTRA_1_2 -[#1E90FF,bold]-> States.CANCEL <> : Events.EVENT_CANCEL_2 States.STATE_EXTRA_1 -[#1E90FF,bold]-> States.CANCEL <> : Events.EVENT_CANCEL_2 -click.kamil.examples.statemachine.inheritanceextrafunctionsstate3.States.STATEZ --> [*] +States.STATEZ --> [*] @enduml diff --git a/state_machine_exporter/src/test/resources/golden/F2StateMachineConfiguration/F2StateMachineConfiguration.scxml.xml b/state_machine_exporter/src/test/resources/golden/F2StateMachineConfiguration/F2StateMachineConfiguration.scxml.xml index 9bd8b8d..bab54d4 100644 --- a/state_machine_exporter/src/test/resources/golden/F2StateMachineConfiguration/F2StateMachineConfiguration.scxml.xml +++ b/state_machine_exporter/src/test/resources/golden/F2StateMachineConfiguration/F2StateMachineConfiguration.scxml.xml @@ -163,9 +163,5 @@ - - - - diff --git a/state_machine_exporter/src/test/resources/golden/ForkJoinStateMachineConfig/ForkJoinStateMachineConfig.puml b/state_machine_exporter/src/test/resources/golden/ForkJoinStateMachineConfig/ForkJoinStateMachineConfig.puml index 0bf86f7..5c5838c 100644 --- a/state_machine_exporter/src/test/resources/golden/ForkJoinStateMachineConfig/ForkJoinStateMachineConfig.puml +++ b/state_machine_exporter/src/test/resources/golden/ForkJoinStateMachineConfig/ForkJoinStateMachineConfig.puml @@ -21,7 +21,7 @@ skinparam ArrowThickness 1 skinparam dpi 110 skinparam svgLinkTarget _self -[*] --> ForkJoinStateMachineConfig.States.START +[*] --> States.START States.START -[#1E90FF,bold]-> States.FORK <> : Events.TO_FORK @@ -33,6 +33,6 @@ States.REGION1_STATE2 -[#8A2BE2,bold]-> States.JOIN <> States.REGION2_STATE2 -[#8A2BE2,bold]-> States.JOIN <> States.JOIN -[#1E90FF,bold]-> States.END <> : Events.TO_END -ForkJoinStateMachineConfig.States.END --> [*] +States.END --> [*] @enduml diff --git a/state_machine_exporter/src/test/resources/golden/ForkJoinStateMachineConfig/ForkJoinStateMachineConfig.scxml.xml b/state_machine_exporter/src/test/resources/golden/ForkJoinStateMachineConfig/ForkJoinStateMachineConfig.scxml.xml index b318734..9da75c6 100644 --- a/state_machine_exporter/src/test/resources/golden/ForkJoinStateMachineConfig/ForkJoinStateMachineConfig.scxml.xml +++ b/state_machine_exporter/src/test/resources/golden/ForkJoinStateMachineConfig/ForkJoinStateMachineConfig.scxml.xml @@ -24,9 +24,5 @@ - - - - diff --git a/state_machine_exporter/src/test/resources/golden/G1StateMachineConfiguration/G1StateMachineConfiguration.puml b/state_machine_exporter/src/test/resources/golden/G1StateMachineConfiguration/G1StateMachineConfiguration.puml index 0ce5596..60f2648 100644 --- a/state_machine_exporter/src/test/resources/golden/G1StateMachineConfiguration/G1StateMachineConfiguration.puml +++ b/state_machine_exporter/src/test/resources/golden/G1StateMachineConfiguration/G1StateMachineConfiguration.puml @@ -21,7 +21,7 @@ skinparam ArrowThickness 1 skinparam dpi 110 skinparam svgLinkTarget _self -[*] --> click.kamil.examples.statemachine.inheritanceextrafunctionsstate3.States.STATE1 +[*] --> States.STATE1 state States.STATEY <> state States.STATE9 <> @@ -53,6 +53,6 @@ States.STATE3 -[#1E90FF,bold]-> States.STATE_EXTRA_2 <> : Events.EVENT States.STATE_EXTRA_2 -[#1E90FF,bold]-> States.STATE_EXTRA_3 <> : Events.EVENT_1_2 States.STATE_EXTRA_3 -[#1E90FF,bold]-> States.CANCEL <> : Events.EVENT_CANCEL -click.kamil.examples.statemachine.inheritanceextrafunctionsstate3.States.STATEZ --> [*] +States.STATEZ --> [*] @enduml diff --git a/state_machine_exporter/src/test/resources/golden/G1StateMachineConfiguration/G1StateMachineConfiguration.scxml.xml b/state_machine_exporter/src/test/resources/golden/G1StateMachineConfiguration/G1StateMachineConfiguration.scxml.xml index c8438f5..ecf7ddc 100644 --- a/state_machine_exporter/src/test/resources/golden/G1StateMachineConfiguration/G1StateMachineConfiguration.scxml.xml +++ b/state_machine_exporter/src/test/resources/golden/G1StateMachineConfiguration/G1StateMachineConfiguration.scxml.xml @@ -71,9 +71,5 @@ - - - - diff --git a/state_machine_exporter/src/test/resources/golden/G2StateMachineConfiguration/G2StateMachineConfiguration.puml b/state_machine_exporter/src/test/resources/golden/G2StateMachineConfiguration/G2StateMachineConfiguration.puml index 903db0f..25ef4aa 100644 --- a/state_machine_exporter/src/test/resources/golden/G2StateMachineConfiguration/G2StateMachineConfiguration.puml +++ b/state_machine_exporter/src/test/resources/golden/G2StateMachineConfiguration/G2StateMachineConfiguration.puml @@ -21,7 +21,7 @@ skinparam ArrowThickness 1 skinparam dpi 110 skinparam svgLinkTarget _self -[*] --> click.kamil.examples.statemachine.inheritanceextrafunctionsstate3.States.STATE1 +[*] --> States.STATE1 state States.STATEY <> state States.STATE9 <> @@ -54,6 +54,6 @@ States.STATE_EXTRA_1 -[#1E90FF,bold]-> States.STATE_EXTRA_2 <> : Event States.STATE_EXTRA_1 -[#1E90FF,bold]-> States.CANCEL <> : Events.EVENT_CANCEL States.STATE_EXTRA_2 -[#1E90FF,bold]-> States.CANCEL <> : Events.EVENT_CANCEL -click.kamil.examples.statemachine.inheritanceextrafunctionsstate3.States.STATEZ --> [*] +States.STATEZ --> [*] @enduml diff --git a/state_machine_exporter/src/test/resources/golden/G2StateMachineConfiguration/G2StateMachineConfiguration.scxml.xml b/state_machine_exporter/src/test/resources/golden/G2StateMachineConfiguration/G2StateMachineConfiguration.scxml.xml index 63396e5..d206b3c 100644 --- a/state_machine_exporter/src/test/resources/golden/G2StateMachineConfiguration/G2StateMachineConfiguration.scxml.xml +++ b/state_machine_exporter/src/test/resources/golden/G2StateMachineConfiguration/G2StateMachineConfiguration.scxml.xml @@ -72,9 +72,5 @@ - - - - diff --git a/state_machine_exporter/src/test/resources/golden/KamilEnumStateMachineConfiguration/KamilEnumStateMachineConfiguration.puml b/state_machine_exporter/src/test/resources/golden/KamilEnumStateMachineConfiguration/KamilEnumStateMachineConfiguration.puml index f224976..f4b8506 100644 --- a/state_machine_exporter/src/test/resources/golden/KamilEnumStateMachineConfiguration/KamilEnumStateMachineConfiguration.puml +++ b/state_machine_exporter/src/test/resources/golden/KamilEnumStateMachineConfiguration/KamilEnumStateMachineConfiguration.puml @@ -21,7 +21,7 @@ skinparam ArrowThickness 1 skinparam dpi 110 skinparam svgLinkTarget _self -[*] --> click.kamil.examples.statemachine.enumstate.OrderStates.SUBMITTED +[*] --> OrderStates.SUBMITTED state OrderStates.PAID1 <> @@ -39,7 +39,7 @@ OrderStates.PAID2 -[#1E90FF,bold]-> OrderStates.CANCELED <> OrderStates.PAID3 -[#1E90FF,bold]-> OrderStates.CANCELED <> OrderStates.PAID2 -[#1E90FF,bold]-> OrderStates.PAID2 <> : OrderEvents.ABCD / λ, action2 -click.kamil.examples.statemachine.enumstate.OrderStates.CANCELED --> [*] -click.kamil.examples.statemachine.enumstate.OrderStates.FULFILLED --> [*] +OrderStates.CANCELED --> [*] +OrderStates.FULFILLED --> [*] @enduml diff --git a/state_machine_exporter/src/test/resources/golden/KamilEnumStateMachineConfiguration/KamilEnumStateMachineConfiguration.scxml.xml b/state_machine_exporter/src/test/resources/golden/KamilEnumStateMachineConfiguration/KamilEnumStateMachineConfiguration.scxml.xml index 4c885ab..6b8dcf8 100644 --- a/state_machine_exporter/src/test/resources/golden/KamilEnumStateMachineConfiguration/KamilEnumStateMachineConfiguration.scxml.xml +++ b/state_machine_exporter/src/test/resources/golden/KamilEnumStateMachineConfiguration/KamilEnumStateMachineConfiguration.scxml.xml @@ -37,11 +37,5 @@ - - - - - - diff --git a/state_machine_exporter/src/test/resources/golden/OneStateMachineConfiguration/OneStateMachineConfiguration.puml b/state_machine_exporter/src/test/resources/golden/OneStateMachineConfiguration/OneStateMachineConfiguration.puml index 1a4633f..7e16fb0 100644 --- a/state_machine_exporter/src/test/resources/golden/OneStateMachineConfiguration/OneStateMachineConfiguration.puml +++ b/state_machine_exporter/src/test/resources/golden/OneStateMachineConfiguration/OneStateMachineConfiguration.puml @@ -21,7 +21,7 @@ skinparam ArrowThickness 1 skinparam dpi 110 skinparam svgLinkTarget _self -[*] --> click.kamil.examples.statemachine.inheritancestate.States.STATE1 +[*] --> States.STATE1 state States.STATEY <> state States.STATE16 <> @@ -78,6 +78,6 @@ States.STATE8 -[#FF6347,bold]-> States.STATE9 <> : [guardVarEquals( States.STATE8 -[#FF6347,bold]-> States.STATE10 <> : (order=1) States.STATE5 -[#1E90FF,bold]-> States.STATE_EXTRA_1 <> : Events.EVENTX -click.kamil.examples.statemachine.inheritancestate.States.STATEZ --> [*] +States.STATEZ --> [*] @enduml diff --git a/state_machine_exporter/src/test/resources/golden/OneStateMachineConfiguration/OneStateMachineConfiguration.scxml.xml b/state_machine_exporter/src/test/resources/golden/OneStateMachineConfiguration/OneStateMachineConfiguration.scxml.xml index 0e86c38..ce49605 100644 --- a/state_machine_exporter/src/test/resources/golden/OneStateMachineConfiguration/OneStateMachineConfiguration.scxml.xml +++ b/state_machine_exporter/src/test/resources/golden/OneStateMachineConfiguration/OneStateMachineConfiguration.scxml.xml @@ -140,9 +140,5 @@ - - - - diff --git a/state_machine_exporter/src/test/resources/golden/OrderStateMachineConfiguration/OrderStateMachineConfiguration.json b/state_machine_exporter/src/test/resources/golden/OrderStateMachineConfiguration/OrderStateMachineConfiguration.json index 86aa4b5..144c915 100644 --- a/state_machine_exporter/src/test/resources/golden/OrderStateMachineConfiguration/OrderStateMachineConfiguration.json +++ b/state_machine_exporter/src/test/resources/golden/OrderStateMachineConfiguration/OrderStateMachineConfiguration.json @@ -158,13 +158,21 @@ "stateMachineId" : null, "sourceState" : null, "lineNumber" : 81, - "polymorphicEvents" : [ "", "", "" ], + "polymorphicEvents" : [ "click.kamil.enterprise.machines.order.OrderEvent.PAY", "click.kamil.enterprise.machines.order.OrderEvent.SHIP" ], "external" : true, "constraint" : "\"ORDER\".equalsIgnoreCase(machineType)", "ambiguous" : false }, "contextMachineId" : null, - "matchedTransitions" : null + "matchedTransitions" : [ { + "sourceState" : "click.kamil.enterprise.machines.order.OrderState.NEW", + "targetState" : "click.kamil.enterprise.machines.order.OrderState.PENDING", + "event" : "click.kamil.enterprise.machines.order.OrderEvent.PAY" + }, { + "sourceState" : "click.kamil.enterprise.machines.order.OrderState.PENDING", + "targetState" : "click.kamil.enterprise.machines.order.OrderState.SHIPPED", + "event" : "click.kamil.enterprise.machines.order.OrderEvent.SHIP" + } ] } ], "properties" : { "default" : { } diff --git a/state_machine_exporter/src/test/resources/golden/OrderStateMachineConfiguration/OrderStateMachineConfiguration.puml b/state_machine_exporter/src/test/resources/golden/OrderStateMachineConfiguration/OrderStateMachineConfiguration.puml index e3e9cfc..97bbeb3 100644 --- a/state_machine_exporter/src/test/resources/golden/OrderStateMachineConfiguration/OrderStateMachineConfiguration.puml +++ b/state_machine_exporter/src/test/resources/golden/OrderStateMachineConfiguration/OrderStateMachineConfiguration.puml @@ -21,12 +21,12 @@ skinparam ArrowThickness 1 skinparam dpi 110 skinparam svgLinkTarget _self -[*] --> click.kamil.enterprise.machines.order.OrderState.NEW +[*] --> OrderState.NEW OrderState.NEW -[#1E90FF,bold]-> OrderState.PENDING <> : OrderEvent.PAY / λ OrderState.PENDING -[#1E90FF,bold]-> OrderState.SHIPPED <> : OrderEvent.SHIP -click.kamil.enterprise.machines.order.OrderState.SHIPPED --> [*] +OrderState.SHIPPED --> [*] @enduml diff --git a/state_machine_exporter/src/test/resources/golden/OrderStateMachineConfiguration/OrderStateMachineConfiguration.scxml.xml b/state_machine_exporter/src/test/resources/golden/OrderStateMachineConfiguration/OrderStateMachineConfiguration.scxml.xml index 595297f..e05c8a3 100644 --- a/state_machine_exporter/src/test/resources/golden/OrderStateMachineConfiguration/OrderStateMachineConfiguration.scxml.xml +++ b/state_machine_exporter/src/test/resources/golden/OrderStateMachineConfiguration/OrderStateMachineConfiguration.scxml.xml @@ -8,9 +8,5 @@ - - - - diff --git a/state_machine_exporter/src/test/resources/golden/PolymorphicStateMachineConfiguration/PolymorphicStateMachineConfiguration.puml b/state_machine_exporter/src/test/resources/golden/PolymorphicStateMachineConfiguration/PolymorphicStateMachineConfiguration.puml index d2ccdae..8fae88b 100644 --- a/state_machine_exporter/src/test/resources/golden/PolymorphicStateMachineConfiguration/PolymorphicStateMachineConfiguration.puml +++ b/state_machine_exporter/src/test/resources/golden/PolymorphicStateMachineConfiguration/PolymorphicStateMachineConfiguration.puml @@ -21,7 +21,7 @@ skinparam ArrowThickness 1 skinparam dpi 110 skinparam svgLinkTarget _self -[*] --> click.kamil.examples.statemachine.polymorphic.OrderStates.SUBMITTED +[*] --> OrderStates.SUBMITTED OrderStates.SUBMITTED -[#1E90FF,bold]-> OrderStates.PAID <> : OrderEvents.PAY @@ -29,7 +29,7 @@ OrderStates.PAID -[#1E90FF,bold]-> OrderStates.FULFILLED <> : OrderEve OrderStates.SUBMITTED -[#1E90FF,bold]-> OrderStates.CANCELED <> : OrderEvents.CANCEL OrderStates.PAID -[#1E90FF,bold]-> OrderStates.CANCELED <> : OrderEvents.ABCD -click.kamil.examples.statemachine.polymorphic.OrderStates.CANCELED --> [*] -click.kamil.examples.statemachine.polymorphic.OrderStates.FULFILLED --> [*] +OrderStates.CANCELED --> [*] +OrderStates.FULFILLED --> [*] @enduml diff --git a/state_machine_exporter/src/test/resources/golden/PolymorphicStateMachineConfiguration/PolymorphicStateMachineConfiguration.scxml.xml b/state_machine_exporter/src/test/resources/golden/PolymorphicStateMachineConfiguration/PolymorphicStateMachineConfiguration.scxml.xml index 119b96c..1e13798 100644 --- a/state_machine_exporter/src/test/resources/golden/PolymorphicStateMachineConfiguration/PolymorphicStateMachineConfiguration.scxml.xml +++ b/state_machine_exporter/src/test/resources/golden/PolymorphicStateMachineConfiguration/PolymorphicStateMachineConfiguration.scxml.xml @@ -12,11 +12,5 @@ - - - - - - diff --git a/state_machine_exporter/src/test/resources/golden/SimpleEnumStateMachineConfiguration/SimpleEnumStateMachineConfiguration.puml b/state_machine_exporter/src/test/resources/golden/SimpleEnumStateMachineConfiguration/SimpleEnumStateMachineConfiguration.puml index fd5ca24..82cada7 100644 --- a/state_machine_exporter/src/test/resources/golden/SimpleEnumStateMachineConfiguration/SimpleEnumStateMachineConfiguration.puml +++ b/state_machine_exporter/src/test/resources/golden/SimpleEnumStateMachineConfiguration/SimpleEnumStateMachineConfiguration.puml @@ -21,7 +21,7 @@ skinparam ArrowThickness 1 skinparam dpi 110 skinparam svgLinkTarget _self -[*] --> click.kamil.examples.statemachine.simple.OrderStates.SUBMITTED +[*] --> OrderStates.SUBMITTED state OrderStates.SUBMITTED <> state OrderStates.PAID <> @@ -41,7 +41,7 @@ OrderStates.PAID2 -[#1E90FF,bold]-> OrderStates.CANCELED <> OrderStates.PAID3 -[#1E90FF,bold]-> OrderStates.CANCELED <> OrderStates.PAID1 -[#1E90FF,bold]-> OrderStates.PAID1 <> : OrderEvents.ABCD / λ, action2 -click.kamil.examples.statemachine.simple.OrderStates.CANCELED --> [*] -click.kamil.examples.statemachine.simple.OrderStates.FULFILLED --> [*] +OrderStates.CANCELED --> [*] +OrderStates.FULFILLED --> [*] @enduml diff --git a/state_machine_exporter/src/test/resources/golden/SimpleEnumStateMachineConfiguration/SimpleEnumStateMachineConfiguration.scxml.xml b/state_machine_exporter/src/test/resources/golden/SimpleEnumStateMachineConfiguration/SimpleEnumStateMachineConfiguration.scxml.xml index 1e1240f..b05bfca 100644 --- a/state_machine_exporter/src/test/resources/golden/SimpleEnumStateMachineConfiguration/SimpleEnumStateMachineConfiguration.scxml.xml +++ b/state_machine_exporter/src/test/resources/golden/SimpleEnumStateMachineConfiguration/SimpleEnumStateMachineConfiguration.scxml.xml @@ -42,11 +42,5 @@ - - - - - - diff --git a/state_machine_exporter/src/test/resources/golden/StandardDocumentStateMachineConfiguration/StandardDocumentStateMachineConfiguration.puml b/state_machine_exporter/src/test/resources/golden/StandardDocumentStateMachineConfiguration/StandardDocumentStateMachineConfiguration.puml index dec2f30..b5b833a 100644 --- a/state_machine_exporter/src/test/resources/golden/StandardDocumentStateMachineConfiguration/StandardDocumentStateMachineConfiguration.puml +++ b/state_machine_exporter/src/test/resources/golden/StandardDocumentStateMachineConfiguration/StandardDocumentStateMachineConfiguration.puml @@ -21,14 +21,14 @@ skinparam ArrowThickness 1 skinparam dpi 110 skinparam svgLinkTarget _self -[*] --> click.kamil.examples.statemachine.layered.document.DocumentState.DRAFT +[*] --> DocumentState.DRAFT DocumentState.DRAFT -[#1E90FF,bold]-> DocumentState.SUBMITTED <> : DocumentTransitionEvent.SUBMIT DocumentState.SUBMITTED -[#1E90FF,bold]-> DocumentState.APPROVED <> : DocumentTransitionEvent.APPROVE DocumentState.SUBMITTED -[#1E90FF,bold]-> DocumentState.REJECTED <> : DocumentTransitionEvent.REJECT -click.kamil.examples.statemachine.layered.document.DocumentState.REJECTED --> [*] -click.kamil.examples.statemachine.layered.document.DocumentState.APPROVED --> [*] +DocumentState.REJECTED --> [*] +DocumentState.APPROVED --> [*] @enduml diff --git a/state_machine_exporter/src/test/resources/golden/StandardDocumentStateMachineConfiguration/StandardDocumentStateMachineConfiguration.scxml.xml b/state_machine_exporter/src/test/resources/golden/StandardDocumentStateMachineConfiguration/StandardDocumentStateMachineConfiguration.scxml.xml index eaba648..8be6741 100644 --- a/state_machine_exporter/src/test/resources/golden/StandardDocumentStateMachineConfiguration/StandardDocumentStateMachineConfiguration.scxml.xml +++ b/state_machine_exporter/src/test/resources/golden/StandardDocumentStateMachineConfiguration/StandardDocumentStateMachineConfiguration.scxml.xml @@ -11,11 +11,5 @@ - - - - - - diff --git a/state_machine_exporter/src/test/resources/golden/StandardOrderStateMachineConfiguration/StandardOrderStateMachineConfiguration.puml b/state_machine_exporter/src/test/resources/golden/StandardOrderStateMachineConfiguration/StandardOrderStateMachineConfiguration.puml index d0f48d5..772b5eb 100644 --- a/state_machine_exporter/src/test/resources/golden/StandardOrderStateMachineConfiguration/StandardOrderStateMachineConfiguration.puml +++ b/state_machine_exporter/src/test/resources/golden/StandardOrderStateMachineConfiguration/StandardOrderStateMachineConfiguration.puml @@ -21,14 +21,14 @@ skinparam ArrowThickness 1 skinparam dpi 110 skinparam svgLinkTarget _self -[*] --> click.kamil.examples.statemachine.layered.order.OrderState.NEW +[*] --> OrderState.NEW OrderState.NEW -[#1E90FF,bold]-> OrderState.PAID <> : OrderTransitionEvent.PAY OrderState.PAID -[#1E90FF,bold]-> OrderState.SHIPPED <> : OrderTransitionEvent.SHIP OrderState.PAID -[#1E90FF,bold]-> OrderState.CANCELLED <> : OrderTransitionEvent.CANCEL -click.kamil.examples.statemachine.layered.order.OrderState.SHIPPED --> [*] -click.kamil.examples.statemachine.layered.order.OrderState.CANCELLED --> [*] +OrderState.SHIPPED --> [*] +OrderState.CANCELLED --> [*] @enduml diff --git a/state_machine_exporter/src/test/resources/golden/StandardOrderStateMachineConfiguration/StandardOrderStateMachineConfiguration.scxml.xml b/state_machine_exporter/src/test/resources/golden/StandardOrderStateMachineConfiguration/StandardOrderStateMachineConfiguration.scxml.xml index 295e6d9..71ef772 100644 --- a/state_machine_exporter/src/test/resources/golden/StandardOrderStateMachineConfiguration/StandardOrderStateMachineConfiguration.scxml.xml +++ b/state_machine_exporter/src/test/resources/golden/StandardOrderStateMachineConfiguration/StandardOrderStateMachineConfiguration.scxml.xml @@ -11,11 +11,5 @@ - - - - - - diff --git a/state_machine_exporter/src/test/resources/golden/StateMachineConfig/StateMachineConfig.puml b/state_machine_exporter/src/test/resources/golden/StateMachineConfig/StateMachineConfig.puml index aefe028..c9cfecb 100644 --- a/state_machine_exporter/src/test/resources/golden/StateMachineConfig/StateMachineConfig.puml +++ b/state_machine_exporter/src/test/resources/golden/StateMachineConfig/StateMachineConfig.puml @@ -21,7 +21,7 @@ skinparam ArrowThickness 1 skinparam dpi 110 skinparam svgLinkTarget _self -[*] --> click.kamil.domain.OrderState.NEW +[*] --> OrderState.NEW OrderState.NEW -[#1E90FF,bold]-> OrderState.PROCESSING <> : OrderEvent.PROCESS @@ -29,7 +29,7 @@ OrderState.PROCESSING -[#1E90FF,bold]-> OrderState.COMPLETED <> : Orde OrderState.NEW -[#1E90FF,bold]-> OrderState.CANCELLED <> : OrderEvent.CANCEL OrderState.PROCESSING -[#1E90FF,bold]-> OrderState.CANCELLED <> : OrderEvent.CANCEL -click.kamil.domain.OrderState.COMPLETED --> [*] -click.kamil.domain.OrderState.CANCELLED --> [*] +OrderState.COMPLETED --> [*] +OrderState.CANCELLED --> [*] @enduml diff --git a/state_machine_exporter/src/test/resources/golden/StateMachineConfig/StateMachineConfig.scxml.xml b/state_machine_exporter/src/test/resources/golden/StateMachineConfig/StateMachineConfig.scxml.xml index eff71a9..c661eba 100644 --- a/state_machine_exporter/src/test/resources/golden/StateMachineConfig/StateMachineConfig.scxml.xml +++ b/state_machine_exporter/src/test/resources/golden/StateMachineConfig/StateMachineConfig.scxml.xml @@ -12,11 +12,5 @@ - - - - - - diff --git a/state_machine_exporter/src/test/resources/golden/ThreeStateMachineConfiguration/ThreeStateMachineConfiguration.puml b/state_machine_exporter/src/test/resources/golden/ThreeStateMachineConfiguration/ThreeStateMachineConfiguration.puml index 34e2cdf..dcb4963 100644 --- a/state_machine_exporter/src/test/resources/golden/ThreeStateMachineConfiguration/ThreeStateMachineConfiguration.puml +++ b/state_machine_exporter/src/test/resources/golden/ThreeStateMachineConfiguration/ThreeStateMachineConfiguration.puml @@ -21,7 +21,7 @@ skinparam ArrowThickness 1 skinparam dpi 110 skinparam svgLinkTarget _self -[*] --> click.kamil.examples.statemachine.inheritanceextrafunctionsstate2.States.STATE1 +[*] --> States.STATE1 state States.STATEY <> state States.STATE16 <> @@ -89,6 +89,6 @@ States.STATE_EXTRA_1 -[#1E90FF,bold]-> States.STATE_EXTRA_3 <> : Event States.STATE_EXTRA_1 -[#1E90FF,bold]-> States.CANCEL <> : Events.EVENT_CANCEL_2 States.STATE_EXTRA_2 -[#1E90FF,bold]-> States.CANCEL <> : Events.EVENT_CANCEL_2 -click.kamil.examples.statemachine.inheritanceextrafunctionsstate2.States.STATEZ --> [*] +States.STATEZ --> [*] @enduml diff --git a/state_machine_exporter/src/test/resources/golden/ThreeStateMachineConfiguration/ThreeStateMachineConfiguration.scxml.xml b/state_machine_exporter/src/test/resources/golden/ThreeStateMachineConfiguration/ThreeStateMachineConfiguration.scxml.xml index 83a22a2..2b81fe0 100644 --- a/state_machine_exporter/src/test/resources/golden/ThreeStateMachineConfiguration/ThreeStateMachineConfiguration.scxml.xml +++ b/state_machine_exporter/src/test/resources/golden/ThreeStateMachineConfiguration/ThreeStateMachineConfiguration.scxml.xml @@ -160,9 +160,5 @@ - - - - diff --git a/state_machine_exporter/src/test/resources/golden/TwoStateMachineExtraFunctionsConfiguration/TwoStateMachineConfiguration.puml b/state_machine_exporter/src/test/resources/golden/TwoStateMachineExtraFunctionsConfiguration/TwoStateMachineConfiguration.puml index c92403d..be25fa3 100644 --- a/state_machine_exporter/src/test/resources/golden/TwoStateMachineExtraFunctionsConfiguration/TwoStateMachineConfiguration.puml +++ b/state_machine_exporter/src/test/resources/golden/TwoStateMachineExtraFunctionsConfiguration/TwoStateMachineConfiguration.puml @@ -21,7 +21,7 @@ skinparam ArrowThickness 1 skinparam dpi 110 skinparam svgLinkTarget _self -[*] --> click.kamil.examples.statemachine.inheritanceextrafunctionsstate.States.STATE1 +[*] --> States.STATE1 state States.STATEY <> state States.STATE16 <> @@ -85,6 +85,6 @@ States.STATE5 -[#1E90FF,bold]-> States.STATE_EXTRA_1 <> : Events.EVENT States.STATE_EXTRA_1 -[#1E90FF,bold]-> States.CANCEL <> : Events.EVENT_CANCEL States.STATE_EXTRA_1 -[#1E90FF,bold]-> States.CANCEL <> : Events.EVENT_CANCEL_2 -click.kamil.examples.statemachine.inheritanceextrafunctionsstate.States.STATEZ --> [*] +States.STATEZ --> [*] @enduml diff --git a/state_machine_exporter/src/test/resources/golden/TwoStateMachineExtraFunctionsConfiguration/TwoStateMachineConfiguration.scxml.xml b/state_machine_exporter/src/test/resources/golden/TwoStateMachineExtraFunctionsConfiguration/TwoStateMachineConfiguration.scxml.xml index df0a692..4f9b7c7 100644 --- a/state_machine_exporter/src/test/resources/golden/TwoStateMachineExtraFunctionsConfiguration/TwoStateMachineConfiguration.scxml.xml +++ b/state_machine_exporter/src/test/resources/golden/TwoStateMachineExtraFunctionsConfiguration/TwoStateMachineConfiguration.scxml.xml @@ -149,9 +149,5 @@ - - - - diff --git a/state_machine_exporter/src/test/resources/golden/UserStateMachineConfiguration/UserStateMachineConfiguration.json b/state_machine_exporter/src/test/resources/golden/UserStateMachineConfiguration/UserStateMachineConfiguration.json index 24e9401..2fa1605 100644 --- a/state_machine_exporter/src/test/resources/golden/UserStateMachineConfiguration/UserStateMachineConfiguration.json +++ b/state_machine_exporter/src/test/resources/golden/UserStateMachineConfiguration/UserStateMachineConfiguration.json @@ -151,13 +151,21 @@ "stateMachineId" : null, "sourceState" : null, "lineNumber" : 93, - "polymorphicEvents" : [ "", "", "" ], + "polymorphicEvents" : [ "click.kamil.enterprise.machines.user.UserEvent.REGISTER", "click.kamil.enterprise.machines.user.UserEvent.VERIFY", "click.kamil.enterprise.machines.user.UserEvent.SUSPEND" ], "external" : true, "constraint" : "!(\"ORDER\".equalsIgnoreCase(machineType)) && !(\"DOCUMENT\".equalsIgnoreCase(machineType)) && \"USER\".equalsIgnoreCase(machineType)", "ambiguous" : false }, "contextMachineId" : null, - "matchedTransitions" : null + "matchedTransitions" : [ { + "sourceState" : "click.kamil.enterprise.machines.user.UserState.GUEST", + "targetState" : "click.kamil.enterprise.machines.user.UserState.REGISTERED", + "event" : "click.kamil.enterprise.machines.user.UserEvent.REGISTER" + }, { + "sourceState" : "click.kamil.enterprise.machines.user.UserState.REGISTERED", + "targetState" : "click.kamil.enterprise.machines.user.UserState.VERIFIED", + "event" : "click.kamil.enterprise.machines.user.UserEvent.VERIFY" + } ] } ], "properties" : { "default" : { } diff --git a/state_machine_exporter/src/test/resources/golden/UserStateMachineConfiguration/UserStateMachineConfiguration.puml b/state_machine_exporter/src/test/resources/golden/UserStateMachineConfiguration/UserStateMachineConfiguration.puml index 113b1bd..366ce20 100644 --- a/state_machine_exporter/src/test/resources/golden/UserStateMachineConfiguration/UserStateMachineConfiguration.puml +++ b/state_machine_exporter/src/test/resources/golden/UserStateMachineConfiguration/UserStateMachineConfiguration.puml @@ -21,12 +21,12 @@ skinparam ArrowThickness 1 skinparam dpi 110 skinparam svgLinkTarget _self -[*] --> click.kamil.enterprise.machines.user.UserState.GUEST +[*] --> UserState.GUEST UserState.GUEST -[#1E90FF,bold]-> UserState.REGISTERED <> : UserEvent.REGISTER UserState.REGISTERED -[#1E90FF,bold]-> UserState.VERIFIED <> : UserEvent.VERIFY -click.kamil.enterprise.machines.user.UserState.VERIFIED --> [*] +UserState.VERIFIED --> [*] @enduml diff --git a/state_machine_exporter/src/test/resources/golden/UserStateMachineConfiguration/UserStateMachineConfiguration.scxml.xml b/state_machine_exporter/src/test/resources/golden/UserStateMachineConfiguration/UserStateMachineConfiguration.scxml.xml index 7090f43..b70b364 100644 --- a/state_machine_exporter/src/test/resources/golden/UserStateMachineConfiguration/UserStateMachineConfiguration.scxml.xml +++ b/state_machine_exporter/src/test/resources/golden/UserStateMachineConfiguration/UserStateMachineConfiguration.scxml.xml @@ -8,9 +8,5 @@ - - - - diff --git a/state_machine_exporter_html/src/test/java/click/kamil/springstatemachineexporter/html/HtmlTransitionLinkConsistencyTest.java b/state_machine_exporter_html/src/test/java/click/kamil/springstatemachineexporter/html/HtmlTransitionLinkConsistencyTest.java index 9d365e6..0bde92a 100644 --- a/state_machine_exporter_html/src/test/java/click/kamil/springstatemachineexporter/html/HtmlTransitionLinkConsistencyTest.java +++ b/state_machine_exporter_html/src/test/java/click/kamil/springstatemachineexporter/html/HtmlTransitionLinkConsistencyTest.java @@ -88,6 +88,31 @@ class HtmlTransitionLinkConsistencyTest { assertThat(html).contains("com.example.order.OrderEvent.PAY"); } + @Test + void htmlShouldNotRenderDuplicateStateNodesForPackageCanonicalStartStates(@TempDir Path tempDir) throws Exception { + writeSampleProject(tempDir); + + AnalysisResult finalizedShape = AnalysisResult.builder() + .name("com.example.config.OrderStateMachineConfiguration") + .stateTypeFqn("com.example.order.OrderState") + .eventTypeFqn("com.example.order.OrderEvent") + .transitions(List.of(shortTransition( + "com.example.order.OrderEvent.PAY", + "com.example.order.OrderState.NEW", + "com.example.order.OrderState.PAID"))) + .startStates(Set.of("com.example.order.OrderState.NEW")) + .endStates(Set.of("com.example.order.OrderState.PAID")) + .build(); + + String html = new HtmlExporter().export(finalizedShape, ExportOptions.builder().build()); + String svg = extractSvg(html); + + assertThat(svg).contains("OrderState.NEW"); + assertThat(svg).contains("OrderState.PAID"); + assertThat(svg).doesNotContain("com.example.order.OrderState.NEW"); + assertThat(svg).doesNotContain("com.example.order.OrderState.PAID"); + } + @Test void enterpriseAstExportHtmlShouldContainTransitionLinkKeys(@TempDir Path tempDir) throws Exception { Path enterprise = findProjectRoot().resolve("state_machines/state_machine_enterprise"); @@ -169,6 +194,15 @@ class HtmlTransitionLinkConsistencyTest { """); } + private static String extractSvg(String html) { + int start = html.indexOf(""); + if (start < 0 || end < 0) { + return html; + } + return html.substring(start, end + "".length()); + } + private static Path findProjectRoot() { Path current = Path.of(".").toAbsolutePath(); while (current != null && !Files.exists(current.resolve("settings.gradle"))) {