Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions TESTING_GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -834,15 +834,18 @@ Prefer the existing helper before writing new setup code.
- `ResolveQueryDataDirWithinWorkspace(workspacePath)` bounds query DB ancestor discovery at the fixture workspace root. Use it when a resolver test must ignore unrelated `.cdidx` directories above a shared temp root while preserving workspace-source fallback behavior.
- `ProjectPath(projectRoot, ...)` resolves fixture paths relative to the temp project and rejects absolute paths or `..` escapes outside that root.
- `CreateDirectory(projectRoot, ...)`, `WriteTextFile(...)`, `WriteTextFiles(...)`, `WriteBinaryFile(...)`, `AppendTextFile(...)`, and `ReadTextFile(...)` centralize fixture directory creation and file setup. Prefer them over local `Path.Combine` + `Directory.CreateDirectory` + `File.*` chains when the path belongs to a temp project.
- When related extractor/query regressions require the production CLI indexing boundary but only read the resulting graph, give each case a collision-free file and query symbol, index one shared immutable workspace, and keep the case-specific assertions together. Retain separate workspaces when a case mutates the source/index, verifies indexing failure or diagnostics, or needs independently observable test discovery.
- Use the `WriteTextFile(..., Encoding)` overload when fixture encoding is part of the behavior under test; do not drop back to `File.WriteAllText(Path.Combine(...), ..., encoding)` for temp-project files.
- In `FileIndexerTests`, use the local relative-path helpers for scan result assertions instead of repeating `Path.GetRelativePath(...)`, separator normalization, sorting, or set creation at each call site.
- `InitializeGitRepo(projectRoot)` initializes git and sets repo-local `user.name` and `user.email`.
- `CreateProjectDb(projectRoot)` creates `<projectRoot>/.cdidx/codeindex.db`, initializes schema, and seeds `codeindex_meta.indexed_project_root` to match the project root.
- `InsertIndexedFile(...)` inserts a realistic indexed file with content-derived checksum, chunks, symbols, and references, and now passes the file path into Python symbol extraction so `__init__.py`-based re-export tests can exercise qualified package names.
- `InsertIndexedFiles(...)` seeds an immutable multi-file fixture through one caller-owned transaction and performs deferred hotspot/reference-identity refresh once for the batch. Prefer it when a test builds many independent files before read-only queries, including mixed-language fixtures. Keep `InsertIndexedFile(...)` when the scenario observes per-file commits, failures, cancellation, refresh boundaries, or performs reads or mutations between inserts.
- `InsertIndexedFile(...)` does not clear process-wide SQLite pools after an ordinary disposed write, and `DeleteSqliteDatabaseFiles(...)` attempts deletion before requesting a pool release. Keep pool clearing as a Windows retry response to an observed deletion failure instead of charging every seeded file and clean database cleanup. When a fixture must immediately read or copy raw database bytes, pass `releasePoolForFileAccess: true` so only that connection pool is invalidated before disposal.
- `RunGit(...)` executes git without shell quoting issues.
- `DeleteDirectory(...)` attempts the recursive delete before walking the fixture to normalize attributes. Keep attribute normalization, SQLite pool release, and the bounded retry delay on the failure path so ordinary cleanup pays only one filesystem traversal while read-only or late-released Windows fixtures still recover.
- `DeleteDirectory(path)` retries temp-project cleanup and normalizes attributes. To avoid process-global cross-test interference, it only requests SQLite pool cleanup through `SqlitePoolCleanup` as a Windows-specific retry fallback after a delete failure.
- The `IndexCommandRunnerTests` partials rely on that failure-driven cleanup; do not call `SqliteConnection.ClearAllPools()` immediately before `DeleteDirectory(...)`. Retain an explicit pool release only when the scenario itself must reopen, replace, copy, or exclusively lock raw database files before cleanup.
- Use `DeleteDirectory(path)` in temp-workspace `finally` / `Dispose` cleanup paths, including tests that intentionally remove the workspace earlier in the scenario.
- Call `DeleteDirectory(path)` directly instead of wrapping it in `Directory.Exists(...)`; the helper already handles missing paths.
- Apply the same direct-call rule to local `DeleteDirectory` wrappers that only delegate to `TestProjectHelper.DeleteDirectory`.
Expand Down Expand Up @@ -1805,13 +1808,16 @@ dotnet test --filter "FullyQualifiedName~GitHelperTests"
- `ResolveQueryDataDirWithinWorkspace(workspacePath)` は query DB の ancestor 探索を fixture の workspace root で打ち切ります。workspace source の fallback 挙動を維持しつつ、共有 temp root より上にある無関係な `.cdidx` directory を resolver test から除外する場合に使ってください。
- `ProjectPath(projectRoot, ...)` は temp project からの相対 fixture path を解決し、その root の外へ出る絶対 path や `..` escape を拒否します。
- `CreateDirectory(projectRoot, ...)`、`WriteTextFile(...)`、`WriteTextFiles(...)`、`WriteBinaryFile(...)`、`AppendTextFile(...)`、`ReadTextFile(...)` は fixture directory 作成と file setup を集約します。path が temp project に属する場合は、ローカルな `Path.Combine` + `Directory.CreateDirectory` + `File.*` の連鎖より優先してください。
- 関連する extractor / query 回帰テストが production CLI の indexing 境界を必要とし、作成後の graph を読むだけなら、case ごとに衝突しない file と query symbol を与え、1 つの共有不変 workspace を 1 回だけ index して、case 固有の assertion をまとめて維持してください。source / index を変更する場合、indexing failure や diagnostic を検証する場合、または test discovery 上で独立して観測する必要がある場合は workspace を分けたままにします。
- fixture encoding がテスト対象の挙動に含まれる場合は `WriteTextFile(..., Encoding)` overload を使い、temp project 配下の file に対して `File.WriteAllText(Path.Combine(...), ..., encoding)` へ戻さないでください。
- `FileIndexerTests` では、scan result assertion ごとに `Path.GetRelativePath(...)`、separator normalization、sorting、set creation を繰り返さず、ローカルの relative-path helper を使ってください。
- `InitializeGitRepo(projectRoot)` は git を初期化し、repo-local の `user.name` と `user.email` を設定します。
- `CreateProjectDb(projectRoot)` は `<projectRoot>/.cdidx/codeindex.db` を作成し、スキーマを初期化したうえで `codeindex_meta.indexed_project_root` に project root を書き込みます。
- `InsertIndexedFile(...)` は内容由来の checksum、chunks、symbols、references を含む現実的なインデックス済みファイルを挿入し、Python の symbol extraction には file path も渡すため、`__init__.py` ベースの再エクスポートテストで package 修飾名を扱えます。
- `InsertIndexedFiles(...)` は、変更しない複数ファイル fixture を 1 つの caller-owned transaction で投入し、遅延した hotspot / reference-identity refresh を batch 全体で 1 回だけ実行します。複数の独立ファイルを作成してから read-only query を行うテストでは、複数言語 fixture も含めてこちらを優先してください。file ごとの commit、failure、cancellation、refresh 境界を観測する場合や、挿入の途中で read / mutation を行う場合は `InsertIndexedFile(...)` を維持してください。
- `RunGit(...)` は shell の quoting 問題に依存せず git を実行します。
- `DeleteDirectory(path)` は temp project cleanup のリトライと属性正規化を扱います。プロセス全体への干渉を避けるため、SQLite pool の解放は Windows で削除に失敗した場合のリトライ時だけに限定します。
- `IndexCommandRunnerTests` の partial 群も、この失敗時解放に委ねます。`DeleteDirectory(...)` の直前で `SqliteConnection.ClearAllPools()` を呼ばないでください。cleanup 前に raw database file を再オープン、置換、コピー、または排他 lock すること自体が scenario の一部である場合だけ、明示的な pool 解放を残します。
- 一時 workspace の `finally` / `Dispose` cleanup では、そのテストシナリオ内で workspace を意図的に先に削除する場合も含めて、`DeleteDirectory(path)` を使ってください。
- `DeleteDirectory(path)` は存在しない path を内部で扱うため、`Directory.Exists(...)` で囲まず直接呼び出してください。
- `TestProjectHelper.DeleteDirectory` に委譲するだけの local `DeleteDirectory` wrapper でも、同じく直接呼び出してください。
Expand Down
5 changes: 0 additions & 5 deletions tests/CodeIndex.Tests/IndexCommandRunnerDryRunTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -535,7 +535,6 @@ public void Run_DryRun_ReusesUnchangedIndexedBinaryFile_Issue4893()
}
finally
{
SqliteConnection.ClearAllPools();
DeleteDirectory(projectRoot);
}
}
Expand Down Expand Up @@ -606,7 +605,6 @@ ON CONFLICT(key) DO UPDATE SET value = excluded.value
}
finally
{
SqliteConnection.ClearAllPools();
DeleteDirectory(projectRoot);
}
}
Expand Down Expand Up @@ -951,7 +949,6 @@ checksum TEXT
}
finally
{
SqliteConnection.ClearAllPools();
DeleteDirectory(projectRoot);
}
}
Expand Down Expand Up @@ -1665,7 +1662,6 @@ public void Run_DryRunAndFullScan_FollowSymlinksAllAgreeForExternalFileLink_Issu
}
finally
{
SqliteConnection.ClearAllPools();
DeleteDirectory(projectRoot);
DeleteDirectory(outsideRoot);
}
Expand Down Expand Up @@ -1725,7 +1721,6 @@ public void Run_DryRunAndFullScan_ClassifyDanglingSymlinkAsWarning_Issue4829()
}
finally
{
SqliteConnection.ClearAllPools();
DeleteDirectory(projectRoot);
}
}
Expand Down
Loading
Loading