// // Licensed under the MIT License. See LICENSE file in the project root for full license information. // namespace MUnique.OpenMU.Tests; using MUnique.OpenMU.GameLogic; /// /// Tests for the state machine. /// [TestFixture] public class StateMachineTest { private StateMachine _stateMachine = null!; private State _initialState = null!; private State _isolatedState = null!; private State _nextState = null!; private State _finishedState = null!; /// /// Sets up the test data. /// [SetUp] public void SetUp() { this._initialState = new State(new Guid("ADBEC1FA-7DB8-4A80-B054-2297B20AF32B")) { Name = "Initial State", PossibleTransitions = new List(), }; this._nextState = new State(new Guid("9954D837-D5FC-4204-AD96-6BD9F19353EA")) { Name = "Next State", PossibleTransitions = new List(), }; this._initialState.PossibleTransitions.Add(this._nextState); this._nextState.PossibleTransitions.Add(this._initialState); this._finishedState = new State(new Guid("F3658D9E-581B-451A-9C35-92A6B13B8C64")) { Name = "Finished", }; this._nextState.PossibleTransitions.Add(this._finishedState); this._isolatedState = new State(new Guid("4D45D4B0-1CA5-4222-91CC-B05DC5D87D56")) { Name = "Isolated State", }; this._stateMachine = new StateMachine(this._initialState); } /// /// Tests if the transition to the next allowed state is successful. /// [Test] public async ValueTask TransitionToNextStateAsync() { var success = await this._stateMachine.TryAdvanceToAsync(this._nextState).ConfigureAwait(false); Assert.That(success, Is.True); Assert.That(this._stateMachine.CurrentState, Is.EqualTo(this._nextState)); Assert.That(this._stateMachine.Finished, Is.False); } /// /// Tests if the transition to an isolated state fails. /// [Test] public async ValueTask TransitionToIsolatedStateAsync() { var success = await this._stateMachine.TryAdvanceToAsync(this._isolatedState).ConfigureAwait(false); Assert.That(success, Is.False); Assert.That(this._stateMachine.CurrentState, Is.EqualTo(this._initialState)); } /// /// Tests if the transition to the finished state succeeds and if the state machine takes notice of it. /// [Test] public async ValueTask TransitionToFinishedStateAsync() { await this._stateMachine.TryAdvanceToAsync(this._nextState).ConfigureAwait(false); var success = await this._stateMachine.TryAdvanceToAsync(this._finishedState).ConfigureAwait(false); Assert.That(success, Is.True); Assert.That(this._stateMachine.CurrentState, Is.EqualTo(this._finishedState)); Assert.That(this._stateMachine.Finished, Is.True); } /// /// Tests if the state change event does get raised with the next state in the event arguments. /// [Test] public async ValueTask ChangesEventStateObjectAsync() { State? stateInEvent = null; this._stateMachine.StateChanges += async args => { stateInEvent = args.NextState; }; await this._stateMachine.TryAdvanceToAsync(this._nextState).ConfigureAwait(false); Assert.That(stateInEvent, Is.EqualTo(this._nextState)); } /// /// Tests the cancellation of state changes. /// [Test] public async ValueTask ChangesEventCancelsAsync() { this._stateMachine.StateChanges += async args => { args.Cancel = true; }; var success = await this._stateMachine.TryAdvanceToAsync(this._nextState).ConfigureAwait(false); Assert.That(success, Is.False); Assert.That(this._stateMachine.CurrentState, Is.EqualTo(this._initialState)); } /// /// Tests if the state change event does get raised. /// [Test] public async ValueTask ChangedEventAsync() { var stateChangeEventCalled = false; this._stateMachine.StateChanged += async _ => stateChangeEventCalled = true; await this._stateMachine.TryAdvanceToAsync(this._nextState).ConfigureAwait(false); Assert.That(stateChangeEventCalled, Is.True); } }