Skip to content

Instantly share code, notes, and snippets.

@HCanber
Created September 15, 2014 13:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save HCanber/e3d8ec8129b0d2721708 to your computer and use it in GitHub Desktop.
Save HCanber/e3d8ec8129b0d2721708 to your computer and use it in GitHub Desktop.
Better FSM spec for Akka.NET
using System;
using Akka.Event;
namespace AkkaTestDemo
{
public enum MoodStates
{
Neutral,
Happy,
Angry
}
public interface MoodData { }
public class MoodActor : ExtendedFSM<MoodStates, MoodData>
{
public MoodActor()
{
StartWith(MoodStates.Neutral, null);
InState(MoodStates.Neutral)
.OnMessage<string>(s => (string)s.FsmEvent == "Mood?")
.StayWithReply("I'm neutral")
.OnMessage<string>(s => (string)s.FsmEvent == "Happy")
.Goto(MoodStates.Happy)
.OnMessage<string>(s => (string)s.FsmEvent == "Angry")
.Goto(MoodStates.Angry);
InState(MoodStates.Happy)
.OnMessage<string>(s => (string)s.FsmEvent == "Mood?")
.StayWithReply("I'm happy")
.OnMessage<string>(s => (string)s.FsmEvent == "Happy")
.Stay()
.OnMessage<string>(s => (string)s.FsmEvent == "Angry")
.Goto(MoodStates.Angry);
InState(MoodStates.Angry, timeout: TimeSpan.FromSeconds(1))
.OnMessage<string>(s => (string)s.FsmEvent == "Mood?")
.StayWithReply("I'm ANGRY!!!!")
.OnMessage<string>(s => (string)s.FsmEvent == "Happy")
.Goto(MoodStates.Happy)
.OnMessage<string>(s => (string)s.FsmEvent == "Angry")
.Stay()
.OnTimeout()
.Goto(MoodStates.Neutral);
var logger = Logging.GetLogger(Context);
OnTransitionTo(MoodStates.Angry, from =>
{
logger.Info("Oh, I was so " + from + " and then someone made me angry!");
});
OnTransition(MoodStates.Angry, MoodStates.Neutral, () =>
{
logger.Info("Snapping out of it");
});
}
}
}
using System;
using Akka.Actor;
using Akka.TestKit;
using Akka.TestKit.Xunit;
using Xunit;
namespace AkkaTestDemo.Tests
{
public class MoodActorTests : TestKit
{
[Fact]
public void Neutral_to_begin_with()
{
var moodActor = Sys.ActorOf<MoodActor>();
moodActor.Tell("Mood?");
ExpectMsg("I'm neutral");
}
[Fact]
public void Testing_states()
{
var moodActor = Sys.ActorOf<MoodActor>();
moodActor.Tell("Happy");
moodActor.Tell("Mood?");
ExpectMsg("I'm happy");
moodActor.Tell("Happy");
moodActor.Tell("Mood?");
ExpectMsg("I'm happy");
moodActor.Tell("Angry");
moodActor.Tell("Mood?");
ExpectMsg("I'm ANGRY!!!!");
}
[Fact]
public void Testing_snapping_out()
{
var moodActor = TestFSMRef.Create<MoodActor, MoodStates, MoodData>(Sys);
moodActor.Tell("Angry");
AwaitCondition(() => moodActor.UnderlyingActor.StateName == MoodStates.Neutral, TimeSpan.FromSeconds(2));
}
[Fact]
public void LogEvents_should_be_sent()
{
var moodActor = Sys.ActorOf<MoodActor>();
EventFilter.Info("Snapping out of it").ExpectOne(() =>
{
EventFilter.Info(start: "Oh, I was so").ExpectOne(() =>
{
moodActor.Tell("Angry");
});
});
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment