diff --git a/LR35902/SM83.HarteTest/ProcessorTestSuite.cs b/LR35902/SM83.HarteTest/ProcessorTestSuite.cs deleted file mode 100644 index 8cf221e..0000000 --- a/LR35902/SM83.HarteTest/ProcessorTestSuite.cs +++ /dev/null @@ -1,19 +0,0 @@ -namespace SM83.HarteTest -{ - internal sealed class ProcessorTestSuite(string location) - { - public string Location { get; set; } = location; - - public IEnumerable OpcodeTests() - { - foreach (var filename in Directory.EnumerateFiles(this.Location, "*.json")) - { - var fileInformation = new FileInfo(filename); - if (fileInformation.Length > 0) - { - yield return new OpcodeTestSuite(filename); - } - } - } - } -} diff --git a/LR35902/SM83.HarteTest/Program.cs b/LR35902/SM83.HarteTest/Program.cs deleted file mode 100644 index 1d43f2b..0000000 --- a/LR35902/SM83.HarteTest/Program.cs +++ /dev/null @@ -1,87 +0,0 @@ -// -// Copyright (c) Adrian Conlon. All rights reserved. -// - -namespace SM83.HarteTest -{ - internal static class Program - { - public static async Task Main(string[] _) - { - var directory = @"C:\github\spectrum\libraries\EightBit\modules\sm83\v1"; - - await ProcessTestSuiteAsync(directory).ConfigureAwait(false); - } - - private static async Task ProcessTestSuiteAsync(string directory) - { - var startTime = DateTime.Now; - - var unimplemented_opcode_count = 0; - var invalid_opcode_count = 0; - - var runner = new TestRunner(); - runner.Initialize(); - - var checker = new Checker(runner); - checker.Initialise(); - - var testSuite = new ProcessorTestSuite(directory); - foreach (var opcode in testSuite.OpcodeTests()) - { - Console.WriteLine($"Processing: {Path.GetFileName(opcode.Path)}"); - - List testNames = []; - var tests = opcode.TestsAsync; - await foreach (var test in tests) - { - if (test is null) - { - throw new InvalidOperationException("Test cannot be null"); - } - - checker.Check(test); - if (checker.Invalid) - { - ++invalid_opcode_count; - - // Was it just unimplemented? - if (checker.Unimplemented) - { - ++unimplemented_opcode_count; - } - - // Let's see if we had any successes! - if (testNames.Count > 0) - { - Console.WriteLine("**** The follow test variations succeeded"); - foreach (var testName in testNames) - { - Console.WriteLine($"****** {testName}"); - } - } - - // OK, we've attempted an implementation, how did it fail? - foreach (var message in checker.Messages) - { - Console.WriteLine($"**** {message}"); - } - - // I'm not really interested in the remaining tests for this opcode - break; - } - - testNames.Add(test.Name); - } - } - - var finishTime = DateTime.Now; - var elapsedTime = finishTime - startTime; - - Console.Write($"Elapsed time: {elapsedTime.TotalSeconds} seconds"); - Console.Write($", unimplemented opcode count: {unimplemented_opcode_count}"); - Console.Write($", invalid opcode count: {invalid_opcode_count - unimplemented_opcode_count}"); - Console.WriteLine(); - } - } -} \ No newline at end of file diff --git a/LR35902/SM83.HarteTest/SM83.HarteTest.csproj b/LR35902/SM83.HarteTest/SM83.HarteTest.csproj index 3c013e2..d8d0428 100644 --- a/LR35902/SM83.HarteTest/SM83.HarteTest.csproj +++ b/LR35902/SM83.HarteTest/SM83.HarteTest.csproj @@ -1,12 +1,18 @@ - + - Exe net10.0 + latest enable enable + true + False + False + Exe + true True - latest-all + latest-all + true @@ -17,9 +23,21 @@ 9999 - - - - + + + + + + + + + + + + + + + + diff --git a/LR35902/SM83.HarteTest/SingleStepTests.cs b/LR35902/SM83.HarteTest/SingleStepTests.cs new file mode 100644 index 0000000..3f2c46e --- /dev/null +++ b/LR35902/SM83.HarteTest/SingleStepTests.cs @@ -0,0 +1,71 @@ +// +// Copyright (c) Adrian Conlon. All rights reserved. +// +namespace SM83.HarteTest +{ + using System.Reflection; + + [TestClass] + public class SingleStepTests + { + private const string TestDataDirectory = @"C:\github\spectrum\libraries\EightBit\modules\sm83\v1"; + + public static IEnumerable OpcodeFiles + { + get + { + if (!Directory.Exists(TestDataDirectory)) + { + yield break; + } + + foreach (var file in Directory.EnumerateFiles(TestDataDirectory, "*.json").OrderBy(f => f)) + { + if (new FileInfo(file).Length > 0) + { + yield return [file]; + } + } + } + } + + public static string GetDisplayName(MethodInfo _, object[] data) + { + ArgumentNullException.ThrowIfNull(data); + return System.IO.Path.GetFileNameWithoutExtension((string)data[0]); + } + + [TestMethod] + [DynamicData(nameof(OpcodeFiles), DynamicDataSourceType.Property, DynamicDataDisplayName = nameof(GetDisplayName))] + public async Task Opcode_SingleStep(string filePath) + { + var runner = new TestRunner(); + runner.Initialize(); + var checker = new Checker(runner); + checker.Initialise(); + + using var suite = new OpcodeTestSuite(filePath); + await foreach (var test in suite.TestsAsync) + { + if (test is null) + { + throw new InvalidOperationException("Test cannot be null"); + } + + checker.Check(test); + + if (checker.Unimplemented) + { + Assert.Inconclusive($"Opcode not implemented: {test.Name}"); + return; + } + + if (checker.Invalid) + { + Assert.Fail($"Test '{test.Name}' failed:{System.Environment.NewLine}{string.Join(System.Environment.NewLine, checker.Messages)}"); + return; + } + } + } + } +} diff --git a/LR35902/SM83.HarteTest/State.cs b/LR35902/SM83.HarteTest/State.cs index db9a46e..5769a2a 100644 --- a/LR35902/SM83.HarteTest/State.cs +++ b/LR35902/SM83.HarteTest/State.cs @@ -1,5 +1,6 @@ namespace SM83.HarteTest { + [System.Diagnostics.CodeAnalysis.SuppressMessage("Performance", "CA1812:Avoid uninstantiated internal classes", Justification = "Instantiated by JSON deserializer")] internal sealed class State { public ushort PC { get; set; } diff --git a/LR35902/SM83.HarteTest/Test.cs b/LR35902/SM83.HarteTest/Test.cs index a50a6ca..5adab74 100644 --- a/LR35902/SM83.HarteTest/Test.cs +++ b/LR35902/SM83.HarteTest/Test.cs @@ -1,5 +1,6 @@ namespace SM83.HarteTest { + [System.Diagnostics.CodeAnalysis.SuppressMessage("Performance", "CA1812:Avoid uninstantiated internal classes", Justification = "Instantiated by JSON deserializer")] internal sealed class Test { public string? Name { get; set; }