Validate loaded save data against schemas; wire Config into Player/SaveFileManager#115
Conversation
…/SaveFileManager Closes #111 Closes #109 - Add a validate_against_schema() helper and call it from each *JsonReaderWriter's create*FromJson after applying the existing .get()-with-defaults fallback, so a save missing keys still loads (backwards compatibility), while out-of-range/wrong-type values that were present are rejected with a jsonschema ValidationError instead of surfacing later as e.g. a ValueError deep in housing.py. - Catch that ValidationError in FishE.loadPlayer/loadStats/loadTimeService the same way IOError/JSONDecodeError are already caught, falling back to a fresh default object. - Construct a Config in FishE.__init__ and thread it into SaveFileManager's data_directory and Player's starting money/fishCount/moneyInBank/ fishMultiplier/priceForBait, turning Config from dead code into an actual session-level override (energy deliberately stays governed by the housing ladder, not Config.initialEnergy - see the comment in Player.__init__). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
{ |
|
Self-review: no issues found. Verified backwards compatibility (missing-key saves still load via the existing .get()-with-defaults fallback; validation only runs against the reconstructed object, not the raw input, so it cannot reject a save merely for omitting optional keys). Verified Config.initialEnergy (100) intentionally is not wired into Player, since it would let a configured player exceed the Homeless housing tier's real energy cap (60) - see the comment in Player.init. Confirmed this is backend-only (no front-end-visible menu/dialogue), so no console/pygame/web parity work is needed. Full suite green (345 passed) with 100% coverage on every newly-touched module. |
|
(Ignore the raw-JSON comment above - it was an artifact from an earlier attempt to post this same self-review through the reviews API; the review content is in the comment below it.) |
Summary
validate_against_schema()helper (src/validation/schemaValidator.py) and call it from each*JsonReaderWriter'screate*FromJson, after the existing.get()-with-defaults fallback runs — so a save missing keys still loads fine (backwards compatibility is untouched), but an out-of-range or wrong-type value that was present (e.g.energy: -500,homeTier: 99, a stringified stat) is now rejected with ajsonschema.exceptions.ValidationErrorinstead of silently loading and surfacing later as an uncaughtValueErrordeep inhousing.py/business.py.ValidationErrorinFishE.loadPlayer/loadStats/loadTimeServicethe same wayIOError/JSONDecodeErrorare already caught — falls back to a fresh default object plus the existing warning print, no new failure mode.Config()inFishE.__init__and thread it through:SaveFileManager(data_directory=config.dataDirectory), and an optionalPlayer(config=None)parameter that seedsmoney/fishCount/moneyInBank/fishMultiplier/priceForBaitfrom it (defaulting to today's literals when omitted, so every existing caller/test is unaffected). This turnsConfigfrom dead code into an actual session-level override, matching the patternPlayer.operatorModealready uses forFISHE_OPERATOR_MODE.energyis deliberately not sourced fromConfig.initialEnergy— the housing ladder (housing.HOUSING_TIERS[0]["maxEnergy"], currently 60) is the real source of truth for starting energy, andConfig.initialEnergy(100) predates/ignores that and would let a configured player start above the Homeless cap. See the comment inPlayer.__init__.Closes #111
Closes #109
Test plan
python3 -m compileall -q src testspytest --verbose -vv --cov=src --cov-report=term-missing --cov-report=xml:cov.xml→ 345 passed, 100% coverage on all newly-touched modules (schemaValidator.py, the three*JsonReaderWriters)ValidationErrorin each reader/writer;FishE.loadPlayerrecovers gracefully from an out-of-range save;Player(config)seeds from a customConfigwhilePlayer()is unaffected;FishE.__init__wiresself.configintoSaveFileManagerandPlayer