Skip to content

test: smoke tests for update.py — last uncovered module#12

Open
bipinhcs11 wants to merge 3 commits into
mainfrom
test/update-module-smoke-tests
Open

test: smoke tests for update.py — last uncovered module#12
bipinhcs11 wants to merge 3 commits into
mainfrom
test/update-module-smoke-tests

Conversation

@bipinhcs11
Copy link
Copy Markdown
Owner

@bipinhcs11 bipinhcs11 commented May 18, 2026

What

Adds tests/test_update.py — 38 stdlib-only smoke tests for tools/skill_generator/update.py, which was the only module in the package with zero test coverage.

Why

update.py is the Phase-2 hot path: it maps changed files to features, bumps versions, rewrites last_updated, and writes refreshed SKILL.mds. Silent bugs here corrupt the skills that every AI session depends on. The existing suite covered crawler, plan, generate, link, validate, and doctorupdate was the gap.

What is tested

Class Coverage
TestBumpVersion (5 tests) Version field present; version 1→2; field absent (fallback to 1); version 0→1; first frontmatter occurrence wins over later body mention
TestDomainFromSkill (8 tests) feature_id used as id and name; description always ""; Java class names extracted; XML/SQL/shell sources extracted with ": from prior skill" suffix; empty text → empty classes; duplicate class names deduplicated
TestResolveSkillsDir (3 tests) .github/skills/ preferred over skills/; skills/ used when .github/skills/ absent; None when neither exists
TestMapFilesToFeatures (6 tests) Empty changed-files list; basename match across deep path; unmatched file absent from result; shared file maps to multiple features; XML file matched; missing skills dir returns {}
TestIngestResponses (7 tests) Version bumped to existing+1; last_updated rewritten to today; missing response → failed[]; missing existing SKILL.md → failed[]; empty/whitespace response → failed[]; markdown fence stripped before write; two-feature batch update
TestIngestResponsesForceCorrections (2 tests) AI returning wrong version number corrected to existing+1; stale last_updated in AI response replaced with today
TestIngestResponsesFeatureFilter (2 tests) feature= kwarg restricts updates to one feature; no filter updates all
TestGitChangedFiles (5 tests) Happy-path diff returns file list; blank lines stripped; CalledProcessError triggers git status fallback; empty diff output also triggers fallback (not silent []); --porcelain 3-char prefix parsed correctly — uses unittest.mock to stay hermetic

All ingest tests use validate_schema=False to isolate update logic from the validator (which has its own 40-test suite in test_validate.py).

Suite size

172 → 210 tests, all green.

Follow-ups noted (not in this PR)

  • emit_prompts integration test (requires a crawled index + skills dir) — could be added alongside the generate-emit integration tests if those are ever added.
  • The _normalize_java_version edge case for "V11" (capital-V prefix, not VERSION_) is worth adding to test_crawler.py.

update.py had zero test coverage despite being the Phase-2 hot path.
Adds 29 stdlib-only tests across four test classes:

  TestBumpVersion       — version parsing + fallback when field absent
  TestDomainFromSkill   — class/XML/SQL/shell extraction; dedup invariant
  TestResolveSkillsDir  — .github/skills/ preferred; None when absent
  TestMapFilesToFeatures — basename matching; multi-feature; unmatched

Plus seven ingest_responses integration tests (validate_schema=False):
version bump to existing+1, last_updated rewritten to today, failed[]
entries for missing response / missing skill / empty response, markdown-
fence stripping, no-skills-dir guard, and multi-feature batch update.

Total suite: 172 → 201 tests.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

https://claude.ai/code/session_01V3GMvToFpDMsnSbSe2Fsgp
…verage

PR #12 added 29 smoke tests for update.py.  This commit adds 4 more that
cover two safety-critical code paths which were not yet exercised:

Force-correction regressions (TestIngestResponsesForceCorrections):
- AI response says "version: 99" but existing skill is version: 3
  → ingest must write version: 4, not 99 or 100.  Verifies the forced
  re.sub always wins regardless of what the AI wrote.
- AI response has a stale last_updated (e.g. 2020-06-15)
  → ingest always rewrites to today.  Verifies the second forced re.sub.

Feature-filter isolation (TestIngestResponsesFeatureFilter):
- feature="alpha" with two response files → only alpha updated, beta untouched
- No feature kwarg → both features updated (batch path)

These cover the two `re.sub` force-overwrite lines in ingest_responses
(lines 224-237 of update.py) and the feature= conditional on line 203,
none of which were reached by the previous test set.

Suite: 29 → 33 tests for update.py; 201 → 205 total, all green.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The existing test_update.py (added in this branch) covered all pure
helpers and the ingest integration path, but left _git_changed_files
untested because it calls subprocess.  Add TestGitChangedFiles (5 tests)
using unittest.mock to keep the suite hermetic:

  - success path returns the diff file list, stripping blank lines
  - CalledProcessError on git-diff triggers the git-status fallback
  - empty diff output (shallow clone / single-commit repo) also triggers
    the fallback rather than silently returning []
  - git status --porcelain 3-char prefix is parsed correctly

Total suite: 210 tests (was 205 before this change, 172 before the branch).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants