Skip to content
Logo

Quick start

This library is particularly useful for defining test fixtures to exercise your code with inputs that you may not have anticipated. In this way, it facilitates a form of fuzzing.

import {  } from "@ghostry/fabricator";
 
const { ,  } = ({
  : new (), // default source of entropy
  : "1234", // optional additional entropy
});
 
const  = .({
  : ..({ : { : 1, : 25 } }),
  : ..({ : 1, : 500 }),
  : .,
  : ..,
  : .(..({ : { : 15 } })).({
    : { : 5 },
  }),
});
 
const  = new ();
 
const  = .();
// { name: "...", price: ..., inStock: ..., createdAt: ..., tags: [...] }

That's the whole loop:

  1. initialize(...) gives you T (a namespace of type builders) and Fabricator (a constructor for turning a Schema into something live).
  2. T.object({ ... }) builds a Schema — inert, serializable data describing a shape. Building it draws no randomness.
  3. new Fabricator(schema) builds a live Fabricator with a .fabricate() method.
  4. .fabricate() is the only place randomness actually happens.

See Mental model for why this three-layer split exists.

Both options passed to initialize() above are optional, and are shown only to name the two knobs. clock already defaults to the instant of the call, and on its own is enough to make every run different and to replay any one of them; a seed is an extra mixer most instances don't need. See Seeds are optional mixers.

Overriding specific fields

Fabricate with everything random except a few fields you care about:

const item = Product.fabricate({ name: "Widget", inStock: true });

This uses the Fabricator's own already-drawn randomness for every other field — it's a per-call override, not a new schema. See Composition for the schema-level equivalent, .override(...).