test: 添加 CLI 命令单元测试
This commit is contained in:
@@ -0,0 +1,85 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace Gpulse.WCT.DataAnalyzer.Tests.Commands;
|
||||
|
||||
[TestFixture]
|
||||
public class AggregateCommandTests : CommandTestBase
|
||||
{
|
||||
[Test]
|
||||
public async Task Aggregate_EmptyDatabase_ReportsZero()
|
||||
{
|
||||
var (code, stdout, _) = await Aggregate().RunCaptureAsync();
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(code, Is.EqualTo(0));
|
||||
Assert.That(stdout, Does.Contain("Aggregated 0 local Ploss records into 0 release records."));
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Aggregate_AfterParse_GroupsByThresholdIntoReleaseDb()
|
||||
{
|
||||
var dir = NewDir();
|
||||
var file = TestFixtures.WritePlossLog(dir, TestFixtures.PlossFileName,
|
||||
new TestFixtures.PlossTwoLineRow(Field7: 100, Field9: 350, Field10: 350),
|
||||
new TestFixtures.PlossTwoLineRow(Field7: 110, Field9: 350, Field10: 350),
|
||||
new TestFixtures.PlossTwoLineRow(Field7: 200, Field9: 500, Field10: 500));
|
||||
await Parse().RunCaptureAsync("--file", file);
|
||||
|
||||
var (code, stdout, _) = await Aggregate().RunCaptureAsync();
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(code, Is.EqualTo(0));
|
||||
Assert.That(stdout, Does.Contain("Aggregated 3 local Ploss records into 1 release records."));
|
||||
});
|
||||
|
||||
var record = await Host.ReleaseDb.ChargingParameters.SingleAsync();
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
// 维度来自文件名:singleMold(TxPanel) / v1.0(TxHardware) / hex2_1(TxSoftware) / iPhone15(RxType)
|
||||
Assert.That(record.CarFactory, Is.EqualTo("singleMold"));
|
||||
Assert.That(record.CarModel, Is.EqualTo("v1.0"));
|
||||
Assert.That(record.PhoneModel, Is.EqualTo("iPhone15"));
|
||||
// Field9=350 的两行 Field7 取平均 = (100+110)/2
|
||||
Assert.That(record.Power350mW, Is.EqualTo(105));
|
||||
Assert.That(record.Power500mW, Is.EqualTo(200));
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Aggregate_DefaultRebuild_DoesNotDuplicateOnSecondRun()
|
||||
{
|
||||
var dir = NewDir();
|
||||
var file = TestFixtures.WritePlossLog(dir, TestFixtures.PlossFileName,
|
||||
new TestFixtures.PlossTwoLineRow(Field7: 100, Field9: 350, Field10: 350));
|
||||
await Parse().RunCaptureAsync("--file", file);
|
||||
|
||||
await Aggregate().RunCaptureAsync();
|
||||
await Aggregate().RunCaptureAsync();
|
||||
|
||||
Assert.That(await Host.ReleaseDb.ChargingParameters.CountAsync(), Is.EqualTo(1));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Aggregate_RebuildFalse_InsertsIntoEmptyTable()
|
||||
{
|
||||
// 注:发布库对业务键 (车厂/车型/手机厂商/型号) 有唯一索引;
|
||||
// append 模式会对全部本地记录重新入库,因此只适合表为空时使用,
|
||||
// 对已聚合过的同一数据再 append 会因唯一索引冲突而失败(聚合命令捕获并输出 "Aggregation failed")。
|
||||
var dir = NewDir();
|
||||
var file = TestFixtures.WritePlossLog(dir, TestFixtures.PlossFileName,
|
||||
new TestFixtures.PlossTwoLineRow(Field7: 100, Field9: 350, Field10: 350));
|
||||
await Parse().RunCaptureAsync("--file", file);
|
||||
|
||||
var (code, stdout, _) = await Aggregate().RunCaptureAsync("--rebuild", "false");
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(code, Is.EqualTo(0));
|
||||
Assert.That(stdout, Does.Contain("Aggregated 1 local Ploss records into 1 release records."));
|
||||
});
|
||||
Assert.That(await Host.ReleaseDb.ChargingParameters.CountAsync(), Is.EqualTo(1));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
namespace Gpulse.WCT.DataAnalyzer.Tests.Commands;
|
||||
|
||||
[TestFixture]
|
||||
public class AnalyzeCommandTests : CommandTestBase
|
||||
{
|
||||
[Test]
|
||||
public async Task Analyze_NoType_ReturnsValidationError()
|
||||
{
|
||||
var (code, stdout, stderr) = await Analyze().RunCaptureAsync();
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(code, Is.EqualTo(1));
|
||||
Assert.That(stdout + stderr, Does.Contain("--type"));
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Analyze_UnknownType_PrintsMessage()
|
||||
{
|
||||
var (code, stdout, _) = await Analyze().RunCaptureAsync("--type", "foo");
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(code, Is.EqualTo(0));
|
||||
Assert.That(stdout, Does.Contain("Unknown type: foo. Use 'ploss' or 'qfod'."));
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Analyze_Ploss_MissingFile_PrintsPrompt()
|
||||
{
|
||||
var (_, stdout, _) = await Analyze().RunCaptureAsync("--type", "ploss");
|
||||
|
||||
Assert.That(stdout, Does.Contain("Please specify --file for Ploss analysis"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Analyze_Ploss_ValidTwoLineFile_ReportsSummary()
|
||||
{
|
||||
var dir = NewDir();
|
||||
var file = TestFixtures.WritePlossLog(dir, TestFixtures.PlossFileName,
|
||||
// 正常两行:margin = 3000-500 = 2500 > 2000,恒等式成立
|
||||
new TestFixtures.PlossTwoLineRow(),
|
||||
// FOD 两行:ploss=2500 threshold=3000 margin=500,恒等式成立,delta_p'=2500+2001+2500-3000=4001
|
||||
new TestFixtures.PlossTwoLineRow(Field5: 8000, Field9: 2500, Field10: 3000, Field12: 1));
|
||||
|
||||
var (code, stdout, _) = await Analyze().RunCaptureAsync("--type", "ploss", "--file", file);
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(code, Is.EqualTo(0));
|
||||
Assert.That(stdout, Does.Contain("=== Ploss Analysis:"));
|
||||
Assert.That(stdout, Does.Contain("Total: 2 (TwoLine: 2, Legacy: 0), FOD: 1, Errors: 0"));
|
||||
Assert.That(stdout, Does.Contain("Normal margin>2000: 1/1 (100.0%)"));
|
||||
Assert.That(stdout, Does.Contain("FOD margin>2000: 0/1 (0.0%)"));
|
||||
Assert.That(stdout, Does.Contain("Identity (delta_p = Tx - Rx - pow_loss - ploss): 2/2"));
|
||||
Assert.That(stdout, Does.Contain("delta_p'=4001"));
|
||||
Assert.That(stdout, Does.Contain("rewrite: pow_loss = 2200, delta_p = 4001"));
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Analyze_Ploss_LegacyFile_CountsLegacyRows()
|
||||
{
|
||||
var dir = NewDir();
|
||||
var file = TestFixtures.WriteLegacyPlossLog(
|
||||
dir, "singleMold-v1.0-hex2_1-iPhone15-ploss_legacy-20260710-1.log",
|
||||
(500, 3000, 0), (2500, 3000, 1));
|
||||
|
||||
var (code, stdout, _) = await Analyze().RunCaptureAsync("--type", "ploss", "--file", file);
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(code, Is.EqualTo(0));
|
||||
Assert.That(stdout, Does.Contain("Total: 2 (TwoLine: 0, Legacy: 2), FOD: 1, Errors: 0"));
|
||||
Assert.That(stdout, Does.Contain("Normal margin>2000: 1/1 (100.0%)"));
|
||||
Assert.That(stdout, Does.Contain("FOD margin>2000: 0/1 (0.0%)"));
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Analyze_Qfod_MissingArgs_PrintsPrompt()
|
||||
{
|
||||
var (_, stdout, _) = await Analyze().RunCaptureAsync("--type", "qfod");
|
||||
|
||||
Assert.That(stdout, Does.Contain("Please specify --pure and --foreign for Qfod calibration"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Analyze_Qfod_ValidFiles_ReportsThreshold()
|
||||
{
|
||||
var dir = NewDir();
|
||||
var pure = TestFixtures.WriteQfodLog(
|
||||
dir, "singleMold-v1.0-hex2_1-iPhone15-qfod_pure-20260710-1.log", 20, 25, 21);
|
||||
var foreign = TestFixtures.WriteQfodLog(
|
||||
dir, "singleMold-v1.0-hex2_1-iPhone15-qfod_foreign-20260710-1.log", 42, 40, 45);
|
||||
|
||||
var (code, stdout, _) = await Analyze().RunCaptureAsync("--type", "qfod", "--pure", pure, "--foreign", foreign);
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(code, Is.EqualTo(0));
|
||||
Assert.That(stdout, Does.Contain("=== Qfod Calibration ==="));
|
||||
Assert.That(stdout, Does.Contain("Pure phone"));
|
||||
Assert.That(stdout, Does.Contain("Foreign object"));
|
||||
Assert.That(stdout, Does.Contain("count=3 min=20 max=25 avg=22.0"));
|
||||
Assert.That(stdout, Does.Contain("count=3 min=40 max=45 avg=42.3"));
|
||||
Assert.That(stdout, Does.Contain("Threshold = (pureMax + foreignMin) / 2 = (25 + 40) / 2 = 32"));
|
||||
Assert.That(stdout, Does.Contain("pureMax - threshold = -7"));
|
||||
Assert.That(stdout, Does.Contain("foreignMin - threshold = 8"));
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Analyze_Qfod_MissingFile_ReportsFailure()
|
||||
{
|
||||
var dir = NewDir();
|
||||
var foreign = TestFixtures.WriteQfodLog(
|
||||
dir, "singleMold-v1.0-hex2_1-iPhone15-qfod_foreign-20260710-1.log", 42, 40);
|
||||
|
||||
var (_, stdout, _) = await Analyze().RunCaptureAsync(
|
||||
"--type", "qfod",
|
||||
"--pure", Path.Combine(dir, "nope.log"),
|
||||
"--foreign", foreign);
|
||||
|
||||
Assert.That(stdout, Does.Contain("FAILED"));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace Gpulse.WCT.DataAnalyzer.Tests.Commands;
|
||||
|
||||
[TestFixture]
|
||||
public class CleanCommandTests : CommandTestBase
|
||||
{
|
||||
[Test]
|
||||
public async Task Clean_NoConfirm_PrintsPrompt()
|
||||
{
|
||||
var (code, stdout, _) = await Clean().RunCaptureAsync("--all");
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(code, Is.EqualTo(0));
|
||||
Assert.That(stdout, Does.Contain("Please add --confirm to confirm the clean operation."));
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Clean_InvalidScenarioGuid_PrintsMessage()
|
||||
{
|
||||
var (_, stdout, _) = await Clean().RunCaptureAsync("--scenario", "not-a-guid", "--confirm");
|
||||
|
||||
Assert.That(stdout, Does.Contain("Invalid scenario ID: not-a-guid"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Clean_Scenario_NotExist_PrintsZeroCount()
|
||||
{
|
||||
var scenarioId = Guid.NewGuid();
|
||||
var (_, stdout, _) = await Clean().RunCaptureAsync("--scenario", scenarioId.ToString(), "--confirm");
|
||||
|
||||
Assert.That(stdout, Does.Contain($"Cleaned 0 records for scenario {scenarioId}"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Clean_Scenario_WithConfirm_SoftDeletesRelatedRecords()
|
||||
{
|
||||
var dir = NewDir();
|
||||
var file = TestFixtures.WritePlossLog(dir, TestFixtures.PlossFileName,
|
||||
new TestFixtures.PlossTwoLineRow(),
|
||||
new TestFixtures.PlossTwoLineRow(Field9: 2500, Field12: 1));
|
||||
await Parse().RunCaptureAsync("--file", file);
|
||||
|
||||
var scenarioId = await Host.LocalDb.TestScenarios.Select(s => s.Id).SingleAsync();
|
||||
|
||||
var (code, stdout, _) = await Clean().RunCaptureAsync("--scenario", scenarioId.ToString(), "--confirm");
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(code, Is.EqualTo(0));
|
||||
Assert.That(stdout, Does.Contain($"Cleaned 3 records for scenario {scenarioId}"));
|
||||
});
|
||||
|
||||
// 2 条 Ploss + 1 个场景全部软删除
|
||||
Assert.That(await Host.LocalDb.PlossRecords.IgnoreQueryFilters().CountAsync(r => r.IsDeleted), Is.EqualTo(2));
|
||||
Assert.That(await Host.LocalDb.TestScenarios.IgnoreQueryFilters().CountAsync(s => s.IsDeleted), Is.EqualTo(1));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Clean_All_WithConfirm_SoftDeletesEverything()
|
||||
{
|
||||
var dir = NewDir();
|
||||
var file = TestFixtures.WritePlossLog(dir, TestFixtures.PlossFileName,
|
||||
new TestFixtures.PlossTwoLineRow(),
|
||||
new TestFixtures.PlossTwoLineRow());
|
||||
await Parse().RunCaptureAsync("--file", file);
|
||||
|
||||
var (code, stdout, _) = await Clean().RunCaptureAsync("--all", "--confirm");
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(code, Is.EqualTo(0));
|
||||
Assert.That(stdout, Does.Contain("Cleaned 3 records in total"));
|
||||
});
|
||||
|
||||
Assert.That(await Host.LocalDb.PlossRecords.IgnoreQueryFilters().CountAsync(r => r.IsDeleted), Is.EqualTo(2));
|
||||
Assert.That(await Host.LocalDb.TestScenarios.IgnoreQueryFilters().CountAsync(s => s.IsDeleted), Is.EqualTo(1));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
using Gpulse.WCT.DataAnalyzer.Core.Domain.Release;
|
||||
|
||||
namespace Gpulse.WCT.DataAnalyzer.Tests.Commands;
|
||||
|
||||
[TestFixture]
|
||||
public class ExportCommandTests : CommandTestBase
|
||||
{
|
||||
private static string ResolveOutputDir(params string[] segments) =>
|
||||
Path.Combine(AppDomain.CurrentDomain.BaseDirectory, string.Join(Path.DirectorySeparatorChar, segments));
|
||||
|
||||
[Test]
|
||||
public async Task Export_ChargingParametersCsv_WritesFile()
|
||||
{
|
||||
Host.ReleaseDb.ChargingParameters.Add(new ChargingParameterRecord
|
||||
{
|
||||
CarFactory = "TestFactory",
|
||||
CarModel = "ModelX",
|
||||
PhoneBrand = "Apple",
|
||||
PhoneModel = "iPhone15",
|
||||
Power350mW = 100,
|
||||
Power500mW = 200,
|
||||
});
|
||||
await Host.ReleaseDb.SaveChangesAsync();
|
||||
|
||||
var (code, stdout, _) = await Export().RunCaptureAsync(
|
||||
"--format", "csv",
|
||||
"--type", "charging-parameters",
|
||||
"--output", "data/output/export_cp");
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(code, Is.EqualTo(0));
|
||||
Assert.That(stdout, Does.Contain("ChargingParameterDatabase CSV exported"));
|
||||
});
|
||||
|
||||
var file = Path.Combine(ResolveOutputDir("data", "output", "export_cp"), "WCT-ChargingParameterDatabase.csv");
|
||||
Assert.That(File.Exists(file), Is.True);
|
||||
|
||||
var content = await File.ReadAllTextAsync(file);
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(content, Does.Contain("车厂"));
|
||||
Assert.That(content, Does.Contain("TestFactory"));
|
||||
Assert.That(content, Does.Contain("iPhone15"));
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Export_QfodCsv_AfterParse_WritesFile()
|
||||
{
|
||||
var dir = NewDir();
|
||||
var file = TestFixtures.WriteQfodLog(dir, TestFixtures.QfodFileName, 20, 25, 21);
|
||||
await Parse().RunCaptureAsync("--file", file);
|
||||
|
||||
// 导出文件名带时间戳,先清空输出目录避免跨运行残留文件
|
||||
var outDir = ResolveOutputDir("data", "output", "export_qfod");
|
||||
if (Directory.Exists(outDir))
|
||||
Directory.Delete(outDir, recursive: true);
|
||||
|
||||
var (code, stdout, _) = await Export().RunCaptureAsync(
|
||||
"--format", "csv",
|
||||
"--type", "qfod",
|
||||
"--output", "data/output/export_qfod");
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(code, Is.EqualTo(0));
|
||||
Assert.That(stdout, Does.Contain("Qfod CSV exported"));
|
||||
});
|
||||
|
||||
var exported = Directory.GetFiles(outDir, "qfod_export_*.csv").Single();
|
||||
var content = await File.ReadAllTextAsync(exported);
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(content, Does.Contain("delta_q"));
|
||||
Assert.That(content, Does.Contain("iPhone15"));
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Export_UnknownFormat_PrintsMessage()
|
||||
{
|
||||
var (code, stdout, _) = await Export().RunCaptureAsync("--format", "xml");
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(code, Is.EqualTo(0));
|
||||
Assert.That(stdout, Does.Contain("Unknown format: xml. Use 'csv' or 'json'."));
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Export_PathTraversal_PrintsFailure()
|
||||
{
|
||||
var (code, stdout, _) = await Export().RunCaptureAsync(
|
||||
"--format", "csv",
|
||||
"--output", "../evil");
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(code, Is.EqualTo(0));
|
||||
Assert.That(stdout, Does.Contain("Export failed"));
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,154 @@
|
||||
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));
|
||||
}
|
||||
|
||||
[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"));
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user