Validate Vega + Vega-Lite specifications against the JSON Schema (vega.github.io/schema), test cross-engine compatibility (Vega-Lite compiles to Vega per the canonical compiler), and verify data-binding correctness. Pair with d3-snapshot-tests when Vega specs render to SVG; pair with chartjs-snapshot-tests when rendered to Canvas. Use when application code generates Vega/Vega-Lite JSON specs at runtime (BI builders, spec templating) and those specs must be proven valid and correctly encoded before render, or before a Vega major-version upgrade.
79
99%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Passed
No findings from the security scan
Vega-Lite specs (Mark, Encoding, Data) compile to Vega, which renders to SVG/Canvas, per the Vega-Lite docs. Tests validate a spec is well-formed AND produces the expected rendered output.
Per the Vega-Lite docs, the spec is JSON; it has a published JSON Schema. Validate:
import Ajv from 'ajv';
import schema from 'vega-lite/build/vega-lite-schema.json';
const ajv = new Ajv({ strict: false });
const validate = ajv.compile(schema);
test('generated bar spec is valid Vega-Lite', () => {
const spec = generateBarSpec({ x: 'quarter', y: 'revenue' });
const valid = validate(spec);
if (!valid) {
console.log(validate.errors);
}
expect(valid).toBe(true);
});Schema URL pattern: https://vega.github.io/schema/vega-lite/v5.json
(track current version per the Vega-Lite docs).
Beyond schema validity, assert business-relevant structure:
test('spec uses correct mark + encoding for bar chart', () => {
const spec = generateBarSpec({ x: 'quarter', y: 'revenue' });
expect(spec.mark.type).toBe('bar');
expect(spec.encoding.x.field).toBe('quarter');
expect(spec.encoding.x.type).toBe('nominal');
expect(spec.encoding.y.field).toBe('revenue');
expect(spec.encoding.y.type).toBe('quantitative');
});Per the Vega-Lite docs: "Vega-Lite compiles a Vega-Lite specification into a lower-level, more detailed Vega specifications and rendered using Vega's compiler."
import * as vl from 'vega-lite';
test('Vega-Lite compiles to valid Vega', () => {
const vlSpec = generateBarSpec(...);
const vegaSpec = vl.compile(vlSpec).spec;
// Validate Vega spec against Vega schema
const vegaValid = validateVegaSchema(vegaSpec);
expect(vegaValid).toBe(true);
});Failed compilation indicates the Vega-Lite spec is well-formed schema-wise but semantically broken (e.g., references a non-existent field).
One test that proves a BI builder's bar-spec generator produces a spec that is schema-valid, correctly encoded, AND compiles - the three core gates in a single first run:
import Ajv from 'ajv';
import vlSchema from 'vega-lite/build/vega-lite-schema.json';
import * as vl from 'vega-lite';
const validate = new Ajv({ strict: false }).compile(vlSchema);
test('generated bar spec is valid, correctly encoded, and compiles', () => {
const spec = generateBarSpec({ x: 'quarter', y: 'revenue' });
// Gate 1 - schema-valid
expect(validate(spec)).toBe(true);
// Gate 2 - correct mark + encoding
expect(spec.mark.type).toBe('bar');
expect(spec.encoding.x.field).toBe('quarter');
expect(spec.encoding.y.type).toBe('quantitative');
// Gate 3 - compiles to Vega without throwing
expect(() => vl.compile(spec)).not.toThrow();
});That single test is the minimum a runtime-generated spec must pass before render. Render-time and semantic verification build on it - see the advanced reference below.
Render-to-SVG assertions, multi-view composition (facet / layer / concat / repeat), data-transform verification, interaction parameters, and spec-snapshot regression each get a full worked test in references/advanced-spec-tests.md.
| Anti-pattern | Why it fails | Fix |
|---|---|---|
| Skip JSON Schema validation; compile direct | Compiler errors are cryptic | Step 1 first |
| Test only the rendered output, not the spec | Spec gen bugs hide behind correct render | Step 2 + spec snapshot (references) |
| Hardcoded Vega-Lite v4 schema | Schema upgrades change validity | Pin AND track |
| Skip transform tests | Aggregate / filter bugs ship silently | Transform test (references) |
Use mark: 'bar' shorthand mixed with object form | Schema accepts both; downstream code may not | Pick one form per project |
chartjs-snapshot-tests,
d3-snapshot-tests - sister
skills for rendered-output testing