Skip to content

Expand unit tests for milestone/achievement helpers - #222

Merged
dmccoystephenson merged 1 commit into
mainfrom
feature/achievements-test-expansion
Oct 9, 2026
Merged

dmccoystephenson merged 1 commit into
mainfrom
feature/achievements-test-expansion

Conversation

@dmccoystephenson

Copy link
Copy Markdown
Member

Summary

Stage B (unit-test expansion) cycle targeting src/achievements/achievements.py. Before this PR the module (238 lines) was covered by 4 tests in tests/achievements/test_achievements.py. arcadeIdForName had no direct test, and the integrity of the MILESTONES data table was not checked anywhere.

15 characterization tests are added. Production code is not changed.

  • Data-integrity guards on MILESTONES: every stat is a real Stats attribute. This matters because isEarned falls back to 0 through getattr, so a typo in stat would make a milestone silently impossible to earn. The guards also check that milestone names are unique and do not collide with GOAL_MILESTONE_NAME (these names are what stats.earnedMilestones persists), and that every threshold is positive and every description is non-empty.
  • isEarned: a missing stat is not earned.
  • getMilestoneStatuses: the order matches MILESTONES, earned flags are correct, and nothing is recorded on stats.earnedMilestones.
  • getNewlyEarned: several milestones earned at once come back in MILESTONES order. Milestones already recorded by a loaded save are skipped. A fresh game returns nothing.
  • arcadeIdForName: maps the goal, maps a milestone that has an arcade id, and returns None for a milestone without an arcade id and for an unknown name.
  • arcadeDeclarations: milestones come first, then the goal, then retirement, with exact goal/retired entries. Title, description and hidden flags come from each milestone. This complements the id-validity checks already in tests/achievements/test_arcade.py.

No tracking issue: the issue backlog was empty at triage, so this cycle was given to test expansion. Every new test passed against the unchanged code, and no bug was found.

Test plan

  • python3 -m pytest tests/achievements/test_achievements.py: 19 passed (4 existing + 15 new)
  • Full suite locally (dummy SDL drivers): 979 passed, 1 failed. The failure is tests/test_saveFileManager.py::test_migrate_old_save_files_skips_a_slot_holding_any_file. It is caused by the sandbox's locally installed editable tak 0.1.1 instead of the commit pinned in requirements.txt, and is unrelated to this test-only diff. CI installs the pinned tak and is the authoritative anchor.
  • CI Run Unit Tests green on the PR head

This PR description was drafted during a Gardener session (https://github.com/Stephenson-Software/gardener).

🤖 Generated with Claude Code


drafted by Claude on behalf of Daniel Stephenson

Cover arcadeIdForName, the ordering and recording behaviour of
getNewlyEarned/getMilestoneStatuses, isEarned on a missing stat, and
data-integrity guards on MILESTONES (every stat exists on Stats, names
are unique and distinct from the goal, thresholds are positive).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@dmccoystephenson

Copy link
Copy Markdown
Member Author

Self-review rubric (Stage B, test-only diff):

  • Scope: PASS. gh pr diff 222 touches only tests/achievements/test_achievements.py (+219 lines, all new test functions). No production code, formatting churn or renames.
  • Tests-new: PASS (not applicable as a gate). No new public functions were added. All 15 new tests target existing functions in src/achievements/achievements.py; arcadeIdForName had no direct test before this PR.
  • Tests-fix: not applicable. No bug fix is included, and every new test passes against the unchanged production code (characterization tests).
  • Sibling structure: PASS. The new tests follow the file's existing createStats() factory and the # prepare / # call / # check layout, with test_<behavior> names.
  • Sibling renames: not applicable. Nothing was renamed.
  • Docs: PASS. The Phase 7 table was checked: no README feature, schema, PLANNING goal or version is affected by a test-only change.
  • Issue resolution: not applicable. There is no Closes reference; the issue backlog was empty at triage.
  • CI: PASS. Run Unit Tests on the PR head ran 980 tests, all passing (run 37902542304). The "Upload coverage reports" step logs a Codecov tokenless-upload error, but the job still succeeds; this matches the run on main and carries no signal for this diff.
  • Schema-sync: not applicable. No persisted fields were touched.
  • Money-format: not applicable. No displays were touched.
  • Deterministic-tests: PASS. The new tests use no randomness; they set Stats attributes directly.
  • Headless-pygame: not applicable. No pygame code path is involved.
  • camelCase: PASS. Locals such as expectedMilestoneIds and byId follow camelCase, as in the existing tests.

Judgment call flagged for the reviewer:

  • tests/achievements/test_achievements.py — test_every_milestone_has_a_positive_threshold_and_a_description makes it an invariant that no milestone has a threshold of 0. Today's data satisfies this. A future deliberate "free on day one" milestone would need to update this test.

Out-of-diff observation: locally, tests/test_saveFileManager.py::test_migrate_old_save_files_skips_a_slot_holding_any_file fails against the sandbox's editable tak 0.1.1. CI, which installs the tak commit pinned in requirements.txt, passes it. This is environmental and has no bearing on this PR.

Summary: a test-only expansion of the achievements helpers. CI is green with 980 tests, and the PR is ready to merge.

This review was drafted during a Gardener session (https://github.com/Stephenson-Software/gardener).


drafted by Claude on behalf of Daniel Stephenson

@dmccoystephenson
dmccoystephenson merged commit 5c6bc93 into main Oct 9, 2026
1 check passed
@dmccoystephenson
dmccoystephenson deleted the feature/achievements-test-expansion branch October 9, 2026 08:04
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.

1 participant