diff --git a/Calc/Calc.Tests/Calc.Tests.csproj b/Calc/Calc.Tests/Calc.Tests.csproj new file mode 100644 index 0000000..28890f6 --- /dev/null +++ b/Calc/Calc.Tests/Calc.Tests.csproj @@ -0,0 +1,28 @@ + + + + net9.0 + latest + enable + enable + + true + + + + + + + + + + + + + + + + + + + diff --git a/Calc/Calc.Tests/CalcErrorTests.cs b/Calc/Calc.Tests/CalcErrorTests.cs new file mode 100644 index 0000000..d045a84 --- /dev/null +++ b/Calc/Calc.Tests/CalcErrorTests.cs @@ -0,0 +1,56 @@ +// +// Copyright (c) Ilya Krivtsov. All rights reserved. +// + +namespace Calc.Tests; + +public class CalcErrorTests +{ + private Calc calc; + + [SetUp] + public void Setup() + { + calc = new(); + } + + [Test] + public void Test_0_Divide_0_Gives_Error() + { + calc.EnterDigit(0); + calc.OperatorPressed(ArithmeticOperation.Division); + calc.EnterDigit(0); + calc.EqualsPressed(); + Assert.That(calc.DisplayResult, Is.EqualTo("Error")); + } + + [Test] + public void Test_Error_State_Persists() + { + calc.EnterDigit(0); + calc.OperatorPressed(ArithmeticOperation.Division); + calc.EnterDigit(0); + calc.EqualsPressed(); + Assert.That(calc.DisplayResult, Is.EqualTo("Error")); + calc.EnterDecimalPoint(); + Assert.That(calc.DisplayResult, Is.EqualTo("Error")); + calc.EnterDigit(4); + Assert.That(calc.DisplayResult, Is.EqualTo("Error")); + calc.OperatorPressed(ArithmeticOperation.Addition); + Assert.That(calc.DisplayResult, Is.EqualTo("Error")); + calc.EqualsPressed(); + Assert.That(calc.DisplayResult, Is.EqualTo("Error")); + } + + [Test] + public void Test_Error_IsRemoved_AfterClear() + { + calc.EnterDigit(0); + calc.OperatorPressed(ArithmeticOperation.Division); + calc.EnterDigit(0); + calc.EqualsPressed(); + Assert.That(calc.DisplayResult, Is.EqualTo("Error")); + calc.Clear(); + Assert.That(calc.DisplayResult, Is.EqualTo("0")); + } +} diff --git a/Calc/Calc.Tests/CalcTests.cs b/Calc/Calc.Tests/CalcTests.cs new file mode 100644 index 0000000..06e5d0a --- /dev/null +++ b/Calc/Calc.Tests/CalcTests.cs @@ -0,0 +1,145 @@ +// +// Copyright (c) Ilya Krivtsov. All rights reserved. +// + +namespace Calc.Tests; + +public class CalcTests +{ + private Calc calc; + + [SetUp] + public void Setup() + { + calc = new(); + } + + [Test] + public void Test_2_Plus_3_Equals_5() + { + calc.EnterDigit(2); + Assert.That(calc.DisplayResult, Is.EqualTo("2")); + + calc.OperatorPressed(ArithmeticOperation.Addition); + Assert.That(calc.DisplayResult, Is.EqualTo("2")); + + calc.EnterDigit(3); + Assert.That(calc.DisplayResult, Is.EqualTo("3")); + + calc.EqualsPressed(); + Assert.That(calc.DisplayResult, Is.EqualTo("5")); + } + + [Test] + public void Test_2_Plus_3_Minus_10_Equals_Minus_5() + { + calc.EnterDigit(2); + Assert.That(calc.DisplayResult, Is.EqualTo("2")); + + calc.OperatorPressed(ArithmeticOperation.Addition); + Assert.That(calc.DisplayResult, Is.EqualTo("2")); + + calc.EnterDigit(3); + Assert.That(calc.DisplayResult, Is.EqualTo("3")); + + calc.OperatorPressed(ArithmeticOperation.Subtraction); + Assert.That(calc.DisplayResult, Is.EqualTo("5")); + + calc.EnterDigit(1); + Assert.That(calc.DisplayResult, Is.EqualTo("1")); + calc.EnterDigit(0); + Assert.That(calc.DisplayResult, Is.EqualTo("10")); + + calc.EqualsPressed(); + Assert.That(calc.DisplayResult, Is.EqualTo("-5")); + } + + [Test] + public void Test_0_Point_1_Plus_0_Point_2_Equals_0_Point_3() + { + calc.EnterDigit(0); + Assert.That(calc.DisplayResult, Is.EqualTo("0")); + calc.EnterDecimalPoint(); + Assert.That(calc.DisplayResult, Is.EqualTo("0.")); + calc.EnterDigit(1); + Assert.That(calc.DisplayResult, Is.EqualTo("0.1")); + + calc.OperatorPressed(ArithmeticOperation.Addition); + Assert.That(calc.DisplayResult, Is.EqualTo("0.1")); + + calc.EnterDigit(0); + Assert.That(calc.DisplayResult, Is.EqualTo("0")); + calc.EnterDecimalPoint(); + Assert.That(calc.DisplayResult, Is.EqualTo("0.")); + calc.EnterDigit(2); + Assert.That(calc.DisplayResult, Is.EqualTo("0.2")); + + calc.EqualsPressed(); + Assert.That(calc.DisplayResult, Is.EqualTo("0.3")); + } + + [Test] + public void Test_Clear() + { + calc.EnterDigit(2); + Assert.That(calc.DisplayResult, Is.EqualTo("2")); + + calc.OperatorPressed(ArithmeticOperation.Addition); + Assert.That(calc.DisplayResult, Is.EqualTo("2")); + + calc.EnterDigit(3); + Assert.That(calc.DisplayResult, Is.EqualTo("3")); + + calc.EqualsPressed(); + Assert.That(calc.DisplayResult, Is.EqualTo("5")); + + calc.Clear(); + Assert.That(calc.DisplayResult, Is.EqualTo("0")); + + calc.EnterDigit(3); + Assert.That(calc.DisplayResult, Is.EqualTo("3")); + + calc.OperatorPressed(ArithmeticOperation.Addition); + Assert.That(calc.DisplayResult, Is.EqualTo("3")); + + calc.EnterDigit(4); + Assert.That(calc.DisplayResult, Is.EqualTo("4")); + + calc.EqualsPressed(); + Assert.That(calc.DisplayResult, Is.EqualTo("7")); + + calc.Clear(); + Assert.That(calc.DisplayResult, Is.EqualTo("0")); + } + + [Test] + public void Test_DoubleDecimalPoint_DoesNotAddNew_DecimalPoint() + { + calc.EnterDigit(2); + Assert.That(calc.DisplayResult, Is.EqualTo("2")); + calc.EnterDecimalPoint(); + Assert.That(calc.DisplayResult, Is.EqualTo("2.")); + calc.EnterDecimalPoint(); + Assert.That(calc.DisplayResult, Is.EqualTo("2.")); + } + + [Test] + public void Test_EnteringDigitsAfter_Equals_SetsResultTo_ThatDigit() + { + calc.EnterDigit(2); + calc.EqualsPressed(); + Assert.That(calc.DisplayResult, Is.EqualTo("2")); + calc.EnterDigit(5); + Assert.That(calc.DisplayResult, Is.EqualTo("5")); + + calc.Clear(); + + calc.EnterDigit(1); + calc.OperatorPressed(ArithmeticOperation.Addition); + calc.EnterDigit(2); + calc.EqualsPressed(); + Assert.That(calc.DisplayResult, Is.EqualTo("3")); + calc.EnterDigit(5); + Assert.That(calc.DisplayResult, Is.EqualTo("5")); + } +} diff --git a/Calc/Calc.Tests/GlobalSuppressions.cs b/Calc/Calc.Tests/GlobalSuppressions.cs new file mode 100644 index 0000000..909e036 --- /dev/null +++ b/Calc/Calc.Tests/GlobalSuppressions.cs @@ -0,0 +1,11 @@ +// +// Copyright (c) Ilya Krivtsov. All rights reserved. +// + +// This file is used by Code Analysis to maintain SuppressMessage +// attributes that are applied to this project. +// Project-level suppressions either have no target or are given +// a specific target and scoped to a namespace, type, member, etc. +using System.Diagnostics.CodeAnalysis; + +[assembly: SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1600:Elements should be documented", Justification = "This is tests project")] diff --git a/Calc/Calc.UI/App.axaml b/Calc/Calc.UI/App.axaml new file mode 100644 index 0000000..9775fbe --- /dev/null +++ b/Calc/Calc.UI/App.axaml @@ -0,0 +1,10 @@ + + + + + + + diff --git a/Calc/Calc.UI/App.axaml.cs b/Calc/Calc.UI/App.axaml.cs new file mode 100644 index 0000000..61be4d6 --- /dev/null +++ b/Calc/Calc.UI/App.axaml.cs @@ -0,0 +1,27 @@ +// +// Copyright (c) Ilya Krivtsov. All rights reserved. +// + +namespace Calc.UI; + +using Avalonia; +using Avalonia.Controls.ApplicationLifetimes; +using Avalonia.Markup.Xaml; + +public partial class App : Application +{ + public override void Initialize() + { + AvaloniaXamlLoader.Load(this); + } + + public override void OnFrameworkInitializationCompleted() + { + if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) + { + desktop.MainWindow = new MainWindow(); + } + + base.OnFrameworkInitializationCompleted(); + } +} diff --git a/Calc/Calc.UI/Calc.UI.csproj b/Calc/Calc.UI/Calc.UI.csproj new file mode 100644 index 0000000..a0be288 --- /dev/null +++ b/Calc/Calc.UI/Calc.UI.csproj @@ -0,0 +1,21 @@ + + + WinExe + net9.0 + enable + true + app.manifest + true + + + + + + + + + + + + + diff --git a/Calc/Calc.UI/GlobalSuppressions.cs b/Calc/Calc.UI/GlobalSuppressions.cs new file mode 100644 index 0000000..a500690 --- /dev/null +++ b/Calc/Calc.UI/GlobalSuppressions.cs @@ -0,0 +1,16 @@ +// +// Copyright (c) Ilya Krivtsov. All rights reserved. +// + +// This file is used by Code Analysis to maintain SuppressMessage +// attributes that are applied to this project. +// Project-level suppressions either have no target or are given +// a specific target and scoped to a namespace, type, member, etc. +using System.Diagnostics.CodeAnalysis; + +[assembly: SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1600:Elements should be documented", Justification = "Entry point", Scope = "type", Target = "~T:Calc.UI.Program")] + +[assembly: SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1601:Partial elements should be documented", Justification = "Application class", Scope = "type", Target = "~T:Calc.UI.App")] +[assembly: SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1601:Partial elements should be documented", Justification = "Window class", Scope = "type", Target = "~T:Calc.UI.MainWindow")] +[assembly: SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1600:Elements should be documented", Justification = "Application class", Scope = "type", Target = "~T:Calc.UI.App")] +[assembly: SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1600:Elements should be documented", Justification = "Window class", Scope = "type", Target = "~T:Calc.UI.MainWindow")] diff --git a/Calc/Calc.UI/MainWindow.axaml b/Calc/Calc.UI/MainWindow.axaml new file mode 100644 index 0000000..0adb7b0 --- /dev/null +++ b/Calc/Calc.UI/MainWindow.axaml @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + + +