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
2 changes: 2 additions & 0 deletions TESTING_GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ Use the full suite by default. Use targeted filters only while iterating locally

## Test Stack

- Issue #5128 compact graph zero-result coverage belongs in `JsonEnvelopeWrapperIssue4585Tests.cs`. Keep `callees` aligned with `references` and `callers` by asserting an empty compact location envelope and zero returned/total cardinality both with and without explicit `--fields`, while reusing the graph-ready bounded-response fixture.
- Issue #5098 inspect projection coverage belongs in `QueryCommandRunnerInspectTests.cs`. Keep one graph-ready partial-type fixture covering canonical and alias selectors, multiple leaves across collections, parent-over-child precedence, stable row order, empty arrays, compact truncation, byte bounds, body paging/recovery, partial-family metadata, queryless catalog discovery, and typed unknown parent/leaf errors. `ConsoleUiTests.cs` separately pins the `<csv|list>` usage, nested-field help text, and examples.
- Path-containment coverage for #5091 pairs platform-independent `PathCasingTests` seams for mixed parent-namespace case policies and directory identities with `FileIndexerTests` integration through an internal file symlink. Keep both checks when changing internal-symlink policy: a case-insensitive project mount must not make a distinct case-only sibling in its case-sensitive parent namespace appear internal, while genuine same-namespace aliases remain accepted.
- `WorkspaceCheckTruncationIssue5055Tests` owns the bounded `workspace_check` list contract. Keep zero, below-limit, exact-limit, and over-limit coverage for all six categories, plus the 1260/20/1240 example and one shared filesystem fixture for raw JSON, list-only projection, compact output, byte-budget trimming, deterministic order, and human sample labeling.
Expand Down Expand Up @@ -1113,6 +1114,7 @@ dotnet test --filter "FullyQualifiedName~GitHelperTests"

## テストスタック

- Issue #5128 の compact graph 0件 coverage は `JsonEnvelopeWrapperIssue4585Tests.cs` が担当します。graph-ready な bounded-response fixture を再利用し、明示的な `--fields` の有無の両方で、`callees` が `references` / `callers` と同様に空の compact location envelope と返却件数・総件数0を維持することを検証してください。
- Issue #5098 の inspect projection coverage は `QueryCommandRunnerInspectTests.cs` が担当します。graph-ready な partial type fixture 1つで canonical / alias selector、collection をまたぐ複数 leaf、parent の child に対する優先、安定した row 順、空配列、compact truncation、byte 上限、body paging / recovery、partial-family metadata、query 不要の catalog discovery、未知 parent / leaf の型付き error を維持してください。`ConsoleUiTests.cs` では `<csv|list>` usage、nested-field help text、例を別途固定します。
- #5091 の path containment coverage は、親 directory namespace の case policy と directory identity が混在する状況を OS 非依存で再現する `PathCasingTests` の seam と、内部 file symlink を通す `FileIndexerTests` の integration を対にします。internal-symlink policy を変更するときは両方を維持し、case-insensitive な project mount の policy で、case-sensitive な親 namespace にある別 identity の case-only sibling を内部 path と誤認しないこと、および同一 namespace の正当な alias は引き続き受理されることを検証してください。
- `WorkspaceCheckTruncationIssue5055Tests` は上限付き `workspace_check` 一覧の契約を担当します。6カテゴリすべての0件・上限未満・上限一致・上限超過、1260/20/1240 の例、および raw JSON、一覧単独 projection、compact 出力、byte budget による短縮、決定的順序、human 向け sample 表示を1つの共有 filesystem fixture で検証する coverage を維持してください。
Expand Down
16 changes: 16 additions & 0 deletions changelog.d/unreleased/5128.fixed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
category: fixed
issues:
- 5128
affected:
- src/CodeIndex/Cli/QueryCommandRunner.Graph.cs
- tests/CodeIndex.Tests/JsonEnvelopeWrapperIssue4585Tests.cs
---

## English

- **Zero-match `callees` queries now preserve the empty compact envelope (#5128)** — compact JSON output reports `count: 0` with an empty `results` array, including bounded projections that use `--fields` or `--max-json-bytes`, instead of fabricating one empty row.

## 日本語

- **0件の `callees` query が空の compact envelope を維持するようになりました (#5128)** — compact JSON 出力は、`--fields` や `--max-json-bytes` を使う bounded projection を含め、空の row を1件生成せず、空の `results` 配列と `count: 0` を返します。
2 changes: 2 additions & 0 deletions src/CodeIndex/Cli/QueryCommandRunner.Graph.cs
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,8 @@ public static int RunCallees(string[] cmdArgs, JsonSerializerOptions jsonOptions
WriteHdlGraphContractWarningIfNeeded(options.Json, hdlGraphSignal);
if (results.Count == 0)
{
if (options.Json && TryWriteEmptyFormattedResult(options, jsonOptions))
return ZeroResultExitCode(options);
if (options.Json)
WriteGraphZeroJsonResult(reader, "callees", jsonOptions, graphAvailable: reader._hasReferencesTable, exact ? exactSignal : (ExactQuerySignal?)null, exactZeroHint, queryOptions: options, extraFields: payload => AddGraphContractJsonFields(payload, reader, jsonOptions, sqlGraphSignal, hdlGraphSignal));
else if (!options.Json)
Expand Down
28 changes: 28 additions & 0 deletions tests/CodeIndex.Tests/JsonEnvelopeWrapperIssue4585Tests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,34 @@ public sealed class Consumer
Assert.True(document.RootElement.GetProperty("results")[0].TryGetProperty("file", out _));
}
}

var zeroCalleeCases = new[]
{
new[]
{
"callees", "DefinitelyNoSuchSymbol", "--exact-name", "--json", "--compact",
"--limit", "1", "--max-json-bytes", "8192", "--db", dbPath,
},
new[]
{
"callees", "DefinitelyNoSuchSymbol", "--exact-name", "--json", "--compact",
"--fields", "path,line", "--limit", "1", "--max-json-bytes", "8192", "--db", dbPath,
},
};
foreach (var args in zeroCalleeCases)
{
var (exitCode, stdout, stderr) = CaptureConsole(() => ProgramRunner.Run(args, _jsonOptions, "1.0.0-test"));

Assert.Equal(CommandExitCodes.Success, exitCode);
Assert.Equal(string.Empty, stderr);
using var document = JsonDocument.Parse(stdout);
var root = document.RootElement;
Assert.Equal("compact", root.GetProperty("format").GetString());
Assert.Equal(0, root.GetProperty("count").GetInt32());
Assert.Empty(root.GetProperty("results").EnumerateArray());
Assert.Equal(0, root.GetProperty("metadata").GetProperty("result_count").GetInt32());
Assert.Equal(0, root.GetProperty("metadata").GetProperty("total_count").GetInt32());
}
}
finally
{
Expand Down
Loading