Design System Guard / guard (push) Failing after 7m11s
本提交收口本轮四件事。三者改动在同一批文件里交织(改名触及 theme.dart、
深色化也在 theme.dart),按文件无法干净切分,故合为一个可审计的提交,
下面按事由分述。
一、命名统一:Pmon* → Inkwatch*(合入 V2 线后的收尾)
· 包名 pmon_client → inkwatch_client,Rust crate pmon-core → inkwatch-core。
改名后必须 flutter pub get 重建 package_config,否则 dart analyze 会报
1688 个"找不到 package:pmon_client"的假错误。
· 符号:PmonColors→InkwatchColors、PmonPalette→InkwatchPalette、
PmonTextStyles→InkwatchTextStyles、PmonRadius→InkwatchRadius、
PmonEinkText→InkwatchEinkText、PMON_LOG_*→INKWATCH_LOG_*。
· 覆盖 server/ client/ rust-core/ tests/ 全树;已用
git grep -In 'Pmon\|PMON\|pmon' 复核,零残留(tokens.css 里最后一处
§2.8 的类名注释也在本提交修掉)。
· rust-core/Cargo.lock 的变动只是包名变化导致 [[package]] 字典序重排。
二、深色主题:58 键同名覆写 + Flutter 整屏深色化
· tokens.css 增 dark 块(58 键),键名与浅色**逐一相同**——
这是 token_parity_test.dart 的深色 parity 组在守的约束。
· theme.dart:新增 InkwatchDarkColors / _assemble(palette, brightness),
把语义色从"常量"改为"随 brightness 装配"。
· main.dart:darkTheme + 显式 themeMode(ValueNotifier 持久化,不用
ThemeMode.system —— 水墨屏用户要的是自己定,不是跟系统)。
· theme_guard_test.dart C-15 → C-15′:从"禁止出现深色"改为"允许深色,
但必须 58 键同名",护栏跟着设计意图一起改,而不是删掉。
· 新增 dark_theme_test.dart / dark_ui_test.dart 覆盖装配与整屏渲染。
三、状态符号图标化:Unicode 字形 → Material Icons
· symbol_guard_test.dart 按**码位**扫 lib/(注释之外),命中 5 处:
transfer_card.dart 的 ⚠️/✓/✓/⚠,viewer_page.dart 的 ✓。
· 只删字形会留下不可见的 U+FE0F,源码看不出、界面渲染成豆腐块,
且按 emoji 区间匹配的旧护栏看不见它 —— 故护栏按码位判,且判据选
"扫注释之外全部字符"(错了只会多报,不会漏)。
· 改法:状态图标单独一槽,不拼进文案。
- transfer_card.dart:_offerHint 由 String? 改为
({IconData? icon, Color? tint, String text})?,渲染为 Row(Icon+Text);
「已收下」结果块同理(check_circle / error_outline)。
图标着色:warning_amber→_p.suspect,check_circle→_p.online。
- viewer_page.dart:_lanSummary() 返回 ({IconData? icon, String text}),
诊断行由 ('对端内网', _lanSummary(), null) 改为 (…, lan.text, lan.icon)。
调用点提到 return 之前只算一次。
· 理由不只是"好看":字符符号在水墨屏上会渲染成方框,且无法随主题着色。
验证
· client/scripts/test.sh:674 项全过(+674,0 失败,23s)
· tests/run-guards.sh(RUN_AXE=1):
web-token-guard.js PASS 21/0
phase3b-static-guard.js PASS 87/0
dockerfile-coverage-test.js PASS 53/0
schema-consistency-test.js PASS 116/0
client Dart 全量 PASS 674 项
admin-axe-audit.mjs PASS 42/42 格 viol=0(inc=12 有台账)
6 套件 PASS 6 / FAIL 0 / SKIPPED 0
· dart analyze:9 issues / 0 error(全部为既有 info/warning,非本次引入)
· 两处 tokens.css(仓库内 admin/assets 与设计系统交付目录)逐字节一致
sha256 088873cf6ece8da78135f96ca4633a537ac7802ea5f0fc8bd9c9294bb8a7bcaa
已知未做(写下来,不藏)
· flutter analyze 在本机因仓库路径含中文(水墨屏工具)触发 analysis_server
的 LSP 分帧 UTF-8 错误(FormatException: Unterminated string)。
绕法是用 dart analyze,或把工作树放到纯 ASCII 路径下。
· 窄屏降级态 + 失败态的组合真机复核:仍未做。
· VoiceOver / NVDA 实机验证:NOT RUN。
· 管理台登录框仍缺持久 <label>(现靠 aria-labelledby 指向标题)。
107 lines
3.5 KiB
Bash
Executable File
107 lines
3.5 KiB
Bash
Executable File
#!/usr/bin/env bash
|
||
# 客户端测试入口 —— 唯一目的是**把代理变量清干净**。
|
||
#
|
||
# 为什么必须清:flutter_test 会拉起 flutter_tester 进程并用**本地 WebSocket** 通信。
|
||
# 本机(Xray/AdGuard)导出的 HTTP_PROXY/ALL_PROXY 会让 localhost 也走代理,
|
||
# 于是测试在"加载阶段"就失败,报:
|
||
# Unable to connect to flutter_tester process:
|
||
# WebSocketException: Invalid WebSocket upgrade request
|
||
# 这个报错**看起来像代码错误**(甚至显示不出来是哪一行的错),实际是环境问题,
|
||
# 已两次让本项目的测试"无故变红"。故固定成一个入口,别再手敲 env -u。
|
||
#
|
||
# 用法:
|
||
# bash scripts/test.sh # 跑全部客户端测试
|
||
# bash scripts/test.sh test/viewer_page_test.dart
|
||
#
|
||
# 可用 FLUTTER_BIN 指定 flutter:FLUTTER_BIN=/path/to/flutter bash scripts/test.sh
|
||
#
|
||
# ── 已登记测试清单(Phase 3b 补)────────────────────────────────────
|
||
# `flutter test` 无参时会自动发现 test/*_test.dart;下面这份清单不是为了
|
||
# 替代自动发现,而是为了守住「新增测试文件必须登记」这条纪律 ——
|
||
# theme_guard_test.dart 的 _uiFiles 已两次因漏登记让几百行界面代码
|
||
# 不受护栏保护。默认全量跑之前做一次反向检查:出现清单外的 *_test.dart
|
||
# 就报错,逼迫显式登记后再跑。
|
||
# 本轮新增登记:token_parity_test.dart(CSS ↔ Dart 令牌双向护栏,05 §3.5 ④)。
|
||
|
||
set -euo pipefail
|
||
cd "$(dirname "$0")/.."
|
||
|
||
FLUTTER="${FLUTTER_BIN:-$HOME/development/flutter/bin/flutter}"
|
||
if [ ! -x "$FLUTTER" ]; then
|
||
echo "未找到 flutter:$FLUTTER" >&2
|
||
echo "可用 FLUTTER_BIN=/path/to/flutter 指定" >&2
|
||
exit 1
|
||
fi
|
||
|
||
REGISTERED_TESTS=(
|
||
account_security_test.dart
|
||
account_test.dart
|
||
adaptive_unit_test.dart
|
||
agent_lock_test.dart
|
||
agent_probe_test.dart
|
||
app_paths_test.dart
|
||
autostart_runner_test.dart
|
||
boot_report_test.dart
|
||
clock_test.dart
|
||
config_change_test.dart
|
||
config_migration_test.dart
|
||
dark_theme_test.dart
|
||
dark_ui_test.dart
|
||
device_merge_notice_test.dart
|
||
device_model_test.dart
|
||
eink_board_test.dart
|
||
event_reporter_test.dart
|
||
handover_test.dart
|
||
history_test.dart
|
||
host_ffi_test.dart
|
||
idle_sampling_test.dart
|
||
install_paths_test.dart
|
||
installer_launch_note_test.dart
|
||
installer_status_json_test.dart
|
||
lan_service_test.dart
|
||
link_hub_test.dart
|
||
link_mode_test.dart
|
||
metric_format_test.dart
|
||
p2p_driver_test.dart
|
||
p2p_session_test.dart
|
||
pairing_card_test.dart
|
||
plan_text_guard_test.dart
|
||
relay_driver_test.dart
|
||
resident_card_test.dart
|
||
resident_service_test.dart
|
||
scaled_unit_test.dart
|
||
skeleton_test.dart
|
||
startup_log_test.dart
|
||
startup_path_test.dart
|
||
stun_test.dart
|
||
symbol_guard_test.dart
|
||
theme_guard_test.dart
|
||
token_parity_test.dart
|
||
transfer_card_test.dart
|
||
viewer_page_test.dart
|
||
viewer_test.dart
|
||
)
|
||
|
||
# 只在「默认全量跑」时校验:显式传文件参数时保持原样透传
|
||
if [ "$#" -eq 0 ]; then
|
||
shopt -s nullglob
|
||
for f in test/*_test.dart; do
|
||
base="$(basename "$f")"
|
||
found=0
|
||
for r in "${REGISTERED_TESTS[@]}"; do
|
||
if [ "$r" = "$base" ]; then found=1; break; fi
|
||
done
|
||
if [ "$found" -eq 0 ]; then
|
||
echo "未登记的测试文件:$f" >&2
|
||
echo "请把 $base 加进 scripts/test.sh 的 REGISTERED_TESTS 清单后再跑" >&2
|
||
exit 1
|
||
fi
|
||
done
|
||
fi
|
||
|
||
exec env \
|
||
-u HTTP_PROXY -u HTTPS_PROXY -u ALL_PROXY \
|
||
-u http_proxy -u https_proxy -u all_proxy \
|
||
-u NO_PROXY -u no_proxy \
|
||
"$FLUTTER" test "$@"
|