/**
* 指示書AY §3 表2(`lib/ds-logs/presets.ts`。now = 2026-10-19T12:00:00+09:00)。
* ブリーフ §5 と監督判断 第2ラウンドから本書で具体化。★P1・P2 の行は §11 Q14・Q15 の採用で確定★。
*
* | # | 入力 | from | to |
* | T1 | 1h(直近1時間) | 2026-10-19T11:00:00+09:00 | なし(D23) |
* | T2 | 3h(直近3時間) | 2026-10-19T09:00:00+09:00 | なし |
* | T3 | 24h(直近24時間) | 2026-10-18T12:00:00+09:00 | なし |
* | T4 | all(全て) | なし | なし |
* | T5 | 2026-10-18〜2026-10-19 | 2026-10-18T00:00:00+09:00 | 2026-10-20T00:00:00+09:00(終了日を含む) |
* | T6 | 2026-10-31〜2026-10-31 | 2026-10-31T00:00:00+09:00 | 2026-11-01T00:00:00+09:00(月またぎ) |
* | T7 | 開始だけ 2026-10-19 | 2026-10-19T00:00:00+09:00 | なし |
* | T8 | 終了だけ 2026-10-18 | なし | 2026-10-19T00:00:00+09:00 |
* | T9 | 2026-10-19〜2026-10-18(逆) | null(不正) | — |
* | T10 | now を UTC で渡す(03:00Z)・1h | 2026-10-19T11:00:00+09:00 | なし(実行環境のタイムゾーンに依存しない) |
*/
import { describe, expect, it } from "vitest";
import { dateRangeError, periodFromDates, periodFromPreset } from "@/lib/ds-logs/presets";
const NOW = new Date("2026-10-19T12:00:00+09:00");
describe("periodFromPreset() — 表2 T1〜T4・T10", () => {
it.each<[string, "1h" | "3h" | "24h" | "all", Date, string | null]>([
["T1 直近1時間", "1h", NOW, "2026-10-19T11:00:00+09:00"],
["T2 直近3時間", "3h", NOW, "2026-10-19T09:00:00+09:00"],
["T3 直近24時間", "24h", NOW, "2026-10-18T12:00:00+09:00"],
["T4 全て", "all", NOW, null],
["T10 now を UTC で渡しても JST で返す", "1h", new Date("2026-10-19T03:00:00Z"), "2026-10-19T11:00:00+09:00"],
])("%s", (_label, preset, now, expectedFrom) => {
expect(periodFromPreset(preset, now)).toEqual({ from: expectedFrom, to: null });
});
});
describe("periodFromDates() — 表2 T5〜T9", () => {
it.each<[string, string | null, string | null, { from: string | null; to: string | null } | null]>([
["T5 終了日を含む", "2026-10-18", "2026-10-19", { from: "2026-10-18T00:00:00+09:00", to: "2026-10-20T00:00:00+09:00" }],
["T6 月またぎ", "2026-10-31", "2026-10-31", { from: "2026-10-31T00:00:00+09:00", to: "2026-11-01T00:00:00+09:00" }],
["T7 開始だけ", "2026-10-19", null, { from: "2026-10-19T00:00:00+09:00", to: null }],
["T8 終了だけ", null, "2026-10-18", { from: null, to: "2026-10-19T00:00:00+09:00" }],
["T9 逆(開始 > 終了)は不正", "2026-10-19", "2026-10-18", null],
])("%s", (_label, start, end, expected) => {
expect(periodFromDates(start, end)).toEqual(expected);
});
});
describe("dateRangeError() — 指示書BJ 表D", () => {
it.each<[string, string | null, string | null, "reversed" | "invalid" | null]>([
["D1 逆順", "2026-10-19", "2026-10-18", "reversed"],
["D2 正常", "2026-10-18", "2026-10-19", null],
["D3 同じ日", "2026-10-18", "2026-10-18", null],
["D4 存在しない日付", "2026-02-30", "2026-03-01", "invalid"],
["D5 開始 null", null, "2026-10-18", null],
["D6 終了 null", "2026-10-19", null, null],
])("%s", (_label, start, end, expected) => {
expect(dateRangeError(start, end)).toBe(expected);
});
});