Skip to content
Open
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
26 changes: 26 additions & 0 deletions HW6/HW6.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@

Microsoft Visual Studio Solution File, Format Version 12.00
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MyNunitWeb.Api", "MyNunitWeb.Api\MyNunitWeb.Api.csproj", "{F3460FEE-64A5-46D3-BFC6-1FC65305B172}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MyNUnit", "MyNUnit\MyNUnit.csproj", "{E723C040-0075-424E-A25F-0380CD4169BD}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{7E056C49-469E-4CCE-B46D-DAAB9542FD05}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7E056C49-469E-4CCE-B46D-DAAB9542FD05}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7E056C49-469E-4CCE-B46D-DAAB9542FD05}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7E056C49-469E-4CCE-B46D-DAAB9542FD05}.Release|Any CPU.Build.0 = Release|Any CPU
{F3460FEE-64A5-46D3-BFC6-1FC65305B172}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F3460FEE-64A5-46D3-BFC6-1FC65305B172}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F3460FEE-64A5-46D3-BFC6-1FC65305B172}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F3460FEE-64A5-46D3-BFC6-1FC65305B172}.Release|Any CPU.Build.0 = Release|Any CPU
{E723C040-0075-424E-A25F-0380CD4169BD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E723C040-0075-424E-A25F-0380CD4169BD}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E723C040-0075-424E-A25F-0380CD4169BD}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E723C040-0075-424E-A25F-0380CD4169BD}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal
46 changes: 46 additions & 0 deletions HW6/MyNUnit.SampleTests/Calculator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// <copyright file="Calculator.cs" company="khusainovilas">
// Copyright (c) khusainovilas. All rights reserved.
// </copyright>

namespace MyNUnit.SampleTests;

/// <summary>
/// Simple calculator class.
/// </summary>
public static class Calculator
{
/// <summary>
/// Adds two numbers.
/// </summary>
/// <param name="a">The first number.</param>
/// <param name="b">The second number.</param>
/// <returns>The sum of a and b.</returns>
public static int Add(int a, int b) => a + b;

/// <summary>
/// Subtracts second number from first.
/// </summary>
/// <param name="a">The number to subtract from.</param>
/// <param name="b">The number to subtract.</param>
/// <returns>The result of a minus b.</returns>
public static int Subtract(int a, int b) => a - b;

/// <summary>
/// Multiplies two numbers.
/// </summary>
/// <param name="a">The first number.</param>
/// <param name="b">The second number.</param>
/// <returns>The product of a and b.</returns>
public static int Multiply(int a, int b) => a * b;

/// <summary>
/// Divides first number by second.
/// </summary>
/// <param name="a">The dividend.</param>
/// <param name="b">The divisor.</param>
/// <returns>The result of a divided by b.</returns>
public static int Divide(int a, int b)
{
return b == 0 ? throw new DivideByZeroException() : a / b;
}
}
75 changes: 75 additions & 0 deletions HW6/MyNUnit.SampleTests/CalculatorTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
// <copyright file="CalculatorTests.cs" company="khusainovilas">
// Copyright (c) khusainovilas. All rights reserved.
// </copyright>

namespace MyNUnit.SampleTests;

using System;

/// <summary>
/// Tests for the <see cref="Calculator"/> class using MyNUnit.
/// </summary>
public class CalculatorTests
{
/// <summary>
/// Checks the addition of two numbers.
/// </summary>
[Test]
public void Calculator_Add_ShouldReturnSum()
{
var result = Calculator.Add(2, 3);
if (result != 5)
{
throw new InvalidOperationException($"Expected 5, but got {result}");
}
}

/// <summary>
/// Checks the subtraction of two numbers.
/// </summary>
[Test]
public void Calculator_Subtract_ShouldReturnDifference()
{
var result = Calculator.Subtract(10, 4);
if (result != 6)
{
throw new InvalidOperationException($"Expected 6, but got {result}");
}
}

/// <summary>
/// Checks division by zero (should throw an exception).
/// </summary>
[Test(Expected = typeof(DivideByZeroException))]
public void Calculator_Divide_ByZero_ShouldThrow()
{
Calculator.Divide(10, 0);
}

/// <summary>
/// Ignored test.
/// </summary>
[Test]
[Ignore("Example of a ignored test")]
public void Calculator_Multiply_ShouldBeIgnored()
{
var result = Calculator.Multiply(3, 4);
if (result != 12)
{
throw new InvalidOperationException($"Expected 12, but got {result}");
}
}

/// <summary>
/// A special test that intentionally crashes.
/// </summary>
[Test]
public void Calculator_FailedTest_ShouldFail()
{
var result = Calculator.Add(1, 1);
if (result != 3)
{
throw new InvalidOperationException("This test is supposed to fail");
}
}
}
13 changes: 13 additions & 0 deletions HW6/MyNUnit.SampleTests/MyNUnit.SampleTests.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">

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

<ItemGroup>
<ProjectReference Include="..\MyNUnit\MyNUnit.csproj" />
</ItemGroup>

</Project>
70 changes: 70 additions & 0 deletions HW6/MyNUnit/Attributes.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
// <copyright file="Attributes.cs" company="khusainovilas">
// Copyright (c) khusainovilas. All rights reserved.
// </copyright>

namespace MyNUnit;

/// <summary>
/// Marks the method as a test.
/// </summary>
[AttributeUsage(AttributeTargets.Method)]
public class TestAttribute : Attribute
{
/// <summary>
/// Gets or sets the expected exception type.
/// </summary>
public Type? Expected { get; set; }
}

/// <summary>
/// Skip the test with an indication of the reason.
/// </summary>
[AttributeUsage(AttributeTargets.Method)]
public class IgnoreAttribute : Attribute
{
/// <summary>
/// Initializes a new instance of the <see cref="IgnoreAttribute"/> class.
/// </summary>
/// <param name="reason">The reason for ignoring the test.</param>
public IgnoreAttribute(string reason)
{
this.Reason = reason ?? throw new ArgumentNullException(nameof(reason));
}

/// <summary>
/// Gets the reason why the test is ignored.
/// </summary>
public string Reason { get; }
}

/// <summary>
/// Runs once before all tests in the class.
/// </summary>
[AttributeUsage(AttributeTargets.Method)]
public class BeforeClassAttribute : Attribute
{
}

/// <summary>
/// Runs once after all the tests in the class.
/// </summary>
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
public class AfterClassAttribute : Attribute
{
}

/// <summary>
/// Runs before each test.
/// </summary>
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
public class BeforeAttribute : Attribute
{
}

/// <summary>
/// Runs after each test.
/// </summary>
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
public class AfterAttribute : Attribute
{
}
22 changes: 22 additions & 0 deletions HW6/MyNUnit/MyNUnit.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Library</OutputType>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>

<ItemGroup>
<AdditionalFiles Include="stylecop.json" />
</ItemGroup>

</Project>
53 changes: 53 additions & 0 deletions HW6/MyNUnit/TestDiscovery.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// <copyright file="TestDiscovery.cs" company="khusainovilas">
// Copyright (c) khusainovilas. All rights reserved.
// </copyright>

namespace MyNUnit;

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;

/// <summary>
/// Searches for test classes and test methods in assemblies.
/// </summary>
public static class TestDiscovery
{
/// <summary>
/// Discovers test classes in a DLL.
/// </summary>
/// <param name="dllPath">Path to test assembly.</param>
/// <returns>List of test class types.</returns>
public static IReadOnlyList<Type> DiscoverFromDll(string dllPath)
{
ArgumentException.ThrowIfNullOrWhiteSpace(dllPath);

if (!File.Exists(dllPath))
{
throw new FileNotFoundException("DLL not found", dllPath);
}

if (!dllPath.EndsWith(".dll", StringComparison.OrdinalIgnoreCase))
{
throw new ArgumentException("File must be a DLL", nameof(dllPath));
}

var assembly = Assembly.LoadFrom(dllPath);

return assembly
.GetTypes()
.Where(ContainsTests)
.ToList();
}

private static bool ContainsTests(Type type)
{
return type.GetMethods(
BindingFlags.Instance |
BindingFlags.Public |
BindingFlags.NonPublic)
.Any(m => m.GetCustomAttribute<TestAttribute>() != null);
}
}
54 changes: 54 additions & 0 deletions HW6/MyNUnit/TestResult.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// <copyright file="TestResult.cs" company="khusainovilas">
// Copyright (c) khusainovilas. All rights reserved.
// </copyright>

namespace MyNUnit;

using System;

/// <summary>
/// Represents the result of a single test execution.
/// </summary>
public class TestResult
{
/// <summary>
/// Gets test full name.
/// </summary>
public string TestName { get; init; } = string.Empty;

/// <summary>
/// Gets test execution status.
/// </summary>
public TestStatus Status { get; init; }

/// <summary>
/// Gets test execution duration.
/// </summary>
public TimeSpan Duration { get; init; }

/// <summary>
/// Gets additional message (failure reason or ignore reason).
/// </summary>
public string? Message { get; init; }
}

/// <summary>
/// Test execution status.
/// </summary>
public enum TestStatus
{
/// <summary>
/// Test passed successfully.
/// </summary>
Passed,

/// <summary>
/// Test failed.
/// </summary>
Failed,

/// <summary>
/// Test was ignored.
/// </summary>
Ignored,
}
Loading