"""Execute the mode preview formatter against actual seat/light parameter shapes.""" from __future__ import annotations import json import shutil import subprocess from pathlib import Path import pytest ROOT = Path(__file__).resolve().parents[2] @pytest.fixture(scope="module") def render_rows(): node = shutil.which("node") if not node: runtime = ( Path.home() / ".cache" / "codex-runtimes" / "codex-primary-runtime" / "dependencies" / "node" / "bin" ) node = next((str(path) for path in (runtime / "node.exe", runtime / "node") if path.is_file()), None) assert node, "Node.js is required to validate rendered mode action text" source = (ROOT / "apps" / "web-console" / "assistant-chat.js").read_text(encoding="utf-8") start = source.index(" function modeDraftRows(") end = source.index("\n function ", start + 1) script = source[start:end] + "\nconst input = JSON.parse(require('node:fs').readFileSync(0, 'utf8'));\n" script += "console.log(JSON.stringify(modeDraftRows(input.draft, input.actions)));" def render(actions, instruction=""): completed = subprocess.run( [node, "-e", script], input=json.dumps({"draft": {"instruction": instruction}, "actions": actions}, ensure_ascii=False), capture_output=True, text=True, encoding="utf-8", check=True, ) return json.loads(completed.stdout) return render def action(capability, parameters, zone="driver"): return { "domain": capability.split(".")[0], "capability": capability, "target": {"zone": zone}, "parameters": parameters, } @pytest.mark.parametrize("kind", ["ventilation", "heating"]) @pytest.mark.parametrize( ("parameters", "expected"), [ ({"state": "on", "level": 1}, "开启 · 3档(高)"), ({"state": "on", "level": 2}, "开启 · 1档(低)"), ({"state": "on"}, "开启 · 1档(低)"), ({"state": "off", "level": 1}, "关闭"), ], ) def test_driver_native_comfort_uses_its_own_level_scale(render_rows, kind, parameters, expected): rows = render_rows([action(f"seat.set_driver_{kind}_native", parameters, "front_left")]) assert rows[0]["label"] == f"主驾座椅{'通风' if kind == 'ventilation' else '加热'}" assert rows[0]["value"] == expected @pytest.mark.parametrize("kind", ["ventilation", "heating"]) @pytest.mark.parametrize("level", [1, 2, 3, 4, 5]) def test_passenger_levels_are_not_translated_using_driver_can_codes(render_rows, kind, level): rows = render_rows([action(f"seat.set_{kind}", {"state": "on", "level": level}, "passenger")]) assert rows[0]["label"] == f"副驾座椅{'通风' if kind == 'ventilation' else '加热'}" assert rows[0]["value"] == f"开启 · {level}档" @pytest.mark.parametrize( ("parameters", "expected"), [ ({"action": "off", "mode": "relax"}, "关闭"), ({"action": "mode", "mode": "wave"}, "波浪模式"), ({"action": "mode", "mode": "pulse"}, "脉冲模式"), ({"action": "mode", "mode": "stretch"}, "舒展模式"), ({"action": "mode", "mode": "slack"}, "舒缓模式"), ({"action": "mode", "mode": "relax"}, "放松模式"), ({"action": "strength", "strength": 1}, "轻柔力度"), ({"action": "strength", "strength": 2}, "中等力度"), ({"action": "strength", "strength": 3}, "较强力度"), ({"action": "mode"}, "按摩模式待确认"), ({"action": "strength"}, "按摩力度待确认"), ], ) def test_massage_preview_distinguishes_operation_mode_and_strength(render_rows, parameters, expected): rows = render_rows([action("seat.set_driver_massage_native", parameters)]) assert rows[0]["label"] == "主驾座椅按摩" assert rows[0]["value"] == expected def test_ambient_native_color_and_brightness_remain_distinct_rows(render_rows): rows = render_rows([ action("ambient_light.set_color_index", {"color_index": 127}, "vehicle"), action("ambient_light.set_brightness_level", {"brightness_level": 2}, "vehicle"), ]) assert [(row["label"], row["value"]) for row in rows] == [ ("氛围灯颜色", "色号 127"), ("氛围灯亮度", "2档"), ] @pytest.mark.parametrize("brightness", [0, 20, 100]) def test_rgb_illumination_keeps_exact_color_and_brightness(render_rows, brightness): rows = render_rows([ action("ambient_light.set_illumination", {"color_hex": "#FFB347", "brightness_pct": brightness}, "vehicle"), ]) assert rows[0]["value"] == f"颜色 #FFB347 · 亮度 {brightness}%" def test_zero_gravity_grouping_keeps_driver_comfort_visible(render_rows): rows = render_rows([ action("seat.set_longitudinal_position", {"position_pct": 100}, "passenger"), action("seat.set_backrest_recline", {"position_pct": 81, "angle_deg": 150}, "front_right"), action("seat.set_driver_massage_native", {"action": "mode", "mode": "relax"}), ], "副驾零重力模式,并开启主驾放松按摩") assert [(row["label"], row["value"]) for row in rows] == [ ("副驾座椅", "零重力模式"), ("主驾座椅按摩", "放松模式"), ] def test_position_and_power_rows_keep_existing_values(render_rows): rows = render_rows([ action("seat.set_backrest_recline", {"position_pct": 81, "angle_deg": 150}, "passenger"), action("ambient_light.set_power", {"state": "off"}, "vehicle"), action("seat.set_ventilation", {"state": "off", "level": 2}, "passenger"), ]) assert [(row["label"], row["value"]) for row in rows] == [ ("副驾靠背位置", "81%(150°)"), ("氛围灯", "关闭"), ("副驾座椅通风", "关闭"), ] @pytest.mark.parametrize( ("capability", "mode", "label", "value"), [ ("climate.set_control_mode", "auto", "空调控制模式", "自动控制"), ("climate.set_control_mode", "manual", "空调控制模式", "手动控制"), ("climate.set_cycle_mode", "internal", "空调循环", "内循环"), ("climate.set_cycle_mode", "external", "空调循环", "外循环"), ("climate.set_outlet_mode", "face", "空调出风模式", "吹面"), ("climate.set_outlet_mode", "face_feet", "空调出风模式", "吹面 / 吹脚"), ("climate.set_outlet_mode", "feet", "空调出风模式", "吹脚"), ("climate.set_outlet_mode", "feet_defrost", "空调出风模式", "吹脚 / 除霜"), ("climate.set_outlet_mode", "defrost", "空调出风模式", "除霜"), ("climate.set_outlet_mode", "face_feet_defrost", "空调出风模式", "吹面 / 吹脚 / 除霜"), ("climate.set_outlet_mode", "face_defrost", "空调出风模式", "吹面 / 除霜"), ], ) def test_climate_modes_use_capability_specific_labels(render_rows, capability, mode, label, value): rows = render_rows([action(capability, {"mode": mode}, "vehicle")]) assert (rows[0]["label"], rows[0]["value"]) == (label, value) def test_climate_control_circulation_and_outlet_are_not_conflated(render_rows): rows = render_rows([ action("climate.set_control_mode", {"mode": "auto"}, "vehicle"), action("climate.set_cycle_mode", {"mode": "internal"}, "vehicle"), action("climate.set_outlet_mode", {"mode": "face_feet"}, "vehicle"), action("climate.set_fan_level", {"level": 2}, "vehicle"), ]) assert [(row["label"], row["value"]) for row in rows] == [ ("空调控制模式", "自动控制"), ("空调循环", "内循环"), ("空调出风模式", "吹面 / 吹脚"), ("空调风量", "2档"), ] def test_mode_preview_localizes_external_device_name_and_action_parameters(render_rows): rows = render_rows([ { "domain": "self_extension", "capability": "infrared.emit", "target": {"device": "flashing-light", "name": "闪烁灯"}, "parameters": {"action": "打开", "slot": 7}, }, ]) assert [(row["label"], row["value"]) for row in rows] == [ ("闪烁灯", "动作:打开"), ] assert "infrared.emit" not in json.dumps(rows, ensure_ascii=False) def test_default_bundle_rows_show_each_passenger_action_separately(render_rows): rows = render_rows([ action("climate.set_power", {"state": "on"}, "vehicle"), action("window.set_position", {"position_pct": 0}, "front_left"), action("seat.set_ventilation", {"state": "on", "level": 1}, "passenger"), action("seat.set_backrest_recline", {"position_pct": 45}, "passenger"), action("seat.set_legrest_height", {"position_pct": 35}, "passenger"), ]) assert [(row["label"], row["value"]) for row in rows] == [ ("空调电源", "开启"), ("主驾车窗", "完全关闭(目标开度 0%)"), ("副驾座椅通风", "开启 · 1档"), ("副驾靠背位置", "45%"), ("副驾腿托位置", "35%"), ] def test_cinema_draft_shows_all_four_axes_and_ventilation(render_rows): actions = [ action("seat.set_longitudinal_position", {"position_pct": 51}, "passenger"), action("seat.set_cushion_tilt", {"position_pct": 30}, "passenger"), action("seat.set_backrest_recline", {"position_pct": 44}, "front_right"), action("seat.set_legrest_height", {"position_pct": 53}, "front_right"), action("seat.set_ventilation", {"state": "off"}, "passenger"), ] rows = render_rows(actions, "进入浪漫影院模式") assert [(row["label"], row["value"]) for row in rows] == [ ("副驾座椅前后位置", "51%"), ("副驾坐垫位置", "30%"), ("副驾靠背位置", "44%"), ("副驾腿托位置", "53%"), ("副驾座椅通风", "关闭"), ]