Skip to content
Closed
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
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

### Added

- Created state machine base class
31 changes: 31 additions & 0 deletions TJC.StateMachine.Tests/Mocks/RevolverMock.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
namespace TJC.StateMachine.Tests.Mocks
{
internal class RevolverMock() : StateMachineBase<RevolverStates>(RevolverStates.Loaded)
{
public int BulletsLoaded { get; private set; } = 6;

public bool TryShoot()
{
switch (State)
{
case RevolverStates.Empty:
return false;
case RevolverStates.Loaded:
BulletsLoaded--;
if (BulletsLoaded == 0)
State = RevolverStates.Empty;
return true;
default:
throw new InvalidOperationException(
$"Unknown State [{State}] for method {nameof(TryShoot)}"
);
}
}

public void Reload()
{
BulletsLoaded = 6;
State = RevolverStates.Loaded;
}
}
}
8 changes: 8 additions & 0 deletions TJC.StateMachine.Tests/Mocks/RevolverStates.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace TJC.StateMachine.Tests.Mocks
{
internal enum RevolverStates
{
Loaded,
Empty,
}
}
5 changes: 5 additions & 0 deletions TJC.StateMachine.Tests/TJC.StateMachine.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
<IsTestProject>true</IsTestProject>
<AppDesignerFolder>Tests</AppDesignerFolder>
</PropertyGroup>

<ItemGroup>
Expand All @@ -15,6 +16,10 @@
<PackageReference Include="MSTest.TestFramework" Version="3.6.1" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\TJC.StateMachine\TJC.StateMachine.csproj" />
</ItemGroup>

<ItemGroup>
<Using Include="Microsoft.VisualStudio.TestTools.UnitTesting" />
</ItemGroup>
Expand Down
61 changes: 61 additions & 0 deletions TJC.StateMachine.Tests/Tests/RevolverMockTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
using TJC.StateMachine.Tests.Mocks;

namespace TJC.StateMachine.Tests.Tests
{
[TestClass]
public class RevolverMockTests
{
[TestMethod]
public void EnsureRevolverStartsFull()
{
var revolver = new RevolverMock();
Assert.AreEqual(6, revolver.BulletsLoaded);
}

[TestMethod]
public void EnsureRevolverShootingLowersBulletsToZeroThenRequiresReloading()
{
var revolver = new RevolverMock();

var result = revolver.TryShoot();
Assert.IsTrue(result);
Assert.AreEqual(5, revolver.BulletsLoaded);

result = revolver.TryShoot();
Assert.IsTrue(result);
Assert.AreEqual(4, revolver.BulletsLoaded);

result = revolver.TryShoot();
Assert.IsTrue(result);
Assert.AreEqual(3, revolver.BulletsLoaded);

result = revolver.TryShoot();
Assert.IsTrue(result);
Assert.AreEqual(2, revolver.BulletsLoaded);

result = revolver.TryShoot();
Assert.IsTrue(result);
Assert.AreEqual(1, revolver.BulletsLoaded);

result = revolver.TryShoot();
Assert.IsTrue(result);
Assert.AreEqual(0, revolver.BulletsLoaded);

result = revolver.TryShoot();
Assert.IsFalse(result);
Assert.AreEqual(0, revolver.BulletsLoaded);
}

[TestMethod]
public void EnsureReloadingResetsBulletsTo6()
{
var revolver = new RevolverMock();

Assert.AreEqual(6, revolver.BulletsLoaded);
revolver.TryShoot();
Assert.AreEqual(5, revolver.BulletsLoaded);
revolver.Reload();
Assert.AreEqual(6, revolver.BulletsLoaded);
}
}
}
32 changes: 32 additions & 0 deletions TJC.StateMachine.Tests/Tests/StatePropertyAccessibility.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using System.Reflection;
using TJC.StateMachine.Tests.Mocks;

namespace TJC.StateMachine.Tests.Tests
{
[TestClass]
public class StatePropertyAccessibility
{
[TestMethod]
public void EnsurePropertyStateIsNotPubliclyAccessible()
{
var prop = typeof(StateMachineBase<RevolverStates>).GetProperty(
"State",
BindingFlags.Instance | BindingFlags.Public
);
Assert.IsNull(prop);
}

[TestMethod]
public void EnsurePropertyStateIsProtectedAccessible()
{
var prop = typeof(StateMachineBase<RevolverStates>).GetProperty(
"State",
BindingFlags.Instance | BindingFlags.NonPublic
);
Assert.IsNotNull(prop);
var getter = prop.GetMethod;
Assert.IsNotNull(getter);
Assert.IsTrue(getter.IsFamily);
}
}
}
9 changes: 0 additions & 9 deletions TJC.StateMachine.Tests/UnitTest1.cs

This file was deleted.

4 changes: 0 additions & 4 deletions TJC.StateMachine/Class1.cs

This file was deleted.

15 changes: 15 additions & 0 deletions TJC.StateMachine/StateMachineBase.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
namespace TJC.StateMachine
{
/// <summary>
/// State machine pattern base class.
/// </summary>
/// <typeparam name="T">State Type.</typeparam>
/// <param name="initialState">Initial State of the State Machine.</param>
public class StateMachineBase<T>(T initialState)
{
/// <summary>
/// State of the state machine.
/// </summary>
protected T State { get; set; } = initialState;
}
}
23 changes: 13 additions & 10 deletions Testing.sln
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,29 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.8.34316.72
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TJC.Rename", "TJC.Rename\TJC.Rename.csproj", "{73B82231-E966-42EC-8635-5B98C99D8B4C}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TJC.StateMachine", "TJC.StateMachine\TJC.StateMachine.csproj", "{0759E8E9-2315-4AC0-898A-A0896F4CB2A3}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TJC.Rename.Tests", "TJC.Rename.Tests\TJC.Rename.Tests.csproj", "{D10EE1DD-1F71-4828-908D-1DEAA0285E71}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TJC.StateMachine.Tests", "TJC.StateMachine.Tests\TJC.StateMachine.Tests.csproj", "{2F309AA3-B442-467B-8B73-7AA31F5840F2}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{73B82231-E966-42EC-8635-5B98C99D8B4C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{73B82231-E966-42EC-8635-5B98C99D8B4C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{73B82231-E966-42EC-8635-5B98C99D8B4C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{73B82231-E966-42EC-8635-5B98C99D8B4C}.Release|Any CPU.Build.0 = Release|Any CPU
{D10EE1DD-1F71-4828-908D-1DEAA0285E71}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D10EE1DD-1F71-4828-908D-1DEAA0285E71}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D10EE1DD-1F71-4828-908D-1DEAA0285E71}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D10EE1DD-1F71-4828-908D-1DEAA0285E71}.Release|Any CPU.Build.0 = Release|Any CPU
{0759E8E9-2315-4AC0-898A-A0896F4CB2A3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0759E8E9-2315-4AC0-898A-A0896F4CB2A3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0759E8E9-2315-4AC0-898A-A0896F4CB2A3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0759E8E9-2315-4AC0-898A-A0896F4CB2A3}.Release|Any CPU.Build.0 = Release|Any CPU
{2F309AA3-B442-467B-8B73-7AA31F5840F2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2F309AA3-B442-467B-8B73-7AA31F5840F2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2F309AA3-B442-467B-8B73-7AA31F5840F2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2F309AA3-B442-467B-8B73-7AA31F5840F2}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {55B3F5F4-C774-4815-8438-CD3E90055A85}
EndGlobalSection
EndGlobal
Loading