using Admin.NET.Plugin.AiDOP.Manufacturing;
using Xunit;
namespace Admin.NET.Plugin.AiDOP.Tests.S6.Manufacturing;
/// S6 Phase 1C 判定引擎单测(纯函数,后端唯一判定真源)。
public class S6ProcessInspectionJudgeTests
{
// ── NUMERIC 逐样本 ──(闭区间 9.8~10.2)
[Theory]
[InlineData("10.0", S6Judgement.Pass)] // inside
[InlineData("9.8", S6Judgement.Pass)] // lower bound (闭)
[InlineData("10.2", S6Judgement.Pass)] // upper bound (闭)
[InlineData("9.79", S6Judgement.Fail)] // below
[InlineData("10.21", S6Judgement.Fail)] // above
[InlineData("abc", S6Judgement.Invalid)]// 非法数字 → 不默认 PASS
[InlineData("", S6Judgement.Invalid)] // 空
public void JudgeSample_Numeric_ClosedInterval(string actual, string expect)
=> Assert.Equal(expect, S6ProcessInspectionJudge.JudgeSample(S6ResultType.Numeric, actual, "9.8", "10.2"));
[Fact]
public void JudgeSample_Numeric_LowerOnly() // 仅下限 >=5
{
Assert.Equal(S6Judgement.Pass, S6ProcessInspectionJudge.JudgeSample(S6ResultType.Numeric, "5", "5", null));
Assert.Equal(S6Judgement.Fail, S6ProcessInspectionJudge.JudgeSample(S6ResultType.Numeric, "4.9", "5", null));
}
[Fact]
public void JudgeSample_Numeric_UpperOnly() // 仅上限 <=10
{
Assert.Equal(S6Judgement.Pass, S6ProcessInspectionJudge.JudgeSample(S6ResultType.Numeric, "10", null, "10"));
Assert.Equal(S6Judgement.Fail, S6ProcessInspectionJudge.JudgeSample(S6ResultType.Numeric, "10.1", null, "10"));
}
[Fact]
public void JudgeSample_Numeric_NoLimits_Invalid() // 无上下限 → 无法判定
=> Assert.Equal(S6Judgement.Invalid, S6ProcessInspectionJudge.JudgeSample(S6ResultType.Numeric, "5", null, null));
// ── NON_NUMERIC 逐样本 ──
[Theory]
[InlineData("OK", S6Judgement.Pass)]
[InlineData("ok", S6Judgement.Pass)]
[InlineData("NG", S6Judgement.Fail)]
[InlineData("maybe", S6Judgement.Invalid)]
public void JudgeSample_NonNumeric(string actual, string expect)
=> Assert.Equal(expect, S6ProcessInspectionJudge.JudgeSample(S6ResultType.NonNumeric, actual, null, null));
// ── 单项聚合 ──(要求 3 样本)
[Fact]
public void AggregateItem_Partial_InProgressPending()
{
var (st, r) = S6ProcessInspectionJudge.AggregateItem(3, new[] { S6Judgement.Pass });
Assert.Equal(S6ItemStatus.InProgress, st);
Assert.Equal(S6Judgement.Pending, r);
}
[Fact]
public void AggregateItem_CompleteAllPass()
{
var (st, r) = S6ProcessInspectionJudge.AggregateItem(3, new[] { S6Judgement.Pass, S6Judgement.Pass, S6Judgement.Pass });
Assert.Equal(S6ItemStatus.Completed, st);
Assert.Equal(S6Judgement.Pass, r);
}
[Fact]
public void AggregateItem_OneFail_Fail()
{
var (st, r) = S6ProcessInspectionJudge.AggregateItem(3, new[] { S6Judgement.Pass, S6Judgement.Fail, S6Judgement.Pass });
Assert.Equal(S6ItemStatus.Completed, st);
Assert.Equal(S6Judgement.Fail, r);
}
[Fact]
public void AggregateItem_ZeroRecorded_NotStarted()
{
var (st, r) = S6ProcessInspectionJudge.AggregateItem(3, System.Array.Empty());
Assert.Equal(S6ItemStatus.NotStarted, st);
Assert.Equal(S6Judgement.Pending, r);
}
[Fact]
public void AggregateItem_NonNumericSingle_CompletePass()
{
var (st, r) = S6ProcessInspectionJudge.AggregateItem(1, new[] { S6Judgement.Pass });
Assert.Equal(S6ItemStatus.Completed, st);
Assert.Equal(S6Judgement.Pass, r);
}
// ── 整单聚合 ──
[Fact]
public void AggregateOverall_AllCompletePass_Pass()
=> Assert.Equal(S6Judgement.Pass, S6ProcessInspectionJudge.AggregateOverall(new[] { (S6ItemStatus.Completed, S6Judgement.Pass), (S6ItemStatus.Completed, S6Judgement.Pass) }));
[Fact]
public void AggregateOverall_OneFail_Fail()
=> Assert.Equal(S6Judgement.Fail, S6ProcessInspectionJudge.AggregateOverall(new[] { (S6ItemStatus.Completed, S6Judgement.Pass), (S6ItemStatus.Completed, S6Judgement.Fail) }));
[Fact]
public void AggregateOverall_Incomplete_Pending()
=> Assert.Equal(S6Judgement.Pending, S6ProcessInspectionJudge.AggregateOverall(new[] { (S6ItemStatus.Completed, S6Judgement.Pass), (S6ItemStatus.InProgress, S6Judgement.Pending) }));
[Fact]
public void AggregateOverall_Invalid_Invalid()
=> Assert.Equal(S6Judgement.Invalid, S6ProcessInspectionJudge.AggregateOverall(new[] { (S6ItemStatus.Completed, S6Judgement.Invalid), (S6ItemStatus.Completed, S6Judgement.Pass) }));
[Fact]
public void AllItemsCompleted_GatesComplete()
{
Assert.True(S6ProcessInspectionJudge.AllItemsCompleted(new[] { (S6ItemStatus.Completed, S6Judgement.Pass) }));
Assert.False(S6ProcessInspectionJudge.AllItemsCompleted(new[] { (S6ItemStatus.Completed, S6Judgement.Pass), (S6ItemStatus.InProgress, S6Judgement.Pending) }));
Assert.False(S6ProcessInspectionJudge.AllItemsCompleted(System.Array.Empty<(string, string)>()));
}
}