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));
+ }
+}