test(ai): add unit coverage for pure helpers in ai.py (#55) #69

Merged
claude-code merged 1 commit from test/issue-55-ai-pure-helpers into main 2026-04-11 10:25:16 -06:00
Collaborator

Closes #55.

ai.py was documented as fully exempt from unit testing because the dir loop and synthesis pass require a live Anthropic API. But several helpers in the module are pure functions with no API dependency, and they're the kind of thing that breaks silently. The #57 refactor added two more (_build_dir_loop_context, _flush_partial_dir_entry) that are also naturally testable.

New file: tests/test_ai_pure.py — 45 tests across 8 helpers

Helper Cases
_should_skip_dir exact-match, *.egg-info glob, no-match (3 sub-cases)
_path_is_safe inside, nested, equals target, outside, traversal escape, sibling-with-target-prefix (the easy-to-miss security case)
_default_survey shape, zero confidence guarantees no filtering, passes through _filter_dir_tools unchanged
_format_survey_block None, empty dict, minimal, with relevant_tools, with skip_tools, with domain_notes, empty-list omission
_filter_dir_tools None, empty, low confidence, high confidence filters, protected tools never removed, unknown skip silently ignored, garbage/None confidence treated as zero, threshold boundary inclusive
_format_survey_signals None, empty, zero total_files, full, partial (only extensions)
_block_to_dict text, tool_use, unknown type
_flush_partial_dir_entry (added by #57) idempotent when entry exists, no-file-entries stub path, with-file-entries summary synthesis, notable_files collection

Uses the same _make_manager() pattern as test_cache.py to construct a _CacheManager rooted in a tempdir, sidestepping CACHE_ROOT entirely.

Doc updates

  • CLAUDE.md, README.md, docs/wiki/DevelopmentGuide.md: ai.py is no longer fully exempt. Only the API-dependent loops are. Pure helpers are covered by test_ai_pure.py. The wiki update is in a separate commit on the wiki repo.

Verification

  • 209 tests pass (164 prior + 45 new).
  • All new tests run in well under a second; no real filesystem outside tempfile.mkdtemp().

Notable

  • _filter_dir_tools was the riskiest helper per the issue, with the most branching. The threshold-boundary case (confidence == _SURVEY_CONFIDENCE_THRESHOLD) confirmed the gate is < not <= — keeping that pinned in a test makes future tweaks loud.
  • The sibling-with-target-prefix case for _path_is_safe (/tmp/foo vs /tmp/foo_sibling) is the easy-to-miss path-traversal edge case. Now pinned.
Closes #55. `ai.py` was documented as fully exempt from unit testing because the dir loop and synthesis pass require a live Anthropic API. But several helpers in the module are pure functions with no API dependency, and they're the kind of thing that breaks silently. The #57 refactor added two more (`_build_dir_loop_context`, `_flush_partial_dir_entry`) that are also naturally testable. ## New file: `tests/test_ai_pure.py` — 45 tests across 8 helpers | Helper | Cases | |---|---| | `_should_skip_dir` | exact-match, `*.egg-info` glob, no-match (3 sub-cases) | | `_path_is_safe` | inside, nested, equals target, outside, traversal escape, sibling-with-target-prefix (the easy-to-miss security case) | | `_default_survey` | shape, zero confidence guarantees no filtering, passes through `_filter_dir_tools` unchanged | | `_format_survey_block` | None, empty dict, minimal, with relevant_tools, with skip_tools, with domain_notes, empty-list omission | | `_filter_dir_tools` | None, empty, low confidence, high confidence filters, protected tools never removed, unknown skip silently ignored, garbage/None confidence treated as zero, threshold boundary inclusive | | `_format_survey_signals` | None, empty, zero total_files, full, partial (only extensions) | | `_block_to_dict` | text, tool_use, unknown type | | `_flush_partial_dir_entry` (added by #57) | idempotent when entry exists, no-file-entries stub path, with-file-entries summary synthesis, notable_files collection | Uses the same `_make_manager()` pattern as `test_cache.py` to construct a `_CacheManager` rooted in a tempdir, sidestepping `CACHE_ROOT` entirely. ## Doc updates - `CLAUDE.md`, `README.md`, `docs/wiki/DevelopmentGuide.md`: `ai.py` is no longer fully exempt. Only the API-dependent loops are. Pure helpers are covered by `test_ai_pure.py`. The wiki update is in a separate commit on the wiki repo. ## Verification - 209 tests pass (164 prior + 45 new). - All new tests run in well under a second; no real filesystem outside `tempfile.mkdtemp()`. ## Notable - `_filter_dir_tools` was the riskiest helper per the issue, with the most branching. The threshold-boundary case (`confidence == _SURVEY_CONFIDENCE_THRESHOLD`) confirmed the gate is `<` not `<=` — keeping that pinned in a test makes future tweaks loud. - The sibling-with-target-prefix case for `_path_is_safe` (`/tmp/foo` vs `/tmp/foo_sibling`) is the easy-to-miss path-traversal edge case. Now pinned.
claude-code added 1 commit 2026-04-11 10:25:11 -06:00
ai.py was documented as fully exempt from unit testing because the dir
loop and synthesis pass require a live Anthropic API. But several
helpers in the module are pure functions with no API dependency, and
they're the kind of thing that breaks silently. The #57 refactor added
two more (_build_dir_loop_context, _flush_partial_dir_entry) that are
also naturally testable.

New tests/test_ai_pure.py — 45 tests across 8 helpers:

- _should_skip_dir: exact-match, *.egg-info glob, no-match cases
- _path_is_safe: inside, nested, equals, outside, traversal,
  sibling-with-target-prefix (the easy-to-miss security case)
- _default_survey: shape, zero confidence guarantees no filtering,
  passes through _filter_dir_tools unchanged
- _format_survey_block: None, empty, minimal, with relevant_tools,
  with skip_tools, with domain_notes, empty-list omission
- _filter_dir_tools: None, empty, low confidence, high confidence
  filters, protected tools never removed, unknown skip silently
  ignored, garbage/None confidence treated as zero, threshold
  boundary inclusive
- _format_survey_signals: None, empty, zero total_files, full,
  partial (only extensions)
- _block_to_dict: text, tool_use, unknown type
- _flush_partial_dir_entry (#57): idempotent when entry exists,
  no-file-entries stub path, with-file-entries summary synthesis,
  notable_files collection

Uses the same _make_manager() pattern as test_cache.py to construct
a _CacheManager rooted in a tempdir, sidestepping CACHE_ROOT entirely.

Doc updates:
- CLAUDE.md, README.md, docs/wiki/DevelopmentGuide.md: ai.py is no
  longer fully exempt — only the API-dependent loops are. Pure
  helpers are covered by test_ai_pure.py.

Verification: 209 tests pass (164 prior + 45 new).
claude-code merged commit e9b40e00e0 into main 2026-04-11 10:25:16 -06:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: archeious/luminos#69
No description provided.