import { describe, expect, it } from "vitest";
import { capConsecutiveDays } from "@/lib/format/consecutive-days";
import { CONSECUTIVE_DAYS_DISPLAY, ESCALATION_THRESHOLDS } from "@/lib/config";
import { judgeEscalationLevel } from "@/lib/judge/escalation";
/**
* `capConsecutiveDays()` の期待値表テスト(指示書AF 段階2-3。`CLAUDE.md` §9.4)。
*
* ★テストに `3` / `30` を直書きしてよいのは「期待値」としてだけ★。
* 入力側(`maxDays` に渡す下限)は `ESCALATION_THRESHOLDS.level3Days` から取る。
*/
/** 設定できる下限(=L3 の日数)。★`3` と直書きしない★ */
const LOWER_BOUND = ESCALATION_THRESHOLDS.level3Days;
describe("capConsecutiveDays(表示上限。判定には使わない)", () => {
// | # | rawDays | maxDays | 期待 days | 期待 capped | 何の境界か |
const cases: [string, number, number, number, boolean][] = [
["#1 上限−1", 29, 30, 29, false],
["#2 上限ちょうど(「以上」にしない)", 30, 30, 30, false],
["#3 上限+1", 31, 30, 30, true],
["#4 十分大きい", 100, 30, 30, true],
["#5 下限の境界", LOWER_BOUND, LOWER_BOUND, LOWER_BOUND, false],
["#6 下限でも「以上」が出る", LOWER_BOUND + 1, LOWER_BOUND, LOWER_BOUND, true],
["#7 問題なし", 0, 30, 0, false],
["#8 L1", 1, 30, 1, false],
["#9 L2", 2, 30, 2, false],
];
it.each(cases)("%s: raw=%i / max=%i → days=%i / capped=%s", (_label, raw, max, days, capped) => {
expect(capConsecutiveDays(raw, max)).toEqual({ days, capped });
});
// #10 引数省略 → 既定値が使われること
it("#10 maxDays を省略すると lib/config の既定値が使われる", () => {
const max = CONSECUTIVE_DAYS_DISPLAY.defaultMax;
expect(capConsecutiveDays(max)).toEqual({ days: max, capped: false });
expect(capConsecutiveDays(max + 1)).toEqual({ days: max, capped: true });
// 省略時と明示時で結果が一致する(既定値の取り違えを固定する)
expect(capConsecutiveDays(max + 1)).toEqual(capConsecutiveDays(max + 1, max));
});
});
describe("表示上限が判定を壊さないこと(禁止事項9)", () => {
// #11 上限を下限まで絞っても、判定は「上限をかける前の生値」で行われ L3 のまま
it("#11 maxDays を下限にしても judgeEscalationLevel(rawDays) は L3 を返し続ける", () => {
const rawDays = 5;
const capped = capConsecutiveDays(rawDays, LOWER_BOUND);
expect(capped).toEqual({ days: LOWER_BOUND, capped: true });
// ★判定に渡すのは生値★。頭打ちにした `capped.days` ではない
expect(judgeEscalationLevel(rawDays)).toBe("L3");
// 頭打ち後の値で判定しても L3 なのは「下限 = L3 の日数」だから。
// ★下限を L3 未満にできないこと(#12)がこの一致を支えている★
expect(judgeEscalationLevel(capped.days)).toBe("L3");
});
// #12 設定同士の関係を固定する
it("#12 CONSECUTIVE_DAYS_DISPLAY.minMax >= ESCALATION_THRESHOLDS.level3Days", () => {
expect(CONSECUTIVE_DAYS_DISPLAY.minMax).toBeGreaterThanOrEqual(
ESCALATION_THRESHOLDS.level3Days
);
});
});