# Protocol fixtures

QuackDB keeps binary protocol fixtures under `test/fixtures/`.

## DuckDB 2.0 server fixtures

`test/fixtures/duckdb_2_0/` holds complete response bodies captured from a real DuckDB 2.0 server, the source of truth for Quack protocol version 3. Regenerate them with:

```sh
QUACKDB_TEST_DUCKDB=/path/to/duckdb-2.0 mix run test/fixtures/duckdb_2_0/capture.exs
```

| Fixture | Covers |
| --- | --- |
| `connection_response.bin` | Protocol version 3 and the negotiated heartbeat lease |
| `error_response_catalog.bin` | Error message, exception type, and transferable extra info |
| `prepare_response_scalar.bin` | Inline scalar chunks in the DuckDB 2.0 string layout |
| `prepare_response_nested.bin` | Inline `LIST`, `STRUCT`, `ARRAY`, and `MAP` chunks |
| `fetch_response_batch.bin` | A fetch batch with its chunk blob after the body, including sequence and dictionary vectors |
| `fetch_response_terminal.bin` | The chunk-less terminal response with the batch count |
| `prepare_response_variant.bin` | Unshredded `VARIANT` scalars, objects, arrays, and NULLs |
| `prepare_response_shredded_variant.bin` | A full shredded `VARIANT` vector from checkpointed storage, with unshredded leftovers |

Tests assert decoded values rather than bytes: DuckDB compresses vectors and orders map entries in ways QuackDB does not reproduce when it re-encodes.

## quack-ts decode fixtures

`test/fixtures/quack_ts/` holds wrapped `DataChunk` fixtures generated by the independent `quack-ts` implementation. They use the pre-2.0 list layout for strings, which DuckDB 2.0 still reads, so they check that QuackDB decodes that layout to the same rows it encodes.

| Fixture | Covers |
| --- | --- |
| `data_chunk_scalar.bin` | Scalar columns |
| `data_chunk_nested.bin` | Nested columns |
| `data_chunk_bignum_extra.bin` | `BIGNUM` values |
| `data_chunk_temporal_extra.bin` | Nanosecond and time-zone temporal values and intervals |
| `data_chunk_spatial_extra.bin` | `GEOMETRY` bytes |
| `data_chunk_nested_nulls_extra.bin` | Null-heavy nested values |

## Malformed fixtures

Malformed fixtures are intentionally invalid protocol messages used to verify that the decoder rejects corrupt input with a structured `QuackDB.Error` instead of crashing or silently returning the wrong value.

| Fixture | Expected error | Invariant |
| --- | --- | --- |
| `test/fixtures/quackdb_malformed/data_chunk_bignum_bad_size.bin` | `:invalid_bignum` | `BIGNUM` payload claims a two-byte magnitude but only includes one byte. |
| `test/fixtures/quackdb_malformed/data_chunk_extra_vector.bin` | `:data_chunk_type_mismatch` | Chunk declares zero logical types but encodes one `INTEGER` vector. |
| `test/fixtures/quackdb_malformed/data_chunk_missing_vector.bin` | `:data_chunk_type_mismatch` | Chunk declares one `INTEGER` logical type but encodes zero vectors. |

Every new fixture should document the exact invariant it covers. Avoid arbitrary random corrupt bytes.
