using System.Collections;
using System.Globalization;
using System.IO;
using CsvHelper;
using CsvHelper.Configuration;
namespace X86DisassemblerTests;
///
/// Provides test data from CSV files in the TestData directory
///
public class TestDataProvider : IEnumerable
{
///
/// Gets all CSV test files from the TestData directory
///
/// An enumerable of test file paths
private IEnumerable GetTestFiles()
{
// Get the directory where the test assembly is located
var assemblyLocation = typeof(TestDataProvider).Assembly.Location;
var assemblyDirectory = Path.GetDirectoryName(assemblyLocation);
// 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 Directory.GetFiles(testDataDirectory, "*.csv");
}
///
/// Loads test entries from a CSV file
///
/// The full path to the CSV file
/// An enumerable of TestFromFileEntry objects
private IEnumerable LoadTestEntries(string filePath)
{
// Check if the file exists
if (!File.Exists(filePath))
{
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
var config = new CsvConfiguration(CultureInfo.InvariantCulture)
{
HasHeaderRecord = true,
Delimiter = ";",
BadDataFound = null, // Ignore bad data
AllowComments = true, // Enable comments in CSV files
Comment = '#', // Use # as the comment character
IgnoreBlankLines = true // Skip empty lines
};
using var streamReader = new StreamReader(stream);
using var csvReader = new CsvReader(streamReader, config);
// Register class map for TestFromFileEntry
csvReader.Context.RegisterClassMap();
// Read all records from CSV
var entries = csvReader.GetRecords().ToList();
// Return each entry with its file name
foreach (var entry in entries)
{
yield return entry;
}
}
///
/// Returns an enumerator that provides test data for each test entry
///
public IEnumerator GetEnumerator()
{
foreach (var filePath in GetTestFiles())
{
// Extract just the filename part for display purposes
string fileName = Path.GetFileName(filePath);
int testIndex = 0;
foreach (var entry in LoadTestEntries(filePath))
{
// Yield each test entry as a separate test case
// Include the file name and index for better test identification
yield return [fileName, testIndex++, entry];
}
}
}
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
}