using SheetMe.Core.Catalog; namespace SheetMe.Core.Tests; /// /// 적용일시 판정 고정. /// /// 환자 문맥 5행이 전부 이 시각을 키로 읽힌다 — 진료과·보험 자격·병동이 모두 /// :AdpDtm BETWEEN StrDtm AND EndDtm 이다. 시각이 한 칸 어긋나면 조인이 0행이 되고 /// 태그가 통째로 빈 값이 된다. 값이 틀리는 것이 아니라 아무것도 안 나온다 — /// 그래서 사용자는 "미리보기가 고장났다"고 읽는다. /// [TestClass] public sealed class VisitMomentTests { #region Methods private static VisitWindow Outpatient(string accepted) => new(false, accepted, string.Empty, "20260101", "20260101"); private static VisitWindow Inpatient(string accepted, string left, string from, string to) => new(true, accepted, left, from, to); [TestMethod] public void 외래는_접수일시가_곧_적용일시다() { // 외래는 자격 구간을 보지 않는다(레거시 dtCommonLib.vb:3344) Assert.AreEqual("202608180930", VisitMoment.Decide(Outpatient("202608180930"), VisitEdge.Last, "202608181500")); Assert.AreEqual("202608180930", VisitMoment.Decide(Outpatient("202608180930"), VisitEdge.First, "202608181500")); } [TestMethod] public void 재원_중이면_지금이_기준이다() { // CoiEndDte = 29991231 이 재원 중 표식이다 var admitted = Inpatient("202608100800", string.Empty, "20260810", "29991231"); Assert.AreEqual("202608181500", VisitMoment.Decide(admitted, VisitEdge.Last, "202608181500")); } [TestMethod] public void 입원_전환이_미래면_접수_시각을_쓴다() { // 지금이 접수보다 이르면(미래 입원 전환) 지금을 쓸 수 없다 — 조인이 0행이 된다. var future = Inpatient("202609010800", string.Empty, "20260901", "29991231"); Assert.AreEqual("202609010800", VisitMoment.Decide(future, VisitEdge.Last, "202608181500")); } [TestMethod] public void 퇴원했으면_자격_종료와_퇴원_중_이른_쪽() { // 자격이 먼저 끝난 경우 var coverageFirst = Inpatient("202608100800", "202608201200", "20260810", "20260815"); Assert.AreEqual("202608152359", VisitMoment.Decide(coverageFirst, VisitEdge.Last, "202608181500")); // 퇴원이 먼저인 경우 var leftFirst = Inpatient("202608100800", "202608121200", "20260810", "20260815"); Assert.AreEqual("202608121200", VisitMoment.Decide(leftFirst, VisitEdge.Last, "202608181500")); } [TestMethod] public void First_는_자격_시작과_접수_중_늦은_쪽() { // 자격이 접수 전에 시작했어도 내원 밖은 의미가 없다 var early = Inpatient("202608100800", "202608201200", "20260801", "20260820"); Assert.AreEqual("202608100800", VisitMoment.Decide(early, VisitEdge.First, "202608181500")); // 자격이 접수 뒤에 시작한 경우 var late = Inpatient("202608100800", "202608201200", "20260812", "20260820"); Assert.AreEqual("202608120000", VisitMoment.Decide(late, VisitEdge.First, "202608181500")); } [TestMethod] public void 지정한_일자는_그_날의_끝을_쓰되_내원_경계를_넘지_않는다() { var visit = Inpatient("202608100800", "202608151030", "20260810", "20260815"); // 퇴원이 그 날 23:59 보다 이르면 퇴원 시각 Assert.AreEqual("202608151030", VisitMoment.Clamp("20260815", visit, VisitEdge.Last)); // 퇴원 전날이면 그 날 끝 Assert.AreEqual("202608122359", VisitMoment.Clamp("20260812", visit, VisitEdge.Last)); // First 는 그 날 시작, 단 접수가 더 늦으면 접수 Assert.AreEqual("202608100800", VisitMoment.Clamp("20260810", visit, VisitEdge.First)); Assert.AreEqual("202608120000", VisitMoment.Clamp("20260812", visit, VisitEdge.First)); } [TestMethod] public void 지정한_일시는_내원_구간_안으로_가둔다() { var visit = Inpatient("202608100800", "202608151030", "20260810", "20260815"); // 구간 안이면 그대로 Assert.AreEqual("202608121200", VisitMoment.Clamp("202608121200", visit, VisitEdge.Last)); // 접수 전이면 접수로 당긴다 — 안 당기면 자격·병실 조인이 0행이다 Assert.AreEqual("202608100800", VisitMoment.Clamp("202608010000", visit, VisitEdge.Last)); // 퇴원 후면 퇴원으로 당긴다 Assert.AreEqual("202608151030", VisitMoment.Clamp("202609010000", visit, VisitEdge.Last)); // 12자리를 넘겨도 앞 12자리만 Assert.AreEqual("202608121200", VisitMoment.Clamp("20260812120059", visit, VisitEdge.Last)); } [TestMethod] public void 해석할_수_없는_값은_자동_판정으로_떨어진다() { var visit = Inpatient("202608100800", "202608151030", "20260810", "20260815"); Assert.AreEqual(string.Empty, VisitMoment.Clamp("2026", visit, VisitEdge.Last)); Assert.AreEqual(string.Empty, VisitMoment.Clamp(string.Empty, visit, VisitEdge.Last)); // Resolve 는 그때 Decide 로 넘어간다 — 빈 값을 그대로 내보내면 조회가 전부 0행이 된다 Assert.AreEqual("202608151030", VisitMoment.Resolve("2026", visit, VisitEdge.Last, "202608181500")); Assert.AreEqual("202608121200", VisitMoment.Resolve("202608121200", visit, VisitEdge.Last, "202608181500")); } [TestMethod] public void 고정폭_잔여_공백을_흡수한다() { // 이 컬럼들은 전부 CHAR 다. 공백이 붙은 채로 비교하면 사전순이 어긋난다. var padded = new VisitWindow(false, "202608180930 ", " ", "20260101", "20260101"); Assert.AreEqual("202608180930", VisitMoment.Decide(padded, VisitEdge.Last, "202608181500")); } #endregion }