/** * E2E tests for `takt repertoire` subcommands. * * All tests are marked as `it.todo()` because the `takt repertoire` command * is not yet implemented. These serve as the specification skeleton; * fill in the callbacks when the implementation lands. * * GitHub fixture repos used: * - github:nrslib/takt-ensemble-fixture (standard: facets/ + pieces/) * - github:nrslib/takt-ensemble-fixture-subdir (path field specified) * - github:nrslib/takt-ensemble-fixture-facets-only (facets only, no pieces/) * */ import { describe, it } from 'vitest'; // --------------------------------------------------------------------------- // E2E: takt repertoire add — 正常系 // --------------------------------------------------------------------------- describe('E2E: takt repertoire add (正常系)', () => { // E1: 標準パッケージのインポート // Given: 空の isolatedEnv // When: takt repertoire add github:nrslib/takt-ensemble-fixture@v1.0.0、y 入力 // Then: {taktDir}/repertoire/@nrslib/takt-ensemble-fixture/ に takt-repertoire.yaml, // .takt-repertoire-lock.yaml, facets/, pieces/ が存在する it.todo('should install standard package and verify directory structure'); // E2: lock ファイルのフィールド確認 // Given: E1 完了後 // When: .takt-repertoire-lock.yaml を読む // Then: source, ref, commit, imported_at フィールドがすべて存在する it.todo('should generate .takt-repertoire-lock.yaml with source, ref, commit, imported_at'); // E3: サブディレクトリ型パッケージのインポート // Given: 空の isolatedEnv // When: takt repertoire add github:nrslib/takt-ensemble-fixture-subdir@v1.0.0、y 入力 // Then: path フィールドで指定されたサブディレクトリ配下のファイルのみコピーされる it.todo('should install subdir-type package and copy only path-specified files'); // E4: ファセットのみパッケージのインポート // Given: 空の isolatedEnv // When: takt repertoire add github:nrslib/takt-ensemble-fixture-facets-only@v1.0.0、y 入力 // Then: facets/ は存在し、pieces/ ディレクトリは存在しない it.todo('should install facets-only package without creating pieces/ directory'); // E4b: コミットSHA指定 // Given: 空の isolatedEnv // When: takt repertoire add github:nrslib/takt-ensemble-fixture@{sha}、y 入力 // Then: .takt-repertoire-lock.yaml の commit フィールドが指定した SHA と一致する it.todo('should populate lock file commit field with the specified commit SHA when installing by SHA'); // E5: インストール前サマリー表示 // Given: 空の isolatedEnv // When: takt repertoire add github:nrslib/takt-ensemble-fixture@v1.0.0、N 入力(確認でキャンセル) // Then: stdout に "📦 nrslib/takt-ensemble-fixture", "faceted:", "pieces:" が含まれる it.todo('should display pre-install summary with package name, faceted count, and pieces list'); // E6: 権限警告表示(edit: true ピース) // Given: edit: true を含むパッケージ // When: repertoire add、N 入力 // Then: stdout に ⚠ が含まれる it.todo('should display warning symbol when package contains piece with edit: true'); // E7: ユーザー確認 N で中断 // Given: 空の isolatedEnv // When: repertoire add、N 入力 // Then: インストールディレクトリが存在しない。exit code 0 it.todo('should abort installation when user answers N to confirmation prompt'); }); // --------------------------------------------------------------------------- // E2E: takt repertoire add — 上書きシナリオ // --------------------------------------------------------------------------- describe('E2E: takt repertoire add (上書きシナリオ)', () => { // E8: 既存パッケージの上書き警告表示 // Given: 1回目インストール済み // When: 2回目 repertoire add // Then: stdout に "⚠ パッケージ @nrslib/takt-ensemble-fixture は既にインストールされています" が含まれる it.todo('should display already-installed warning on second add'); // E9: 上書き y で原子的更新 // Given: E8後、y 入力 // When: インストール完了後 // Then: .tmp/, .bak/ が残っていない。新 lock ファイルが配置済み it.todo('should atomically update package when user answers y to overwrite prompt'); // E10: 上書き N でキャンセル // Given: E8後、N 入力 // When: コマンド終了後 // Then: 既存パッケージが維持される(元 lock ファイルが変わらない) it.todo('should keep existing package when user answers N to overwrite prompt'); // E11: 前回異常終了残留物(.tmp/)クリーンアップ // Given: {repertoireDir}/@nrslib/takt-ensemble-fixture.tmp/ が既に存在する状態 // When: repertoire add、y 入力 // Then: インストールが正常完了する。exit code 0 it.todo('should clean up leftover .tmp/ directory from previous failed installation'); // E12: 前回異常終了残留物(.bak/)クリーンアップ // Given: {repertoireDir}/@nrslib/takt-ensemble-fixture.bak/ が既に存在する状態 // When: repertoire add、y 入力 // Then: インストールが正常完了する。exit code 0 it.todo('should clean up leftover .bak/ directory from previous failed installation'); }); // --------------------------------------------------------------------------- // E2E: takt repertoire add — バリデーション・エラー系 // --------------------------------------------------------------------------- describe('E2E: takt repertoire add (バリデーション・エラー系)', () => { // E13: takt-repertoire.yaml 不在リポジトリ // Given: takt-repertoire.yaml のないリポジトリを指定 // When: repertoire add // Then: exit code 非0。エラーメッセージ表示 it.todo('should fail with error when repository has no takt-repertoire.yaml'); // E14: path に絶対パス(/foo) // Given: path: /foo の takt-repertoire.yaml // When: repertoire add // Then: exit code 非0 it.todo('should reject takt-repertoire.yaml with absolute path in path field (/foo)'); // E15: path に .. によるリポジトリ外参照 // Given: path: ../outside の takt-repertoire.yaml // When: repertoire add // Then: exit code 非0 it.todo('should reject takt-repertoire.yaml with path traversal via ".." segments'); // E16: 空パッケージ(facets/ も pieces/ もない) // Given: facets/, pieces/ のどちらもない takt-repertoire.yaml // When: repertoire add // Then: exit code 非0 it.todo('should reject package with neither facets/ nor pieces/ directory'); // E17: min_version 不正形式(1.0、セグメント不足) // Given: takt.min_version: "1.0" // When: repertoire add // Then: exit code 非0 it.todo('should reject takt-repertoire.yaml with min_version "1.0" (missing patch segment)'); // E18: min_version 不正形式(v1.0.0、v プレフィックス) // Given: takt.min_version: "v1.0.0" // When: repertoire add // Then: exit code 非0 it.todo('should reject takt-repertoire.yaml with min_version "v1.0.0" (v prefix)'); // E19: min_version 不正形式(1.0.0-alpha、pre-release) // Given: takt.min_version: "1.0.0-alpha" // When: repertoire add // Then: exit code 非0 it.todo('should reject takt-repertoire.yaml with min_version "1.0.0-alpha" (pre-release suffix)'); // E20: min_version が現在の TAKT より新しい // Given: takt.min_version: "999.0.0" // When: repertoire add // Then: exit code 非0。必要バージョンと現在バージョンが表示される it.todo('should fail with version mismatch message when min_version exceeds current takt version'); }); // --------------------------------------------------------------------------- // E2E: takt repertoire remove // --------------------------------------------------------------------------- describe('E2E: takt repertoire remove', () => { // E21: 正常削除 y // Given: パッケージインストール済み // When: takt repertoire remove @nrslib/takt-ensemble-fixture、y 入力 // Then: ディレクトリが削除される。@nrslib/ 配下が空なら @nrslib/ も削除 it.todo('should remove installed package directory when user answers y'); // E22: owner dir 残存(他パッケージがある場合) // Given: @nrslib 配下に別パッケージもインストール済み // When: remove、y 入力 // Then: 対象パッケージのみ削除。@nrslib/ は残る it.todo('should keep @scope directory when other packages remain under same owner'); // E23: 参照ありでの警告付き削除 // Given: ~/.takt/pieces/ に @scope 参照するファイルあり // When: remove、y 入力 // Then: 警告("⚠ 次のファイルが...を参照しています")が表示され、削除は実行される it.todo('should display reference warning before deletion but still proceed when user answers y'); // E24: 参照ファイル自体は変更されない // Given: E23後 // When: 参照ファイルを読む // Then: 元の @scope 参照がそのまま残っている it.todo('should not modify reference files during removal'); // E25: 削除キャンセル N // Given: パッケージインストール済み // When: remove、N 入力 // Then: ディレクトリが残る。exit code 0 it.todo('should keep package directory when user answers N to removal prompt'); }); // --------------------------------------------------------------------------- // E2E: takt repertoire list // --------------------------------------------------------------------------- describe('E2E: takt repertoire list', () => { // E26: インストール済みパッケージ一覧表示 // Given: パッケージ1件インストール済み // When: takt repertoire list // Then: "📦 インストール済みパッケージ:" と @nrslib/takt-ensemble-fixture、 // description、ref、commit 先頭7文字が表示される it.todo('should list installed packages with name, description, ref, and abbreviated commit'); // E27: 空状態での表示 // Given: repertoire/ が空(パッケージなし) // When: takt repertoire list // Then: パッケージなし相当のメッセージ。exit code 0 it.todo('should display empty-state message when no packages are installed'); // E28: 複数パッケージの一覧 // Given: 2件以上インストール済み // When: takt repertoire list // Then: すべてのパッケージが表示される it.todo('should list all installed packages when multiple packages exist'); });