Files
Jyotisha/frontend/tests/report-calculation-charts.test.tsx
T
Jesse_ChenandClaude Opus 5.5 ae18952e51
Independent Staging Quality Gate / validate (push) Successful in 15m27s
Independent Staging Quality Gate / publish (push) Successful in 3m42s
fix(report,chart): blank columns — drop Kranti, split Ashtakavarga house SAV, ascendant nakshatra, engine varga dignity, no duplicate charts (BUG-1199..1203)
- Report p33 table: no Kranti column (no producer; materials.kranti stays blocked).
- Report p53 table: the "SAV" column was the with-Lagna total (386). Split in the
  reader into SAV / Lagna BAV / SAV + Lagna with a totals row; ashtakavarga.py is
  untouched (frozen rectification identity, ERR-115).
- /api/chart ascendant carries nakshatra / pada / lord (_nakshatra_fields shared with
  the nine bodies); chart cache schema 4 -> 5.
- /api/varga_full bodies carry dignity_level from varga_dignity_level, the function
  the Vimsopaka path now shares (A/B identical); the chart page shows the D1 status
  wording and no longer derives a three-level dignity itself.
- Report page draws each chart once: the trailing block skips charts the body already
  fenced (same rule as the export); the birth-time caveat moves under the body's
  chart heading.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017eEAG8HD3mm8gsKXgk8uU8
2026-10-03 09:11:15 +08:00

49 lines
2.7 KiB
TypeScript

import assert from "node:assert/strict";
import { readFileSync } from "node:fs";
import React from "react";
import { renderToStaticMarkup } from "react-dom/server";
import test from "node:test";
import { ReportCalculationCharts } from "../src/components/personal-report/report-calculation-charts.tsx";
import { buildReportExportBlocks } from "../src/lib/report-export-blocks.ts";
import { fencedReportChartIds } from "../src/lib/report-chart-block.ts";
import { assembleLongformCharts } from "../src/lib/personal-report-generation.ts";
Object.assign(globalThis, { React });
// Real engine output and its real reader body (fictional chart).
const fixture = JSON.parse(readFileSync(new URL("./fixtures/report-density-fictional-reader.json", import.meta.url), "utf8"));
const engine = JSON.parse(readFileSync(new URL("./fixtures/report-density-fictional-engine.json", import.meta.url), "utf8"));
const charts = assembleLongformCharts(engine, "ev-cover-longform");
function render(markdown: string, language: "zh" | "en" = "zh"): string {
return renderToStaticMarkup(React.createElement(ReportCalculationCharts, { charts, markdown, language }));
}
// BUG-1203: the body already drew these charts; the tail drew them again.
test("a report whose body draws every chart has no trailing chart section", () => {
const drawn = fencedReportChartIds(fixture.markdown);
assert.ok(charts.length > 0);
for (const chart of charts) assert.ok(drawn.has(chart.id), chart.id);
assert.equal(render(fixture.markdown), "");
assert.equal(render(fixture.markdown, "en"), "");
});
test("an older body without chart fences keeps its charts, without the moved caveat", () => {
const markup = render("# 报告\n\n正文");
assert.match(markup, /<h2>分盘核对<\/h2>/);
assert.equal((markup.match(/personal-report-chart-card/g) ?? []).length, charts.filter(chart => chart.houses.some(house => house.occupants.length)).length);
assert.doesNotMatch(markup, /出生时间敏感/);
});
test("the page and the export skip the same charts", () => {
const first = /```jyotish-chart\n[\s\S]*?```/.exec(fixture.markdown)![0];
const drawn = [...fencedReportChartIds(first)];
assert.equal(drawn.length, 1);
const markup = render(first);
const pageIds = charts.filter(chart => !drawn.includes(chart.id) && chart.houses.some(house => house.occupants.length)).map(chart => chart.id);
assert.equal((markup.match(/personal-report-chart-card/g) ?? []).length, pageIds.length);
const exported = buildReportExportBlocks({ markdown: first, charts }).filter(block => block.group === "chart" && !/^chart:[^:]+:\d+$/.test(block.id)); // fence charts carry an occurrence suffix
assert.deepEqual(exported.map(block => block.id.replace(/^chart:/, "")), pageIds);
});