From 2f4cdc46906552f219bd1d932053653bc8028532 Mon Sep 17 00:00:00 2001 From: Victoria Date: Sun, 7 Jun 2026 23:31:44 +0300 Subject: [PATCH] done --- .gitignore | 15 +++ BugPro/BugPro.csproj | 14 +++ BugPro/Program.cs | 88 ++++++++++++++++++ BugTests/BugTests.csproj | 23 +++++ BugTests/GlobalUsings.cs | 1 + BugTests/UnitTest1.cs | 193 +++++++++++++++++++++++++++++++++++++++ ST-4.sln | 14 +++ 7 files changed, 348 insertions(+) create mode 100644 .gitignore create mode 100644 BugPro/BugPro.csproj create mode 100644 BugPro/Program.cs create mode 100644 BugTests/BugTests.csproj create mode 100644 BugTests/GlobalUsings.cs create mode 100644 BugTests/UnitTest1.cs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c9fc8ea --- /dev/null +++ b/.gitignore @@ -0,0 +1,15 @@ +# Сборка .NET +bin/ +obj/ + +# IDEs +.idea/ +.vscode/ +*.user +*.suo +*.userosscache +*.sln.docstates + +# Системные файлы +.DS_Store +Thumbs.db diff --git a/BugPro/BugPro.csproj b/BugPro/BugPro.csproj new file mode 100644 index 0000000..4c1a789 --- /dev/null +++ b/BugPro/BugPro.csproj @@ -0,0 +1,14 @@ + + + + Exe + net9.0 + enable + enable + + + + + + + diff --git a/BugPro/Program.cs b/BugPro/Program.cs new file mode 100644 index 0000000..afd73aa --- /dev/null +++ b/BugPro/Program.cs @@ -0,0 +1,88 @@ +using System; +using Stateless; + +namespace BugPro +{ + public enum State + { + NewDefect, + Triage, + Fixing, + Closed + } + + public enum Trigger + { + Assign, + StartFix, + NotADefect, + WontFix, + Duplicate, + NoTimeNow, + NeedsSeparateSolution, + OtherProductProblem, + NeedMoreInfo, + CannotReproduceAndOK, + CannotReproduceAndNotOK, + FixAccepted, + FixRejected, + Reopen + } + + public class Bug + { + private readonly StateMachine _machine; + + public State CurrentState => _machine.State; + + public Bug() + { + _machine = new StateMachine(State.NewDefect); + + _machine.Configure(State.NewDefect) + .Permit(Trigger.Assign, State.Triage); + + _machine.Configure(State.Triage) + .Permit(Trigger.StartFix, State.Fixing) + .Permit(Trigger.NotADefect, State.Closed) + .Permit(Trigger.WontFix, State.Closed) + .Permit(Trigger.Duplicate, State.Closed); + + _machine.Configure(State.Fixing) + .Permit(Trigger.NoTimeNow, State.Triage) + .Permit(Trigger.NeedsSeparateSolution, State.Triage) + .Permit(Trigger.OtherProductProblem, State.Triage) + .Permit(Trigger.NeedMoreInfo, State.Triage) + .Permit(Trigger.CannotReproduceAndOK, State.Closed) + .Permit(Trigger.CannotReproduceAndNotOK, State.Triage) + .Permit(Trigger.FixAccepted, State.Closed) + .Permit(Trigger.FixRejected, State.Triage); + + _machine.Configure(State.Closed) + .Permit(Trigger.Reopen, State.Triage); + } + + public void Fire(Trigger trigger) + { + _machine.Fire(trigger); + } + } + + class Program + { + static void Main(string[] args) + { + var bug = new Bug(); + Console.WriteLine($"Начальное состояние: {bug.CurrentState}"); + + bug.Fire(Trigger.Assign); + Console.WriteLine($"После назначения: {bug.CurrentState}"); + + bug.Fire(Trigger.StartFix); + Console.WriteLine($"Взято в работу: {bug.CurrentState}"); + + bug.Fire(Trigger.FixAccepted); + Console.WriteLine($"Проблема решена (ДА): {bug.CurrentState}"); + } + } +} diff --git a/BugTests/BugTests.csproj b/BugTests/BugTests.csproj new file mode 100644 index 0000000..8e7de44 --- /dev/null +++ b/BugTests/BugTests.csproj @@ -0,0 +1,23 @@ + + + + net9.0 + enable + enable + + false + true + + + + + + + + + + + + + + diff --git a/BugTests/GlobalUsings.cs b/BugTests/GlobalUsings.cs new file mode 100644 index 0000000..ab67c7e --- /dev/null +++ b/BugTests/GlobalUsings.cs @@ -0,0 +1 @@ +global using Microsoft.VisualStudio.TestTools.UnitTesting; \ No newline at end of file diff --git a/BugTests/UnitTest1.cs b/BugTests/UnitTest1.cs new file mode 100644 index 0000000..b08d989 --- /dev/null +++ b/BugTests/UnitTest1.cs @@ -0,0 +1,193 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using BugPro; +using Stateless; +namespace BugTests +{ + [TestClass] + public class UnitTest1 + { + [TestMethod] + public void InitialState_IsNewDefect() + { + var bug = new Bug(); + Assert.AreEqual(State.NewDefect, bug.CurrentState); + } + [TestMethod] + public void Assign_FromNewDefect_GoesToTriage() + { + var bug = new Bug(); + bug.Fire(Trigger.Assign); + Assert.AreEqual(State.Triage, bug.CurrentState); + } + [TestMethod] + public void StartFix_FromTriage_GoesToFixing() + { + var bug = new Bug(); + bug.Fire(Trigger.Assign); + bug.Fire(Trigger.StartFix); + Assert.AreEqual(State.Fixing, bug.CurrentState); + } + [TestMethod] + public void NotADefect_FromTriage_GoesToClosed() + { + var bug = new Bug(); + bug.Fire(Trigger.Assign); + bug.Fire(Trigger.NotADefect); + Assert.AreEqual(State.Closed, bug.CurrentState); + } + [TestMethod] + public void WontFix_FromTriage_GoesToClosed() + { + var bug = new Bug(); + bug.Fire(Trigger.Assign); + bug.Fire(Trigger.WontFix); + Assert.AreEqual(State.Closed, bug.CurrentState); + } + [TestMethod] + public void Duplicate_FromTriage_GoesToClosed() + { + var bug = new Bug(); + bug.Fire(Trigger.Assign); + bug.Fire(Trigger.Duplicate); + Assert.AreEqual(State.Closed, bug.CurrentState); + } + [TestMethod] + public void NoTimeNow_FromFixing_GoesToTriage() + { + var bug = new Bug(); + bug.Fire(Trigger.Assign); + bug.Fire(Trigger.StartFix); + bug.Fire(Trigger.NoTimeNow); + Assert.AreEqual(State.Triage, bug.CurrentState); + } + [TestMethod] + public void NeedsSeparateSolution_FromFixing_GoesToTriage() + { + var bug = new Bug(); + bug.Fire(Trigger.Assign); + bug.Fire(Trigger.StartFix); + bug.Fire(Trigger.NeedsSeparateSolution); + Assert.AreEqual(State.Triage, bug.CurrentState); + } + [TestMethod] + public void OtherProductProblem_FromFixing_GoesToTriage() + { + var bug = new Bug(); + bug.Fire(Trigger.Assign); + bug.Fire(Trigger.StartFix); + bug.Fire(Trigger.OtherProductProblem); + Assert.AreEqual(State.Triage, bug.CurrentState); + } + [TestMethod] + public void NeedMoreInfo_FromFixing_GoesToTriage() + { + var bug = new Bug(); + bug.Fire(Trigger.Assign); + bug.Fire(Trigger.StartFix); + bug.Fire(Trigger.NeedMoreInfo); + Assert.AreEqual(State.Triage, bug.CurrentState); + } + [TestMethod] + public void CannotReproduceAndOK_FromFixing_GoesToClosed() + { + var bug = new Bug(); + bug.Fire(Trigger.Assign); + bug.Fire(Trigger.StartFix); + bug.Fire(Trigger.CannotReproduceAndOK); + Assert.AreEqual(State.Closed, bug.CurrentState); + } + [TestMethod] + public void CannotReproduceAndNotOK_FromFixing_GoesToTriage() + { + var bug = new Bug(); + bug.Fire(Trigger.Assign); + bug.Fire(Trigger.StartFix); + bug.Fire(Trigger.CannotReproduceAndNotOK); + Assert.AreEqual(State.Triage, bug.CurrentState); + } + [TestMethod] + public void FixAccepted_FromFixing_GoesToClosed() + { + var bug = new Bug(); + bug.Fire(Trigger.Assign); + bug.Fire(Trigger.StartFix); + bug.Fire(Trigger.FixAccepted); + Assert.AreEqual(State.Closed, bug.CurrentState); + } + [TestMethod] + public void FixRejected_FromFixing_GoesToTriage() + { + var bug = new Bug(); + bug.Fire(Trigger.Assign); + bug.Fire(Trigger.StartFix); + bug.Fire(Trigger.FixRejected); + Assert.AreEqual(State.Triage, bug.CurrentState); + } + [TestMethod] + public void Reopen_FromClosed_GoesToTriage() + { + var bug = new Bug(); + bug.Fire(Trigger.Assign); + bug.Fire(Trigger.NotADefect); + bug.Fire(Trigger.Reopen); + Assert.AreEqual(State.Triage, bug.CurrentState); + } + [TestMethod] + [ExpectedException(typeof(InvalidOperationException))] + public void Invalid_StartFix_FromNewDefect_ThrowsException() + { + var bug = new Bug(); + bug.Fire(Trigger.StartFix); + } + [TestMethod] + [ExpectedException(typeof(InvalidOperationException))] + public void Invalid_FixAccepted_FromNewDefect_ThrowsException() + { + var bug = new Bug(); + bug.Fire(Trigger.FixAccepted); + } + [TestMethod] + [ExpectedException(typeof(InvalidOperationException))] + public void Invalid_Assign_FromTriage_ThrowsException() + { + var bug = new Bug(); + bug.Fire(Trigger.Assign); + bug.Fire(Trigger.Assign); + } + [TestMethod] + [ExpectedException(typeof(InvalidOperationException))] + public void Invalid_StartFix_FromFixing_ThrowsException() + { + var bug = new Bug(); + bug.Fire(Trigger.Assign); + bug.Fire(Trigger.StartFix); + bug.Fire(Trigger.StartFix); + } + [TestMethod] + [ExpectedException(typeof(InvalidOperationException))] + public void Invalid_FixAccepted_FromClosed_ThrowsException() + { + var bug = new Bug(); + bug.Fire(Trigger.Assign); + bug.Fire(Trigger.NotADefect); + bug.Fire(Trigger.FixAccepted); + } + [TestMethod] + [ExpectedException(typeof(InvalidOperationException))] + public void Invalid_StartFix_FromClosed_ThrowsException() + { + var bug = new Bug(); + bug.Fire(Trigger.Assign); + bug.Fire(Trigger.NotADefect); + bug.Fire(Trigger.StartFix); + } + [TestMethod] + [ExpectedException(typeof(InvalidOperationException))] + public void Invalid_Reopen_FromNewDefect_ThrowsException() + { + var bug = new Bug(); + bug.Fire(Trigger.Reopen); + } + } +} diff --git a/ST-4.sln b/ST-4.sln index 58ea566..286c2bc 100644 --- a/ST-4.sln +++ b/ST-4.sln @@ -3,6 +3,10 @@ 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", "{69E7D115-E4A0-4D84-8EA8-EECEB5B1815D}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BugTests", "BugTests\BugTests.csproj", "{C898FD7F-75FA-4A27-A73E-18ABACB1A198}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -11,4 +15,14 @@ Global GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {69E7D115-E4A0-4D84-8EA8-EECEB5B1815D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {69E7D115-E4A0-4D84-8EA8-EECEB5B1815D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {69E7D115-E4A0-4D84-8EA8-EECEB5B1815D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {69E7D115-E4A0-4D84-8EA8-EECEB5B1815D}.Release|Any CPU.Build.0 = Release|Any CPU + {C898FD7F-75FA-4A27-A73E-18ABACB1A198}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C898FD7F-75FA-4A27-A73E-18ABACB1A198}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C898FD7F-75FA-4A27-A73E-18ABACB1A198}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C898FD7F-75FA-4A27-A73E-18ABACB1A198}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection EndGlobal