@moqtap/test-vectors
Canonical wire bytes + expected decoded output for every MoQT message type.
What it is
Section titled “What it is”@moqtap/test-vectors is a language-agnostic test suite for MoQT codec implementations. Each vector pairs hex-encoded wire bytes with the expected decoded representation, so any implementation — Rust, Go, TypeScript, Python, C — can validate its parser and serializer against a shared, authoritative data set.
The package ships pure JSON files with zero runtime dependencies.
Coverage
Section titled “Coverage”| Spec | Draft | Messages | Data streams |
|---|---|---|---|
| MoQ Transport | draft-07 | 26 control messages | 3 stream types |
| MoQ Transport | draft-11 | 27 control messages | 3 stream types |
| MoQ Transport | draft-14 | 31 control messages | 3 stream types |
| MoQ Transport | draft-15 | 24 control messages | 3 stream types |
| MoQ Transport | draft-16 | 25 control messages | 3 stream types |
Each draft directory is fully self-contained — no inheritance or cross-references between versions.
Installation
Section titled “Installation”npm install --save-dev @moqtap/test-vectorsOr as a git submodule:
git submodule add https://github.com/moqtap/test-vectors.git test-vectorsImport a vector file and iterate the vectors array:
import vectors from '@moqtap/test-vectors/transport/draft14/codec/messages/subscribe.json';
for (const v of vectors.vectors) { const bytes = hexToBytes(v.hex); const isCanonical = v.canonical ?? true;
if (v.decoded) { // Valid vector — test decode const result = decodeMessage(bytes); expect(result).toEqual(v.decoded);
// Canonical vectors also test encode if (isCanonical) { const reEncoded = encodeMessage(result); expect(bytesToHex(reEncoded)).toBe(v.hex); } } else if (v.error) { // Invalid vector — must reject expect(() => decodeMessage(bytes)).toThrow(); }}Available exports:
import manifest from '@moqtap/test-vectors/manifest'; // spec/version indeximport subscribe from '@moqtap/test-vectors/transport/draft14/codec/messages/subscribe.json';import varint from '@moqtap/test-vectors/transport/draft14/codec/varint.json';import subgroup from '@moqtap/test-vectors/transport/draft14/codec/data-streams/subgroup.json';Vector format
Section titled “Vector format”Each file contains a vectors array. Valid vectors have a decoded object; invalid vectors have an error category. These are mutually exclusive.
{ "message_type": "subscribe", "message_type_id": "0x03", "vectors": [ { "id": "filter-latest-group", "description": "SUBSCRIBE with LatestGroup filter", "hex": "0300120101046c69766505766964656f8000000100", "decoded": { "request_id": "1", "track_namespace": ["live"], "track_name": "video", "subscriber_priority": "128", "group_order": "0", "forward": "0", "filter_type": "1", "parameters": {} } }, { "id": "truncated", "description": "truncated SUBSCRIBE — missing track_name", "hex": "0300120101046c697665", "error": "incomplete" } ]}Key conventions
Section titled “Key conventions”Integers are strings. All protocol values — VarInts, error codes, status codes — are JSON strings to avoid IEEE 754 precision loss on 64-bit values.
Bidirectional by default. Valid vectors test both decode(hex) == decoded and encode(decoded) == hex. Vectors marked "canonical": false are decode-only (valid but non-minimal encodings).
Numeric, not symbolic. Error codes and filter types use numeric strings matching the wire values. The description field names the constant for readability.
Test vectors cover codec correctness only — wire encoding and decoding of individual messages. They do not test session state machines, transport behavior, or media-layer concerns.