fix(persistence): complete M8 JSON store contracts (#81) #97

Merged
gronod merged 1 commits from feat/81-json-store-contracts into milestone/m8-consolidation 2026-09-11 10:38:54 +01:00
Owner

Refs #81

Gap fixes

  • JSONFileStore: centralised JSONEncoder creation — a single internal JSONEncoder.icceryPretty(dateEncoding:) helper now owns the .prettyPrinted + .sortedKeys configuration; the duplicate encoder path is removed and PresetStore.export resolves to the same helper.
  • VerificationHistoryStore.clear(): now calls load() before writing. A corrupt/unreadable history file propagates the error, leaves the on-disk bytes and in-memory cache untouched, and no replacement file is written.
  • ISO-8601 formatting maintained for history timestamps; settings order stays validate → atomic write → notification; .replaceWithDefault kept for settings/wizard, .throwCorrupt for history.

Target files

  • Packages/ICCeryCore/Sources/ICCeryCore/Files/JSONFileStore.swift
  • Packages/ICCeryCore/Sources/ICCeryCore/Profile/VerificationHistoryStore.swift
  • Packages/ICCeryCore/Sources/ICCeryCore/Settings/PresetStore.swift
  • Tests/ICCeryCoreTests/JSONFileStoreTests.swift
  • Tests/ICCeryCoreTests/SettingsTests.swift
  • Tests/ICCeryCoreTests/WizardGatingTests.swift
  • Tests/ICCeryCoreTests/VerificationHistoryStoreTests.swift

Tests added/updated

  • Missing file returns default (JSONFileStore).
  • .replaceWithDefault returns default on corrupt JSON and leaves file bytes unchanged.
  • .throwCorrupt throws on corrupt JSON and leaves bytes unchanged (existing, retained).
  • Pretty output contains newlines and asserts lexical ordering of top-level keys.
  • Invalid settings save over an existing valid file throws, preserves original bytes, and emits no success notification.
  • Corrupt wizard JSON returns .default without overwriting corrupt bytes.
  • Wizard session mode + calibrationOriginalBasename round-trip (existing roundTrip, retained).
  • Malformed history file: load(), append(), and clear() all throw with bytes unchanged.
  • History ISO-8601 timestamp round-trips through a fresh store.

Test gate

xcodebuild test -scheme ICCery -only-testing:ICCeryCoreTests/{JSONFileStoreTests,SettingsStoreTests,WizardStateStoreTests,VerificationHistoryStoreTests,PresetStoreTests}25/25 passed, 0 failures (DerivedData-feat-81-json-store-contracts, universal arm64+x86_64).

Refs #81 ## Gap fixes - `JSONFileStore`: centralised `JSONEncoder` creation — a single internal `JSONEncoder.icceryPretty(dateEncoding:)` helper now owns the `.prettyPrinted` + `.sortedKeys` configuration; the duplicate encoder path is removed and `PresetStore.export` resolves to the same helper. - `VerificationHistoryStore.clear()`: now calls `load()` before writing. A corrupt/unreadable history file propagates the error, leaves the on-disk bytes and in-memory cache untouched, and no replacement file is written. - ISO-8601 formatting maintained for history timestamps; settings order stays validate → atomic write → notification; `.replaceWithDefault` kept for settings/wizard, `.throwCorrupt` for history. ## Target files - `Packages/ICCeryCore/Sources/ICCeryCore/Files/JSONFileStore.swift` - `Packages/ICCeryCore/Sources/ICCeryCore/Profile/VerificationHistoryStore.swift` - `Packages/ICCeryCore/Sources/ICCeryCore/Settings/PresetStore.swift` - `Tests/ICCeryCoreTests/JSONFileStoreTests.swift` - `Tests/ICCeryCoreTests/SettingsTests.swift` - `Tests/ICCeryCoreTests/WizardGatingTests.swift` - `Tests/ICCeryCoreTests/VerificationHistoryStoreTests.swift` ## Tests added/updated - Missing file returns default (`JSONFileStore`). - `.replaceWithDefault` returns default on corrupt JSON and leaves file bytes unchanged. - `.throwCorrupt` throws on corrupt JSON and leaves bytes unchanged (existing, retained). - Pretty output contains newlines and asserts lexical ordering of top-level keys. - Invalid settings save over an existing valid file throws, preserves original bytes, and emits no success notification. - Corrupt wizard JSON returns `.default` without overwriting corrupt bytes. - Wizard session mode + `calibrationOriginalBasename` round-trip (existing `roundTrip`, retained). - Malformed history file: `load()`, `append()`, and `clear()` all throw with bytes unchanged. - History ISO-8601 timestamp round-trips through a fresh store. ## Test gate `xcodebuild test -scheme ICCery -only-testing:ICCeryCoreTests/{JSONFileStoreTests,SettingsStoreTests,WizardStateStoreTests,VerificationHistoryStoreTests,PresetStoreTests}` — **25/25 passed, 0 failures** (DerivedData-feat-81-json-store-contracts, universal arm64+x86_64).
gronod added 1 commit 2026-09-11 10:35:07 +01:00
gronod self-assigned this 2026-09-11 10:35:15 +01:00
gronod added this to the M7 — Deduplicate & consolidate (develop) milestone 2026-09-11 10:35:16 +01:00
gronod merged commit bb4512e129 into milestone/m8-consolidation 2026-09-11 10:38:54 +01:00
Sign in to join this conversation.
No Reviewers
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: gronod/iccery-v2-mac#97