Rendered from specs/F16-sample-data.md — edit it there, not here.
F16 — Sample Data Generation
Overview
The inverse of inference (F06): generate a valid example instance from a schema. Useful for seeding test fixtures, trying out a schema right after binding it, and understanding what a (possibly private) schema actually describes. Generation is deterministic by default so repeated runs produce stable fixtures suitable for committing.
User Stories
- As a developer who just bound a schema, I want a valid starter document generated for me, so I don't hand-type boilerplate to satisfy
required. - As a tester, I want deterministic fixtures generated from the schema, so fixture diffs in code review only change when the schema changes.
- As a schema author, I want generation to fail loudly when my schema is unsatisfiable, because that's a bug in the schema.
Functional Requirements
Command
- F16-FR-01 A command
jsonschema.generateSampleDataMUST be available whenjsonschema.isJsonSchemaistrue, and MUST also be reachable from the Bind Schema… success notification ("Generate sample file?"). - F16-FR-02 An output-format picker MUST offer JSON and YAML (extending to TOML when F11 lands); the result opens in a new untitled editor of that language.
Generation Rules
- F16-FR-03 Value selection MUST honour, in priority order:
const,examples[0],default, firstenumentry, then a type-derived value. - F16-FR-04 Type-derived values MUST satisfy the subschema's constraints: string
minLength/maxLength/pattern(best-effort for simple patterns) and commonformats (date-time,date,email,uri,uuid); numericminimum/maximum/multipleOf; arrayminItems(generate exactlymax(minItems, 1)items); objectrequiredproperties always, optional properties only whenminPropertiesdemands more. - F16-FR-05 Composition keywords:
allOfsubschemas are merged best-effort; foroneOf/anyOfthe first branch that yields a valid value is used. - F16-FR-06
$refs MUST resolve with the same semantics as F13 (local, relative, cached remote; uncached remote refs offer Cache Schema Locally). - F16-FR-07 Recursive schemas MUST be depth-capped (default 5); beyond the cap, optional branches are dropped and required recursive branches use the minimal terminating value. Generation MUST always terminate.
- F16-FR-08 The generated instance MUST be validated against the schema with Ajv (the F03 pipeline) before being shown. If validation fails — unsatisfiable or unsupported schema — the command MUST show an error listing the failing keywords/paths instead of opening an invalid document.
- F16-FR-09 Generation MUST be deterministic for a given schema (fixed seed); a "Regenerate with random values" variant MAY be offered.
Non-Functional Requirements
- F16-NFR-01 Generation MUST run in-process, no subprocess and no network beyond cached-ref reads.
- F16-NFR-02 The generator MUST be a pure module with unit tests per rule above, plus a
fast-checkproperty test: for arbitrary schemas from a supported-keyword generator, the output validates or generation errors cleanly (never an invalid document, ≥ 80 % coverage, Article V).
Out of Scope
- Invalid/negative-case generation (fuzzing) — future spec.
- Guaranteed satisfaction of arbitrary
pattern/not/complexif-then-elseschemas — unsatisfied cases must fail loudly per F16-FR-08, never silently emit invalid data. - Bulk generation (N documents / JSONL output).
Acceptance Criteria
- Generating from a schema with
required: ["name"], aformat: "email"field, and adefaultproduces an untitled document that Validate This File confirms valid, using thedefaultwhere declared. - Running the command twice on the same schema yields byte-identical output.
- A recursive
person → children: person[]schema generates and terminates. - A schema with
{ "type": "string", "minLength": 5, "maxLength": 2 }shows an error naming the conflicting constraints; no editor opens. - YAML output parses as YAML and validates against the schema.
Open Questions
- Q1 — Library (
json-schema-faker) vs in-house generator: JSF is featureful but heavy and randomness-oriented; determinism and Ajv-checked output may be simpler in-house. Decide at plan time (Article II amendment if a dependency is added).
Relation to Existing Specs
- Mirrors F06 (inference) UX: command → new untitled editor.
- Reuses F03 validation as the output gate, F13 ref resolution semantics, F08 cached remote refs.
- S03: depth caps guarantee termination; S05: no network, no telemetry.
Requirement traceability
Status of each requirement in specs/traceability.json. Test coverage is auto-discovered from [ID] tags in test titles and is not listed here.
| Requirement | Status | Implementation | Note |
|---|---|---|---|
F16-FR-01 | implemented | src/extension.ts, src/SchemaBindingManager.ts | jsonschema.generateSampleData; gated on isJsonSchemaFile; also reachable from the bind-success notification, which passes the schema ref |
F16-FR-02 | implemented | src/extension.ts | QuickPick JSON/YAML → new untitled editor of that language |
F16-FR-03 | implemented | src/sampleDataGenerator.ts | value priority const → examples[0] → default → enum[0] |
F16-FR-04 | implemented | src/sampleDataGenerator.ts | type-derived: string len/format, number min/multipleOf, array minItems, object required/minProperties |
F16-FR-05 | implemented | src/sampleDataGenerator.ts | allOf merged; oneOf/anyOf use first branch |
F16-FR-06 | implemented | src/sampleDataGenerator.ts, src/extension.ts | resolveRef callback: local pointer, relative file, cached remote |
F16-FR-07 | implemented | src/sampleDataGenerator.ts | maxDepth cap (default 5) returns minimalValue; recursion terminates |
F16-FR-08 | implemented | src/sampleDataGenerator.ts | generateAndValidate gates output through Ajv; returns errors instead of invalid data |
F16-FR-09 | implemented | src/sampleDataGenerator.ts | deterministic (no randomness); byte-identical repeated output |
F16-NFR-01 | implemented | src/sampleDataGenerator.ts | pure in-process; no subprocess, network only via caller-supplied cached-ref reads |
F16-NFR-02 | implemented | src/sampleDataGenerator.ts | pure module unit-tested per rule + fast-check property (never invalid, never throws) |