// season.test.ts - the season guard lab, pre-written tests.
//
// HOW THIS FILE WORKS:
// - Do NOT edit this file. Your code goes in season.ts, next door.
// - Right now all four tests FAIL (red) because seasonFromString is a
//   stub that throws. That is the starting line, not a bug.
// - Your job: implement seasonFromString so all four tests PASS
//   (green). Then break your guard once on purpose and watch one
//   test go red again - that red is proof the test actually guards
//   something.
// - Run:  npm test && npm run typecheck   (from the lab directory)
// - Rules: no `any`, no bare casts (`as`). Strict equality only.
//
// WHAT EACH TEST DEMANDS OF YOUR GUARD:
//  1. accepts every season in the union - the four true members pass.
//  2. returns null for a near miss - wrong case ("Fall") and plausible
//     outsiders ("autumn") are strangers, not seasons.
//  3. returns null for non-strings - null, undefined, numbers, and
//     objects are strangers even when they mention a season.
//  4. narrows the type for the caller - after your guard returns, a
//     null check must be enough for TypeScript to treat the result as
//     a real Season (so .toUpperCase() typechecks with no cast).

import { describe, expect, it } from "vitest";
import { seasonFromString } from "./season";

describe("season guard lab", () => {
	it("accepts every season in the union", () => {
		// each true member comes back unchanged, typed as Season
		expect(seasonFromString("winter")).toBe("winter");
		expect(seasonFromString("spring")).toBe("spring");
		expect(seasonFromString("summer")).toBe("summer");
		expect(seasonFromString("fall")).toBe("fall");
	});

	it("returns null for a near miss", () => {
		// "Fall" is a case stranger; "autumn" is not in the union -
		// both must come back null, never throw
		expect(seasonFromString("Fall")).toBeNull();
		expect(seasonFromString("autumn")).toBeNull();
	});

	it("returns null for non-strings", () => {
		// nothing that is not a string is a season, even an object
		// that happens to mention one
		expect(seasonFromString(null)).toBeNull();
		expect(seasonFromString(undefined)).toBeNull();
		expect(seasonFromString(42)).toBeNull();
		expect(seasonFromString({ season: "winter" })).toBeNull();
	});

	it("narrows the type for the caller", () => {
		// the payoff: value arrives unknown, the guard proves it, and
		// after one null check TypeScript knows it is a Season - no
		// cast needed for .toUpperCase() to typecheck
		const value: unknown = "summer";
		const season = seasonFromString(value);
		if (season === null) throw new Error("should have narrowed");
		const upper: string = season.toUpperCase();
		expect(upper).toBe("SUMMER");
	});
});
