Skip to content
This repository was archived by the owner on Jun 10, 2026. It is now read-only.
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
11 changes: 11 additions & 0 deletions BugPro/BugPro.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net9.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Stateless" Version="5.13.0" />
</ItemGroup>
</Project>
82 changes: 82 additions & 0 deletions BugPro/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
// Copyright 2026 NNTU-CS
using Stateless;
using System;

namespace BugPro {
public class Bug {
public enum State {
Open, Assigned, InProgress, Resolved, Closed, Reopened
}

public enum Trigger {
Assign, Start, Resolve, Close, Reopen, Reset
}

private readonly StateMachine<State, Trigger> _machine;
private string _title;

public State CurrentState => _machine.State;

public Bug(string title) {
_title = title;
_machine = new StateMachine<State, Trigger>(State.Open);

_machine.Configure(State.Open)
.Permit(Trigger.Assign, State.Assigned);

_machine.Configure(State.Assigned)
.Permit(Trigger.Start, State.InProgress)
.Permit(Trigger.Reset, State.Open);

_machine.Configure(State.InProgress)
.Permit(Trigger.Resolve, State.Resolved)
.Permit(Trigger.Reset, State.Open);

_machine.Configure(State.Resolved)
.Permit(Trigger.Close, State.Closed)
.Permit(Trigger.Reopen, State.Reopened);

_machine.Configure(State.Closed)
.Permit(Trigger.Reopen, State.Reopened);

_machine.Configure(State.Reopened)
.Permit(Trigger.Assign, State.Assigned)
.Permit(Trigger.Resolve, State.Resolved);
}

public void Assign() => _machine.Fire(Trigger.Assign);
public void Start() => _machine.Fire(Trigger.Start);
public void Resolve() => _machine.Fire(Trigger.Resolve);
public void Close() => _machine.Fire(Trigger.Close);
public void Reopen() => _machine.Fire(Trigger.Reopen);
public void Reset() => _machine.Fire(Trigger.Reset);

public bool CanAssign() => _machine.CanFire(Trigger.Assign);
public bool CanStart() => _machine.CanFire(Trigger.Start);
public bool CanResolve() => _machine.CanFire(Trigger.Resolve);
public bool CanClose() => _machine.CanFire(Trigger.Close);
public bool CanReopen() => _machine.CanFire(Trigger.Reopen);
}

class Program {
static void Main(string[] args) {
var bug = new Bug("Sample Bug");
Console.WriteLine($"Initial state: {bug.CurrentState}");

bug.Assign();
Console.WriteLine($"After Assign: {bug.CurrentState}");

bug.Start();
Console.WriteLine($"After Start: {bug.CurrentState}");

bug.Resolve();
Console.WriteLine($"After Resolve: {bug.CurrentState}");

bug.Close();
Console.WriteLine($"After Close: {bug.CurrentState}");

bug.Reopen();
Console.WriteLine($"After Reopen: {bug.CurrentState}");
}
}
}
17 changes: 17 additions & 0 deletions BugTests/BugTests.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
<PackageReference Include="MSTest.TestAdapter" Version="3.1.1" />
<PackageReference Include="MSTest.TestFramework" Version="3.1.1" />
<PackageReference Include="Stateless" Version="5.13.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\BugPro\BugPro.csproj" />
</ItemGroup>
</Project>
179 changes: 179 additions & 0 deletions BugTests/UnitTest1.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
// Copyright 2026 NNTU-CS
using Microsoft.VisualStudio.TestTools.UnitTesting;
using BugPro;
using Stateless;
using System;

namespace BugTests {
[TestClass]
public class UnitTest1 {
[TestMethod]
public void Bug_InitialState_IsOpen() {
var bug = new Bug("Test");
Assert.AreEqual(Bug.State.Open, bug.CurrentState);
}

[TestMethod]
public void Bug_Assign_MovesToAssigned() {
var bug = new Bug("Test");
bug.Assign();
Assert.AreEqual(Bug.State.Assigned, bug.CurrentState);
}

[TestMethod]
public void Bug_Start_MovesToInProgress() {
var bug = new Bug("Test");
bug.Assign();
bug.Start();
Assert.AreEqual(Bug.State.InProgress, bug.CurrentState);
}

[TestMethod]
public void Bug_Resolve_MovesToResolved() {
var bug = new Bug("Test");
bug.Assign();
bug.Start();
bug.Resolve();
Assert.AreEqual(Bug.State.Resolved, bug.CurrentState);
}

[TestMethod]
public void Bug_Close_MovesToClosed() {
var bug = new Bug("Test");
bug.Assign();
bug.Start();
bug.Resolve();
bug.Close();
Assert.AreEqual(Bug.State.Closed, bug.CurrentState);
}

[TestMethod]
public void Bug_Reopen_FromClosed_MovesToReopened() {
var bug = new Bug("Test");
bug.Assign();
bug.Start();
bug.Resolve();
bug.Close();
bug.Reopen();
Assert.AreEqual(Bug.State.Reopened, bug.CurrentState);
}

[TestMethod]
public void Bug_Reopen_FromResolved_MovesToReopened() {
var bug = new Bug("Test");
bug.Assign();
bug.Start();
bug.Resolve();
bug.Reopen();
Assert.AreEqual(Bug.State.Reopened, bug.CurrentState);
}

[TestMethod]
public void Bug_Reset_FromAssigned_MovesToOpen() {
var bug = new Bug("Test");
bug.Assign();
bug.Reset();
Assert.AreEqual(Bug.State.Open, bug.CurrentState);
}

[TestMethod]
public void Bug_Reset_FromInProgress_MovesToOpen() {
var bug = new Bug("Test");
bug.Assign();
bug.Start();
bug.Reset();
Assert.AreEqual(Bug.State.Open, bug.CurrentState);
}

[TestMethod]
public void Bug_ReopenedCanAssign() {
var bug = new Bug("Test");
bug.Assign();
bug.Start();
bug.Resolve();
bug.Reopen();
Assert.IsTrue(bug.CanAssign());
}

[TestMethod]
public void Bug_CanAssign_WhenOpen() {
var bug = new Bug("Test");
Assert.IsTrue(bug.CanAssign());
}

[TestMethod]
public void Bug_CannotStart_WhenOpen() {
var bug = new Bug("Test");
Assert.IsFalse(bug.CanStart());
}

[TestMethod]
public void Bug_CannotClose_WhenOpen() {
var bug = new Bug("Test");
Assert.IsFalse(bug.CanClose());
}

[TestMethod]
public void Bug_CannotReopen_WhenOpen() {
var bug = new Bug("Test");
Assert.IsFalse(bug.CanReopen());
}

[TestMethod]
public void Bug_CannotResolve_WhenOpen() {
var bug = new Bug("Test");
Assert.IsFalse(bug.CanResolve());
}

[TestMethod]
[ExpectedException(typeof(InvalidOperationException))]
public void Bug_Start_WhenOpen_ThrowsException() {
var bug = new Bug("Test");
bug.Start();
}

[TestMethod]
[ExpectedException(typeof(InvalidOperationException))]
public void Bug_Resolve_WhenOpen_ThrowsException() {
var bug = new Bug("Test");
bug.Resolve();
}

[TestMethod]
[ExpectedException(typeof(InvalidOperationException))]
public void Bug_Close_WhenOpen_ThrowsException() {
var bug = new Bug("Test");
bug.Close();
}

[TestMethod]
[ExpectedException(typeof(InvalidOperationException))]
public void Bug_Reopen_WhenOpen_ThrowsException() {
var bug = new Bug("Test");
bug.Reopen();
}

[TestMethod]
[ExpectedException(typeof(InvalidOperationException))]
public void Bug_Assign_WhenInProgress_ThrowsException() {
var bug = new Bug("Test");
bug.Assign();
bug.Start();
bug.Assign();
}

[TestMethod]
public void Bug_FullCycle_WorksCorrectly() {
var bug = new Bug("Test");
Assert.AreEqual(Bug.State.Open, bug.CurrentState);
bug.Assign();
Assert.AreEqual(Bug.State.Assigned, bug.CurrentState);
bug.Start();
Assert.AreEqual(Bug.State.InProgress, bug.CurrentState);
bug.Resolve();
Assert.AreEqual(Bug.State.Resolved, bug.CurrentState);
bug.Close();
Assert.AreEqual(Bug.State.Closed, bug.CurrentState);
}
}
}
20 changes: 14 additions & 6 deletions ST-4.sln
Original file line number Diff line number Diff line change
@@ -1,14 +1,22 @@


Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.0.31903.59
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BugPro", "BugPro\BugPro.csproj", "{11111111-1111-1111-1111-111111111111}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BugTests", "BugTests\BugTests.csproj", "{22222222-2222-2222-2222-222222222222}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{11111111-1111-1111-1111-111111111111}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{11111111-1111-1111-1111-111111111111}.Debug|Any CPU.Build.0 = Debug|Any CPU
{11111111-1111-1111-1111-111111111111}.Release|Any CPU.ActiveCfg = Release|Any CPU
{11111111-1111-1111-1111-111111111111}.Release|Any CPU.Build.0 = Release|Any CPU
{22222222-2222-2222-2222-222222222222}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{22222222-2222-2222-2222-222222222222}.Debug|Any CPU.Build.0 = Debug|Any CPU
{22222222-2222-2222-2222-222222222222}.Release|Any CPU.ActiveCfg = Release|Any CPU
{22222222-2222-2222-2222-222222222222}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal
Loading