0
mirror of https://github.com/sampletext32/ParkanPlayground.git synced 2025-05-19 03:41:18 +03:00

Update TestDataProvider to use CSV files directly from filesystem instead of embedded resources

This commit is contained in:
bird_egop 2025-04-15 23:21:52 +03:00
parent 61e92a50a5
commit 6882f0bd86
4 changed files with 64 additions and 78 deletions

View File

@ -136,19 +136,25 @@ public enum InstructionType
Fst, // Store floating point value Fst, // Store floating point value
Fstp, // Store floating point value and pop Fstp, // Store floating point value and pop
Fadd, // Add floating point Fadd, // Add floating point
Faddp, // Add floating point and pop
Fiadd, // Add integer to floating point Fiadd, // Add integer to floating point
Fild, // Load integer to floating point Fild, // Load integer to floating point
Fist, // Store integer Fist, // Store integer
Fistp, // Store integer and pop Fistp, // Store integer and pop
Fsub, // Subtract floating point Fsub, // Subtract floating point
Fsubp, // Subtract floating point and pop
Fisub, // Subtract integer from floating point Fisub, // Subtract integer from floating point
Fsubr, // Subtract floating point reversed Fsubr, // Subtract floating point reversed
Fsubrp, // Subtract floating point reversed and pop
Fisubr, // Subtract floating point from integer (reversed) Fisubr, // Subtract floating point from integer (reversed)
Fmul, // Multiply floating point Fmul, // Multiply floating point
Fmulp, // Multiply floating point and pop
Fimul, // Multiply integer with floating point Fimul, // Multiply integer with floating point
Fdiv, // Divide floating point Fdiv, // Divide floating point
Fdivp, // Divide floating point and pop
Fidiv, // Divide integer by floating point Fidiv, // Divide integer by floating point
Fdivr, // Divide floating point reversed Fdivr, // Divide floating point reversed
Fdivrp, // Divide floating point reversed and pop
Fidivr, // Divide floating point by integer (reversed) Fidivr, // Divide floating point by integer (reversed)
Fcom, // Compare floating point Fcom, // Compare floating point
Ficom, // Compare integer with floating point Ficom, // Compare integer with floating point
@ -159,6 +165,7 @@ public enum InstructionType
Fcomi, // Compare floating point, set EFLAGS Fcomi, // Compare floating point, set EFLAGS
Fucom, // Unordered compare floating point Fucom, // Unordered compare floating point
Fucomp, // Unordered compare floating point and pop Fucomp, // Unordered compare floating point and pop
Fucompp, // Unordered compare floating point and pop twice
Fucomip, // Unordered compare floating point and pop, set EFLAGS Fucomip, // Unordered compare floating point and pop, set EFLAGS
Fucomi, // Unordered compare floating point, set EFLAGS Fucomi, // Unordered compare floating point, set EFLAGS
Ffreep, // Free floating point register and pop Ffreep, // Free floating point register and pop
@ -174,9 +181,12 @@ public enum InstructionType
Finit, // Initialize FPU (with FWAIT prefix) Finit, // Initialize FPU (with FWAIT prefix)
Fninit, // Initialize FPU without checking for pending unmasked exceptions Fninit, // Initialize FPU without checking for pending unmasked exceptions
Fclex, // Clear floating-point exceptions Fclex, // Clear floating-point exceptions
Fnclex, // Clear floating-point exceptions without checking for pending unmasked exceptions
Fldenv, // Load FPU environment Fldenv, // Load FPU environment
Fnstenv, // Store FPU environment Fnstenv, // Store FPU environment
Frstor, // Restore FPU state Frstor, // Restore FPU state
Fnsave, // Save FPU state without checking for pending unmasked exceptions
Fsave, // Save FPU state
// Flag control instructions // Flag control instructions
Stc, // Set Carry Flag Stc, // Set Carry Flag
@ -188,27 +198,26 @@ public enum InstructionType
Cli, // Clear Interrupt Flag Cli, // Clear Interrupt Flag
Sahf, // Store AH into Flags Sahf, // Store AH into Flags
Lahf, // Load Flags into AH Lahf, // Load Flags into AH
Fnsave, // Save FPU state
Fxch, // Exchange floating point registers Fxch, // Exchange floating point registers
Fchs, // Change sign of floating point value Fchs, // Change sign of floating point value
Fabs, // Absolute value of floating point Fabs, // Absolute value of floating point
Ftst, // Test floating point Ftst, // Test floating point
F2xm1, // 2^x - 1 F2xm1, // 2^x - 1
Fyl2x, // y * log2(x) Fyl2x, // y * log2(x)
Fyl2xp1, // y * log2(x+1)
Fptan, // Partial tangent Fptan, // Partial tangent
Fpatan, // Partial arctangent Fpatan, // Partial arctangent
Fxtract, // Extract exponent and significand Fxtract, // Extract exponent and significand
Fprem1, // Partial remainder (IEEE)
Fdecstp, // Decrement stack pointer
Fincstp, // Increment stack pointer
Fprem, // Partial remainder Fprem, // Partial remainder
Fyl2xp1, // y * log2(x+1) Fprem1, // Partial remainder (IEEE)
Fsqrt, // Square root Fdecstp, // Decrement FPU stack pointer
Fsincos, // Sine and cosine Fincstp, // Increment FPU stack pointer
Frndint, // Round to integer Frndint, // Round to integer
Fscale, // Scale by power of 2 Fscale, // Scale by power of 2
Fsin, // Sine Fsin, // Sine
Fcos, // Cosine Fcos, // Cosine
Fsincos, // Sine and cosine
Fsqrt, // Square root
Fnop, // No operation Fnop, // No operation
Fwait, // Wait for FPU Fwait, // Wait for FPU

View File

@ -1,15 +1,20 @@
using System.Text.Json; using System.Text.Json;
using System.Text.Json.Serialization;
using CsvHelper; using CsvHelper;
using CsvHelper.Configuration; using CsvHelper.Configuration;
using CsvHelper.TypeConversion; using CsvHelper.TypeConversion;
using X86Disassembler.X86;
namespace X86DisassemblerTests; namespace X86DisassemblerTests;
// ReSharper disable once ClassNeverInstantiated.Global // ReSharper disable once ClassNeverInstantiated.Global
public sealed class CsvJsonConverter<T> : DefaultTypeConverter public sealed class CsvJsonConverter<T> : DefaultTypeConverter
{ {
private static JsonSerializerOptions _options = new JsonSerializerOptions() // Configure JSON options with case-insensitive enum handling
private static readonly JsonSerializerOptions _options = new JsonSerializerOptions
{ {
PropertyNameCaseInsensitive = true,
Converters = { new JsonStringEnumConverter(JsonNamingPolicy.CamelCase) }
}; };
public override object? ConvertFromString(string? text, IReaderRow row, MemberMapData memberMapData) public override object? ConvertFromString(string? text, IReaderRow row, MemberMapData memberMapData)
@ -19,11 +24,11 @@ public sealed class CsvJsonConverter<T> : DefaultTypeConverter
return null; return null;
} }
return JsonSerializer.Deserialize<T>(text); return JsonSerializer.Deserialize<T>(text, _options);
} }
public override string? ConvertToString(object? value, IWriterRow row, MemberMapData memberMapData) public override string? ConvertToString(object? value, IWriterRow row, MemberMapData memberMapData)
{ {
return JsonSerializer.Serialize(value); return JsonSerializer.Serialize(value, _options);
} }
} }

View File

@ -1,6 +1,6 @@
using System.Collections; using System.Collections;
using System.Globalization; using System.Globalization;
using System.Reflection; using System.IO;
using CsvHelper; using CsvHelper;
using CsvHelper.Configuration; using CsvHelper.Configuration;
@ -14,39 +14,52 @@ public class TestDataProvider : IEnumerable<object[]>
/// <summary> /// <summary>
/// Gets all CSV test files from the TestData directory /// Gets all CSV test files from the TestData directory
/// </summary> /// </summary>
/// <returns>An enumerable of test file names</returns> /// <returns>An enumerable of test file paths</returns>
private IEnumerable<string> GetTestFiles() private IEnumerable<string> GetTestFiles()
{ {
// Get all CSV files from the TestData directory in the assembly // Get the directory where the test assembly is located
var assembly = Assembly.GetExecutingAssembly(); var assemblyLocation = typeof(TestDataProvider).Assembly.Location;
var resourceNames = assembly.GetManifestResourceNames() var assemblyDirectory = Path.GetDirectoryName(assemblyLocation);
.Where(name => name.StartsWith("X86DisassemblerTests.TestData.") && name.EndsWith(".csv"));
// Navigate to the TestData directory
// First try to find it in the project structure (for development)
string testDataDirectory = Path.Combine(assemblyDirectory!, "..", "..", "..", "TestData");
// If the directory doesn't exist (e.g., in a published build), try the output directory
if (!Directory.Exists(testDataDirectory))
{
testDataDirectory = Path.Combine(assemblyDirectory!, "TestData");
// If still not found, throw an exception
if (!Directory.Exists(testDataDirectory))
{
throw new DirectoryNotFoundException($"Could not find TestData directory at {testDataDirectory}");
}
}
// Get the absolute path
testDataDirectory = Path.GetFullPath(testDataDirectory);
// Return all CSV files from the TestData directory // Return all CSV files from the TestData directory
// All files have been converted to the new format return Directory.GetFiles(testDataDirectory, "*.csv");
foreach (var resourceName in resourceNames)
{
// Return the full resource name
yield return resourceName;
}
} }
/// <summary> /// <summary>
/// Loads test entries from a CSV file /// Loads test entries from a CSV file
/// </summary> /// </summary>
/// <param name="resourceName">The full resource name of the CSV file</param> /// <param name="filePath">The full path to the CSV file</param>
/// <returns>An enumerable of TestFromFileEntry objects</returns> /// <returns>An enumerable of TestFromFileEntry objects</returns>
private IEnumerable<TestFromFileEntry> LoadTestEntries(string resourceName) private IEnumerable<TestFromFileEntry> LoadTestEntries(string filePath)
{ {
// Load the CSV test file from embedded resources // Check if the file exists
using var stream = Assembly.GetExecutingAssembly() if (!File.Exists(filePath))
.GetManifestResourceStream(resourceName);
if (stream == null)
{ {
throw new InvalidOperationException($"Could not find {resourceName} embedded resource"); throw new FileNotFoundException($"Could not find test file at {filePath}");
} }
// Open the file directly from the file system
using var stream = File.OpenRead(filePath);
// Configure CSV reader with semicolon delimiter // Configure CSV reader with semicolon delimiter
var config = new CsvConfiguration(CultureInfo.InvariantCulture) var config = new CsvConfiguration(CultureInfo.InvariantCulture)
{ {
@ -79,13 +92,13 @@ public class TestDataProvider : IEnumerable<object[]>
/// </summary> /// </summary>
public IEnumerator<object[]> GetEnumerator() public IEnumerator<object[]> GetEnumerator()
{ {
foreach (var resourceName in GetTestFiles()) foreach (var filePath in GetTestFiles())
{ {
// Extract just the filename part for display purposes // Extract just the filename part for display purposes
string fileName = resourceName.Replace("X86DisassemblerTests.TestData.", ""); string fileName = Path.GetFileName(filePath);
int testIndex = 0; int testIndex = 0;
foreach (var entry in LoadTestEntries(resourceName)) foreach (var entry in LoadTestEntries(filePath))
{ {
// Yield each test entry as a separate test case // Yield each test entry as a separate test case
// Include the file name and index for better test identification // Include the file name and index for better test identification

View File

@ -28,50 +28,9 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<EmbeddedResource Include="TestData\adc_tests.csv"/> <Content Include="TestData\**\*.csv">
<EmbeddedResource Include="TestData\add_tests.csv"/> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<EmbeddedResource Include="TestData\and_tests.csv"/> </Content>
<EmbeddedResource Include="TestData\bit_tests.csv"/>
<EmbeddedResource Include="TestData\call_tests.csv"/>
<EmbeddedResource Include="TestData\cmp_tests.csv"/>
<EmbeddedResource Include="TestData\div_tests.csv"/>
<EmbeddedResource Include="TestData\flag_tests.csv"/>
<EmbeddedResource Include="TestData\fnstsw_tests.csv"/>
<EmbeddedResource Include="TestData\fpu_tests.csv"/>
<EmbeddedResource Include="TestData\group3_instruction_tests.csv"/>
<EmbeddedResource Include="TestData\idiv_tests.csv"/>
<EmbeddedResource Include="TestData\imul_tests.csv"/>
<EmbeddedResource Include="TestData\jcc_tests.csv"/>
<EmbeddedResource Include="TestData\jmp_tests.csv"/>
<EmbeddedResource Include="TestData\lea_tests.csv"/>
<EmbeddedResource Include="TestData\misc_tests.csv"/>
<EmbeddedResource Include="TestData\mov_tests.csv"/>
<EmbeddedResource Include="TestData\mul_tests.csv"/>
<EmbeddedResource Include="TestData\neg_tests.csv"/>
<EmbeddedResource Include="TestData\nop_tests.csv"/>
<EmbeddedResource Include="TestData\not_tests.csv"/>
<EmbeddedResource Include="TestData\or_tests.csv"/>
<EmbeddedResource Include="TestData\popreg_tests.csv"/>
<EmbeddedResource Include="TestData\poprm_tests.csv"/>
<EmbeddedResource Include="TestData\pushimm_tests.csv"/>
<EmbeddedResource Include="TestData\pushreg_tests.csv"/>
<EmbeddedResource Include="TestData\pushrm_tests.csv"/>
<EmbeddedResource Include="TestData\rcl_tests.csv"/>
<EmbeddedResource Include="TestData\rcr_tests.csv"/>
<EmbeddedResource Include="TestData\ret_tests.csv"/>
<EmbeddedResource Include="TestData\rol_tests.csv"/>
<EmbeddedResource Include="TestData\ror_tests.csv"/>
<EmbeddedResource Include="TestData\sar_tests.csv"/>
<EmbeddedResource Include="TestData\sbb_tests.csv"/>
<EmbeddedResource Include="TestData\segment_override_tests.csv"/>
<EmbeddedResource Include="TestData\shl_tests.csv"/>
<EmbeddedResource Include="TestData\shr_tests.csv"/>
<EmbeddedResource Include="TestData\stack_tests.csv"/>
<EmbeddedResource Include="TestData\string_tests.csv"/>
<EmbeddedResource Include="TestData\sub_tests.csv"/>
<EmbeddedResource Include="TestData\test_tests.csv"/>
<EmbeddedResource Include="TestData\xchg_tests.csv"/>
<EmbeddedResource Include="TestData\xor_tests.csv"/>
</ItemGroup> </ItemGroup>
</Project> </Project>