活跃时间只累加相邻两次上屏之间的间隔,首键之前与末键之后的时间不在其中。零散输入的日子分母可能只剩几秒,按它外推会得到没人打过的速率:本机 20261004 记录 81 个可读字符 / 1.9 秒活跃,页面显示 2503 字/分。 CharsPerMinute 在 active_ms > 0 时改用 max(active_ms, kMinSpeedActiveMs) 作分母。active_ms <= 0 仍返回 0——那是没有测量,不是测量小,不该被下限救活。 kMinSpeedActiveMs 与 kFastestSpeedMinActiveMs 保持为两个常量、两个理由:下限管数值,排名门槛管资格。没有门槛的话,被下限压到「每分钟字数」量级的爆发日仍会拿下最快日。 前端 speedOf 是同一公式的手写副本,一并改,并把运算顺序对齐 C++ 的 chars / (ms / 60000),否则两侧会差一个 ulp。落库口径不变,无需迁移历史数据。
Tests
This project now includes a lightweight regression test target wired into the main CMake build.
What It Covers
Current tests focus on high-value IME behaviors that are easy to accidentally break during refactors:
shuangpinscheme request constructionquanpinscheme request construction- case-preserving shuangpin segmentation
- full-helpcode detection
engine + shuangpincontinuation behavior- cloud suggestion trigger timing for shuangpin
The goal is not to fully simulate the whole IME UI pipeline yet. The goal is to protect the core input rules and session behavior.
Build and run
Run these commands from the MSIME-Windows repository root after preparing
vcpkg and Boost with python server/scripts/prepare_env.py:
python scripts/product_lock.py fetch-dictionaries --staging-root .
if ($LASTEXITCODE -ne 0) { throw 'Dictionary verification failed' }
$env:LOCALAPPDATA = Join-Path $PWD 'build/test-data/user-local'
$env:METASEQUOIA_IME_DATA_DIR = Join-Path $env:LOCALAPPDATA 'metasequoiaime'
New-Item -ItemType Directory -Force $env:METASEQUOIA_IME_DATA_DIR | Out-Null
Copy-Item MetasequoiaImeDict/out/* $env:METASEQUOIA_IME_DATA_DIR -Force
Copy-Item engine/helpcode/helpcodes $env:METASEQUOIA_IME_DATA_DIR -Recurse -Force
Copy-Item server/assets/tables/* $env:METASEQUOIA_IME_DATA_DIR -Force
Copy-Item server/assets/config/config.toml $env:METASEQUOIA_IME_DATA_DIR -Force
.\server\tests\scripts\llaunch.ps1 -Configuration Release
Use a dedicated PowerShell terminal: these environment variables isolate both Windows helpers and the shared Engine from the installed user's data for the rest of that session. The scripts run CTest; they do not launch the interactive Server, install or register the input method. CI additionally runs the native Win32/x64 pipe probe after building the full Server.
Tests belong to the Server CMake project, which provides the Engine, GUI and
third-party targets. server/tests/CMakeLists.txt is an add_subdirectory input,
not an independent project. The obsolete test presets have been removed; an old
locally generated server/tests/CMakePresets.json is no longer used.
Once test data is prepared, the convenience scripts work from any directory:
.\server\tests\scripts\llaunch.ps1 -Configuration Release # build, then CTest
.\server\tests\scripts\lrun.ps1 -Configuration Release # CTest only
Omitting -Configuration selects Debug in server/build; Release uses
server/build-release. Both compile MetasequoiaImeServerTests and
test_webview_contract in the parent build tree. Configuration, compilation,
test failures and an empty CTest registry return failure rather than launching a
stale executable or reporting success.
The equivalent direct CTest command from the repository root is:
ctest --test-dir server/build-release -C Release --output-on-failure --no-tests=error
Test Layout
tests/src/main.cpp- tiny custom test runner
tests/includes/test_framework.h- lightweight assertion helpers
tests/src/test_shuangpin_scheme.cpp- shuangpin scheme unit tests
tests/src/test_quanpin_scheme.cpp- quanpin scheme unit tests
tests/src/test_shuangpin_query.cpp- query/helper function tests
tests/src/test_engine_shuangpin_session.cpp- session-level behavior tests
Recommended Practice
When you change input behavior, add a regression test if the change affects:
- input segmentation
- space/enter/backspace behavior
- helpcode handling
- continuation after candidate selection
- create-word flow
- cloud suggestion timing
The best tests in this project are the ones that capture a concrete input example that previously broke.