using Microsoft.EntityFrameworkCore; namespace Gpulse.WCT.DataAnalyzer.Tests.Commands; [TestFixture] public class ParseCommandTests : CommandTestBase { [Test] public async Task Parse_File_Missing_ReturnsFailureReport() { var missing = Path.Combine(Host.TempDir, "not-exist.log"); var (code, stdout, _) = await Parse().RunCaptureAsync("--file", missing); Assert.Multiple(() => { Assert.That(code, Is.EqualTo(0)); Assert.That(stdout, Does.Contain("not-exist.log")); Assert.That(stdout, Does.Contain("FAILED")); }); } [Test] public async Task Parse_File_WithBadFileName_ReportsFilenameError() { var dir = NewDir(); var file = Path.Combine(dir, "bad-name.log"); await File.WriteAllTextAsync(file, "0#:Q 1->25 45.5 20.5 2 0\n"); var (code, stdout, _) = await Parse().RunCaptureAsync("--file", file); Assert.Multiple(() => { Assert.That(code, Is.EqualTo(0)); Assert.That(stdout, Does.Contain("bad-name.log")); Assert.That(stdout, Does.Contain("文件名格式不匹配")); }); } [Test] public async Task Parse_File_QfodLog_StoresRecordsAndReportsCount() { var dir = NewDir(); var file = TestFixtures.WriteQfodLog(dir, TestFixtures.QfodFileName, 20, 25, 21, -8); var (code, stdout, _) = await Parse().RunCaptureAsync("--file", file); Assert.Multiple(() => { Assert.That(code, Is.EqualTo(0)); Assert.That(stdout, Does.Contain(TestFixtures.QfodFileName)); Assert.That(stdout, Does.Contain("Qfod: 4")); Assert.That(stdout, Does.Contain("Ploss: 0")); }); Assert.That(await Host.LocalDb.QfodRecords.CountAsync(), Is.EqualTo(4)); } [Test] public async Task Parse_File_PlossLog_StoresRecordsAndReportsCount() { var dir = NewDir(); var file = TestFixtures.WritePlossLog(dir, TestFixtures.PlossFileName, new TestFixtures.PlossTwoLineRow(), new TestFixtures.PlossTwoLineRow(Field9: 2500, Field10: 3000, Field12: 1)); var (code, stdout, _) = await Parse().RunCaptureAsync("--file", file); Assert.Multiple(() => { Assert.That(code, Is.EqualTo(0)); Assert.That(stdout, Does.Contain("Qfod: 0")); Assert.That(stdout, Does.Contain("Ploss: 2")); }); Assert.That(await Host.LocalDb.PlossRecords.CountAsync(), Is.EqualTo(2)); } [TestCase("0C", 12)] // 上位 nibble = 0,下位 nibble = C [TestCase("0xFF", 255)] // 标准 0x 前缀 [TestCase("0xff", 255)] // 小写 hex [TestCase("0A", 10)] [TestCase("0", 0)] // 纯 0:应识别为十进制 0 [TestCase("10", 10)] // 纯十进制:应识别为 10(不是 0x10 = 16) public async Task Parse_File_PlossLog_HexField1_DecodedCorrectly(string field1Raw, int expected) { var dir = NewDir(); var file = TestFixtures.WritePlossLog(dir, TestFixtures.PlossFileName, new TestFixtures.PlossTwoLineRow(Field1AsHex: field1Raw)); var (code, stdout, _) = await Parse().RunCaptureAsync("--file", file); Assert.Multiple(() => { Assert.That(code, Is.EqualTo(0)); Assert.That(stdout, Does.Contain("Ploss: 1")); }); var record = await Host.LocalDb.PlossRecords.SingleAsync(); Assert.That(record.Field1, Is.EqualTo(expected)); } [Test] public async Task Parse_File_WithForceOption_Accepted() { var dir = NewDir(); var file = TestFixtures.WriteQfodLog(dir, TestFixtures.QfodFileName, 20, 25, 21); var (code, stdout, _) = await Parse().RunCaptureAsync("--file", file, "--force"); Assert.Multiple(() => { Assert.That(code, Is.EqualTo(0)); Assert.That(stdout, Does.Contain("Qfod: 3")); }); } [Test] public async Task Parse_Dir_ReportsSummaryAndTotals() { var dir = NewDir(); TestFixtures.WriteQfodLog(dir, TestFixtures.QfodFileName, 20, 25, 21); TestFixtures.WritePlossLog(dir, TestFixtures.PlossFileName, new TestFixtures.PlossTwoLineRow(), new TestFixtures.PlossTwoLineRow()); var (code, stdout, _) = await Parse().RunCaptureAsync("--dir", dir); Assert.Multiple(() => { Assert.That(code, Is.EqualTo(0)); Assert.That(stdout, Does.Contain("2 files processed")); Assert.That(stdout, Does.Contain("Total: Qfod=3, Ploss=2, Errors=0")); }); } [Test] public async Task Parse_Dir_Recursive_IncludesSubfolders() { var root = NewDir(); var sub = Directory.CreateDirectory(Path.Combine(root, "sub")).FullName; TestFixtures.WriteQfodLog(root, TestFixtures.QfodFileName, 20, 25); TestFixtures.WritePlossLog(sub, TestFixtures.PlossFileName, new TestFixtures.PlossTwoLineRow()); var (_, plain, _) = await Parse().RunCaptureAsync("--dir", root); Assert.That(plain, Does.Contain("1 files processed")); var (_, recursive, _) = await Parse().RunCaptureAsync("--dir", root, "--recursive"); Assert.That(recursive, Does.Contain("2 files processed")); } [Test] public async Task Parse_Dir_NotExists_ReturnsFailureReport() { var missing = Path.Combine(Host.TempDir, "no-such-dir"); var (code, stdout, _) = await Parse().RunCaptureAsync("--dir", missing); Assert.Multiple(() => { Assert.That(code, Is.EqualTo(0)); Assert.That(stdout, Does.Contain("FAILED")); Assert.That(stdout, Does.Contain("目录不存在")); }); } [Test] public async Task Parse_NeitherFileNorDir_PrintsPrompt() { var (code, stdout, _) = await Parse().RunCaptureAsync(); Assert.Multiple(() => { Assert.That(code, Is.EqualTo(0)); Assert.That(stdout, Does.Contain("Please specify --file or --dir")); }); } }