Newer
Older
client_dwatch / lib / format / __tests__ / precheck-status.test.ts
/**
 * `lib/format/precheck-status.ts` の期待値表(D-171 / D-178)
 *
 * 清掃詳細ログ(`CleanLogTable`)の「事前チェック1回目 / 2回目」のセルの中身を決める。
 * ★null = その回の事前チェックの予定が無い★(ユーザー指示 2026-10-07「事前チェックがないものは-にしてください」)。
 *
 * | #  | 入力              | 期待                              | 何を固定するか |
 * |----|-------------------|-----------------------------------|----------------|
 * | S1 | null              | { kind: "none", text: "-" }       | Pill を出さず「-」(N2 の行は2列とも「-」) |
 * | S2 | "Standby."        | { kind: "pill", text: "Standby." }| 予定があって異常なし(N1)は今までどおり Pill |
 * | S3 | "EmergencyStop"   | { kind: "pill", ... }             | 生値のまま(D-077。変換しない) |
 * | S4 | ""(空文字)      | { kind: "pill", text: "" }        | ★「-」にするのは null だけ★(空文字は値として運ぶ) |
 * | S5 | "-"               | { kind: "pill", text: "-" }       | ★DB の値が "-" でも予定ありとして Pill★(見た目で区別がつく) |
 *
 * `precheckMinutesLabel(lang, minutes)` — Pill の横に出す「何分前か」(D-178)
 *
 * | #  | lang | minutes | 期待      | 何を固定するか |
 * |----|------|---------|-----------|----------------|
 * | M1 | ja   | 60      | "60分前"  | JP の書き方 |
 * | M2 | en   | 60      | "60 min"  | EN は短く(辞書の "{n} min before" ではない) |
 * | M3 | ja   | 10      | "10分前"  | ★30 以外の分数も出る★(設定を 60/10 にした場合。D-178 の発端) |
 * | M4 | ja   | 1       | "1分前"   | ★生値のまま★(旧コード値 1 / 2 を 60 / 30 に読み替えない) |
 * | M5 | ja/en| 0       | "0分前" / "0 min" | 0 は null ではない(falsy で落とさない) |
 * | M6 | ja/en| null    | null      | 分数が無ければ文字を出さない(Pill だけ) |
 */
import { describe, expect, it } from "vitest";
import {
  PRECHECK_STATUS_NONE,
  precheckMinutesLabel,
  precheckStatusCell,
} from "@/lib/format/precheck-status";

describe("precheckStatusCell", () => {
  it("S1: null(事前チェックの予定が無い)は Pill を出さず「-」", () => {
    expect(precheckStatusCell(null)).toEqual({ kind: "none", text: "-" });
    expect(PRECHECK_STATUS_NONE).toBe("-");
  });

  it("S2: Standby.(予定があり異常なし)は Pill", () => {
    expect(precheckStatusCell("Standby.")).toEqual({ kind: "pill", text: "Standby." });
  });

  it("S3: エラーの生値はそのまま Pill(変換しない。D-077)", () => {
    expect(precheckStatusCell("EmergencyStop")).toEqual({
      kind: "pill",
      text: "EmergencyStop",
    });
  });

  it("S4: 空文字は null ではないので Pill のまま(「-」にするのは null だけ)", () => {
    expect(precheckStatusCell("")).toEqual({ kind: "pill", text: "" });
  });

  it("S5: 値そのものが \"-\" でも予定ありとして Pill", () => {
    expect(precheckStatusCell("-")).toEqual({ kind: "pill", text: "-" });
  });
});

describe("precheckMinutesLabel", () => {
  it("M1: JP は「60分前」", () => {
    expect(precheckMinutesLabel("ja", 60)).toBe("60分前");
  });

  it("M2: EN は「60 min」", () => {
    expect(precheckMinutesLabel("en", 60)).toBe("60 min");
  });

  it("M3: 30 以外の分数も出る(60/10 の設定)", () => {
    expect(precheckMinutesLabel("ja", 10)).toBe("10分前");
    expect(precheckMinutesLabel("en", 10)).toBe("10 min");
  });

  it("M4: 分数は生値のまま(旧コード値 1 を読み替えない)", () => {
    expect(precheckMinutesLabel("ja", 1)).toBe("1分前");
  });

  it("M5: 0 は null ではないので文字を出す", () => {
    expect(precheckMinutesLabel("ja", 0)).toBe("0分前");
    expect(precheckMinutesLabel("en", 0)).toBe("0 min");
  });

  it("M6: null なら null(Pill だけを出す)", () => {
    expect(precheckMinutesLabel("ja", null)).toBeNull();
    expect(precheckMinutesLabel("en", null)).toBeNull();
  });
});