Files
Scoreboard/console/main/platform.test.js
T
AskaEth efa049c827 feat(platform): Console 支持 Linux(arm64),Windows 行为逐字不变;版本 dev_0.5.10
需求:让积分榜能在飞腾 D2000(ARM64)的 Linux 上跑起来,**同时不破坏 Windows**。

## 一、Go 服务端:交叉编译即可(**已实测**)
- SQLite 用的是 `modernc.org/sqlite`(纯 Go 驱动),全项目**没有一处 `import "C"`** → `CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build` 直接出;
- 产物是**静态链接**(`ELF 64-bit LSB executable, ARM aarch64, statically linked`)→ **不依赖 glibc 版本**,对国产系统友好;
- 本机(arm64)**实际启动验证**:数据目录、局域网地址探测、数据库迁移(0001/0002/0003)全部正常;
- 产物:`debug/服务端-arm64/scoreboard`(29 MB,`-s -w`)。

## 二、Console(Electron 宿主):平台差异收口到一个新文件
- **新增 `console/main/platform.js`**:平台差异集中在这 45 行里,其余代码不写平台判断。
  ⚠️ **`platform` 参数缺省按 Windows 解析** —— 漏传参数走的就是改动前那条老路(这比"改了再小心"更保守:**默认行为不变,新行为必须显式传参**)。
- `userpaths.js` / `datadir.js`:Windows 分支 `%LOCALAPPDATA%\ScoreboardConsole\` **逐字保留**;Linux 分支按 XDG(`$XDG_DATA_HOME`,缺省 `~/.local/share`)。两平台各自的"拿不到用户目录"提示文案分开写(免得现场去设一个本平台不存在的环境变量)。
- `config.js`:服务端文件名按平台取(Windows `scoreboard.exe` / Linux `scoreboard`)。
- **新增 `console/main/autostart.js`**:Linux 用 `~/.config/autostart/*.desktop`(开=写文件、关=删文件;Linux 没有"已注册但未启用"这个中间态)。
- 托盘与窗口行为:Linux 的通知区多数不派发 double-click,因此按平台分支成单击。

## 三、怎么保证没弄坏 Windows
1. **设计上**:平台差异集中 + 缺省值就是 Windows(见上);
2. **逐行核对 diff**:Windows 分支那几行原样未动;
3. **测试**:Console 由 **68 → 96 例**,新增全是平台分支用例,**既有断言一条没改**;
4. **真机验证**:构建机重打 Windows 包并跑(这一道才算收口)。

## 四、自检
全量自检两轮**全绿、`EXIT=0`**:服务端 14 包 / 前端 **944 例** / Console **96 例**。

## 版本
`dev_0.5.9` → **`dev_0.5.10`**;安装器素材同步重生成(照例只动 `brand.bmp` 两张)。
2026-09-15 00:53:16 +08:00

50 lines
2.3 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
'use strict'
const assert = require('node:assert/strict')
const path = require('node:path')
const test = require('node:test')
const { APP_DIR_NAME, serverExeName, xdgDataHome, xdgConfigHome } = require('./platform')
// 用绝对路径字符串拼测试目录,避免依赖运行平台的盘符写法
const HOME = path.resolve('/home/operator')
const XDG_DATA = path.resolve('/xdg/data')
const XDG_CONFIG = path.resolve('/xdg/config')
test('目录名两个平台一致,只有它上面那一级不同', () => {
assert.equal(APP_DIR_NAME, 'ScoreboardConsole')
})
test('服务端可执行文件名按平台取:Windows 带 .exe,Linux 没有后缀', () => {
assert.equal(serverExeName('win32'), 'scoreboard.exe')
assert.equal(serverExeName('linux'), 'scoreboard')
// 不传平台时按 Windows 解析:这是这些纯函数改动前就有的口径
assert.equal(serverExeName(), 'scoreboard.exe')
})
test('Linux 用户数据基座:$XDG_DATA_HOME 优先,缺省用 ~/.local/share', () => {
assert.equal(xdgDataHome({ XDG_DATA_HOME: XDG_DATA, HOME }), XDG_DATA)
assert.equal(xdgDataHome({ HOME }), path.join(HOME, '.local', 'share'))
// 空串与纯空格都算「没设」,否则会拼出一个以空格命名的目录
assert.equal(xdgDataHome({ XDG_DATA_HOME: '', HOME }), path.join(HOME, '.local', 'share'))
assert.equal(xdgDataHome({ XDG_DATA_HOME: ' ', HOME }), path.join(HOME, '.local', 'share'))
})
test('$XDG_DATA_HOME 是相对路径时按规范忽略(规范要求它必须是绝对路径)', () => {
assert.equal(xdgDataHome({ XDG_DATA_HOME: 'xdg-data', HOME }), path.join(HOME, '.local', 'share'))
})
test('拿不到 $XDG_DATA_HOME 也拿不到 $HOME 时返回 null,由调用方回落安装目录', () => {
assert.equal(xdgDataHome({}), null)
assert.equal(xdgDataHome(undefined), null)
// HOME 是相对路径同样不认:拼出来会是个「相对当前目录」的路径,比没有更糟
assert.equal(xdgDataHome({ HOME: 'home/operator' }), null)
})
test('自启目录的基座 $XDG_CONFIG_HOME 是同一套规格', () => {
assert.equal(xdgConfigHome({ XDG_CONFIG_HOME: XDG_CONFIG, HOME }), XDG_CONFIG)
assert.equal(xdgConfigHome({ HOME }), path.join(HOME, '.config'))
assert.equal(xdgConfigHome({ XDG_CONFIG_HOME: 'cfg', HOME }), path.join(HOME, '.config'))
assert.equal(xdgConfigHome({}), null)
})