Skip to content
Merged
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
28 changes: 28 additions & 0 deletions Calc/Calc.Tests/Calc.Tests.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<LangVersion>latest</LangVersion>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>

<IsTestProject>true</IsTestProject>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="coverlet.collector" Version="6.0.2" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.12.0" />
<PackageReference Include="NUnit" Version="4.2.2" />
<PackageReference Include="NUnit.Analyzers" Version="4.4.0" />
<PackageReference Include="NUnit3TestAdapter" Version="4.6.0" />
</ItemGroup>

<ItemGroup>
<Using Include="NUnit.Framework" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="../Calc/Calc.csproj"/>
</ItemGroup>

</Project>
56 changes: 56 additions & 0 deletions Calc/Calc.Tests/CalcErrorTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
// <copyright file="CalcErrorTests.cs" company="Ilya Krivtsov">
// Copyright (c) Ilya Krivtsov. All rights reserved.
// </copyright>

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"));
}
}
145 changes: 145 additions & 0 deletions Calc/Calc.Tests/CalcTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
// <copyright file="CalcTests.cs" company="Ilya Krivtsov">
// Copyright (c) Ilya Krivtsov. All rights reserved.
// </copyright>

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"));
}
}
11 changes: 11 additions & 0 deletions Calc/Calc.Tests/GlobalSuppressions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// <copyright file="GlobalSuppressions.cs" company="Ilya Krivtsov">
// Copyright (c) Ilya Krivtsov. All rights reserved.
// </copyright>

// 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")]
10 changes: 10 additions & 0 deletions Calc/Calc.UI/App.axaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<Application xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="Calc.UI.App"
RequestedThemeVariant="Default">
<!-- "Default" ThemeVariant follows system theme variant. "Dark" or "Light" are other available options. -->

<Application.Styles>
<FluentTheme />
</Application.Styles>
</Application>
27 changes: 27 additions & 0 deletions Calc/Calc.UI/App.axaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// <copyright file="App.axaml.cs" company="Ilya Krivtsov">
// Copyright (c) Ilya Krivtsov. All rights reserved.
// </copyright>

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();
}
}
21 changes: 21 additions & 0 deletions Calc/Calc.UI/Calc.UI.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net9.0</TargetFramework>
<Nullable>enable</Nullable>
<BuiltInComInteropSupport>true</BuiltInComInteropSupport>
<ApplicationManifest>app.manifest</ApplicationManifest>
<AvaloniaUseCompiledBindingsByDefault>true</AvaloniaUseCompiledBindingsByDefault>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Avalonia" Version="11.2.7" />
<PackageReference Include="Avalonia.Desktop" Version="11.2.7" />
<PackageReference Include="Avalonia.Themes.Fluent" Version="11.2.7" />
<PackageReference Include="Avalonia.Fonts.Inter" Version="11.2.7" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="../Calc/Calc.csproj" />
</ItemGroup>
</Project>
16 changes: 16 additions & 0 deletions Calc/Calc.UI/GlobalSuppressions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// <copyright file="GlobalSuppressions.cs" company="Ilya Krivtsov">
// Copyright (c) Ilya Krivtsov. All rights reserved.
// </copyright>

// 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")]
47 changes: 47 additions & 0 deletions Calc/Calc.UI/MainWindow.axaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<Window xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="512" d:DesignHeight="640"
x:Class="Calc.UI.MainWindow"
Width="512" Height="640" CanResize="false">

<Grid x:Name="buttonsGrid">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="120"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>

<Label x:Name="resultText" Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="4" FontSize="80" Content="0"
HorizontalContentAlignment="Right" VerticalContentAlignment="Center"/>

<Button Grid.Row="5" Grid.Column="0" Grid.ColumnSpan="2" Content="0" FontSize="48" Margin="4" Click="OnZero"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch" HorizontalContentAlignment="Center" VerticalContentAlignment="Center"/>
<Button Grid.Row="5" Grid.Column="2" Content="." FontSize="48" Margin="4" Click="OnDecimal"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch" HorizontalContentAlignment="Center" VerticalContentAlignment="Center"/>

<Button Grid.Row="1" Grid.Column="0" Content="C" FontSize="48" Margin="4" Click="OnClear"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch" HorizontalContentAlignment="Center" VerticalContentAlignment="Center"/>
<Button Grid.Row="1" Grid.Column="1" Content="÷" FontSize="48" Margin="4" Click="OnOperator" Tag="Division"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch" HorizontalContentAlignment="Center" VerticalContentAlignment="Center"/>
<Button Grid.Row="1" Grid.Column="2" Content="×" FontSize="48" Margin="4" Click="OnOperator" Tag="Multiplication"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch" HorizontalContentAlignment="Center" VerticalContentAlignment="Center"/>
<Button Grid.Row="1" Grid.Column="3" Content="-" FontSize="48" Margin="4" Click="OnOperator" Tag="Subtraction"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch" HorizontalContentAlignment="Center" VerticalContentAlignment="Center"/>

<Button Grid.Row="2" Grid.Column="3" Grid.RowSpan="2" Content="+" FontSize="48" Margin="4" Click="OnOperator" Tag="Addition"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch" HorizontalContentAlignment="Center" VerticalContentAlignment="Center"/>
<Button Grid.Row="4" Grid.Column="3" Grid.RowSpan="2" Content="=" FontSize="48" Margin="4" Click="OnEquals"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch" HorizontalContentAlignment="Center" VerticalContentAlignment="Center"/>
</Grid>
</Window>
Loading