Skip to content

Commit 8f84a1d

Browse files
test: cross-check codec classification against zarrita registry
Dev-only guard (zarrita is already a devDependency) asserting classifyCodec agrees with zarrita's actual codec kind for every registry entry, so the hand-maintained table can't silently drift.
1 parent c635cac commit 8f84a1d

1 file changed

Lines changed: 66 additions & 0 deletions

File tree

src/codecs.zarrita.test.ts

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/**
2+
* Cross-check our hand-maintained codec classification against zarrita's actual
3+
* codec registry. zarrita is a devDependency only — this coupling exists purely
4+
* to keep `classifyCodec` honest, so the runtime library stays sync and
5+
* dependency-free (see codecs.ts). If zarrita adds or re-classifies a codec,
6+
* these tests fail and prompt us to update the table deliberately.
7+
*/
8+
import { describe, it, expect } from 'vitest';
9+
import { registry } from 'zarrita';
10+
import { classifyCodec } from './codecs.js';
11+
12+
type Kind = 'array_to_array' | 'array_to_bytes' | 'bytes_to_bytes';
13+
14+
// Best-effort extraction of a codec's pipeline `kind`. `kind` is a per-instance
15+
// field, so the codec must be instantiated; some (numcodecs-backed blosc/lz4/
16+
// zstd) cannot be constructed without async wasm init, so we return undefined
17+
// and skip kind-based assertions for those — the "no unknowns" check still
18+
// covers them.
19+
async function kindOf(name: string): Promise<Kind | undefined> {
20+
try {
21+
const Codec = (await registry.get(name)?.()) as
22+
| { fromConfig: (cfg: unknown, meta: unknown) => { kind: Kind } }
23+
| undefined;
24+
if (!Codec) return undefined;
25+
const meta = { data_type: 'uint8', shape: [4, 4], chunk_shape: [2, 2], codecs: [] };
26+
for (const cfg of [{}, { endian: 'little' }, { order: [0, 1] }, { keepbits: 8 }]) {
27+
try {
28+
return Codec.fromConfig(cfg, meta).kind;
29+
} catch {
30+
/* try next config shape */
31+
}
32+
}
33+
} catch {
34+
/* codec module failed to load */
35+
}
36+
return undefined;
37+
}
38+
39+
describe('classifyCodec cross-check against zarrita registry', () => {
40+
const names = [...registry.keys()];
41+
42+
it('classifies every codec in zarrita\'s registry (no unknowns)', () => {
43+
const unknown = names.filter((n) => classifyCodec(n) === 'unknown');
44+
expect(unknown).toEqual([]);
45+
});
46+
47+
it.each(names)(
48+
'classification of "%s" is consistent with its zarrita kind',
49+
async (name) => {
50+
const kind = await kindOf(name);
51+
const classification = classifyCodec(name);
52+
53+
// array_to_array transforms and array_to_bytes serialization codecs are
54+
// never compression — misclassifying one as compression is the exact
55+
// false-incompatible bug this guards against.
56+
if (kind === 'array_to_array' || kind === 'array_to_bytes') {
57+
expect(classification).toBe('structural');
58+
}
59+
60+
// Anything we call compression must be a bytes_to_bytes codec in zarrita.
61+
if (classification === 'compression' && kind !== undefined) {
62+
expect(kind).toBe('bytes_to_bytes');
63+
}
64+
}
65+
);
66+
});

0 commit comments

Comments
 (0)