diff --git a/src/Stateless/StateRepresentation.cs b/src/Stateless/StateRepresentation.cs index 6c306553..5f372aa2 100644 --- a/src/Stateless/StateRepresentation.cs +++ b/src/Stateless/StateRepresentation.cs @@ -320,12 +320,23 @@ public IEnumerable PermittedTriggers public IEnumerable GetPermittedTriggers(params object[] args) { - var result = TriggerBehaviours - .Where(t => t.Value.Any(a => !a.UnmetGuardConditions(args).Any())) - .Select(t => t.Key); + var result = new HashSet(); + foreach (var triggerBehaviour in TriggerBehaviours) + { + try + { + if (triggerBehaviour.Value.Any(a => !a.UnmetGuardConditions(args).Any())) + result.Add(triggerBehaviour.Key); + } + catch (Exception) + { + //Ignore + //There is no need to throw an exception when trying to get the Permitted Triggers. If it's not valid just don't return it. + } + } if (Superstate != null) - result = result.Union(Superstate.GetPermittedTriggers(args)); + result.UnionWith(Superstate.GetPermittedTriggers(args)); return result; } diff --git a/test/Stateless.Tests/Trigger.cs b/test/Stateless.Tests/Trigger.cs index 2fa9959b..11b663e3 100644 --- a/test/Stateless.Tests/Trigger.cs +++ b/test/Stateless.Tests/Trigger.cs @@ -4,4 +4,15 @@ enum Trigger { X, Y, Z } + class FirstFakeTrigger + { + public bool IsAllowed { get; set; } + } + + + + class SecondFakeTrigger + { + public bool IsOk { get; set; } + } } diff --git a/test/Stateless.Tests/TriggerWithParametersFixture.cs b/test/Stateless.Tests/TriggerWithParametersFixture.cs index 8d92f147..66e75182 100644 --- a/test/Stateless.Tests/TriggerWithParametersFixture.cs +++ b/test/Stateless.Tests/TriggerWithParametersFixture.cs @@ -104,5 +104,39 @@ public void Arguments_Returs_Three_Arguments() Assert.Equal(typeof(string), args[1]); Assert.Equal(typeof(List), args[2]); } + + [Fact] + public void GetPermittedTriggersShouldAcceptStronglyTypedTriggersWithConditionalGuardsConfigurations() + { + var stateMachine = new StateMachine(State.A); + var firstTrigger = new StateMachine.TriggerWithParameters(Trigger.X); + var secondTrigger = new StateMachine.TriggerWithParameters(Trigger.Y); + + stateMachine.Configure(State.A) + .PermitIf(firstTrigger, State.B, trigger => trigger.IsAllowed) + .PermitIf(secondTrigger, State.C, trigger => trigger.IsOk); + + var fakeTriggers = new List() + { + new FirstFakeTrigger + { + IsAllowed = true + }, + new SecondFakeTrigger + { + IsOk = false + }, + }; + + var availableTriggers = new List(); + foreach (var fakeTrigger in fakeTriggers) + { + var temp = stateMachine.GetPermittedTriggers(fakeTrigger); + availableTriggers.AddRange(temp); + } + + Assert.Contains(Trigger.X, availableTriggers); + Assert.DoesNotContain(Trigger.Y, availableTriggers); + } } }