diff --git a/BugPro/BugPro.csproj b/BugPro/BugPro.csproj
new file mode 100644
index 0000000..7fc7560
--- /dev/null
+++ b/BugPro/BugPro.csproj
@@ -0,0 +1,11 @@
+
+
+ Exe
+ net9.0
+ enable
+ enable
+
+
+
+
+
diff --git a/BugPro/Program.cs b/BugPro/Program.cs
new file mode 100644
index 0000000..9a5cde6
--- /dev/null
+++ b/BugPro/Program.cs
@@ -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 _machine;
+ private string _title;
+
+ public State CurrentState => _machine.State;
+
+ public Bug(string title) {
+ _title = title;
+ _machine = new StateMachine(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}");
+ }
+ }
+}
diff --git a/BugTests/BugTests.csproj b/BugTests/BugTests.csproj
new file mode 100644
index 0000000..9ee27db
--- /dev/null
+++ b/BugTests/BugTests.csproj
@@ -0,0 +1,17 @@
+
+
+ net9.0
+ enable
+ enable
+ false
+
+
+
+
+
+
+
+
+
+
+
diff --git a/BugTests/UnitTest1.cs b/BugTests/UnitTest1.cs
new file mode 100644
index 0000000..7f641eb
--- /dev/null
+++ b/BugTests/UnitTest1.cs
@@ -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);
+ }
+ }
+}
diff --git a/ST-4.sln b/ST-4.sln
index 58ea566..06cf042 100644
--- a/ST-4.sln
+++ b/ST-4.sln
@@ -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