Skip to content

test(app): add the plugin contract runner and fixture replay - #184

Merged
1morr merged 5 commits into
mainfrom
feat/plugin-contract
Sep 30, 2026
Merged

1morr merged 5 commits into
mainfrom
feat/plugin-contract

Conversation

@1morr

@1morr 1morr commented Sep 30, 2026

Copy link
Copy Markdown
Owner

M1 PR 9b:插件契約執行器、fixture 錄製與重播、checks.json(ADR 0015 §決定 4–6;擁有者決定 8)。

做了什麼

  • fixture:
    • 一次請求與回應存成一個 JSON 檔,欄位名沿用 WireMock stub mapping,外層加 meta。
    • 錄製與重播都在 SourceHttpClient 最底層的 dio adapter。
    • 重播比對 method、排序後的 URL 和請求順序,參考 Polly.js 與 VCR。比對前先用同一個遮蔽函式遮過實際網址;fixture 值是 *** 的欄位只要求存在,不比值。對不上,或有 fixture 沒被用到,都讓測試失敗。
  • checks.json:鍵是能力名,格式本身就保證每個能力最多一條案例。期望寫成筆數、欄位非空,或 AppError 類別加原因。
  • 契約執行器:放在 app/test/plugins/contract/。對任一插件目錄執行的指令是 FMP_PLUGIN_DIR=<目錄> flutter test test/plugins/contract/contract_test.dart。斷言涵蓋:
    • 能力與匯出一致;
    • DTO 驗證;
    • 案例期望;
    • 錯誤類別;
    • 串流 headers 不帶憑證;
    • 只連 manifest 的網域;
    • log 經過遮蔽。
  • 執行器沒做成獨立套件:
    • QuickJS 的預載入和零聯網防線都在 app/test/;
    • 獨立套件會和 fmp 互相依賴;
    • 放進 lib/ 會違反分層 lint。
    • ADR 0015 §決定 6 已補更正。
  • 錄製模式(擁有者決定 8):
    • 在命令列執行,要帶 live tag,只給不需要登入的案例用;寫檔前一律經過遮蔽。
    • 案例結果不符 checks.json 的期望就整組不寫,原本的檔案不動。
    • meta.edited 標記的手寫 fixture 不會被重錄。
    • 這個 PR 沒有對真實音源錄製。
  • fixture 掃描:app/ 內所有 fixture 都不得有未遮蔽的憑證。兩道檢查(重跑遮蔽函式、比對常見欄位)各自做過變異驗證。
  • 測試插件:fmp-test 補上 checks.json;新增一個會發 HTTP 請求的 fmp-test-http,網域是 *.fmp.test,fixture 手寫。
  • CI:契約測試已包含在 flutter test 內,ci.yml 只補註解說明。

驗證

  • dart format、dart analyze --fatal-infos、flutter analyze:零問題。
  • build_runner:沒有實質變動。哨兵:13 條規則全部報出。
  • flutter test:516 個通過,2 個跳過(都是 live);test/plugins 連跑兩次都穩定。
  • 對 app/ 外的插件目錄實際跑過,路徑用 Windows 反斜線、含空格也試過:7 個通過。
  • opus 審查修了 4 個缺陷,每個都有修正前會紅的測試:
    • 陣列形式的遮蔽值被誤判成沒遮;
    • log 檢查可能空轉;
    • 重播前遮蔽網址這一步沒有測試守;
    • 錄製時連線失敗會蓋掉原本的 fixture。
  • 審查途中有一次 flutter test 卡在 loading 階段,之後依序重跑 14 次都沒重現,已記進後續待辦。

沒有使用者看得到的改動,不需要實機驗證。

Review 指南

  • 先看 contract_runner.dart(_execute、recordContract)和 fixture_adapters.dart(重播比對、錄製遮蔽)。
  • contract_runner_test.dart 是每條規則的雙向變異測試。
  • 格式說明在 fmp-plugin.d.ts(FmpChecks、FmpFixture)和 .trellis/spec/app/plugins/index.md。

@1morr
1morr merged commit a37b2fe into main Sep 30, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant