fix(report): project annual sections and thicken dasha reading

完整数据版第二轮。年运章写出资料包里已有的节,没有数据的不新算。大运解释补回可能段落。瑜伽作用不再断言寿命。术语替换不进标识符。罗睺和计都不写守护第未列出宫。未合入 staging。
This commit is contained in:
jesse-ux
2026-10-08 22:30:32 +08:00
committed by Jesse_Chen
parent 25d067bf12
commit b8eef75871
14 changed files with 1148 additions and 165 deletions
+76
View File
@@ -208,6 +208,82 @@ def test_english_focus_and_new_sections_have_no_han() -> None:
assert leaked == [], leaked[:12]
def test_yoga_effect_does_not_assert_lifespan() -> None:
# 原值:作用列写「长寿;健康良好」/ Longevity。
# 新值:作用列改成体质与恢复力的参考句。名称「长寿格局」和 Ayur Yoga (Strong Longevity) 可以留下。
# 原因:格局名称是传统叫法,作用说明不再把寿命当断语。
packet = _packet("zh")
packet["worksheets"]["advanced_systems"]["yoga"]["detected_yogas"].append({
"name": "Ayur Yoga (Strong Longevity)",
"name_cn": "长寿格局",
"category": "ayur",
"strength": "strong",
"effects": ["长寿", "健康良好"],
"effects_en": ["Longevity", "Good health"],
"combination": "traditional name only",
})
chinese = render_full_data_markdown(packet)
english_packet = copy.deepcopy(packet)
english_packet["report_language"] = "en"
english = render_full_data_markdown(english_packet)
def without_names(text: str) -> str:
text = text.replace("长寿格局", "")
return re.sub(r"Ayur Yoga \(Strong Longevity\)", "", text, flags=re.IGNORECASE)
for phrase in ("长寿", "寿命长", "短寿"):
assert phrase not in without_names(chinese)
assert "longevity" not in without_names(english).lower()
assert "传统上与体质和恢复力有关,仅作参考" in chinese
assert "constitution and recovery" in english.lower()
def test_term_replacement_does_not_enter_identifiers() -> None:
# 原值:functional_benefics / Kendras / conditions 变成「功能吉星s」「角宫s」「宫条件s」,字段名里的 sign 被换成星座。
# 新值:散文里的复数 s 吃进英文词;反引号和标识符保持原文。
# 原因:术语替换只能作用于自然语言。
raw = "\n".join([
"# 标题",
"",
"strict_functional_benefic_malefic_v2",
"bphs_ch34_general_with_sign_exceptions_v2",
"functional_benefics and Kendras and house conditions",
"`functional_benefics`",
])
text = _sanitize_pl9_ai_density_markdown(raw)
assert "strict_functional_benefic_malefic_v2" in text
assert "bphs_ch34_general_with_sign_exceptions_v2" in text
assert "`functional_benefics`" in text
assert "功能吉星s" not in text
assert "角宫s" not in text
assert "宫条件s" not in text
assert "功能吉星" in text
assert re.search(r"[一-鿿]+s\b", text) is None
rendered = render_full_data_markdown(_packet("zh"))
assert re.search(r"[一-鿿]+s\b", rendered) is None
mixed = re.search(r"[A-Za-z0-9_]*_[一-鿿]|[一-鿿]_[A-Za-z0-9_]", rendered)
assert mixed is None, mixed.group(0) if mixed else ""
def test_rahu_ketu_do_not_rule_an_unlisted_house() -> None:
from scripts.pl9_interpretation_packs import _natal_en, _natal_zh, _sub_paragraph
# 原值:空守护列表写成「守护第未列出宫」。
# 新值:罗睺、计都写「不守护宫位」/ rules no house。中文全文该病句计数为 0。
# 原因:这两颗星不守护宫位。其他「未列出」按句意保留。
empty = {"ownership": [], "house": 6, "nakshatra": "Mula"}
filled = {"ownership": [1], "house": 6}
row = {"start": "2001-01-01", "end": "2001-02-01"}
assert "不守护宫位" in _sub_paragraph("Sun", "Rahu", row, empty, "zh", level="PD")
assert "守护第未列出宫" not in _sub_paragraph("Sun", "Rahu", row, empty, "zh", level="PD")
assert "不守护宫位" in _natal_zh("Ketu", filled, {})
assert "守护第1宫" in _natal_zh("Sun", filled, {})
assert "守护宫未单独列出" in _sub_paragraph("Sun", "Mars", row, empty, "zh", level="AD")
assert "rules no house" in _natal_en("Rahu", filled, {})
text = render_full_data_markdown(_packet("zh"))
assert text.count("守护第未列出宫") == 0
def test_chinese_render_stays_stable_when_english_uses_a_copy() -> None:
packet = _packet("zh")
before = render_full_data_markdown(copy.deepcopy(packet))
+5 -7
View File
@@ -128,14 +128,12 @@ def test_report_shows_the_blocked_sentence_in_both_editions(blocked_selector) ->
zh_rows = [line for line in zh.splitlines() if line.startswith("| Selection basis |")]
en_rows = [line for line in en.splitlines() if line.startswith("| Selection basis |")]
assert zh_rows and all("年主暂无法确定(年盘缺太阳或月亮位置)" in row for row in zh_rows)
# 原值:英文行是 Year lord cannot be determined yet,且无汉字;年主格是 "-"
# 新值:清干净时仍要求那句英文;否则必须保留中文阻断句并标成 source text retained。年主格是 "-" 或「未列」
# 原因:BUG-1272。不得改回 Muntha 主星。空位标记随完整数据版清理器变成「未列」
# 原值:英文行含「年主暂无法确定」,并包成 [source text retained: ...]。
# 新值:英文行是 Year lord cannot be determined yet,不要求中文,也不要求 source text retained。
# 原因:英文汉字已清零,那条中文断言没有对象。不得把汉字塞回英文。
assert en_rows
if any(re.search(r"[一-鿿]", row) for row in en_rows):
assert all("年主暂无法确定" in row and "[source text retained:" in row for row in en_rows)
else:
assert all("Year lord cannot be determined yet" in row for row in en_rows)
assert all("Year lord cannot be determined yet" in row for row in en_rows)
assert all("年主暂无法确定" not in row and "[source text retained:" not in row for row in en_rows)
assert any(
line.startswith("| Varshesha | - |") or line.startswith("| Varshesha | 未列 |")
for line in zh.splitlines()