From 01ce9944ffc2a6861183ce822c0d4d7feec16f0b Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 25 Mar 2026 05:28:05 +0000 Subject: [PATCH 1/2] Initial plan From 2bf266d5fcdd6a9ecc05d83e4bdc7b8f7c1355c6 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 25 Mar 2026 05:33:44 +0000 Subject: [PATCH 2/2] Add MathService with factorial calculation and unit tests Co-authored-by: kavyashri-as <213833080+kavyashri-as@users.noreply.github.com> Agent-Logs-Url: https://github.com/CanarysPlayground/CourseApplication/sessions/4bc2795d-b601-4b49-8ef4-e6d7287f2484 --- .../Services/IMathService.cs | 16 ++++ .../Services/MathService.cs | 34 +++++++++ .../Services/MathServiceTests.cs | 75 +++++++++++++++++++ 3 files changed, 125 insertions(+) create mode 100644 api/CourseRegistration.Application/Services/IMathService.cs create mode 100644 api/CourseRegistration.Application/Services/MathService.cs create mode 100644 api/CourseRegistration.Tests/Services/MathServiceTests.cs diff --git a/api/CourseRegistration.Application/Services/IMathService.cs b/api/CourseRegistration.Application/Services/IMathService.cs new file mode 100644 index 0000000..5a0c780 --- /dev/null +++ b/api/CourseRegistration.Application/Services/IMathService.cs @@ -0,0 +1,16 @@ +namespace CourseRegistration.Application.Services; + +/// +/// Interface for mathematical utility operations. +/// +public interface IMathService +{ + /// + /// Calculates the factorial of a non-negative integer. + /// + /// A non-negative integer whose factorial is to be computed. + /// The factorial of as a . + /// Thrown when is negative. + /// Thrown when the result exceeds . + long CalculateFactorial(int n); +} diff --git a/api/CourseRegistration.Application/Services/MathService.cs b/api/CourseRegistration.Application/Services/MathService.cs new file mode 100644 index 0000000..89723eb --- /dev/null +++ b/api/CourseRegistration.Application/Services/MathService.cs @@ -0,0 +1,34 @@ +namespace CourseRegistration.Application.Services; + +/// +/// Provides mathematical utility operations such as factorial calculation. +/// +public class MathService : IMathService +{ + // 20! is the largest factorial that fits in a long (Int64) + private const int MaxFactorialInput = 20; + + /// + /// Calculates the factorial of a non-negative integer iteratively. + /// + /// A non-negative integer (0 – 20) whose factorial is to be computed. + /// The factorial of . + /// Thrown when is negative. + /// Thrown when exceeds 20 and the result would overflow . + public long CalculateFactorial(int n) + { + if (n < 0) + throw new ArgumentOutOfRangeException(nameof(n), "Factorial is not defined for negative numbers."); + + if (n > MaxFactorialInput) + throw new OverflowException($"Input {n} is too large; factorial exceeds the range of a 64-bit integer (max supported: {MaxFactorialInput})."); + + long result = 1; + for (int i = 2; i <= n; i++) + { + result *= i; + } + + return result; + } +} diff --git a/api/CourseRegistration.Tests/Services/MathServiceTests.cs b/api/CourseRegistration.Tests/Services/MathServiceTests.cs new file mode 100644 index 0000000..474e5ce --- /dev/null +++ b/api/CourseRegistration.Tests/Services/MathServiceTests.cs @@ -0,0 +1,75 @@ +using Xunit; +using CourseRegistration.Application.Services; + +namespace CourseRegistration.Tests.Services; + +/// +/// Unit tests for factorial calculation. +/// +public class MathServiceTests +{ + private readonly MathService _mathService = new(); + + // ── Base cases ───────────────────────────────────────────────────────────── + + [Fact] + public void CalculateFactorial_Zero_ReturnsOne() + { + // Arrange / Act + var result = _mathService.CalculateFactorial(0); + + // Assert + Assert.Equal(1L, result); + } + + [Fact] + public void CalculateFactorial_One_ReturnsOne() + { + // Arrange / Act + var result = _mathService.CalculateFactorial(1); + + // Assert + Assert.Equal(1L, result); + } + + // ── Typical positive values ──────────────────────────────────────────────── + + [Theory] + [InlineData(2, 2L)] + [InlineData(3, 6L)] + [InlineData(4, 24L)] + [InlineData(5, 120L)] + [InlineData(10, 3628800L)] + [InlineData(15, 1307674368000L)] + [InlineData(20, 2432902008176640000L)] + public void CalculateFactorial_PositiveInput_ReturnsCorrectResult(int n, long expected) + { + // Arrange / Act + var result = _mathService.CalculateFactorial(n); + + // Assert + Assert.Equal(expected, result); + } + + // ── Error paths ──────────────────────────────────────────────────────────── + + [Theory] + [InlineData(-1)] + [InlineData(-100)] + [InlineData(int.MinValue)] + public void CalculateFactorial_NegativeInputs_ThrowsArgumentOutOfRangeException(int n) + { + // Arrange / Act / Assert + Assert.Throws(() => _mathService.CalculateFactorial(n)); + } + + [Theory] + [InlineData(21)] + [InlineData(100)] + [InlineData(int.MaxValue)] + public void CalculateFactorial_LargeInputs_ThrowsOverflowException(int n) + { + // Arrange / Act / Assert + Assert.Throws(() => _mathService.CalculateFactorial(n)); + } +}