88 lines
2.8 KiB
C#
88 lines
2.8 KiB
C#
namespace LiquidCode.Tester.Worker.Services;
|
|
|
|
public class OutputCheckerService : IOutputCheckerService
|
|
{
|
|
private readonly ILogger<OutputCheckerService> _logger;
|
|
private readonly CheckerService _checkerService;
|
|
|
|
public OutputCheckerService(ILogger<OutputCheckerService> logger, CheckerService checkerService)
|
|
{
|
|
_logger = logger;
|
|
_checkerService = checkerService;
|
|
}
|
|
|
|
public async Task<bool> CheckOutputAsync(string actualOutput, string expectedOutputPath)
|
|
{
|
|
try
|
|
{
|
|
var expectedOutput = await File.ReadAllTextAsync(expectedOutputPath);
|
|
|
|
// Normalize outputs for comparison
|
|
var normalizedActual = NormalizeOutput(actualOutput);
|
|
var normalizedExpected = NormalizeOutput(expectedOutput);
|
|
|
|
var match = normalizedActual == normalizedExpected;
|
|
|
|
if (!match)
|
|
{
|
|
_logger.LogDebug("Output mismatch. Expected length: {ExpectedLength}, Actual length: {ActualLength}",
|
|
normalizedExpected.Length, normalizedActual.Length);
|
|
}
|
|
|
|
return match;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "Error checking output against {ExpectedFile}", expectedOutputPath);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
private string NormalizeOutput(string output)
|
|
{
|
|
// Remove trailing whitespace from each line and normalize line endings
|
|
var lines = output.Split(new[] { "\r\n", "\r", "\n" }, StringSplitOptions.None)
|
|
.Select(line => line.TrimEnd())
|
|
.ToList();
|
|
|
|
// Remove trailing empty lines
|
|
while (lines.Count > 0 && string.IsNullOrWhiteSpace(lines[^1]))
|
|
{
|
|
lines.RemoveAt(lines.Count - 1);
|
|
}
|
|
|
|
return string.Join("\n", lines);
|
|
}
|
|
|
|
public async Task<bool> CheckOutputWithCheckerAsync(
|
|
string actualOutput,
|
|
string inputFilePath,
|
|
string expectedOutputPath,
|
|
string? checkerPath)
|
|
{
|
|
// If custom checker is available, use it
|
|
if (!string.IsNullOrEmpty(checkerPath) && File.Exists(checkerPath))
|
|
{
|
|
_logger.LogDebug("Using custom checker: {CheckerPath}", checkerPath);
|
|
|
|
var checkerResult = await _checkerService.CheckAsync(
|
|
checkerPath,
|
|
inputFilePath,
|
|
actualOutput,
|
|
expectedOutputPath);
|
|
|
|
if (!checkerResult.Accepted)
|
|
{
|
|
_logger.LogWarning("Custom checker verdict: {Verdict} - {Message}",
|
|
checkerResult.Verdict, checkerResult.Message);
|
|
}
|
|
|
|
return checkerResult.Accepted;
|
|
}
|
|
|
|
// Fall back to standard string comparison
|
|
_logger.LogDebug("No custom checker, using standard comparison");
|
|
return await CheckOutputAsync(actualOutput, expectedOutputPath);
|
|
}
|
|
}
|