| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135 |
- using Application.Helpers;
- namespace Application.Tests;
- [TestClass]
- public sealed class DartBackfillTests
- {
- // ── ClampToSpecWindow — corp_code 미지정 3개월 스펙 제한 ──
- [TestMethod]
- public void ClampToSpecWindow_WithinLimit_NotClamped()
- {
- var today = new DateOnly(2026, 7, 7);
- var begin = today.AddDays(-30);
- var (result, clamped) = DartBackfill.ClampToSpecWindow(begin, today);
- Assert.IsFalse(clamped, "30일 창은 3개월 이내 — 클램프 없음");
- Assert.AreEqual(begin, result);
- }
- [TestMethod]
- public void ClampToSpecWindow_ExactBoundary_NotClamped()
- {
- var today = new DateOnly(2026, 7, 7);
- var begin = today.AddMonths(-3); // 정확히 3개월 = 허용
- var (result, clamped) = DartBackfill.ClampToSpecWindow(begin, today);
- Assert.IsFalse(clamped, "정확히 3개월 경계는 허용");
- Assert.AreEqual(begin, result);
- }
- [TestMethod]
- public void ClampToSpecWindow_OverLimit_ClampedToThreeMonths()
- {
- var today = new DateOnly(2026, 7, 7);
- var begin = today.AddDays(-365); // BackfillDays=365 과설정
- var (result, clamped) = DartBackfill.ClampToSpecWindow(begin, today);
- Assert.IsTrue(clamped, "3개월 초과 창은 클램프");
- Assert.AreEqual(today.AddMonths(-3), result, "클램프 결과는 today-3개월");
- }
- // ── SplitWeekly — 초기 백필 주 단위 분할 경계 ──
- [TestMethod]
- public void SplitWeekly_ExactTwoWeeks_TwoChunksNoOverlapNoGap()
- {
- var begin = new DateOnly(2026, 6, 1);
- var end = new DateOnly(2026, 6, 14); // 14일 = 정확히 2주
- var chunks = DartBackfill.SplitWeekly(begin, end);
- Assert.AreEqual(2, chunks.Count);
- Assert.AreEqual((new DateOnly(2026, 6, 1), new DateOnly(2026, 6, 7)), chunks[0]);
- Assert.AreEqual((new DateOnly(2026, 6, 8), new DateOnly(2026, 6, 14)), chunks[1], "청크 간 겹침/공백 없음");
- }
- [TestMethod]
- public void SplitWeekly_PartialLastChunk_TruncatedAtEnd()
- {
- var begin = new DateOnly(2026, 6, 1);
- var end = new DateOnly(2026, 6, 10); // 10일 = 1주 + 3일
- var chunks = DartBackfill.SplitWeekly(begin, end);
- Assert.AreEqual(2, chunks.Count);
- Assert.AreEqual((new DateOnly(2026, 6, 8), new DateOnly(2026, 6, 10)), chunks[1], "마지막 청크는 end 에서 잘림");
- }
- [TestMethod]
- public void SplitWeekly_SingleDay_OneChunk()
- {
- var day = new DateOnly(2026, 7, 7);
- var chunks = DartBackfill.SplitWeekly(day, day);
- Assert.AreEqual(1, chunks.Count);
- Assert.AreEqual((day, day), chunks[0]);
- }
- [TestMethod]
- public void SplitWeekly_BeginAfterEnd_Empty()
- {
- var chunks = DartBackfill.SplitWeekly(new DateOnly(2026, 7, 8), new DateOnly(2026, 7, 7));
- Assert.AreEqual(0, chunks.Count, "역전 범위는 빈 목록");
- }
- [TestMethod]
- public void SplitWeekly_CoversWholeRange_NoDateMissing()
- {
- var begin = new DateOnly(2026, 1, 1);
- var end = new DateOnly(2026, 3, 31); // 90일 창
- var chunks = DartBackfill.SplitWeekly(begin, end);
- // 연속성: 각 청크의 다음 시작일 = 이전 종료일 + 1
- Assert.AreEqual(begin, chunks[0].Begin);
- Assert.AreEqual(end, chunks[^1].End);
- for (var i = 1; i < chunks.Count; i++)
- {
- Assert.AreEqual(chunks[i - 1].End.AddDays(1), chunks[i].Begin, $"청크 {i} 경계 연속성");
- }
- }
- // ── ShouldStopEarly — 증분 수집 조기 종료 보수 조건 ──
- [TestMethod]
- public void ShouldStopEarly_Page1_AllExisting_False()
- {
- // 같은 날 재실행/부분 적재 방어 — 1페이지 전체 기존이어도 종료하지 않는다
- Assert.IsFalse(DartBackfill.ShouldStopEarly(pageNo: 1, rowCount: 100, newCount: 0));
- }
- [TestMethod]
- public void ShouldStopEarly_Page2_AllExisting_True()
- {
- Assert.IsTrue(DartBackfill.ShouldStopEarly(pageNo: 2, rowCount: 100, newCount: 0));
- }
- [TestMethod]
- public void ShouldStopEarly_Page2_HasNewRows_False()
- {
- Assert.IsFalse(DartBackfill.ShouldStopEarly(pageNo: 2, rowCount: 100, newCount: 1), "신규가 있으면 계속 페이징");
- }
- [TestMethod]
- public void ShouldStopEarly_EmptyPage_False()
- {
- Assert.IsFalse(DartBackfill.ShouldStopEarly(pageNo: 2, rowCount: 0, newCount: 0), "빈 페이지는 조기 종료 판정 대상 아님 (루프가 자체 종료)");
- }
- }
|