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: 5 additions & 1 deletion REQUIREMENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

> **Note:** This document is automatically generated and verified against the live test suite by `scripts/generate_requirements.py` and `tests/backend/test_requirements_sync.py`.

**Test Verification Baseline:** **1185 Automated Tests** (821 Pytest Backend + 314 Vitest Frontend + 50 Playwright E2E).
**Test Verification Baseline:** **1187 Automated Tests** (823 Pytest Backend + 314 Vitest Frontend + 50 Playwright E2E).

---

Expand Down Expand Up @@ -1399,6 +1399,10 @@ over the PostgresConnectionAdapter using an initialized test engine._
- `test_upsert_reports_failure_when_every_record_is_rejected`
- `test_rejected_record_warnings_do_not_log_the_chunk_text`

#### `tests/test_trace_path_case_insensitive.py` (2 tests)
- `test_lowercase_symbol_resolves_to_the_indexed_symbol`
- `test_graph_traversal_sql_has_no_sqlite_only_collation`

#### `tests/test_trace_path_compact.py` (3 tests)
- `test_trace_nodes_have_no_permalinks_by_default_but_the_target_keeps_one`
- `test_include_permalinks_returns_them_on_every_node`
Expand Down
4 changes: 2 additions & 2 deletions app/services/graph_traversal.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ def trace_symbol_path(
if not symbols_found:
nc_query = (
"SELECT id, repo, filepath, name, full_symbol, kind, start_line, end_line, signature "
"FROM ast_symbols WHERE (name = ? COLLATE NOCASE OR full_symbol = ? COLLATE NOCASE OR full_symbol LIKE ? COLLATE NOCASE)"
"FROM ast_symbols WHERE (LOWER(name) = LOWER(?) OR LOWER(full_symbol) = LOWER(?) OR LOWER(full_symbol) LIKE LOWER(?))"
+ repo_sql
)
symbols_found = conn.execute(nc_query, [target_sym, target_sym, f"%.{target_sym}"] + repo_arg).fetchall()
Expand All @@ -107,7 +107,7 @@ def trace_symbol_path(
if not rel_hit:
rel_hit = conn.execute(
"SELECT source_symbol, target_symbol FROM ast_relationships "
"WHERE (source_symbol = ? COLLATE NOCASE OR target_symbol = ? COLLATE NOCASE)"
"WHERE (LOWER(source_symbol) = LOWER(?) OR LOWER(target_symbol) = LOWER(?))"
+ repo_sql + " LIMIT 1",
[target_sym, target_sym] + repo_arg,
).fetchone()
Expand Down
22 changes: 22 additions & 0 deletions tests/test_trace_path_case_insensitive.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
"""trace_path: a symbol in another letter case resolves, with SQL that PostgreSQL accepts (no SQLite-only COLLATE NOCASE)."""

import inspect
import json

import app.services.graph_traversal as graph_traversal
from app.services.graph_traversal import trace_symbol_path

# Same database setup as the DI caller tests: the method rows and CALLS rows of a small C# graph.
from tests.test_trace_path_di_callers import REPO, di_graph # noqa: F401 (pytest fixture)


def test_lowercase_symbol_resolves_to_the_indexed_symbol(di_graph): # noqa: F811
result = json.loads(trace_symbol_path(symbol="assistantservice.publishinstance", repo=REPO, direction="callers", depth=1))
assert "error" not in result
assert result["target"]["symbol"] == "AssistantService.PublishInstance"
assert [c["symbol"] for c in result["callers"]] == ["AssistantsController.PublishInstance"]


def test_graph_traversal_sql_has_no_sqlite_only_collation():
# PostgreSQL rejects `COLLATE NOCASE` ("collation nocase for encoding UTF8 does not exist").
assert "NOCASE" not in inspect.getsource(graph_traversal).upper()
Loading