mirror of
https://github.com/iDvel/rime-ice.git
synced 2026-05-14 00:30:37 +08:00
test: add rime smoke framework (#1511)
* test: add config smoke framework * ci: add smoke test before packing * ci: add cache
This commit is contained in:
45
.github/workflows/pages.yml
vendored
45
.github/workflows/pages.yml
vendored
@@ -1,45 +0,0 @@
|
||||
name: Deploy rime-ice with fcitx5-rime.js
|
||||
|
||||
on:
|
||||
# push:
|
||||
# branches:
|
||||
# - main
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
deploy:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Build rime-ice
|
||||
uses: rimeinn/deploy-schema@master
|
||||
with:
|
||||
user-recipe-list: |-
|
||||
iDvel/rime-ice:others/recipes/full
|
||||
shared-recipe-list:
|
||||
package-items: |-
|
||||
build
|
||||
lua
|
||||
opencc
|
||||
custom_phrase.txt
|
||||
|
||||
- name: Download fcitx5-rime.js
|
||||
run: |
|
||||
curl -L -o fcitx5-rime.tgz https://github.com/rimeinn/fcitx5-rime.js/releases/download/latest/fcitx5-rime.tgz
|
||||
mkdir -p fcitx5-rime
|
||||
tar -xzvf fcitx5-rime.tgz -C fcitx5-rime
|
||||
|
||||
- name: Move files to publish directory
|
||||
run: |
|
||||
mkdir -p ./public/dist
|
||||
mv /tmp/deploy-schema/artifact.zip ./public/rime-ice.zip
|
||||
mv fcitx5-rime/package/dist/* ./public/dist
|
||||
cp others/pages/index.html ./public/index.html
|
||||
|
||||
- name: Deploy to GitHub Pages
|
||||
uses: peaceiris/actions-gh-pages@v4
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
publish_dir: ./public
|
||||
39
.github/workflows/release.yml
vendored
39
.github/workflows/release.yml
vendored
@@ -14,13 +14,40 @@ on:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
Release:
|
||||
runs-on: ubuntu-latest
|
||||
smoke:
|
||||
name: Smoke test before release
|
||||
runs-on: ubuntu-24.04
|
||||
# if: github.repository == 'iDvel/rime-ice'
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Cache rime cli bundle
|
||||
uses: actions/cache@v5
|
||||
with:
|
||||
path: ${{ runner.temp }}/rime-cli-cache/rime-cli-linux-1.6.1.zip
|
||||
key: rime-cli-linux-1.6.1
|
||||
|
||||
- name: Run smoke test suite
|
||||
env:
|
||||
RIME_CLI_URL: https://github.com/mirtlecn/public/releases/download/v1.6.1/rime-cli-linux-1.6.1.zip
|
||||
RIME_CLI_CACHE_PATH: ${{ runner.temp }}/rime-cli-cache/rime-cli-linux-1.6.1.zip
|
||||
run: bash ./others/script/smoke/run.sh rime_ice
|
||||
|
||||
package:
|
||||
name: Package and release
|
||||
runs-on: ubuntu-24.04
|
||||
if: github.repository == 'iDvel/rime-ice'
|
||||
needs:
|
||||
- smoke
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Setup Go
|
||||
if: ${{ contains(github.event.head_commit.message, ' [build]') || github.event_name == 'workflow_dispatch' }}
|
||||
@@ -56,7 +83,7 @@ jobs:
|
||||
|
||||
- name: Create nightly release
|
||||
if: ${{ github.ref == 'refs/heads/main' }}
|
||||
uses: "softprops/action-gh-release@v2"
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
body: |
|
||||
## 说明
|
||||
@@ -79,7 +106,7 @@ jobs:
|
||||
|
||||
- name: Create stable release
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
uses: "softprops/action-gh-release@v2"
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
body: |
|
||||
## 说明
|
||||
@@ -108,4 +135,4 @@ jobs:
|
||||
git push
|
||||
else
|
||||
echo "No changes to commit."
|
||||
fi
|
||||
fi
|
||||
|
||||
37
.github/workflows/test.yml
vendored
Normal file
37
.github/workflows/test.yml
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
name: Smoke test
|
||||
|
||||
on:
|
||||
push:
|
||||
branches-ignore:
|
||||
- main
|
||||
paths:
|
||||
- "**/**"
|
||||
- "!**.md"
|
||||
- "!**.gitignore"
|
||||
- "!.github/**"
|
||||
pull_request:
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
smoke-linux:
|
||||
name: Rime smoke test
|
||||
runs-on: ubuntu-24.04
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Cache rime cli bundle
|
||||
uses: actions/cache@v5
|
||||
with:
|
||||
path: ${{ runner.temp }}/rime-cli-cache/rime-cli-linux-1.6.1.zip
|
||||
key: rime-cli-linux-1.6.1
|
||||
|
||||
- name: Run smoke test suite
|
||||
env:
|
||||
RIME_CLI_URL: https://github.com/mirtlecn/public/releases/download/v1.6.1/rime-cli-linux-1.6.1.zip
|
||||
RIME_CLI_CACHE_PATH: ${{ runner.temp }}/rime-cli-cache/rime-cli-linux-1.6.1.zip
|
||||
run: bash ./others/script/smoke/run.sh rime_ice
|
||||
40
others/script/smoke/README.md
Normal file
40
others/script/smoke/README.md
Normal file
@@ -0,0 +1,40 @@
|
||||
# Smoke Test Framework
|
||||
|
||||
This directory contains the shell-based smoke test framework for the current repository.
|
||||
|
||||
## Layout
|
||||
|
||||
- `run.sh`: suite entrypoint
|
||||
- `lib/common.sh`: shared shell helpers
|
||||
- `suites/config_repo.sh`: generic suite implementation for the current config repository
|
||||
- `cases/rime_ice/input_cases.tsv`: data-driven input cases
|
||||
|
||||
## Current Flow
|
||||
|
||||
- uses local `rime_deployer` and `rime_api_console` from `PATH` when available
|
||||
- otherwise downloads the public Linux CLI bundle when `RIME_CLI_URL` is set
|
||||
- deploys the current repository with `rime_deployer --build`
|
||||
- runs `rime_api_console`
|
||||
- verifies basic pinyin commit and a stable Lua-driven Unicode commit
|
||||
|
||||
## Environment Variables
|
||||
|
||||
- `RIME_CLI_URL`: optional public CLI bundle URL
|
||||
- `RIME_CONFIG_ROOT`: optional repository root override
|
||||
|
||||
## Extending
|
||||
|
||||
Add more rows to `cases/rime_ice/input_cases.tsv`.
|
||||
The current tab-separated case format is:
|
||||
|
||||
- `case_id`
|
||||
- `schema_id`
|
||||
- `key_sequence`
|
||||
- `expected_text`
|
||||
|
||||
`expected_text` also supports:
|
||||
|
||||
- `@today:<date format>`, for example `@today:%Y-%m-%d`
|
||||
- `@regex:<pattern>`, matched against the normalized stdout log
|
||||
|
||||
`rime_api_console` is used as the default runner because it is more reliable than `rime_console` for smoke tests that reuse an already deployed workspace.
|
||||
242
others/script/smoke/cases/rime_ice/input_cases.tsv
Normal file
242
others/script/smoke/cases/rime_ice/input_cases.tsv
Normal file
@@ -0,0 +1,242 @@
|
||||
# ------------------
|
||||
# 方案:rime_ice
|
||||
# ------ 基础 ------
|
||||
# case_id schema_id key_sequence expected_text
|
||||
基础:中文输入 rime_ice wusongpinyin{space} 雾凇拼音
|
||||
基础:英文输入 rime_ice hello{space} hello
|
||||
基础:英文派生 rime_ice PtwoP{space} P2P
|
||||
基础:中英混输 rime_ice Xguang{space} X光
|
||||
基础:自定义短语 rime_ice ig{space} 一个
|
||||
基础:Emoji输入 rime_ice nihao{2} 👋
|
||||
基础:uU拆字反查 rime_ice uUrenrenren{space} 众
|
||||
基础:v键符号输入 rime_ice v1{space} 一
|
||||
|
||||
# ------ 插件 ------
|
||||
# case_id schema_id key_sequence expected_text
|
||||
插件:英文全大写 rime_ice HELLO{space} HELLO
|
||||
插件:英文首字母大写 rime_ice Hello{space} Hello
|
||||
插件:置顶候选 rime_ice d{space} 的
|
||||
插件:Unicode输入 rime_ice U4f60{space} 你
|
||||
插件:日期输入 rime_ice rq{space} @today:%Y-%m-%d
|
||||
插件:UUID输入 rime_ice uuid{space} @regex:^commit: [0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$
|
||||
插件:英文降权 rime_ice ranch{space} 染成
|
||||
插件:英文降权 rime_ice ranch{2} ranch
|
||||
插件:数字输入 rime_ice R123{space} 一百二十三
|
||||
插件:计算器 rime_ice cC1+2{space} 3
|
||||
插件:农历输入:农历 rime_ice N19700101{space} 一九六九年冬月廿四
|
||||
插件:农历输入:干支 rime_ice N19700101{2} 己酉年(鸡)冬月廿四
|
||||
插件:以词定字:左中括号取首字 rime_ice nihao{bracketleft} 你
|
||||
插件:以词定字:右中括号取尾字 rime_ice nihao{bracketright} 好
|
||||
插件:部件辅码 rime_ice ni`ren{space} 你
|
||||
插件:错字错音提示 rime_ice qikefu{Control+Shift+Return} 契诃(hē)夫
|
||||
|
||||
# ------------------
|
||||
# 方案:自然码双拼
|
||||
# ------ 基础 ------
|
||||
基础:中文输入 double_pinyin wusspnyn{space} 雾凇拼音
|
||||
基础:英文输入 double_pinyin hello{space} hello
|
||||
基础:英文派生 double_pinyin PtwoP{space} P2P
|
||||
基础:中英混输 double_pinyin Xgd{space} X光
|
||||
# 基础:自定义短语 double_pinyin ig{space} 一个
|
||||
基础:Emoji输入 double_pinyin nihk{2} 👋
|
||||
基础:uU拆字反查 double_pinyin uUrenrenren{space} 众
|
||||
基础:v键符号输入 double_pinyin V1{space} 一
|
||||
|
||||
# ------ 插件 ------
|
||||
插件:英文全大写 double_pinyin HELLO{space} HELLO
|
||||
插件:英文首字母大写 double_pinyin Hello{space} Hello
|
||||
插件:置顶候选 double_pinyin d{space} 的
|
||||
插件:Unicode输入 double_pinyin U4f60{space} 你
|
||||
插件:日期输入 double_pinyin date{space} @today:%Y-%m-%d
|
||||
插件:UUID输入 double_pinyin uuid{space} @regex:^commit: [0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$
|
||||
插件:英文降权 double_pinyin bail{space} 把拆
|
||||
插件:英文降权 double_pinyin bail{2} bail
|
||||
插件:数字输入 double_pinyin R123{space} 一百二十三
|
||||
插件:计算器 double_pinyin cC1+2{space} 3
|
||||
插件:农历输入:农历 double_pinyin N19700101{space} 一九六九年冬月廿四
|
||||
插件:农历输入:干支 double_pinyin N19700101{2} 己酉年(鸡)冬月廿四
|
||||
插件:以词定字:左中括号取首字 double_pinyin nihk{bracketleft} 你
|
||||
插件:以词定字:右中括号取尾字 double_pinyin nihk{bracketright} 好
|
||||
插件:部件辅码 double_pinyin ni`ren{space} 你
|
||||
插件:错字错音提示 double_pinyin qikefu{Control+Shift+Return} 契诃(hē)夫
|
||||
|
||||
# ------------------
|
||||
# 方案:智能 ABC 双拼
|
||||
# ------ 基础 ------
|
||||
基础:中文输入 double_pinyin_abc wusspcyc{space} 雾凇拼音
|
||||
基础:英文输入 double_pinyin_abc hello{space} hello
|
||||
基础:英文派生 double_pinyin_abc PtwoP{space} P2P
|
||||
基础:中英混输 double_pinyin_abc Xgt{space} X光
|
||||
# 基础:自定义短语 double_pinyin_abc ig{space} 一个
|
||||
基础:Emoji输入 double_pinyin_abc nihk{2} 👋
|
||||
基础:uU拆字反查 double_pinyin_abc uUrenrenren{space} 众
|
||||
基础:v键符号输入 double_pinyin_abc V1{space} 一
|
||||
|
||||
# ------ 插件 ------
|
||||
插件:英文全大写 double_pinyin_abc HELLO{space} HELLO
|
||||
插件:英文首字母大写 double_pinyin_abc Hello{space} Hello
|
||||
插件:置顶候选 double_pinyin_abc d{space} 的
|
||||
插件:Unicode输入 double_pinyin_abc U4f60{space} 你
|
||||
插件:日期输入 double_pinyin_abc date{space} @today:%Y-%m-%d
|
||||
插件:UUID输入 double_pinyin_abc uuid{space} @regex:^commit: [0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$
|
||||
# 插件:英文降权 double_pinyin_abc bail{space} 不确定
|
||||
# 插件:英文降权 double_pinyin_abc bail{2} 不确定
|
||||
插件:数字输入 double_pinyin_abc R123{space} 一百二十三
|
||||
插件:计算器 double_pinyin_abc cC1+2{space} 3
|
||||
插件:农历输入:农历 double_pinyin_abc N19700101{space} 一九六九年冬月廿四
|
||||
插件:农历输入:干支 double_pinyin_abc N19700101{2} 己酉年(鸡)冬月廿四
|
||||
插件:以词定字:左中括号取首字 double_pinyin_abc nihk{bracketleft} 你
|
||||
插件:以词定字:右中括号取尾字 double_pinyin_abc nihk{bracketright} 好
|
||||
插件:部件辅码 double_pinyin_abc ni`ren{space} 你
|
||||
插件:错字错音提示 double_pinyin_abc qikefu{Control+Shift+Return} 契诃(hē)夫
|
||||
|
||||
# ------------------
|
||||
# 方案:微软双拼
|
||||
# ------ 基础 ------
|
||||
基础:中文输入 double_pinyin_mspy wusspnyn{space} 雾凇拼音
|
||||
基础:英文输入 double_pinyin_mspy hello{space} hello
|
||||
基础:英文派生 double_pinyin_mspy PtwoP{space} P2P
|
||||
基础:中英混输 double_pinyin_mspy Xgd{space} X光
|
||||
# 基础:自定义短语 double_pinyin_mspy ig{space} 一个
|
||||
基础:Emoji输入 double_pinyin_mspy nihk{2} 👋
|
||||
基础:uU拆字反查 double_pinyin_mspy uUrenrenren{space} 众
|
||||
基础:v键符号输入 double_pinyin_mspy V1{space} 一
|
||||
|
||||
# ------ 插件 ------
|
||||
插件:英文全大写 double_pinyin_mspy HELLO{space} HELLO
|
||||
插件:英文首字母大写 double_pinyin_mspy Hello{space} Hello
|
||||
插件:置顶候选 double_pinyin_mspy d{space} 的
|
||||
插件:Unicode输入 double_pinyin_mspy U4f60{space} 你
|
||||
插件:日期输入 double_pinyin_mspy date{space} @today:%Y-%m-%d
|
||||
插件:UUID输入 double_pinyin_mspy uuid{space} @regex:^commit: [0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$
|
||||
插件:英文降权 double_pinyin_mspy bail{space} 把拆
|
||||
插件:英文降权 double_pinyin_mspy bail{2} bail
|
||||
插件:数字输入 double_pinyin_mspy R123{space} 一百二十三
|
||||
插件:计算器 double_pinyin_mspy cC1+2{space} 3
|
||||
插件:农历输入:农历 double_pinyin_mspy N19700101{space} 一九六九年冬月廿四
|
||||
插件:农历输入:干支 double_pinyin_mspy N19700101{2} 己酉年(鸡)冬月廿四
|
||||
插件:以词定字:左中括号取首字 double_pinyin_mspy nihk{bracketleft} 你
|
||||
插件:以词定字:右中括号取尾字 double_pinyin_mspy nihk{bracketright} 好
|
||||
插件:部件辅码 double_pinyin_mspy ni`ren{space} 你
|
||||
插件:错字错音提示 double_pinyin_mspy qikefu{Control+Shift+Return} 契诃(hē)夫
|
||||
|
||||
# ------------------
|
||||
# 方案:搜狗双拼
|
||||
# ------ 基础 ------
|
||||
基础:中文输入 double_pinyin_sogou wusspnyn{space} 雾凇拼音
|
||||
基础:英文输入 double_pinyin_sogou hello{space} hello
|
||||
基础:英文派生 double_pinyin_sogou PtwoP{space} P2P
|
||||
基础:中英混输 double_pinyin_sogou Xgd{space} X光
|
||||
# 基础:自定义短语 double_pinyin_sogou ig{space} 一个
|
||||
基础:Emoji输入 double_pinyin_sogou nihk{2} 👋
|
||||
基础:uU拆字反查 double_pinyin_sogou uUrenrenren{space} 众
|
||||
基础:v键符号输入 double_pinyin_sogou V1{space} 一
|
||||
|
||||
# ------ 插件 ------
|
||||
插件:英文全大写 double_pinyin_sogou HELLO{space} HELLO
|
||||
插件:英文首字母大写 double_pinyin_sogou Hello{space} Hello
|
||||
插件:置顶候选 double_pinyin_sogou d{space} 的
|
||||
插件:Unicode输入 double_pinyin_sogou U4f60{space} 你
|
||||
插件:日期输入 double_pinyin_sogou date{space} @today:%Y-%m-%d
|
||||
插件:UUID输入 double_pinyin_sogou uuid{space} @regex:^commit: [0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$
|
||||
插件:英文降权 double_pinyin_sogou bail{space} 把拆
|
||||
插件:英文降权 double_pinyin_sogou bail{2} bail
|
||||
插件:数字输入 double_pinyin_sogou R123{space} 一百二十三
|
||||
插件:计算器 double_pinyin_sogou cC1+2{space} 3
|
||||
插件:农历输入:农历 double_pinyin_sogou N19700101{space} 一九六九年冬月廿四
|
||||
插件:农历输入:干支 double_pinyin_sogou N19700101{2} 己酉年(鸡)冬月廿四
|
||||
插件:以词定字:左中括号取首字 double_pinyin_sogou nihk{bracketleft} 你
|
||||
插件:以词定字:右中括号取尾字 double_pinyin_sogou nihk{bracketright} 好
|
||||
插件:部件辅码 double_pinyin_sogou ni`ren{space} 你
|
||||
插件:错字错音提示 double_pinyin_sogou qikefu{Control+Shift+Return} 契诃(hē)夫
|
||||
|
||||
# ------------------
|
||||
# 方案:紫光双拼
|
||||
# ------ 基础 ------
|
||||
基础:中文输入 double_pinyin_ziguang wushpyyy{space} 雾凇拼音
|
||||
基础:英文输入 double_pinyin_ziguang hello{space} hello
|
||||
基础:英文派生 double_pinyin_ziguang PtwoP{space} P2P
|
||||
基础:中英混输 double_pinyin_ziguang Xgg{space} X光
|
||||
# 基础:自定义短语 double_pinyin_ziguang ig{space} 一个
|
||||
基础:Emoji输入 double_pinyin_ziguang nihq{2} 👋
|
||||
基础:uU拆字反查 double_pinyin_ziguang uUrenrenren{space} 众
|
||||
基础:v键符号输入 double_pinyin_ziguang V1{space} 一
|
||||
|
||||
# ------ 插件 ------
|
||||
插件:英文全大写 double_pinyin_ziguang HELLO{space} HELLO
|
||||
插件:英文首字母大写 double_pinyin_ziguang Hello{space} Hello
|
||||
插件:置顶候选 double_pinyin_ziguang d{space} 的
|
||||
插件:Unicode输入 double_pinyin_ziguang U4f60{space} 你
|
||||
插件:日期输入 double_pinyin_ziguang date{space} @today:%Y-%m-%d
|
||||
插件:UUID输入 double_pinyin_ziguang uuid{space} @regex:^commit: [0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$
|
||||
插件:英文降权 double_pinyin_ziguang bail{space} 把栓
|
||||
插件:英文降权 double_pinyin_ziguang bail{2} bail
|
||||
插件:数字输入 double_pinyin_ziguang R123{space} 一百二十三
|
||||
插件:计算器 double_pinyin_ziguang cC1+2{space} 3
|
||||
插件:农历输入:农历 double_pinyin_ziguang N19700101{space} 一九六九年冬月廿四
|
||||
插件:农历输入:干支 double_pinyin_ziguang N19700101{2} 己酉年(鸡)冬月廿四
|
||||
插件:以词定字:左中括号取首字 double_pinyin_ziguang nihq{bracketleft} 你
|
||||
插件:以词定字:右中括号取尾字 double_pinyin_ziguang nihq{bracketright} 好
|
||||
插件:部件辅码 double_pinyin_ziguang ni`ren{space} 你
|
||||
插件:错字错音提示 double_pinyin_ziguang qikefu{Control+Shift+Return} 契诃(hē)夫
|
||||
|
||||
# ------------------
|
||||
# 方案:拼音加加双拼
|
||||
# ------ 基础 ------
|
||||
基础:中文输入 double_pinyin_jiajia wusyplyl{space} 雾凇拼音
|
||||
基础:英文输入 double_pinyin_jiajia hello{space} hello
|
||||
基础:英文派生 double_pinyin_jiajia PtwoP{space} P2P
|
||||
基础:中英混输 double_pinyin_jiajia Xgh{space} X光
|
||||
# 基础:自定义短语 double_pinyin_jiajia ig{space} 一个
|
||||
基础:Emoji输入 double_pinyin_jiajia nihd{2} 👋
|
||||
基础:uU拆字反查 double_pinyin_jiajia uUrenrenren{space} 众
|
||||
基础:v键符号输入 double_pinyin_jiajia V1{space} 一
|
||||
|
||||
# ------ 插件 ------
|
||||
插件:英文全大写 double_pinyin_jiajia HELLO{space} HELLO
|
||||
插件:英文首字母大写 double_pinyin_jiajia Hello{space} Hello
|
||||
插件:置顶候选 double_pinyin_jiajia d{space} 的
|
||||
插件:Unicode输入 double_pinyin_jiajia U4f60{space} 你
|
||||
插件:日期输入 double_pinyin_jiajia date{space} @today:%Y-%m-%d
|
||||
插件:UUID输入 double_pinyin_jiajia uuid{space} @regex:^commit: [0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$
|
||||
# 插件:英文降权 double_pinyin_jiajia bail{space} 不确定
|
||||
# 插件:英文降权 double_pinyin_jiajia bail{2} 不确定
|
||||
插件:数字输入 double_pinyin_jiajia R123{space} 一百二十三
|
||||
插件:计算器 double_pinyin_jiajia cC1+2{space} 3
|
||||
插件:农历输入:农历 double_pinyin_jiajia N19700101{space} 一九六九年冬月廿四
|
||||
插件:农历输入:干支 double_pinyin_jiajia N19700101{2} 己酉年(鸡)冬月廿四
|
||||
插件:以词定字:左中括号取首字 double_pinyin_jiajia nihd{bracketleft} 你
|
||||
插件:以词定字:右中括号取尾字 double_pinyin_jiajia nihd{bracketright} 好
|
||||
插件:部件辅码 double_pinyin_jiajia ni`ren{space} 你
|
||||
插件:错字错音提示 double_pinyin_jiajia qikefu{Control+Shift+Return} 契诃(hē)夫
|
||||
|
||||
# ------------------
|
||||
# 方案:小鹤双拼
|
||||
# ------ 基础 ------
|
||||
基础:中文输入 double_pinyin_flypy wusspbyb{space} 雾凇拼音
|
||||
基础:英文输入 double_pinyin_flypy hello{space} hello
|
||||
基础:英文派生 double_pinyin_flypy PtwoP{space} P2P
|
||||
基础:中英混输 double_pinyin_flypy Xgl{space} X光
|
||||
# 基础:自定义短语 double_pinyin_flypy ig{space} 一个
|
||||
基础:Emoji输入 double_pinyin_flypy nihc{2} 👋
|
||||
基础:uU拆字反查 double_pinyin_flypy uUrenrenren{space} 众
|
||||
基础:v键符号输入 double_pinyin_flypy V1{space} 一
|
||||
|
||||
# ------ 插件 ------
|
||||
# case_id schema_id key_sequence expected_text
|
||||
插件:英文全大写 double_pinyin_flypy HELLO{space} HELLO
|
||||
插件:英文首字母大写 double_pinyin_flypy Hello{space} Hello
|
||||
插件:置顶候选 double_pinyin_flypy d{space} 的
|
||||
插件:Unicode输入 double_pinyin_flypy U4f60{space} 你
|
||||
插件:日期输入 double_pinyin_flypy date{space} @today:%Y-%m-%d
|
||||
插件:UUID输入 double_pinyin_flypy uuid{space} @regex:^commit: [0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$
|
||||
插件:英文降权 double_pinyin_flypy bail{space} 把床
|
||||
插件:英文降权 double_pinyin_flypy bail{2} bail
|
||||
插件:数字输入 double_pinyin_flypy R123{space} 一百二十三
|
||||
插件:计算器 double_pinyin_flypy cC1+2{space} 3
|
||||
插件:农历输入:农历 double_pinyin_flypy N19700101{space} 一九六九年冬月廿四
|
||||
插件:农历输入:干支 double_pinyin_flypy N19700101{2} 己酉年(鸡)冬月廿四
|
||||
插件:以词定字:左中括号取首字 double_pinyin_flypy nihc{bracketleft} 你
|
||||
插件:以词定字:右中括号取尾字 double_pinyin_flypy nihc{bracketright} 好
|
||||
插件:部件辅码 double_pinyin_flypy ni`ren{space} 你
|
||||
插件:错字错音提示 double_pinyin_flypy qikefu{Control+Shift+Return} 契诃(hē)夫
|
||||
|
Can't render this file because it has a wrong number of fields in line 4.
|
257
others/script/smoke/lib/common.sh
Normal file
257
others/script/smoke/lib/common.sh
Normal file
@@ -0,0 +1,257 @@
|
||||
#!/bin/bash
|
||||
|
||||
if [[ -z "${SMOKE_ROOT:-}" ]]; then
|
||||
SMOKE_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.."; pwd)"
|
||||
fi
|
||||
if [[ -z "${SMOKE_REPO_ROOT:-}" ]]; then
|
||||
SMOKE_REPO_ROOT="$(cd "${SMOKE_ROOT}/../../.."; pwd)"
|
||||
fi
|
||||
if [[ -z "${SMOKE_WORK_ROOT:-}" ]]; then
|
||||
SMOKE_WORK_ROOT="${RUNNER_TEMP:-/tmp}/rime-ice-smoke"
|
||||
fi
|
||||
if [[ -z "${SMOKE_LOG_ROOT:-}" ]]; then
|
||||
SMOKE_LOG_ROOT="${SMOKE_WORK_ROOT}/logs"
|
||||
fi
|
||||
|
||||
SMOKE_CURRENT_LABEL="${SMOKE_CURRENT_LABEL:-}"
|
||||
SMOKE_CURRENT_LOG_FILE="${SMOKE_CURRENT_LOG_FILE:-}"
|
||||
|
||||
log() {
|
||||
printf '[smoke] %s\n' "$*"
|
||||
}
|
||||
|
||||
log_step() {
|
||||
printf '[smoke] 🔹 %s\n' "$*"
|
||||
}
|
||||
|
||||
log_pass() {
|
||||
printf '[smoke] ✅ %s\n' "$*"
|
||||
}
|
||||
|
||||
log_warn() {
|
||||
printf '[smoke] ⚠️ %s\n' "$*"
|
||||
}
|
||||
|
||||
fail() {
|
||||
printf '[smoke] 🔴 %s\n' "$*" >&2
|
||||
if [[ -n "${SMOKE_CURRENT_LABEL}" ]]; then
|
||||
printf '[smoke][context] %s\n' "${SMOKE_CURRENT_LABEL}" >&2
|
||||
fi
|
||||
if [[ -n "${SMOKE_CURRENT_LOG_FILE}" && -f "${SMOKE_CURRENT_LOG_FILE}" ]]; then
|
||||
printf '[smoke][log] begin %s\n' "${SMOKE_CURRENT_LOG_FILE}" >&2
|
||||
sed -n '1,240p' "${SMOKE_CURRENT_LOG_FILE}" >&2
|
||||
printf '[smoke][log] end %s\n' "${SMOKE_CURRENT_LOG_FILE}" >&2
|
||||
fi
|
||||
exit 1
|
||||
}
|
||||
|
||||
set_failure_context() {
|
||||
local label="$1"
|
||||
local log_file="$2"
|
||||
SMOKE_CURRENT_LABEL="${label}"
|
||||
SMOKE_CURRENT_LOG_FILE="${log_file}"
|
||||
}
|
||||
|
||||
clear_failure_context() {
|
||||
SMOKE_CURRENT_LABEL=""
|
||||
SMOKE_CURRENT_LOG_FILE=""
|
||||
}
|
||||
|
||||
require_command() {
|
||||
local command_name="$1"
|
||||
command -v "${command_name}" >/dev/null 2>&1 ||
|
||||
fail "required command not found: ${command_name}"
|
||||
}
|
||||
|
||||
ensure_clean_dir() {
|
||||
local dir_path="$1"
|
||||
rm -rf "${dir_path}"
|
||||
mkdir -p "${dir_path}"
|
||||
}
|
||||
|
||||
clean_config_artifacts() {
|
||||
local config_root="$1"
|
||||
local build_dir="${config_root}/build"
|
||||
|
||||
if [[ -d "${build_dir}" ]]; then
|
||||
log_step "removing ${build_dir}"
|
||||
rm -rf "${build_dir}"
|
||||
fi
|
||||
|
||||
find "${config_root}" -mindepth 1 -maxdepth 1 -type d -name '*.userdb' -print0 |
|
||||
while IFS= read -r -d '' userdb_dir; do
|
||||
log_step "removing ${userdb_dir}"
|
||||
rm -rf "${userdb_dir}"
|
||||
done
|
||||
}
|
||||
|
||||
download_file() {
|
||||
local file_url="$1"
|
||||
local output_path="$2"
|
||||
curl -fsSL --retry 3 -o "${output_path}" "${file_url}"
|
||||
}
|
||||
|
||||
prepare_cli_archive() {
|
||||
local cli_url="$1"
|
||||
local output_path="$2"
|
||||
local cache_path="${RIME_CLI_CACHE_PATH:-}"
|
||||
|
||||
if [[ -n "${cache_path}" && -f "${cache_path}" ]]; then
|
||||
log_step "using cached rime cli bundle ${cache_path}" >&2
|
||||
cp "${cache_path}" "${output_path}"
|
||||
return 0
|
||||
fi
|
||||
|
||||
log_step "downloading rime cli bundle" >&2
|
||||
download_file "${cli_url}" "${output_path}"
|
||||
|
||||
if [[ -n "${cache_path}" ]]; then
|
||||
mkdir -p "$(dirname "${cache_path}")"
|
||||
cp "${output_path}" "${cache_path}"
|
||||
fi
|
||||
}
|
||||
|
||||
extract_zip() {
|
||||
local archive_path="$1"
|
||||
local output_dir="$2"
|
||||
unzip -q "${archive_path}" -d "${output_dir}"
|
||||
}
|
||||
|
||||
prepare_cli_bundle() {
|
||||
local archive_path="$1"
|
||||
local output_dir="$2"
|
||||
local nested_archive_path
|
||||
local bundle_root
|
||||
|
||||
extract_zip "${archive_path}" "${output_dir}"
|
||||
|
||||
nested_archive_path="$(find "${output_dir}" -maxdepth 2 -type f \( -name 'rime_cli-*.zip' -o -name 'rime-cli-*.zip' \) | head -n 1)"
|
||||
if [[ -n "${nested_archive_path}" ]]; then
|
||||
local nested_root="${output_dir}/nested"
|
||||
mkdir -p "${nested_root}"
|
||||
extract_zip "${nested_archive_path}" "${nested_root}"
|
||||
output_dir="${nested_root}"
|
||||
fi
|
||||
|
||||
bundle_root="$(find "${output_dir}" -maxdepth 3 -type f -path '*/bin/rime_deployer' | head -n 1)"
|
||||
[[ -n "${bundle_root}" ]] || fail "rime_deployer not found in bundle"
|
||||
dirname "$(dirname "${bundle_root}")"
|
||||
}
|
||||
|
||||
resolve_cli_commands() {
|
||||
local cli_url="${1:-}"
|
||||
local work_root="$2"
|
||||
local deployer_path
|
||||
local api_console_path
|
||||
local cli_archive
|
||||
local extract_root
|
||||
local bundle_root
|
||||
|
||||
if [[ -n "${cli_url}" ]]; then
|
||||
require_command curl
|
||||
require_command unzip
|
||||
|
||||
cli_archive="${work_root}/rime-cli.zip"
|
||||
extract_root="${work_root}/cli"
|
||||
|
||||
prepare_cli_archive "${cli_url}" "${cli_archive}"
|
||||
log_step "extracting rime cli bundle" >&2
|
||||
bundle_root="$(prepare_cli_bundle "${cli_archive}" "${extract_root}")"
|
||||
deployer_path="${bundle_root}/bin/rime_deployer"
|
||||
api_console_path="${bundle_root}/bin/rime_api_console"
|
||||
else
|
||||
deployer_path="$(command -v rime_deployer || true)"
|
||||
api_console_path="$(command -v rime_api_console || true)"
|
||||
[[ -n "${deployer_path}" ]] || fail "RIME_CLI_URL is not set and local rime_deployer was not found in PATH"
|
||||
[[ -n "${api_console_path}" ]] || fail "RIME_CLI_URL is not set and local rime_api_console was not found in PATH"
|
||||
log_step "using local rime cli commands from PATH" >&2
|
||||
fi
|
||||
|
||||
[[ -x "${deployer_path}" ]] || fail "rime_deployer is not executable: ${deployer_path}"
|
||||
[[ -x "${api_console_path}" ]] || fail "rime_api_console is not executable: ${api_console_path}"
|
||||
printf '%s\n%s\n' "${deployer_path}" "${api_console_path}"
|
||||
}
|
||||
|
||||
combine_logs() {
|
||||
local stdout_path="$1"
|
||||
local stderr_path="$2"
|
||||
local output_path="$3"
|
||||
{
|
||||
printf '== stdout ==\n'
|
||||
cat "${stdout_path}"
|
||||
printf '\n== stderr ==\n'
|
||||
cat "${stderr_path}"
|
||||
} >"${output_path}"
|
||||
}
|
||||
|
||||
normalize_console_output() {
|
||||
local input_path="$1"
|
||||
local output_path="$2"
|
||||
tr -d '\r' <"${input_path}" >"${output_path}"
|
||||
}
|
||||
|
||||
assert_file_exists() {
|
||||
local file_path="$1"
|
||||
[[ -f "${file_path}" ]] || fail "expected file not found: ${file_path}"
|
||||
}
|
||||
|
||||
assert_file_contains() {
|
||||
local file_path="$1"
|
||||
local expected_text="$2"
|
||||
grep -F -- "${expected_text}" "${file_path}" >/dev/null ||
|
||||
fail "expected '${expected_text}' in ${file_path}"
|
||||
}
|
||||
|
||||
assert_file_matches() {
|
||||
local file_path="$1"
|
||||
local expected_pattern="$2"
|
||||
grep -E -- "${expected_pattern}" "${file_path}" >/dev/null ||
|
||||
fail "expected pattern '${expected_pattern}' in ${file_path}"
|
||||
}
|
||||
|
||||
resolve_expected_text() {
|
||||
local expected_text="$1"
|
||||
if [[ "${expected_text}" == @today:* ]]; then
|
||||
local date_format="${expected_text#@today:}"
|
||||
date +"${date_format}"
|
||||
return 0
|
||||
fi
|
||||
printf '%s\n' "${expected_text}"
|
||||
}
|
||||
|
||||
assert_no_error_lines() {
|
||||
local file_path="$1"
|
||||
local match_path="${file_path}.errors"
|
||||
if grep -En '(^E[0-9]{4}[[:space:]])|(^F[0-9]{4}[[:space:]])|(^ERROR[:[:space:]])|(^Error([^[:alpha:]]|$))' "${file_path}" >"${match_path}"; then
|
||||
cat "${match_path}" >&2
|
||||
fail "unexpected error output detected in ${file_path}"
|
||||
fi
|
||||
rm -f "${match_path}"
|
||||
}
|
||||
|
||||
collect_warning_lines() {
|
||||
local file_path="$1"
|
||||
local output_path="$2"
|
||||
grep -En '(^W[0-9]{4}[[:space:]])|(^WARNING[:[:space:]])|([Ww]arning)' "${file_path}" >"${output_path}" || true
|
||||
}
|
||||
|
||||
run_deployer() {
|
||||
local deployer_path="$1"
|
||||
local user_data_dir="$2"
|
||||
local shared_data_dir="$3"
|
||||
local stdout_path="$4"
|
||||
local stderr_path="$5"
|
||||
"${deployer_path}" --build "${user_data_dir}" "${shared_data_dir}" >"${stdout_path}" 2>"${stderr_path}"
|
||||
}
|
||||
|
||||
run_api_console_script() {
|
||||
local api_console_path="$1"
|
||||
local shared_data_dir="$2"
|
||||
local user_data_dir="$3"
|
||||
local input_path="$4"
|
||||
local stdout_path="$5"
|
||||
local stderr_path="$6"
|
||||
RIME_SHARED_DATA_DIR="${shared_data_dir}" \
|
||||
RIME_USER_DATA_DIR="${user_data_dir}" \
|
||||
"${api_console_path}" <"${input_path}" >"${stdout_path}" 2>"${stderr_path}"
|
||||
}
|
||||
23
others/script/smoke/run.sh
Normal file
23
others/script/smoke/run.sh
Normal file
@@ -0,0 +1,23 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")"; pwd)"
|
||||
export SMOKE_ROOT="${script_dir}"
|
||||
export SMOKE_REPO_ROOT="$(cd "${SMOKE_ROOT}/../../.."; pwd)"
|
||||
export SMOKE_WORK_ROOT="${SMOKE_WORK_ROOT:-${RUNNER_TEMP:-/tmp}/rime-ice-smoke}"
|
||||
export SMOKE_LOG_ROOT="${SMOKE_LOG_ROOT:-${SMOKE_WORK_ROOT}/logs}"
|
||||
|
||||
source "${SMOKE_ROOT}/lib/common.sh"
|
||||
|
||||
suite_name="${1:-rime_ice}"
|
||||
|
||||
case "${suite_name}" in
|
||||
rime_ice)
|
||||
source "${SMOKE_ROOT}/suites/config_repo.sh"
|
||||
run_config_repo_suite "${suite_name}"
|
||||
;;
|
||||
*)
|
||||
fail "unknown smoke suite: ${suite_name}"
|
||||
;;
|
||||
esac
|
||||
230
others/script/smoke/suites/config_repo.sh
Normal file
230
others/script/smoke/suites/config_repo.sh
Normal file
@@ -0,0 +1,230 @@
|
||||
#!/bin/bash
|
||||
|
||||
run_config_repo_suite() {
|
||||
local suite_name="$1"
|
||||
local suite_root="${SMOKE_ROOT}/cases/${suite_name}"
|
||||
local work_root="${SMOKE_WORK_ROOT}/${suite_name}"
|
||||
local log_root="${SMOKE_LOG_ROOT}/${suite_name}"
|
||||
local cli_url="${RIME_CLI_URL:-}"
|
||||
local config_root="${RIME_CONFIG_ROOT:-${SMOKE_REPO_ROOT}}"
|
||||
local cli_paths_file="${work_root}/cli-paths.txt"
|
||||
local deployer_path
|
||||
local api_console_path
|
||||
local user_data_dir="${work_root}/user-data"
|
||||
local deploy_stdout="${log_root}/deploy.stdout.log"
|
||||
local deploy_stderr="${log_root}/deploy.stderr.log"
|
||||
local deploy_combined="${log_root}/deploy.combined.log"
|
||||
local deploy_warnings="${log_root}/deploy.warnings.log"
|
||||
|
||||
ensure_clean_dir "${work_root}"
|
||||
ensure_clean_dir "${log_root}"
|
||||
mkdir -p "${user_data_dir}"
|
||||
|
||||
assert_file_exists "${config_root}/default.yaml"
|
||||
assert_file_exists "${config_root}/${suite_name}.schema.yaml"
|
||||
clean_config_artifacts "${config_root}"
|
||||
|
||||
resolve_cli_commands "${cli_url}" "${work_root}" >"${cli_paths_file}"
|
||||
deployer_path="$(sed -n '1p' "${cli_paths_file}")"
|
||||
api_console_path="$(sed -n '2p' "${cli_paths_file}")"
|
||||
|
||||
log_step "using config root ${config_root}"
|
||||
log_step "running deployer"
|
||||
if ! run_deployer "${deployer_path}" "${user_data_dir}" "${config_root}" "${deploy_stdout}" "${deploy_stderr}"; then
|
||||
combine_logs "${deploy_stdout}" "${deploy_stderr}" "${deploy_combined}"
|
||||
set_failure_context "deployment" "${deploy_combined}"
|
||||
fail "rime_deployer exited with non-zero status"
|
||||
fi
|
||||
|
||||
combine_logs "${deploy_stdout}" "${deploy_stderr}" "${deploy_combined}"
|
||||
set_failure_context "deployment" "${deploy_combined}"
|
||||
assert_no_error_lines "${deploy_combined}"
|
||||
collect_warning_lines "${deploy_combined}" "${deploy_warnings}"
|
||||
assert_file_exists "${user_data_dir}/build/default.yaml"
|
||||
assert_file_exists "${user_data_dir}/build/${suite_name}.schema.yaml"
|
||||
log_pass "deployment passed"
|
||||
|
||||
if [[ -s "${deploy_warnings}" ]]; then
|
||||
log_warn "deployment warnings detected"
|
||||
cat "${deploy_warnings}"
|
||||
fi
|
||||
clear_failure_context
|
||||
|
||||
run_config_input_cases "${suite_root}/input_cases.tsv" "${api_console_path}" "${config_root}" "${user_data_dir}" "${log_root}"
|
||||
}
|
||||
|
||||
run_config_input_cases() {
|
||||
local case_file="$1"
|
||||
local api_console_path="$2"
|
||||
local shared_data_dir="$3"
|
||||
local user_data_dir="$4"
|
||||
local log_root="$5"
|
||||
local raw_line
|
||||
local pending_schema_id=""
|
||||
local pending_case_file="${log_root}/pending_cases.tsv"
|
||||
|
||||
[[ -f "${case_file}" ]] || fail "case file not found: ${case_file}"
|
||||
: >"${pending_case_file}"
|
||||
|
||||
while IFS= read -r raw_line || [[ -n "${raw_line}" ]]; do
|
||||
if [[ -z "${raw_line}" ]]; then
|
||||
flush_schema_case_group \
|
||||
"${pending_schema_id}" \
|
||||
"${pending_case_file}" \
|
||||
"${api_console_path}" \
|
||||
"${shared_data_dir}" \
|
||||
"${user_data_dir}" \
|
||||
"${log_root}"
|
||||
pending_schema_id=""
|
||||
: >"${pending_case_file}"
|
||||
continue
|
||||
fi
|
||||
if [[ "${raw_line}" == \#* ]]; then
|
||||
flush_schema_case_group \
|
||||
"${pending_schema_id}" \
|
||||
"${pending_case_file}" \
|
||||
"${api_console_path}" \
|
||||
"${shared_data_dir}" \
|
||||
"${user_data_dir}" \
|
||||
"${log_root}"
|
||||
pending_schema_id=""
|
||||
: >"${pending_case_file}"
|
||||
printf '%s\n' "${raw_line}"
|
||||
continue
|
||||
fi
|
||||
|
||||
local case_id
|
||||
local schema_id
|
||||
local key_sequence
|
||||
local expected_text
|
||||
IFS=$'\t' read -r case_id schema_id key_sequence expected_text <<<"${raw_line}"
|
||||
if [[ -z "${case_id}" ]]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
if [[ -n "${pending_schema_id}" && "${schema_id}" != "${pending_schema_id}" ]]; then
|
||||
flush_schema_case_group \
|
||||
"${pending_schema_id}" \
|
||||
"${pending_case_file}" \
|
||||
"${api_console_path}" \
|
||||
"${shared_data_dir}" \
|
||||
"${user_data_dir}" \
|
||||
"${log_root}"
|
||||
: >"${pending_case_file}"
|
||||
fi
|
||||
|
||||
pending_schema_id="${schema_id}"
|
||||
printf '%s\t%s\t%s\n' "${case_id}" "${key_sequence}" "${expected_text}" >>"${pending_case_file}"
|
||||
done <"${case_file}"
|
||||
|
||||
flush_schema_case_group \
|
||||
"${pending_schema_id}" \
|
||||
"${pending_case_file}" \
|
||||
"${api_console_path}" \
|
||||
"${shared_data_dir}" \
|
||||
"${user_data_dir}" \
|
||||
"${log_root}"
|
||||
}
|
||||
|
||||
flush_schema_case_group() {
|
||||
local schema_id="$1"
|
||||
local case_group_file="$2"
|
||||
local api_console_path="$3"
|
||||
local shared_data_dir="$4"
|
||||
local user_data_dir="$5"
|
||||
local log_root="$6"
|
||||
|
||||
[[ -n "${schema_id}" ]] || return 0
|
||||
[[ -s "${case_group_file}" ]] || return 0
|
||||
|
||||
local group_name="${schema_id}"
|
||||
local group_input_path="${log_root}/${group_name}.group.input.txt"
|
||||
local group_stdout_path="${log_root}/${group_name}.group.stdout.log"
|
||||
local group_stderr_path="${log_root}/${group_name}.group.stderr.log"
|
||||
local group_combined_path="${log_root}/${group_name}.group.combined.log"
|
||||
local group_normalized_path="${log_root}/${group_name}.group.normalized.log"
|
||||
|
||||
build_schema_group_input "${schema_id}" "${case_group_file}" "${group_input_path}"
|
||||
log_step "running schema group ${schema_id}"
|
||||
if ! run_api_console_script "${api_console_path}" "${shared_data_dir}" "${user_data_dir}" "${group_input_path}" "${group_stdout_path}" "${group_stderr_path}"; then
|
||||
combine_logs "${group_stdout_path}" "${group_stderr_path}" "${group_combined_path}"
|
||||
set_failure_context "schema group ${schema_id}" "${group_combined_path}"
|
||||
fail "rime_api_console exited with non-zero status"
|
||||
fi
|
||||
|
||||
combine_logs "${group_stdout_path}" "${group_stderr_path}" "${group_combined_path}"
|
||||
set_failure_context "schema group ${schema_id}" "${group_combined_path}"
|
||||
assert_no_error_lines "${group_combined_path}"
|
||||
normalize_console_output "${group_stdout_path}" "${group_normalized_path}"
|
||||
clear_failure_context
|
||||
|
||||
assert_schema_group_cases "${schema_id}" "${case_group_file}" "${group_normalized_path}" "${group_combined_path}" "${log_root}"
|
||||
}
|
||||
|
||||
build_schema_group_input() {
|
||||
local schema_id="$1"
|
||||
local case_group_file="$2"
|
||||
local output_path="$3"
|
||||
local case_id
|
||||
local key_sequence
|
||||
local expected_text
|
||||
|
||||
: >"${output_path}"
|
||||
while IFS=$'\t' read -r case_id key_sequence expected_text; do
|
||||
[[ -n "${case_id}" ]] || continue
|
||||
printf 'select schema %s\n%s\n' "${schema_id}" "${key_sequence}" >>"${output_path}"
|
||||
done <"${case_group_file}"
|
||||
printf 'exit\n' >>"${output_path}"
|
||||
}
|
||||
|
||||
extract_case_output_block() {
|
||||
local normalized_path="$1"
|
||||
local schema_id="$2"
|
||||
local occurrence="$3"
|
||||
local output_path="$4"
|
||||
awk -v marker="selected schema: [${schema_id}]" -v target="${occurrence}" '
|
||||
$0 == marker {
|
||||
count++
|
||||
if (count == target) {
|
||||
printing = 1
|
||||
} else if (count > target && printing) {
|
||||
exit
|
||||
}
|
||||
}
|
||||
printing {
|
||||
print
|
||||
}
|
||||
' "${normalized_path}" >"${output_path}"
|
||||
}
|
||||
|
||||
assert_schema_group_cases() {
|
||||
local schema_id="$1"
|
||||
local case_group_file="$2"
|
||||
local group_normalized_path="$3"
|
||||
local group_combined_path="$4"
|
||||
local log_root="$5"
|
||||
local case_index=0
|
||||
local case_id
|
||||
local key_sequence
|
||||
local expected_text
|
||||
local resolved_expected_text
|
||||
|
||||
while IFS=$'\t' read -r case_id key_sequence expected_text; do
|
||||
[[ -n "${case_id}" ]] || continue
|
||||
((case_index += 1))
|
||||
resolved_expected_text="$(resolve_expected_text "${expected_text}")"
|
||||
|
||||
local case_stdout_path="${log_root}/${case_id}.stdout.log"
|
||||
extract_case_output_block "${group_normalized_path}" "${schema_id}" "${case_index}" "${case_stdout_path}"
|
||||
|
||||
set_failure_context "case ${case_id}" "${group_combined_path}"
|
||||
assert_file_contains "${case_stdout_path}" "selected schema: [${schema_id}]"
|
||||
if [[ "${expected_text}" == @regex:* ]]; then
|
||||
assert_file_matches "${case_stdout_path}" "${expected_text#@regex:}"
|
||||
else
|
||||
assert_file_contains "${case_stdout_path}" "commit: ${resolved_expected_text}"
|
||||
fi
|
||||
log_pass "input case passed: ${case_id}"
|
||||
clear_failure_context
|
||||
done <"${case_group_file}"
|
||||
}
|
||||
Reference in New Issue
Block a user