Files
WCTDataMiner/tests/Gpulse.WCT.DataAnalyzer.Tests/Commands/AnalyzeCommandTests.cs
Scottxjw 6d56a4a01b feat(parser): 支持 Ploss Field1 十六进制解析
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-08-17 10:47:33 +08:00

150 lines
5.8 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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_Ploss_LegacyFile_HexField1_DecodedCorrectly()
{
var dir = NewDir();
// 旧单行格式 Field1=0C (十六进制) 应被解析为十进制 12
var file = TestFixtures.WriteLegacyPlossLog(
dir,
"singleMold-v1.0-hex2_1-iPhone15-ploss_legacy-20260710-1.log",
new (int, int, int)[] { (500, 3000, 0) },
field1Hex: "0C");
var (code, stdout, _) = await Analyze().RunCaptureAsync("--type", "ploss", "--file", file);
Assert.Multiple(() =>
{
Assert.That(code, Is.EqualTo(0));
Assert.That(stdout, Does.Contain("Total: 1 (TwoLine: 0, Legacy: 1), FOD: 0, Errors: 0"));
});
}
[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"));
}
}