From 48ce60a7d845405bc5d62c55a2e66b17a226770b Mon Sep 17 00:00:00 2001 From: Mike Clift Date: Wed, 3 Jul 2024 21:51:56 +0100 Subject: [PATCH] Fix entry function being shown on internal transitions in dot graph output #587 --- src/Stateless/Graph/StateGraph.cs | 2 +- .../Reflection/FixedTransitionInfo.cs | 3 ++- src/Stateless/Reflection/TransitionInfo.cs | 5 ++++ test/Stateless.Tests/DotGraphFixture.cs | 24 +++++++++++++++++++ 4 files changed, 32 insertions(+), 2 deletions(-) diff --git a/src/Stateless/Graph/StateGraph.cs b/src/Stateless/Graph/StateGraph.cs index 3477bfd4..ec05045a 100644 --- a/src/Stateless/Graph/StateGraph.cs +++ b/src/Stateless/Graph/StateGraph.cs @@ -137,7 +137,7 @@ void AddTransitions(StateMachineInfo machineInfo) State toState = States[fix.DestinationState.UnderlyingState.ToString()]; if (fromState == toState) { - StayTransition stay = new StayTransition(fromState, fix.Trigger, fix.GuardConditionsMethodDescriptions, true); + StayTransition stay = new StayTransition(fromState, fix.Trigger, fix.GuardConditionsMethodDescriptions, !fix.IsInternalTransition); Transitions.Add(stay); fromState.Leaving.Add(stay); fromState.Arriving.Add(stay); diff --git a/src/Stateless/Reflection/FixedTransitionInfo.cs b/src/Stateless/Reflection/FixedTransitionInfo.cs index 0aed3ec9..60275476 100644 --- a/src/Stateless/Reflection/FixedTransitionInfo.cs +++ b/src/Stateless/Reflection/FixedTransitionInfo.cs @@ -15,7 +15,8 @@ internal static FixedTransitionInfo Create(StateMachine() : behaviour.Guard.Conditions.Select(c => c.MethodDescription) + ? new List() : behaviour.Guard.Conditions.Select(c => c.MethodDescription), + IsInternalTransition = behaviour is StateMachine.InternalTriggerBehaviour }; return transition; diff --git a/src/Stateless/Reflection/TransitionInfo.cs b/src/Stateless/Reflection/TransitionInfo.cs index 4cd53321..75ef1367 100644 --- a/src/Stateless/Reflection/TransitionInfo.cs +++ b/src/Stateless/Reflection/TransitionInfo.cs @@ -17,5 +17,10 @@ public abstract class TransitionInfo /// Returns a non-null but empty list if there are no guard conditions /// public IEnumerable GuardConditionsMethodDescriptions; + + /// + /// When true, the transition is internal and does not invoke the entry/exit actions of the state. + /// + public bool IsInternalTransition { get; protected set; } } } diff --git a/test/Stateless.Tests/DotGraphFixture.cs b/test/Stateless.Tests/DotGraphFixture.cs index b16234b4..784c262c 100644 --- a/test/Stateless.Tests/DotGraphFixture.cs +++ b/test/Stateless.Tests/DotGraphFixture.cs @@ -537,6 +537,30 @@ public void TransitionWithIgnoreAndEntry() Assert.Equal(expected, dotGraph); } + [Fact] + public void Internal_Transition_Does_Not_Show_Entry_Exit_Functions() + { + var expected = Prefix(Style.UML) + + Box(Style.UML, "A", new List { "DoEntry" }, new List { "DoExit" }) + + Line("A", "A", "X [Function]") + + suffix; + + var sm = new StateMachine(State.A); + + sm.Configure(State.A) + .OnEntry(x => { }, "DoEntry") + .OnExit(x => { }, "DoExit") + .InternalTransition(Trigger.X, x => { }); + + string dotGraph = UmlDotGraph.Format(sm.GetInfo()); + +#if WRITE_DOTS_TO_FOLDER + System.IO.File.WriteAllText(DestinationFolder + "Internal_Transition_Does_Not_Show_Entry_Exit_Functions.dot", dotGraph); +#endif + + Assert.Equal(expected, dotGraph); + } + [Fact] public void Initial_State_Not_Changed_After_Trigger_Fired() {