# tests/unit/presentation/palette_token_pairwise_test.gd — 语义/UI token 板两两互查守门 # 断言面:ui_kit 全部 Color 常量两两 RGB 三通道差禁止全部 <8/255(圣经 §4.1 色板增量纪律第二道门的 # 存量面执法件,数值门=本件 NEAR_EPS);六对已登记欠账走豁免账(债面=圣经 §4.1 欠账清单+待办清单 # 「色板近色欠账六对清偿」条;新增欠账禁直入本账,须走待办清单修订)。 # 豁免账中两对伙伴色(3e3731/3e4048/3f4147)为迷雾合成底素材侧色——不在 ui_kit 常量面, # 其清偿随素材批处理;本测试扫常量面,素材侧对子由互辨抽测件近色读数承载。 # 运行:godot --headless --path game --script res://tests/unit/presentation/palette_token_pairwise_test.gd extends SceneTree const Kit := preload("res://tests/unit/test_kit.gd") const UI_KIT_PATH := "res://presentation/views/ui_kit.gd" const NEAR_EPS := 8 # 存量近色关系在册账(键=两色 hex 升序拼接,值=性质标签)。账面=常量面全量现状的机器真值; # 闸只拦「账外新增」。标「欠账」四对=art-bible 原六对债的常量面部分(清偿批销账); # 另两对(3e362c3e3731/3e40483f4147)伙伴为迷雾合成底素材侧色,不在常量面,随素材批清偿。 # 同一键可覆盖多名对(同值别名与其伙伴构成的同 hex 对)。 const EXEMPT_LEDGER := { "140f0d18120c": "深墨族(DIM↔DIM_NIGHT)", "140f0d181410": "深墨族(DIM↔INK_ROUTE)", "18120c181410": "深墨族(DIM_NIGHT↔INK_ROUTE)〔欠账〕", "18120c1e1812": "深墨族(DIM_NIGHT↔FOG_OUTLINE)", "291f172e2218": "暗底族(INK_LABEL↔TIP_BG)", "2820182e2218": "暗底族(CAMP_BADGE_PANEL↔INK_LABEL)", "282018291f17": "暗底族(CAMP_BADGE_PANEL↔TIP_BG)", "33261b342a20": "墨族近结构件(E_FACADE_FOOT_COL↔INK)", "33261b362b20": "墨族近屏底(INK↔BG_OVERLAY)〔欠账〕", "342a20362b20": "结构件暗棕近屏底(E_FACADE_FOOT_COL↔BG_OVERLAY)", "342a203a2e22": "结构件暗棕近屏底(E_FACADE_FOOT_COL↔BG_ROOT)", "362b203a2e22": "屏底双件(BG_OVERLAY↔BG_ROOT)〔欠账〕", "3a3a3a403a34": "暗板族(DARK_UPCOMING↔FOG_MEMORY_PLATE)", "4537234a3b2a": "暖亮底双件(BG_BRIGHT↔BG_MAP_TOP)〔欠账〕", "4a3b2a4a3e30": "同域暗棕(BG_MAP_TOP↔HINT_STRIP_EDGE)", "6e45266e4526": "α 派生别名(CAMP_HEADER_BAND↔CAMP_HUD_BAND,非色板新增)", "786e58786e58": "文档别名(DOT_OFF↔PANEL_BORDER——兼熄灭点阵)", "1a17141e1812": "深墨族(FOG_OUTLINE↔ICON_TINT_ON_GOLD)", "1814101a1714": "深墨族(ICON_TINT_ON_GOLD↔INK_ROUTE)", "1a17141e1a16": "深墨族(ICON_TINT_ON_GOLD↔INK_TITLE)", "1814101e1812": "深墨族(FOG_OUTLINE↔INK_ROUTE)", "1e18121e1a16": "深墨族(FOG_OUTLINE↔INK_TITLE)", "1814101e1a16": "深墨族(INK_ROUTE↔INK_TITLE)", "1a1a1c1e1a16": "深墨族(HP_BAR_TRACK↔INK_TITLE)", "2e221833261b": "墨族(INK↔INK_LABEL)", "c9b88ecdb88c": "暖米族(MAP_VDIV↔WARM_FAINT)", "e0b860e6be5a": "金族亮档双件(GOLD_BRIGHT↔GOLD_LIT)", "f0e2c8f0e2c8": "同值别名(INK_L_WARM↔WARM)", "f0e2c8f0e4c8": "暖米板族(INK_L_WARM/MAP_BAR_PLATE/WARM 同 hex 双名对)", "f0e2c8f0e6ce": "暖米板族(CAMP_ROW_PLATE↔INK_L_WARM/WARM 同 hex 双名对)", "f0e4c8f0e6ce": "暖米板族(CAMP_ROW_PLATE↔MAP_BAR_PLATE)", "f0e6cef5ead3": "暖米板族(CAMP_ROW_PLATE↔DIGIT_PLATE)", "f0e8d6f5ead3": "暖纸板族(DIGIT_PLATE↔TOAST_BG)", "f5ead3f6eeda": "暖纸板族(DIGIT_PLATE↔INK_ON_DEEP)", "f0e8d6f6eeda": "暖纸板族(INK_ON_DEEP↔TOAST_BG)", "f8e2a8f8e3a8": "同族亮金墨(INK_L_GOLD↔RAP_DOT_CORE_WARM)", } func _init() -> void: # 判据出处: design/art/art-bible.md:220 (色板增量纪律条——存量两两互查组) _test_pairwise() quit(Kit.finish("palette_token_pairwise_test")) func _token_colors() -> Dictionary: var script: Script = load(UI_KIT_PATH) var cmap: Dictionary = script.get_script_constant_map() var out: Dictionary = {} for name: String in cmap: if cmap[name] is Color: out[name] = cmap[name] return out func _hex(c: Color) -> String: return "%02x%02x%02x" % [c.r8, c.g8, c.b8] # 存量两两互查:豁免账外零近色对(扫描面>0 前置防静默绿) func _test_pairwise() -> void: # 判据出处: design/art/art-bible.md:220 (色板增量纪律条——存量两两互查组) var tokens := _token_colors() Kit.check("token 面非空(扫描面>0)〔token互查 V1〕", tokens.size() >= 40) var names: Array = tokens.keys() names.sort() var bad: Array = [] for i in range(names.size()): for j in range(i + 1, names.size()): var a: Color = tokens[names[i]] var b: Color = tokens[names[j]] if absi(a.r8 - b.r8) < NEAR_EPS and absi(a.g8 - b.g8) < NEAR_EPS \ and absi(a.b8 - b.b8) < NEAR_EPS: var pair: Array = [_hex(a), _hex(b)] pair.sort() var key: String = pair[0] + pair[1] if not EXEMPT_LEDGER.has(key): bad.append("%s↔%s(%s)" % [names[i], names[j], key]) Kit.check("豁免账外零新增近色对〔token互查 V2〕", bad.is_empty()) if not bad.is_empty(): for item: String in bad: print(" [近色对] ", item)