From 958d187b71d6119558fc5276f5a16a44a2deee41 Mon Sep 17 00:00:00 2001 From: DualFroz Date: Thu, 27 Aug 2026 20:43:58 +0200 Subject: [PATCH] chore(tests): scaffold Chip8.Tests project with test harness --- tests/Chip8.Tests/Chip8.Tests.csproj | 27 +++++++++ tests/Chip8.Tests/TestHarness.cs | 88 ++++++++++++++++++++++++++++ 2 files changed, 115 insertions(+) create mode 100644 tests/Chip8.Tests/Chip8.Tests.csproj create mode 100644 tests/Chip8.Tests/TestHarness.cs diff --git a/tests/Chip8.Tests/Chip8.Tests.csproj b/tests/Chip8.Tests/Chip8.Tests.csproj new file mode 100644 index 0000000..b29ef17 --- /dev/null +++ b/tests/Chip8.Tests/Chip8.Tests.csproj @@ -0,0 +1,27 @@ + + + + net6.0 + disable + enable + false + Chip8.Tests + Chip8.Tests + 10 + + + + + + + + + + + + + + + + + diff --git a/tests/Chip8.Tests/TestHarness.cs b/tests/Chip8.Tests/TestHarness.cs new file mode 100644 index 0000000..93b86ef --- /dev/null +++ b/tests/Chip8.Tests/TestHarness.cs @@ -0,0 +1,88 @@ +using System; +using System.IO; +using Chip8.Core; + +namespace Chip8.Tests; + +static class TestHarness +{ + static string repoRoot() + { + var dir = new DirectoryInfo(AppContext.BaseDirectory); + while (dir is not null && !Directory.Exists(Path.Combine(dir.FullName, "roms"))) + { + dir = dir.Parent; + } + + if (dir is null) + { + throw new DirectoryNotFoundException("Could not locate repo root with a 'roms' directory."); + } + + return dir.FullName; + } + + public static byte[] romBytes(string name) => File.ReadAllBytes(Path.Combine(repoRoot(), "roms", name)); + + public static string goldenText(string name) => + File.ReadAllText(Path.Combine(AppContext.BaseDirectory, "goldens", name)); + + public static Machine withOpcode(ushort opcode, Quirks? quirks = null) + { + var machine = new Machine(quirks ?? Quirks.modern(), randomSeed: 1); + machine.memory[Machine.programStart] = (byte)(opcode >> 8); + machine.memory[Machine.programStart + 1] = (byte)(opcode & 0xFF); + return machine; + } + + public static Machine withOpcode(ushort opcode, Platform platform, Quirks? quirks = null) + { + var machine = new Machine(quirks, randomSeed: 1, platform); + machine.memory[Machine.programStart] = (byte)(opcode >> 8); + machine.memory[Machine.programStart + 1] = (byte)(opcode & 0xFF); + return machine; + } + + public static Machine withProgram(Platform platform, params ushort[] words) + { + var machine = new Machine(null, randomSeed: 1, platform); + for (int index = 0; index < words.Length; index++) + { + machine.memory[Machine.programStart + index * 2] = (byte)(words[index] >> 8); + machine.memory[Machine.programStart + index * 2 + 1] = (byte)(words[index] & 0xFF); + } + return machine; + } + + public const int instructionsPerFrame = 11; + + public static Machine runRom(string name, int cycles, Quirks? quirks = null) + { + var machine = new Machine(quirks ?? Quirks.modern(), randomSeed: 1); + machine.loadRom(romBytes(name)); + for (int cycle = 0; cycle < cycles; cycle++) + { + machine.step(); + if (cycle % instructionsPerFrame == instructionsPerFrame - 1) + { + machine.tickTimers(); + } + } + return machine; + } + + public static Machine runRomExtended(string name, int cycles, Platform platform, Quirks? quirks = null) + { + var machine = new Machine(quirks, randomSeed: 1, platform); + machine.loadRom(romBytes(name)); + for (int cycle = 0; cycle < cycles && !machine.exited; cycle++) + { + machine.step(); + if (cycle % instructionsPerFrame == instructionsPerFrame - 1) + { + machine.tickTimers(); + } + } + return machine; + } +}