Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions source/.editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
# - https://github.com/dotnet/roslyn/blob/main/.editorconfig
# - https://github.com/microsoft/microsoft-ui-xaml/blob/master/.editorconfig
# - https://learn.microsoft.com/en-us/visualstudio/ide/cpp-editorconfig-properties
#
# - https://learn.microsoft.com/en-us/visualstudio/ide/text-spell-checker?view=visualstudio

# Top-most EditorConfig file
root = true
Expand All @@ -40,10 +40,16 @@ root = true
end_of_line = crlf
indent_style = space

# Visual Studio's Spell Checker (Edit > Advanced > Toggle Spell Checker)
spelling_languages = en-us
spelling_checkable_types = strings,identifiers,comments
spelling_error_severity = information
spelling_exclusion_path = ./exclusion.dic

# VSSPELL: Spell checker settings for all files
vsspell_section_id = 001
#vsspell_ignored_words_001 = \transform|csharp|Guid|ble|html|htmlx|hunspells|jquery|json|mimetype|nav|plaintext|resheader|Suess|Soll|uuid|xaml|xml
vsspell_ignored_words_001 = File:IgnoredWords.dic
vsspell_ignored_words_001 = File:exclusion.dic
vsspell_dictionary_languages_001 = en-US
vsspell_exclusion_expressions_001 = [a-z]{2}-([A-Z]{2}|Cyrl|Latn)(?@@PND@@/Options/None)\\\\\w+(?@@PND@@/Options/None)

Expand Down
71 changes: 0 additions & 71 deletions source/Lite.State.Tests/SimpleStateTests/Test1.cs

This file was deleted.

110 changes: 110 additions & 0 deletions source/Lite.State.Tests/StateTests/CompositeStateTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
// Copyright Xeno Innovations, Inc. 2025
// See the LICENSE file in the project root for more information.

namespace Lite.State.Tests.StateTests;

[TestClass]
public class CompositeStateTest
{
public const string PARAM_SUB_ENTERED = "SubEntered";
public const string SUCCESS = "success";

public enum StateId
{
State1,
State2,
State2_Sub1,
State2_Sub2,
State3,
}

[TestMethod]
public void TransitionWithErrorToSuccessTest()
{
// Assemble
var machine = new StateMachine<StateId>();
machine.RegisterState(new State1(StateId.State1));
machine.RegisterState(new State2(StateId.State2));

// Sub-state machine (Composite State + children
// POC - Register Initial: var comState2 = new State2(StateId.State2, StateId.State2_Sub1);
var comState2 = new State2(StateId.State2);
machine.RegisterState(comState2);
var subMachine = comState2.Submachine;
subMachine.RegisterState(new State2_Sub1(StateId.State2_Sub1));
subMachine.RegisterState(new State2_Sub2(StateId.State2_Sub2));

machine.RegisterState(new State3(StateId.State3));

// Configure initial states
machine.SetInitial(StateId.State1);
subMachine.SetInitial(StateId.State2_Sub1);

// Act
machine.Start();

// Assert
var ctxFinal = machine.Context.Parameters;
Assert.IsNotNull(ctxFinal);
Assert.AreEqual(SUCCESS, ctxFinal[PARAM_SUB_ENTERED]);
}

private class State1 : BaseState<StateId>
{
public State1(StateId id) : base(id)
{
AddTransition(Result.Ok, StateId.State2);
}

public override void OnEnter(Context<StateId> context) =>
context.NextState(Result.Ok);
}

/// <summary>Composite Parent State.</summary>
private class State2 : CompositeState<StateId>
{
/// <param name="id"></param>
public State2(StateId id) : base(id)
{
AddTransition(Result.Ok, StateId.State3);
}

public override void OnEnter(Context<StateId> context) =>
context.NextState(Result.Ok);
}

private class State2_Sub1 : BaseState<StateId>
{
public State2_Sub1(StateId id) : base(id)
{
AddTransition(Result.Ok, StateId.State2_Sub2);
}

public override void OnEnter(Context<StateId> context)
{
context.Parameters.Add(PARAM_SUB_ENTERED, SUCCESS);
context.NextState(Result.Ok);
}
}

private class State2_Sub2 : BaseState<StateId>
{
public State2_Sub2(StateId id) : base(id)
{
// NOTE: We're not defining the 'NextState' intentionally
// to demonstrate the bubble-up
}

public override void OnEnter(Context<StateId> context) =>
context.NextState(Result.Ok);
}

private class State3(StateId id)
: BaseState<StateId>(id)
{
public override void OnEnter(Context<StateId> context)
{
// context.NextState(Result.Ok);
}
}
}
101 changes: 101 additions & 0 deletions source/Lite.State.Tests/StateTests/ErrorStateExTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
// Copyright Xeno Innovations, Inc. 2025
// See the LICENSE file in the project root for more information.

using System;

namespace Lite.State.Tests.StateTests;

[TestClass]
public class ErrorStateExTest
{
public const string PARAM_TEST = "param1";
public const string SUCCESS = "success";

public enum StateId
{
State1,
State2,
State2Error,
State3,
}

[TestMethod]
public void TransitionWithErrorToSuccessTest()
{
// Assemble
var machine = new StateMachine<StateId>()
.RegisterStateEx(new State1(StateId.State1), StateId.State2)
.RegisterStateEx(new State2(StateId.State2), StateId.State3, StateId.State2Error)
.RegisterStateEx(new State2Error(StateId.State2Error), StateId.State2)
.RegisterStateEx(new State3(StateId.State3));

// Set starting point
machine.SetInitial(StateId.State1);

// Act - Start your engine!
var ctxProperties = new PropertyBag() { { PARAM_TEST, "not-finished" }, };
machine.Start(ctxProperties);

// Assert Results
var ctxFinalParams = machine.Context.Parameters;

Assert.IsNotNull(ctxFinalParams);
Assert.AreEqual(SUCCESS, ctxFinalParams[PARAM_TEST]);
}

//// private class State1 : IState<BasicStateTest.BasicFsm>
private class State1(StateId id)
: BaseState<StateId>(id)
{
public override void OnEnter(Context<StateId> context)
{
Console.WriteLine("[State1] OnEntering");
context.NextState(Result.Ok);
}
}

private class State2(StateId id)
: BaseState<StateId>(id)
{
private int _counter = 0;

public override void OnEnter(Context<StateId> context)
{
_counter++;
Console.WriteLine($"[State2] OnEntering: Counter={_counter}");

// On first pass, simulate an "error"
// We'll come back again a second time and succeed.
if (_counter == 1)
context.NextState(Result.Error);
else
context.NextState(Result.Ok);
}
}

/// <summary>Simulated error state handler, goes back to State2.</summary>
private class State2Error(StateId id)
: BaseState<StateId>(id)
{
public override void OnEnter(Context<StateId> context)
{
Console.WriteLine("[State2Error] OnEntering");
context.NextState(Result.Ok);
}
}

private class State3(StateId id)
: BaseState<StateId>(id)
{
public override void OnEntering(Context<StateId> context)
{
context.Parameters[PARAM_TEST] = SUCCESS;
Console.WriteLine("[State3] OnEntering");
}

public override void OnEnter(Context<StateId> context)
{
context.NextState(Result.Ok);
}
}
}
Loading