Files
Jyotisha/frontend/tests/birth-sky-sentence.test.ts
T
Jesse_ChenandClaude Opus 5.5 dec36bce01 feat(birth-sky): poster-only dialog, date/time/city caption, slower reveal, paywall on first refused send (P1–P5, BUG-1080)
TASK-birth-sky-polish-20260928.
- P1: chart page dialog shows only the picture on a dimmed stage, 「保存图片」 below, icon × in the corner.
- P2: BFF returns one server-built `caption` (「1994年5月18日 07:40 · 杭州」); printed under the fact line in all three places; adopted time adds 「 · 校正后」.
- P3: convergence 3 s + words 2.5 s + fade 1 s; settled frame still equals the exported cover.
- P4: redeem paywall no longer opens when the starter home appears; first send refused for credits opens it, later ones open billing; convergence dialog portalled to <body>. BUG-1080 investigating (Chrome repro rules out the overlay covering the convergence).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N4f2nya58RoRu4yEmJgRGE
2026-09-29 00:03:46 +08:00

78 lines
3.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import assert from "node:assert/strict";
import test from "node:test";
import {
BIRTH_SKY_HEADLINES,
birthSkyFactLine,
birthSkyCaptionLine,
birthSkyHeadline,
octantName,
} from "../src/lib/birth-sky/sentence.ts";
import type { BirthSkyOk } from "../src/lib/birth-sky/contract.ts";
import { birthSkyGolden, goldenSky } from "./birth-sky-test-support.ts";
test("the fictional sample (07:40) reads exactly as the brief", () => {
const sky = goldenSky("day");
assert.equal(birthSkyGolden.times.day, "07:40");
assert.equal(birthSkyHeadline(sky), "星星都在,只是还看不见。");
assert.equal(birthSkyFactLine(sky), "太阳在东,月亮在脚下,火星正悬在东南");
});
test("each phase takes its one headline from the four-line table", () => {
assert.deepEqual(Object.values(BIRTH_SKY_HEADLINES), [
"星星都在,只是还看不见。",
"天快亮了,星星正一颗颗退场。",
"天刚暗下来,星星正一颗颗出来。",
"那一刻,头顶就是这片天。",
]);
assert.equal(birthSkyHeadline(goldenSky("day")), BIRTH_SKY_HEADLINES.day);
assert.equal(birthSkyHeadline(goldenSky("twilight_morning")), "天快亮了,星星正一颗颗退场。");
assert.equal(birthSkyHeadline(goldenSky("twilight_evening")), "天刚暗下来,星星正一颗颗出来。");
assert.equal(birthSkyHeadline(goldenSky("night")), "那一刻,头顶就是这片天。");
});
test("outside daytime the fact line never names the Sun", () => {
for (const phase of ["twilight_morning", "twilight_evening", "night"] as const) {
const line = birthSkyFactLine(goldenSky(phase));
assert.doesNotMatch(line, /太阳/);
assert.match(line, /^月亮在(脚下|北|东北|东|东南|南|西南|西|西北)/);
assert.ok(line.split(",").length <= 2, line);
}
});
test("fact line combinations: moon above, no visible planet, highest planet wins", () => {
const base = goldenSky("night");
const planets = (overrides: Record<string, [number, number]>): BirthSkyOk["planets"] => base.planets.map((planet) => {
const next = overrides[planet.id];
return next ? { ...planet, altitude: next[0], azimuth: next[1] } : { ...planet, altitude: -10 };
});
assert.equal(
birthSkyFactLine({ phase: "night", planets: planets({ moon: [40, 225], jupiter: [20, 10], venus: [35, 300] }) }),
"月亮在西南,金星正悬在西北",
);
assert.equal(birthSkyFactLine({ phase: "night", planets: planets({}) }), "月亮在脚下");
assert.equal(
birthSkyFactLine({ phase: "day", planets: planets({ sun: [10, 225], saturn: [5, 170] }) }),
"太阳在西南,月亮在脚下,土星正悬在南",
);
});
test("eight-point compass rounds to the nearest 45 degrees, north at both ends", () => {
assert.equal(octantName(0), "北");
assert.equal(octantName(22.4), "北");
assert.equal(octantName(22.6), "东北");
assert.equal(octantName(84.69), "东");
assert.equal(octantName(117.24), "东南");
assert.equal(octantName(191.14), "南");
assert.equal(octantName(350), "北");
});
// 原值: 「按你填写的时间」 footnote for a reported time, none for an adopted one.
// 新值: the caption line; an adopted time appends 「 · 校正后」, a reported one adds nothing.
// 原因: TASK-birth-sky-polish-20260928 P2 — the cover prints date, time and city in that line.
test("the caption line appends 「· 校正后」 only for an adopted time", () => {
const caption = "1994年5月18日 07:40 · 杭州";
assert.equal(birthSkyCaptionLine({ timeBasis: "reported", caption }), caption);
assert.equal(birthSkyCaptionLine({ timeBasis: "adopted", caption }), "1994年5月18日 07:40 · 杭州 · 校正后");
});