diff --git a/07/CamelCards.Tests/GlobalUsings.cs b/07/CamelCards.Tests/GlobalUsings.cs
index 2d5b473..d6f0167 100644
--- a/07/CamelCards.Tests/GlobalUsings.cs
+++ b/07/CamelCards.Tests/GlobalUsings.cs
@@ -1,3 +1,3 @@
global using FluentAssertions;
-global using Xunit;
+global using Xunit;
\ No newline at end of file
diff --git a/08/HauntedWasteland.Tests/GlobalUsings.cs b/08/HauntedWasteland.Tests/GlobalUsings.cs
index 7fef4b0..2d5b473 100644
--- a/08/HauntedWasteland.Tests/GlobalUsings.cs
+++ b/08/HauntedWasteland.Tests/GlobalUsings.cs
@@ -1,2 +1,3 @@
+global using FluentAssertions;
+
global using Xunit;
-global using FluentAssertions;
\ No newline at end of file
diff --git a/09/MirageMaintenance.Tests/GlobalUsings.cs b/09/MirageMaintenance.Tests/GlobalUsings.cs
new file mode 100644
index 0000000..2d5b473
--- /dev/null
+++ b/09/MirageMaintenance.Tests/GlobalUsings.cs
@@ -0,0 +1,3 @@
+global using FluentAssertions;
+
+global using Xunit;
diff --git a/09/MirageMaintenance.Tests/MirageMaintenance.Tests.csproj b/09/MirageMaintenance.Tests/MirageMaintenance.Tests.csproj
new file mode 100644
index 0000000..52a586c
--- /dev/null
+++ b/09/MirageMaintenance.Tests/MirageMaintenance.Tests.csproj
@@ -0,0 +1,36 @@
+
+
+
+ net8.0
+ enable
+ enable
+
+ false
+ true
+
+
+
+
+
+
+
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+ all
+
+
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+ all
+
+
+
+
+
+
+
+
+
+ PreserveNewest
+
+
+
+
diff --git a/09/MirageMaintenance.Tests/OasisReportTests.cs b/09/MirageMaintenance.Tests/OasisReportTests.cs
new file mode 100644
index 0000000..c69fc91
--- /dev/null
+++ b/09/MirageMaintenance.Tests/OasisReportTests.cs
@@ -0,0 +1,77 @@
+namespace MirageMaintenance.Tests;
+
+public class UnitTest1
+{
+ [Theory]
+ [MemberData(nameof(TestData.OasisReportParseTestData), MemberType = typeof(TestData))]
+ public void Parse_GivenAReportInput_ItShouldReturnExpectedOasisReportInstance(string[] input, OasisReport expected)
+ {
+ OasisReport
+ .Parse(input)
+ .Should()
+ .BeEquivalentTo(expected);
+ }
+
+ [Fact]
+ public void CalculateSumOfNextValues_GivenAReportInput_ItShouldReturnTheSumOfAllNextValues()
+ {
+ var input = new string[]
+ {
+ "0 3 6 9 12 15",
+ "1 3 6 10 15 21",
+ "10 13 16 21 30 45",
+ };
+
+ OasisReport
+ .Parse(input)
+ .CalculateSumOfNextValues()
+ .Should()
+ .Be(114);
+ }
+
+ [Fact]
+ public void CalculateSumOfNextValues_WhenGivenInput_ItShouldReturnTheSumOfAllNextValues()
+ {
+ OasisReport
+ .Parse(TestData.Input)
+ .CalculateSumOfNextValues()
+ .Should()
+ .Be(2175229206);
+ }
+
+ [Fact]
+ public void CalculateSumOfNextValues_WhenGivenInputAndBackwardsIsTrue_ItShouldReturnTheSumOfAllNextValues()
+ {
+ OasisReport
+ .Parse(TestData.Input)
+ .CalculateSumOfNextValues(true)
+ .Should()
+ .Be(942);
+ }
+
+ public static class TestData
+ {
+ public static readonly string[] Input = File.ReadAllLines("INPUT.txt");
+
+ public static IEnumerable