Skip to content

@moqtap/test-vectors

Canonical wire bytes + expected decoded output for every MoQT message type.

npm | GitHub

@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.

SpecDraftMessagesData streams
MoQ Transportdraft-0726 control messages3 stream types
MoQ Transportdraft-1127 control messages3 stream types
MoQ Transportdraft-1431 control messages3 stream types
MoQ Transportdraft-1524 control messages3 stream types
MoQ Transportdraft-1625 control messages3 stream types

Each draft directory is fully self-contained — no inheritance or cross-references between versions.

Terminal window
npm install --save-dev @moqtap/test-vectors

Or as a git submodule:

Terminal window
git submodule add https://github.com/moqtap/test-vectors.git test-vectors

Import 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 index
import 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';

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"
}
]
}

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.