Characterize LivingEntity with a dedicated test suite, and add the missing src/world/__init__.py - #48
Conversation
src/world was the only package under src/ without an __init__.py, which contradicts the file-structure rule in .github/copilot-instructions.md and would leave the package out of a setuptools find_packages() build. The file carries the same two-line header as its five siblings. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
LivingEntity is the core domain class and had no dedicated test file, sitting at 53% line coverage. These 57 characterization tests assert current behavior across construction, movement rolls, action selection, reproduction, fighting, befriending, the four chance adjusters, relationship tracking, isAlive and regeneration, taking the module to 100%. No production behavior is changed. Several quirks are deliberately pinned rather than fixed: friendship is matched by name rather than identity, the "nothing" branch of getNextAction does not increment numActionsTaken, befriend permits duplicate friendships, and regenerateHealth does not check isAlive. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
A directory without __init__.py is still importable as an implicit namespace package, so nothing fails at run time and the omission goes unnoticed until packaging. This asserts the convention directly, and was confirmed to fail when src/world/__init__.py is moved aside. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Self-reviewScored against the local test suite as the external anchor, on head Anchor:
FindingsAn all-PASS table invites suspicion, so the three things that were genuinely close calls are recorded here rather than smoothed over.
Observations outside the diffRecorded here rather than as inline comments, since they fall on lines this pull request does not touch.
This review was drafted during a Gardener session (https://github.com/Stephenson-Software/gardener). drafted by Claude on behalf of Daniel Stephenson |
Summary
Two gaps in
src/structural quality, both found during the same triage pass, are addressed here.LivingEntityis now characterized end to end. The core domain class had no dedicated test file and sat at 53% line coverage, withgetNextAction,reproduce,befriend, the four chance adjusters andregenerateHealthentirely unexercised.tests/test_living_entity.pyadds 57 tests across construction, movement rolls, action selection, reproduction, fighting, befriending, behavioural-chance adjustment, relationship tracking,isAliveand regeneration.src/entity/livingEntity.pygoes from 53% to 100%; the repository total goes from 59% to 72%.src/world/__init__.pyis added.src/worldwas the only package directory undersrc/without one, which contradicts the rule stated at.github/copilot-instructions.md:39("Each module should have an__init__.pyfile"). Imports resolve today only because the directory is picked up as an implicit namespace package; a futurefind_packages()build would silently omit it while including its five siblings. The file carries the same two-line header those siblings carry and nothing else.No production behavior is changed by this pull request. Per the test-expansion convention, the new tests assert what the code does today rather than what it arguably should do.
Behavior deliberately pinned rather than fixed
Four quirks were surfaced while writing these tests. Each is asserted as-is, with a comment recording why, and none is changed here:
getNextActionis matched by name, not identity, so a distinct creature sharing a friend's name is treated as that friend. Already under discussion on Optimize simulation code #38."nothing"branch ofgetNextActionreturns beforestats.numActionsTakenis incremented, unlike every other branch. Filed as getNextAction does not count declining to fight a friend as an action, unlike its three other branches #49.befriendhas no guard against a repeat friendship, so friend lists andnumFriendshipsForgedcan both be inflated. Filed as befriend has no guard against a duplicate friendship #50.regenerateHealthdoes not checkisAlive(). This one is not filed: the sole call site,Kreatures.regenerateAllEntities, already filters onisAlive(), so the method is never reached with a dead entity. The test records the division of responsibility so a future caller does not assume the guard lives inregenerateHealth.Test plan
python3 -m compileall -q src— cleanpython3 -m pytest --verbose -vv --cov=src --cov-report=term-missing --cov-report=xml:cov.xml— 123 passed, up from 66 onmastersrc/entity/livingEntity.pyreports 100% line coverage, with no lines listed as missingblackrun against the two changed files only; no unrelated file was reformattedCloses #47
Backlog deferred this cycle
Every other open issue was left untouched, for the reasons below:
Config.maxEntitiesLimitis 200.COPYRIGHT.mdlinks to the wrong organization) —COPYRIGHT.mdis on this project's do-not-auto-merge list, so the change wants explicit human sign-off and was not folded into an autonomous cycle.copilot-instructions.mddocuments tab indentation) —.github/copilot-instructions.mdis agent-loaded configuration and requires separate, explicit authorization before being edited.This PR description was drafted during a Gardener session (https://github.com/Stephenson-Software/gardener).
drafted by Claude on behalf of Daniel Stephenson