コンテンツにスキップ

seizu-cli Contract仕様書

seizu-cli Contract Specification

seizu-cli domain logic contracts — self-documenting dogfooding example

シナリオ

複数のContract操作を組み合わせたビジネスワークフローです。

doc.generate

doc.generate

受け入れ条件

このContractが担保するビジネス要求です。

  • ソースファイルからContract仕様書を自動生成できる
#操作入力
1doc.parsesourceFiles: input.sourceFiles
2doc.filterfilterIds: input.filterIds
3doc.link-
4doc.analyzeenabled: input.coverageEnabled
5doc.render-
フローチャート (Mermaid)
flowchart TD
  n1(["start"])
  n2(["end"])
  n3["step doc.parse"]
  n4["step doc.filter"]
  n5["step doc.link"]
  n6["step doc.analyze"]
  n7["step doc.render"]
  n1 --> n3
  n3 --> n4
  n4 --> n5
  n5 --> n6
  n6 --> n7
  n7 --> n2

Flow Summary

指標
処理ステップ数5
分岐数0
エラー経路数0
解析不能数0

coverage.generate

coverage.generate

受け入れ条件

このContractが担保するビジネス要求です。

  • テストカバレッジレポートを生成できる
#操作入力
1doc.parsesourceFiles: input.sourceFiles
2doc.filterfilterIds: input.filterIds
3doc.link-
4doc.analyzeenabled: true
フローチャート (Mermaid)
flowchart TD
  n1(["start"])
  n2(["end"])
  n3["step doc.parse"]
  n4["step doc.filter"]
  n5["step doc.link"]
  n6["step doc.analyze"]
  n1 --> n3
  n3 --> n4
  n4 --> n5
  n5 --> n6
  n6 --> n2

Flow Summary

指標
処理ステップ数4
分岐数0
エラー経路数0
解析不能数0

render.markdown

render.markdown

受け入れ条件

このContractが担保するビジネス要求です。

  • タイトル・シナリオ・目次をMarkdownとして組み立てられる
#操作入力
1render.titletitle: input.title, description: input.description
2render.scenarioSectionscenarios: input.scenarios, messages: input.messages, flowEnabled: input.flowEnabled
3render.toccontracts: […input.contracts].sort((a, b) => a.contract.name.localeCompare(b.contract.name) ), messages: input.messages
フローチャート (Mermaid)
flowchart TD
  n1(["start"])
  n2(["end"])
  n3["step render.title"]
  n4["step render.scenarioSection"]
  n5["step render.toc"]
  n1 --> n3
  n3 --> n4
  n4 --> n5
  n5 --> n2

Flow Summary

指標
処理ステップ数3
分岐数0
エラー経路数0
解析不能数0

目次

  • doc.analyze (事前条件: 0件, テスト: 4件)
  • doc.filter (事前条件: 0件, テスト: 4件)
  • doc.link (事前条件: 0件, テスト: 2件)
  • doc.parse (事前条件: 2件, テスト: 8件)
  • doc.render (事前条件: 0件, テスト: 3件)
  • render.scenarioSection (事前条件: 0件, テスト: 2件)
  • render.title (事前条件: 1件, テスト: 3件)
  • render.toc (事前条件: 0件, テスト: 3件)
  • report.replay (事前条件: 1件, テスト: 4件)
  • report.summary (事前条件: 1件, テスト: 5件)

Contract詳細


doc.analyze

受け入れ条件

このContractが担保するビジネス要求です。

  • テストカバレッジを分析してレポートを生成できる
項目
状態 (State)DocPipelineState
入力 (Input)AnalyzeInput
エラー (Error)never
フローチャート (Mermaid)
flowchart TD
  n1(["start"])
  n2(["ok"])
  n3["transition"]
  n4{"if !input.enabled"}
  n5["return state"]
  n6["const coverageReport = analyzeCoverage(state.linked);"]
  n7["return { ...state, coverageReport }"]
  n8["post.1"]
  n1 --> n3
  n3 --> n4
  n4 -->|true| n5
  n4 -->|false| n6
  n5 --> n8
  n6 --> n7
  n7 --> n8
  n8 --> n2

Flow Summary

指標
処理ステップ数6
分岐数1
エラー経路数0
解析不能数0

事前条件

この処理を実行する前に満たされている必要がある条件です。条件を満たさない場合、対応するエラーが返されます。

定義なし

事後条件

この処理が正常に完了した後に保証される条件です。

#条件
1coverage report is present when analysis is enabled

不変条件

この処理の前後を問わず、常に成り立つべき条件です。

定義なし

エラー一覧

エラー定義なし

テストケース

この処理の動作を検証するテストシナリオです。

#シナリオ期待結果
1generates coverage report when enabled正常に処理される
2skips coverage when disabled正常に処理される
3post/invariant: hold when enabled正常に処理される
4post/invariant: hold when disabled正常に処理される

doc.filter

受け入れ条件

このContractが担保するビジネス要求です。

  • 指定されたIDでContractをフィルタリングできる
項目
状態 (State)DocPipelineState
入力 (Input)FilterInput
エラー (Error)never
フローチャート (Mermaid)
flowchart TD
  n1(["start"])
  n2(["ok"])
  n3["transition"]
  n4{"if input.filterIds && input.filterIds.size > 0"}
  n5["return { ...state, filtered: state.contracts.filter( (c) => input.fi..."]
  n6["return { ...state, filtered: [...state.contracts] }"]
  n7["post.1"]
  n1 --> n3
  n3 --> n4
  n4 -->|true| n5
  n4 -->|false| n6
  n5 --> n7
  n6 --> n7
  n7 --> n2

Flow Summary

指標
処理ステップ数5
分岐数1
エラー経路数0
解析不能数0

事前条件

この処理を実行する前に満たされている必要がある条件です。条件を満たさない場合、対応するエラーが返されます。

定義なし

事後条件

この処理が正常に完了した後に保証される条件です。

#条件
1filtered contracts are a subset of all contracts

不変条件

この処理の前後を問わず、常に成り立つべき条件です。

定義なし

エラー一覧

エラー定義なし

テストケース

この処理の動作を検証するテストシナリオです。

#シナリオ期待結果
1filters contracts by IDs正常に処理される
2passes all contracts when no filter正常に処理される
3returns empty when filter matches nothing正常に処理される
4post/invariant: hold after transition正常に処理される

受け入れ条件

このContractが担保するビジネス要求です。

  • Contractとテストスイートを紐付けできる
項目
状態 (State)DocPipelineState
入力 (Input)Record<string, never>
エラー (Error)never
フローチャート (Mermaid)
flowchart TD
  n1(["start"])
  n2(["ok"])
  n3["transition"]
  n4["const linked = linkContractsToTests(state.filtered, state.tes..."]
  n5["const linkedScenarios = linkScenarios(state.scenarios, state...."]
  n6["return { ...state, linked, linkedScenarios }"]
  n7["post.1"]
  n1 --> n3
  n3 --> n4
  n4 --> n5
  n5 --> n6
  n6 --> n7
  n7 --> n2

Flow Summary

指標
処理ステップ数5
分岐数0
エラー経路数0
解析不能数0

事前条件

この処理を実行する前に満たされている必要がある条件です。条件を満たさない場合、対応するエラーが返されます。

定義なし

事後条件

この処理が正常に完了した後に保証される条件です。

#条件
1every filtered contract has a corresponding linked entry

不変条件

この処理の前後を問わず、常に成り立つべき条件です。

定義なし

エラー一覧

エラー定義なし

テストケース

この処理の動作を検証するテストシナリオです。

#シナリオ期待結果
1links contracts to tests正常に処理される
2post/invariant: hold after transition正常に処理される

doc.parse

受け入れ条件

このContractが担保するビジネス要求です。

  • ソースファイルからContract・Scenario・テストをパースできる
  • ソースファイルが未指定の場合はエラーを返す
項目
状態 (State)DocPipelineState
入力 (Input)ParseInput
エラー (Error)PipelineError
フローチャート (Mermaid)
flowchart TD
  n1(["start"])
  n2(["ok"])
  n3{"pre.1"}
  n4(["error(pre.1)"])
  n5{"pre.2"}
  n6(["error(pre.2)"])
  n7["transition"]
  n8["const contracts: ParsedContract[] = [];"]
  n9["const scenarios: ParsedScenario[] = [];"]
  n10["const testSuites: ParsedTestSuite[] = [];"]
  n11["const sourceFilePaths: string[] = [];"]
  n12{"for-of input.sourceFiles"}
  n13["sourceFilePaths.push(entry.path);"]
  n14[["unsupported: SwitchStatement"]]
  n15["return { ...state, sourceFiles: [...new Set(sourceFilePaths)], contr..."]
  n16["post.1"]
  n1 --> n3
  n3 -->|fail| n4
  n3 -->|pass| n5
  n5 -->|fail| n6
  n5 -->|pass| n7
  n7 --> n8
  n8 --> n9
  n9 --> n10
  n10 --> n11
  n11 --> n12
  n12 -->|iterate| n13
  n12 -->|done| n15
  n13 --> n14
  n14 -->|next| n12
  n15 --> n16
  n16 --> n2

Flow Summary

指標
処理ステップ数11
分岐数1
エラー経路数2
解析不能数1

注意: 未対応構文により 1 件の解析不能経路があります。

事前条件

この処理を実行する前に満たされている必要がある条件です。条件を満たさない場合、対応するエラーが返されます。

#条件エラー
1source files must not be emptyNoSourceFiles
2scenario flow must be deterministicDynamicScenarioFlow

事後条件

この処理が正常に完了した後に保証される条件です。

#条件
1source file paths are tracked uniquely

不変条件

この処理の前後を問わず、常に成り立つべき条件です。

定義なし

エラー一覧

エラータグ発生元
NoSourceFiles事前条件 #1
DynamicScenarioFlow事前条件 #2

テストケース

この処理の動作を検証するテストシナリオです。

#シナリオ期待結果
1parses contracts from source files正常に処理される
2parses test suites from source files正常に処理される
3rejects empty source filesエラーが返される
4rejects dynamic scenario flow patternsエラーが返される
5rejects non-direct step elements in scenario flow arraysエラーが返される
6preserves title and messages正常に処理される
7post/invariant: hold after transition-
8exposes contract metadata-

doc.render

受け入れ条件

このContractが担保するビジネス要求です。

  • パイプライン状態からMarkdownドキュメントを生成できる
項目
状態 (State)DocPipelineState
入力 (Input)Record<string, never>
エラー (Error)never
フローチャート (Mermaid)
flowchart TD
  n1(["start"])
  n2(["ok"])
  n3["transition"]
  n4["const result = renderMarkdownScenario([], { title: state.titl..."]
  n5["const baseLines = isOk(result) ? result.value : [];"]
  n6["let lines = renderContractSections(baseLines, { contracts: st..."]
  n7{"if state.coverageReport"}
  n8["lines = renderCoverageSection(lines, { report: state.coverage..."]
  n9["const markdown = lines.join('\\n').replace(/\\n{3,}/g, '\\n\\n');"]
  n10["return { ...state, markdown }"]
  n11["post.1"]
  n1 --> n3
  n3 --> n4
  n4 --> n5
  n5 --> n6
  n6 --> n7
  n7 -->|true| n8
  n7 -->|false| n9
  n8 --> n9
  n9 --> n10
  n10 --> n11
  n11 --> n2

Flow Summary

指標
処理ステップ数9
分岐数1
エラー経路数0
解析不能数0

事前条件

この処理を実行する前に満たされている必要がある条件です。条件を満たさない場合、対応するエラーが返されます。

定義なし

事後条件

この処理が正常に完了した後に保証される条件です。

#条件
1non-empty linked state produces non-empty markdown

不変条件

この処理の前後を問わず、常に成り立つべき条件です。

定義なし

エラー一覧

エラー定義なし

テストケース

この処理の動作を検証するテストシナリオです。

#シナリオ期待結果
1renders markdown from linked state正常に処理される
2renders title-only markdown for empty state正常に処理される
3post/invariant: hold after transition正常に処理される

render.scenarioSection

受け入れ条件

このContractが担保するビジネス要求です。

  • シナリオセクションをレンダリングできる
項目
状態 (State)readonly string[]
入力 (Input)ScenarioSectionInput
エラー (Error)RenderError
フローチャート (Mermaid)
flowchart TD
  n1(["start"])
  n2(["ok"])
  n3["transition"]
  n4["return input.scenarios.length === 0 ? lines : [ ...lines, ...renderS..."]
  n5["post.1"]
  n1 --> n3
  n3 --> n4
  n4 --> n5
  n5 --> n2

Flow Summary

指標
処理ステップ数3
分岐数0
エラー経路数0
解析不能数0

事前条件

この処理を実行する前に満たされている必要がある条件です。条件を満たさない場合、対応するエラーが返されます。

定義なし

事後条件

この処理が正常に完了した後に保証される条件です。

#条件
1rendering scenario section appends lines only when scenarios exist

不変条件

この処理の前後を問わず、常に成り立つべき条件です。

定義なし

エラー一覧

エラー定義なし

テストケース

この処理の動作を検証するテストシナリオです。

#シナリオ期待結果
1renders scenario section正常に処理される
2skips scenario section when scenarios are empty正常に処理される

render.title

受け入れ条件

このContractが担保するビジネス要求です。

  • ドキュメントのタイトルと説明をレンダリングできる
項目
状態 (State)readonly string[]
入力 (Input)TitleInput
エラー (Error)RenderError
フローチャート (Mermaid)
flowchart TD
  n1(["start"])
  n2(["ok"])
  n3{"pre.1"}
  n4(["error(pre.1)"])
  n5["transition"]
  n6["const result = [...lines, `# ${input.title}`, ''];"]
  n7{"if input.description"}
  n8["return [...result, `> ${input.description}`, '']"]
  n9["return result"]
  n10["post.1"]
  n1 --> n3
  n3 -->|fail| n4
  n3 -->|pass| n5
  n5 --> n6
  n6 --> n7
  n7 -->|true| n8
  n7 -->|false| n9
  n8 --> n10
  n9 --> n10
  n10 --> n2

Flow Summary

指標
処理ステップ数7
分岐数1
エラー経路数1
解析不能数0

事前条件

この処理を実行する前に満たされている必要がある条件です。条件を満たさない場合、対応するエラーが返されます。

#条件エラー
1document title must not be emptyTitleEmpty

事後条件

この処理が正常に完了した後に保証される条件です。

#条件
1rendering a title always appends new lines

不変条件

この処理の前後を問わず、常に成り立つべき条件です。

定義なし

エラー一覧

エラータグ発生元
TitleEmpty事前条件 #1

テストケース

この処理の動作を検証するテストシナリオです。

#シナリオ期待結果
1renders title with description正常に処理される
2rejects empty titleエラーが返される
3post: lines increase after transition-

render.toc

受け入れ条件

このContractが担保するビジネス要求です。

  • 2つ以上のContractがある場合に目次を生成できる
項目
状態 (State)readonly string[]
入力 (Input)TocInput
エラー (Error)RenderError
フローチャート (Mermaid)
flowchart TD
  n1(["start"])
  n2(["ok"])
  n3["transition"]
  n4["const { contracts, messages } = input;"]
  n5{"if contracts.length < 2"}
  n6["return lines"]
  n7["const result = [...lines];"]
  n8["result.push(`## ${messages.toc.title}`);"]
  n9["result.push('');"]
  n10{"for-of contracts"}
  n11["const { contract } = linked;"]
  n12["const firstLine = contract.description?.split('\\n')[0]?.trim();"]
  n13["const testCount = linked.testSuite?.tests.length ?? 0;"]
  n14["const guardCount = contract.guards.length;"]
  n15["const label = firstLine ? `**${contract.name}** - ${firstLine..."]
  n16["const meta = messages.toc.meta(guardCount, testCount);"]
  n17["result.push(`- ${label} (${meta})`);"]
  n18["result.push('');"]
  n19["return result"]
  n20["post.1"]
  n1 --> n3
  n3 --> n4
  n4 --> n5
  n5 -->|true| n6
  n5 -->|false| n7
  n6 --> n20
  n7 --> n8
  n8 --> n9
  n9 --> n10
  n10 -->|iterate| n11
  n10 -->|done| n18
  n11 --> n12
  n12 --> n13
  n13 --> n14
  n14 --> n15
  n15 --> n16
  n16 --> n17
  n17 -->|next| n10
  n18 --> n19
  n19 --> n20
  n20 --> n2

Flow Summary

指標
処理ステップ数18
分岐数2
エラー経路数0
解析不能数0

事前条件

この処理を実行する前に満たされている必要がある条件です。条件を満たさない場合、対応するエラーが返されます。

定義なし

事後条件

この処理が正常に完了した後に保証される条件です。

#条件
1rendering TOC appends lines only when two or more contracts are present

不変条件

この処理の前後を問わず、常に成り立つべき条件です。

定義なし

エラー一覧

エラー定義なし

テストケース

この処理の動作を検証するテストシナリオです。

#シナリオ期待結果
1renders TOC for 2+ contracts正常に処理される
2skips TOC when fewer than 2 contracts正常に処理される
3post: lines increase after transition-

report.replay

受け入れ条件

このContractが担保するビジネス要求です。

  • 失敗したPBT検証のリプレイコマンドを生成できる
項目
状態 (State)string
入力 (Input)ReporterInput
エラー (Error)ReporterError
フローチャート (Mermaid)
flowchart TD
  n1(["start"])
  n2(["ok"])
  n3{"pre.1"}
  n4(["error(pre.1)"])
  n5["transition"]
  n6["return replay(input.result)"]
  n7["post.1"]
  n8["invariant.1"]
  n1 --> n3
  n3 -->|fail| n4
  n3 -->|pass| n5
  n5 --> n6
  n6 --> n7
  n7 --> n8
  n8 --> n2

Flow Summary

指標
処理ステップ数5
分岐数0
エラー経路数1
解析不能数0

事前条件

この処理を実行する前に満たされている必要がある条件です。条件を満たさない場合、対応するエラーが返されます。

#条件エラー
1must have at least one failure to generate replayNoFailures

事後条件

この処理が正常に完了した後に保証される条件です。

#条件
1output is non-empty

不変条件

この処理の前後を問わず、常に成り立つべき条件です。

#条件
1output is always a string

エラー一覧

エラータグ発生元
NoFailures事前条件 #1

テストケース

この処理の動作を検証するテストシナリオです。

#シナリオ期待結果
1formats failed result正常に処理される
2rejects successful resultエラーが返される
3post/invariant: hold after transition-
4exposes contract metadata-

report.summary

受け入れ条件

このContractが担保するビジネス要求です。

  • PBT検証結果のサマリーレポートを生成できる
項目
状態 (State)string
入力 (Input)ReporterInput
エラー (Error)ReporterError
フローチャート (Mermaid)
flowchart TD
  n1(["start"])
  n2(["ok"])
  n3{"pre.1"}
  n4(["error(pre.1)"])
  n5["transition"]
  n6["return summary(input.result)"]
  n7["post.1"]
  n8["invariant.1"]
  n1 --> n3
  n3 -->|fail| n4
  n3 -->|pass| n5
  n5 --> n6
  n6 --> n7
  n7 --> n8
  n8 --> n2

Flow Summary

指標
処理ステップ数5
分岐数0
エラー経路数1
解析不能数0

事前条件

この処理を実行する前に満たされている必要がある条件です。条件を満たさない場合、対応するエラーが返されます。

#条件エラー
1verification results must not be emptyNoResults

事後条件

この処理が正常に完了した後に保証される条件です。

#条件
1output contains seizu-verify header

不変条件

この処理の前後を問わず、常に成り立つべき条件です。

#条件
1output is always a string

エラー一覧

エラータグ発生元
NoResults事前条件 #1

テストケース

この処理の動作を検証するテストシナリオです。

#シナリオ期待結果
1formats passing result正常に処理される
2formats result with multiple contracts正常に処理される
3rejects empty resultsエラーが返される
4post/invariant: hold after transition-
5exposes contract metadata-

テスト網羅性

各Contractに対するテストの網羅状況です。

Contractテスト数エラータグ網羅状態
doc.parse80/2テスト済
doc.filter4-テスト済
doc.link2-テスト済
doc.analyze4-テスト済
doc.render3-テスト済
render.title30/1テスト済
render.toc3-テスト済
render.scenarioSection2-テスト済
report.summary50/1テスト済
report.replay40/1テスト済

Contract網羅率: 10/10 (100.0%) エラータグ網羅率: 0/5 (0.0%)