Skip to content
19 changes: 15 additions & 4 deletions src/Stateless/StateRepresentation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -320,12 +320,23 @@ public IEnumerable<TTrigger> PermittedTriggers

public IEnumerable<TTrigger> 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<TTrigger>();
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;
}
Expand Down
11 changes: 11 additions & 0 deletions test/Stateless.Tests/Trigger.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,15 @@ enum Trigger
{
X, Y, Z
}
class FirstFakeTrigger
{
public bool IsAllowed { get; set; }
}



class SecondFakeTrigger
{
public bool IsOk { get; set; }
}
}
34 changes: 34 additions & 0 deletions test/Stateless.Tests/TriggerWithParametersFixture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -104,5 +104,39 @@ public void Arguments_Returs_Three_Arguments()
Assert.Equal(typeof(string), args[1]);
Assert.Equal(typeof(List<bool>), args[2]);
}

[Fact]
public void GetPermittedTriggersShouldAcceptStronglyTypedTriggersWithConditionalGuardsConfigurations()
{
var stateMachine = new StateMachine<State, Trigger>(State.A);
var firstTrigger = new StateMachine<State, Trigger>.TriggerWithParameters<FirstFakeTrigger>(Trigger.X);
var secondTrigger = new StateMachine<State, Trigger>.TriggerWithParameters<SecondFakeTrigger>(Trigger.Y);

stateMachine.Configure(State.A)
.PermitIf(firstTrigger, State.B, trigger => trigger.IsAllowed)
.PermitIf(secondTrigger, State.C, trigger => trigger.IsOk);

var fakeTriggers = new List<object>()
{
new FirstFakeTrigger
{
IsAllowed = true
},
new SecondFakeTrigger
{
IsOk = false
},
};

var availableTriggers = new List<Trigger>();
foreach (var fakeTrigger in fakeTriggers)
{
var temp = stateMachine.GetPermittedTriggers(fakeTrigger);
availableTriggers.AddRange(temp);
}

Assert.Contains(Trigger.X, availableTriggers);
Assert.DoesNotContain(Trigger.Y, availableTriggers);
}
}
}