Phase 1 ticket T3. Depends on #649 (T2 CI workflow).
Context
Every per-tool ticket from T4 onward runs an integration test against the same fixture project. Without a shared fixture and assertion contract, each tool ticket has to invent its own — creating drift, duplicate work, and weak coverage. This ticket builds the fixture once so subsequent tickets can lean on it.
Scope
In:
- New
tests/mcp/fixtures/sample_project/ directory containing:
- A Python module with a known call graph:
entrypoint() → service() → repo() → db(), plus a small class hierarchy (e.g. BaseRepo ← UserRepo, OrderRepo).
- At least one Java file and one C# file with a known call graph (so the multilspy second-pass code paths are exercised).
- A handful of imports between files so
IMPORTS edges exist.
- New
tests/mcp/fixtures/expected.yaml declaring the assertion contract:
- Expected node counts per label (
File, Class, Function).
- Expected callers/callees for named symbols (e.g.
service is called by entrypoint and calls repo).
- Expected paths between named symbols (e.g.
entrypoint → ... → db).
- Expected prefix-search hits for sample prefixes.
- New
tests/mcp/conftest.py with:
- A session-scoped pytest fixture that boots a clean FalkorDB graph (using a unique graph name per test session to avoid stomping on real data).
- Indexes the sample project once via
Project.from_local_directory() + Project.analyze_sources() (api/project.py:79-94).
- Yields a handle that subsequent tests use to query the indexed graph.
- A trivial sanity test in
tests/mcp/test_fixture.py that loads expected.yaml, indexes the fixture, and asserts the actual node/edge counts match the contract — catches drift if anyone edits the fixture without updating the contract.
Out:
- Any tool implementation (T4–T8, T11).
- Per-tool tests (those land with their tools).
- Per-branch graph naming (T17 — fixture will be migrated when T17 lands).
Files to create / modify
- new
tests/mcp/fixtures/sample_project/python/entrypoint.py
- new
tests/mcp/fixtures/sample_project/python/service.py
- new
tests/mcp/fixtures/sample_project/python/repo.py
- new
tests/mcp/fixtures/sample_project/python/db.py
- new
tests/mcp/fixtures/sample_project/java/Main.java (small known call graph)
- new
tests/mcp/fixtures/sample_project/csharp/Main.cs (small known call graph)
- new
tests/mcp/fixtures/expected.yaml
- new
tests/mcp/conftest.py
- new
tests/mcp/test_fixture.py
Acceptance criteria
Dependencies
Out of scope (do NOT do in this PR)
- Tool implementations.
- Per-language additions beyond Python/Java/C# (T16 will add fixtures for the new tree-sitter languages).
- Per-branch graph naming (T17).
Notes for the implementer
- The fixture should be small but not trivial — 4-5 functions per language is enough to assert call/callers/paths/search/impact-analysis without bloating CI runtime.
- Use a unique graph name like
code:test_fixture:_default (the _default branch suffix anticipates T17 — it will line up with the per-branch convention).
- Document the fixture's call graph in a
tests/mcp/fixtures/sample_project/README.md so future contributors don't have to reverse-engineer it.
- Reference: see how
tests/endpoints/ boots and tears down test data for an existing pattern.
Phase 1 ticket T3. Depends on #649 (T2 CI workflow).
Context
Every per-tool ticket from T4 onward runs an integration test against the same fixture project. Without a shared fixture and assertion contract, each tool ticket has to invent its own — creating drift, duplicate work, and weak coverage. This ticket builds the fixture once so subsequent tickets can lean on it.
Scope
In:
tests/mcp/fixtures/sample_project/directory containing:entrypoint() → service() → repo() → db(), plus a small class hierarchy (e.g.BaseRepo←UserRepo,OrderRepo).IMPORTSedges exist.tests/mcp/fixtures/expected.yamldeclaring the assertion contract:File,Class,Function).serviceis called byentrypointand callsrepo).entrypoint → ... → db).tests/mcp/conftest.pywith:Project.from_local_directory()+Project.analyze_sources()(api/project.py:79-94).tests/mcp/test_fixture.pythat loadsexpected.yaml, indexes the fixture, and asserts the actual node/edge counts match the contract — catches drift if anyone edits the fixture without updating the contract.Out:
Files to create / modify
tests/mcp/fixtures/sample_project/python/entrypoint.pytests/mcp/fixtures/sample_project/python/service.pytests/mcp/fixtures/sample_project/python/repo.pytests/mcp/fixtures/sample_project/python/db.pytests/mcp/fixtures/sample_project/java/Main.java(small known call graph)tests/mcp/fixtures/sample_project/csharp/Main.cs(small known call graph)tests/mcp/fixtures/expected.yamltests/mcp/conftest.pytests/mcp/test_fixture.pyAcceptance criteria
Project.from_local_directory()/analyze_sources()against the FalkorDB CI service.expected.yamlis loaded and validated by a small Python helper (e.g. pydantic or dataclasses + yaml).test_fixture.pyasserts:Dependencies
Out of scope (do NOT do in this PR)
Notes for the implementer
code:test_fixture:_default(the_defaultbranch suffix anticipates T17 — it will line up with the per-branch convention).tests/mcp/fixtures/sample_project/README.mdso future contributors don't have to reverse-engineer it.tests/endpoints/boots and tears down test data for an existing pattern.