test: add property-based tests for import normalization and chunking invariants#57
Conversation
…invariants Adds fast-check (devDependency) and two focused property suites per issue #44: - tests/lib/chunk.property.test.ts — chunked() order preservation, exactly-once processing via flatten round-trip, chunk-count formula, boundary lengths 0/1/499/500/501/999/1000/1001 plus larger N (bounded at 2,500), RangeError on invalid sizes, input non-mutation. - tests/lib/conversation-import.property.test.ts — shared normalizeSession contract across all three source adapters (required fields preserved or derived, sanitized session IDs, sorted timestamps, message stamping), whitespace-only and empty conversations rejected, unrecognized input rejected deterministically by every adapter, and parse determinism for fully-timestamped payloads. Export (#43) and dedup (#45) property groups are deferred until those issues land, per the dependency note on #44.
Review — PR #57 (property-based tests for import normalization + chunking)Verified independently before this review:
This is strong work — disciplined scope, bounded generators, the shared Blocking1. 2. Timestamp values are never pinned — a parser that stamps every message with 3. claude-ai role mapping ( Non-blocking suggestions
VerdictREQUEST CHANGES — the invariant architecture is sound and mutation-verified, but items 2–3 leave two of #44's "required fields preserved/derived correctly" criteria (timestamps, claude-ai roles) silently corruptible across the whole repo suite, and item 1 would auto-close a tracking issue that must stay open. All three are small, contained fixes; happy to re-review immediately after. |
…ontent) tuples Addresses PR #57 review blocking items 2 and 3: the content-only multiset comparison was blind to a parser restamping every message with the fallback timestamp, and claude-ai's human→user role mapping was asserted nowhere in the repo. The shared expectMessageTuples helper now compares multisets of JSON-encoded (role, timestamp, content) tuples for all three adapters. Mutation-verified: fallbackNow restamping fails 4 properties; human→assistant mis-mapping fails the claude-ai property.
|
Review blocking items addressed in 4a29472:
Gates re-verified at head: |
Re-review — delta at
|
Part of #44 — completes the unblocked import + chunking property groups; the issue stays open to track the export (#43) and dedup (#45) groups.
Summary
Adds
fast-check(devDependency, Bun-compatible, runs underbun:test) and two focused property-based test suites covering the groups of #44 that are currently unblocked. Property oracles are implemented independently on generator inputs (spec restated, not implementation mirrored), and a manual mutation check (i += size→i += size + 1inchunked) confirmed the chunking properties fail loudly on an exactly-once/order bug.Chunking properties —
tests/lib/chunk.property.test.tssizeSQLITE_SAFE_CHUNK_SIZERangeErroron every non-positive/non-integer size (incl. NaN/±Infinity); input never mutatedImport normalization properties —
tests/lib/conversation-import.property.test.tsnormalizeSessioncontract across all three source adapters (table-driven for claude-ai/chatgpt; slack separate for its single-session/path-derived semantics): sanitized + prefixed session IDs, trimmed non-empty titles, project derivation incl. empty-string fallback,startedAt/endedAtfrom sorted message timestamps, every message stamped with session ID/project/valid role/non-empty contentnew Date()fallback in the parsers, which would make determinism assertions meaningless)Deferred scope (per #44 dependencies)
Issue #44 should stay open-tracked for those two groups; this PR completes only the currently unblocked import + chunking groups (chunking helper from #41/PR #55, adapter registry from PR #56).
Testing
bun run lintclean (tsc --noEmit)Post-Deploy Monitoring & Validation
No additional operational monitoring required — test-only change plus a devDependency; no runtime code touched. CI green on both platforms is the validation signal.