Our input and encoding helpers are validated with hand-picked examples. Property-based testing asserts invariants over thousands of generated inputs and is where encoding, boundary, and platform (posix vs Windows) bugs hide.
Proposal: add fast-check as a dev dependency plus a property-test module, kept isomorphic so it runs under Node, Bun, and the browser matrix like the rest of the suite, with a fixed seed for reproducibility.
Candidate invariants, each backed by a real SDK function:
- Filename wire-encoding round-trips: for any string,
decodeFileName(encodeFileName(s)) === s, and the encoded form never contains a raw character B2 forbids.
- SHA-1 streaming equals one-shot: for any buffer split at random chunk boundaries, feeding the chunks through
IncrementalSha1 equals sha1Hex over the whole buffer.
- Retry backoff stays in bounds: for any attempt index and
RetryOptions, the delay is non-negative, grows as documented, and never exceeds the configured cap (jitter included).
classifyError totality: for any {status, code} it returns a B2Error, preserves .status/.code, and .retryable matches isTransient(status, code).
- SSE-C keys: any 32-byte key round-trips through
EncryptionKey.fromBytes (correct MD5, redaction holds); non-32-byte inputs reject deterministically.
- Sync key/path mapping stays within the destination prefix and never emits
// or escapes the prefix.
Acceptance criteria:
fast-check added; a property test module covering the invariants above.
- Runs in the existing Node + Bun + browser flows with a fixed seed and a documented way to reproduce a failing case.
Related: the adversarial/fuzz issue shares the fast-check dependency but targets no-crash/no-injection on hostile inputs rather than invariants.
Our input and encoding helpers are validated with hand-picked examples. Property-based testing asserts invariants over thousands of generated inputs and is where encoding, boundary, and platform (posix vs Windows) bugs hide.
Proposal: add
fast-checkas a dev dependency plus a property-test module, kept isomorphic so it runs under Node, Bun, and the browser matrix like the rest of the suite, with a fixed seed for reproducibility.Candidate invariants, each backed by a real SDK function:
decodeFileName(encodeFileName(s)) === s, and the encoded form never contains a raw character B2 forbids.IncrementalSha1equalssha1Hexover the whole buffer.RetryOptions, the delay is non-negative, grows as documented, and never exceeds the configured cap (jitter included).classifyErrortotality: for any{status, code}it returns aB2Error, preserves.status/.code, and.retryablematchesisTransient(status, code).EncryptionKey.fromBytes(correct MD5, redaction holds); non-32-byte inputs reject deterministically.//or escapes the prefix.Acceptance criteria:
fast-checkadded; a property test module covering the invariants above.Related: the adversarial/fuzz issue shares the
fast-checkdependency but targets no-crash/no-injection on hostile inputs rather than invariants.