using AvParser.Core.Parsing;
namespace AvParser.Core.Tests;
/// Collection helpers so the tests read as assertions rather than as loops.
internal static class ParserTestExtensions
{
///
/// Drains a parse into memory, using the ambient test cancellation token.
///
///
/// Deliberately takes no : every call site would otherwise have
/// to pass TestContext.Current.CancellationToken to satisfy xUnit1051. Cancellation
/// behaviour is covered by driving directly.
///
internal static async Task<(List Records, List Errors)> CollectAsync(
this ITextParser parser,
string input,
IProgress? progress = null
)
{
var records = new List();
var errors = new List();
await foreach (var outcome in parser.ParseAsync(input, progress, TestContext.Current.CancellationToken))
{
if (outcome.IsSuccess)
{
records.Add(outcome.Value!);
}
else
{
errors.Add(outcome.Error);
}
}
return (records, errors);
}
/// Reads a field by name, failing the test if it is absent.
internal static string Field(this ParsedRecord record, string name) =>
record[name] ?? throw new InvalidOperationException($"Field '{name}' is missing.");
/// Builds a delimited document with a header plus data rows.
internal static string DelimitedDocument(int rows) =>
string.Join('\n', Enumerable.Range(0, rows + 1).Select(i => i == 0 ? "id,name" : $"{i},row{i}"));
}