/** * 两个客户端必须用**同一份设计词表**。 * * 用户下一步要求:「同步 ui 设计到客户端」。同步的第一件事不是把每个页面重画一遍, * 而是两边共用同一套令牌(颜色/圆角/玻璃透明度)—— 否则每加一个页面就重抄一遍色值, * 两个客户端会越走越远,而且这种漂移**没有任何判据会红**。 * * 这里只断言"两边对同一件事的取值一致",不断言实现方式(WebUI 用 CSS 变量、 * 鸿蒙用 ArkTS 常量,本来就该不同)。 */ import { test } from 'node:test'; import assert from 'node:assert/strict'; import { readFileSync } from 'node:fs'; import { dirname, join } from 'node:path'; import { fileURLToPath } from 'node:url'; const HERE = dirname(fileURLToPath(import.meta.url)); const ROOT = join(HERE, '..', '..', '..'); const web = readFileSync(join(ROOT, 'client/electron/src/index.css'), 'utf8'); const harmony = readFileSync( join(ROOT, 'client/harmony/entry/src/main/ets/common/Theme.ets'), 'utf8' ); const hex = h => h.toUpperCase(); test('品牌蓝一致', () => { // WebUI: --c-blue-600 应该是 37 99 235 = #2563EB const webBlue = web.match(/--c-blue-600:\s*(\d+)\s+(\d+)\s+(\d+)/); assert.ok(webBlue, 'WebUI 要有 --c-blue-600'); const asHex = hex( '#' + [webBlue[1], webBlue[2], webBlue[3]] .map(n => Number(n).toString(16).padStart(2, '0')) .join('') ); const harmonyBlue = harmony.match(/accent: string = '(#[0-9A-Fa-f]{6})'/); assert.ok(harmonyBlue, '鸿蒙要有 accent'); assert.equal(hex(harmonyBlue[1]), asHex, `品牌蓝不一致:WebUI ${asHex} vs 鸿蒙 ${harmonyBlue[1]}`); }); test('卡片圆角一致(WebUI 0.875rem = 14px)', () => { assert.match(web, /--radius-card:\s*0\.875rem/); assert.match(harmony, /radiusCard: number = 14/); }); test('导航玻璃不透明度一致(都是 0.72)', () => { assert.match(web, /--nav-bg:\s*255 255 255 \/ 0\.72/); // 0.72 × 255 ≈ 184 = 0xB8(鸿蒙用 #AARRGGBB,顺序与 CSS 不同) assert.match(harmony, /navBgLight: string = '#B8FFFFFF'/); }); test('★ 判据自检:把鸿蒙的品牌蓝改成别的必须判红', () => { const mutated = harmony.replace(/accent: string = '#2563EB'/, "accent: string = '#FF0000'"); const m = mutated.match(/accent: string = '(#[0-9A-Fa-f]{6})'/); assert.notEqual(hex(m[1]), '#2563EB'); }); test('鸿蒙的令牌文件说明了与 WebUI 的对应关系(不是凭空一套)', () => { assert.match(harmony, /与 WebUI 的令牌\*\*一一对应|对应 WebUI/); }); test('★ 鸿蒙页面里不得再出现与 WebUI 不同的旧调色板', () => { /* * 对齐之前的鸿蒙调色板是另一套(#1A73E8 Google 蓝、#333333、#F5F7FA…), * 与 WebUI 的品牌色/灰阶并不同。203 处已换成 Theme 令牌;这条判据防止 * 以后新写的页面又随手写死一个"差不多"的颜色 —— 那正是漂移的开始。 */ const pages = ['MainPage', 'InboxPage', 'SessionsPage', 'MailDetailPage', 'ComposePage', 'SettingsPage', 'LoginPage']; const old = ['#1A73E8', '#333333', '#666666', '#999999', '#F5F7FA', '#F5F5F5', '#FF4444', '#F0F7FF']; for (const name of pages) { const src = readFileSync(join(ROOT, `client/harmony/entry/src/main/ets/pages/${name}.ets`), 'utf8'); for (const c of old) { assert.ok(!src.includes(`'${c}'`), `${name}.ets 里还有旧调色板色值 ${c}(应改用 Theme 令牌)`); } } // 反向对照:判据本身要能抓到 assert.ok("#1A73E8".length > 0 && old.includes('#1A73E8')); });