Files
ExperionCrawler/tests/ExperionCrawler.Tests/TempProfileJudgeTests.cs
windpacer 06b1ecc6c0 feat: §10 온도 역전 판정 (TempProfileJudge)
- TempProfileJudge(순수함수): 조성 트레이 A,B,C 단조검증 → 정상/약화/프로파일붕괴/온도역전/입력부족 (tolInv 0.5, warn 0.5, collapse 0.3)
- 엔진 JudgeTempProfile: temp_tags 마지막(탑정 D=환류 서브쿨 오염) 제외, spanRef 최초정상 시드, 역전/붕괴 시 front trim HOLD
- AdvisoryResult.{TempProfileState,InversionPair,TempSpan,TempSpanRef} + 컨트롤러 노출
- 단위 6건(37/37). 후속: ApplyRecovery sigInv 연동 + 코러보레이션(센서vs공정)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-01 16:52:32 +09:00

64 lines
2.2 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.
using System.Collections.Generic;
using ExperionCrawler.Infrastructure.Control;
using Xunit;
namespace ExperionCrawler.Tests;
// §10.3 온도 역전 판정. trays = 하단→상단 조성 트레이(A,B,C), 정상 A≥B≥C.
public class TempProfileJudgeTests
{
private static List<(string, double, bool)> T(double a, double b, double c, bool good = true)
=> new() { ("A", a, good), ("B", b, good), ("C", c, good) };
const double Tol = 0.5, Warn = 0.5, Coll = 0.3;
[Fact]
public void Normal_monotonic_seeds_span()
{
var r = TempProfileJudge.Evaluate(T(90, 85, 82), spanRef: double.NaN, Tol, Warn, Coll);
Assert.Equal("정상", r.State);
Assert.Equal(8, r.Span, 6); // AC = 9082
Assert.Null(r.InversionPair);
}
[Fact]
public void Inversion_when_upper_hotter()
{
// C(상단)가 B(하단)보다 tolInv 이상 뜨거움 → 역전
var r = TempProfileJudge.Evaluate(T(90, 80, 85), spanRef: 8, Tol, Warn, Coll);
Assert.Equal("온도역전", r.State);
Assert.Equal("B-C", r.InversionPair);
}
[Fact]
public void Small_nonmonotonic_within_tol_is_not_inversion()
{
// BC = -0.2 (데모 노이즈 수준) → tolInv 0.5 내라 역전 아님
var r = TempProfileJudge.Evaluate(T(79.2, 78.47, 78.69), spanRef: double.NaN, Tol, Warn, Coll);
Assert.NotEqual("온도역전", r.State);
}
[Fact]
public void Collapse_when_span_below_fraction()
{
// spanRef=10, span = 9088 = 2 < 0.3*10=3 → 붕괴
var r = TempProfileJudge.Evaluate(T(90, 89, 88), spanRef: 10, Tol, Warn, Coll);
Assert.Equal("프로파일붕괴", r.State);
}
[Fact]
public void Weakening_between_warn_and_collapse()
{
// spanRef=10, span = 9086 = 4 (3<4<5) → 약화
var r = TempProfileJudge.Evaluate(T(90, 88, 86), spanRef: 10, Tol, Warn, Coll);
Assert.Equal("약화", r.State);
}
[Fact]
public void Bad_tray_is_input_insufficient()
{
var r = TempProfileJudge.Evaluate(T(90, 85, 82, good: false), spanRef: 8, Tol, Warn, Coll);
Assert.Equal("입력부족", r.State);
}
}