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)>())); } }