Skip to content

ngxp/builder

Repository files navigation

@ngxp/builder

Create objects from blueprints using reusable builders.

Too abstract? Here's an example where we use @ngxp/builder to create test data for a log.

Example

import { Blueprint, createBlueprintBuilder } from './src';

// we're using faker to create random values
import * as faker from 'faker';

interface LogEntry {
    date: Date;
    author: string;
    message: string;
}

// a blueprint provides a value generator function
// for each property of our object
const logEntryBlueprint: Blueprint<LogEntry> = {
    date: () => faker.date.past(),
    author: () => faker.name.findName(),
    message: () => faker.lorem.sentences()
};

// each time the builder's build method is called, the
// methods of the blueprint are used to retrieve
// a new set of values for the object to be created
const logEntryBuilder = createBlueprintBuilder(logEntryBlueprint);

// create some log entries
const log = [
    logEntryBuilder().build(),
    logEntryBuilder().build()
];

log now contains this array:

[
    {
        "date": "2018-10-22T12:31:52.169Z",
        "author": "Jevon Hintz V",
        "message": "Sit repellat consequatur fugit qui. Tempore vero aut."
    },
    {
        "date": "2019-02-06T09:50:54.421Z",
        "author": "Libby Crist I",
        "message": "Aspernatur tempore quia molestiae praesentium ut sed quia aperiam consequatur. Culpa hic enim blanditiis recusandae iste maiores."
    }
]

Build multiple objects at once

When creating test data, it can be useful to create a lot of objects at once. Just use buildMany instead of build:

const log = logEntryBuilder().buildMany(100);

Overriding blueprint values

You can override some of the values using either the optional values parameter of createBlueprintBuilder or setter methods that are named according to the blueprint:

const logEntry = logEntryBuilder({
    author: `Miles O'Brien`
})
    .message(`I'm bored...`)
    .buildMany(2);

These values are always used instead of the ones generated by the blueprint:

[
    {
        "date": "2018-06-02T04:49:24.531Z",
        "author": "Miles O'Brien",
        "message": "I'm bored..."
    },
    {
        "date": "2018-09-10T09:33:57.386Z",
        "author": "Miles O'Brien",
        "message": "I'm bored..."
    }
]

Make objects immutable

When creating test data, it can be useful to make the data immutable to prevent tests from changing data and thereby affecting other tests. Luckily, we have a freeze method!

const testLogEntry = logEntryBuilder()
    .freeze()
    .build();

testLogEntry.date = new Date(); // throws ☠

Transform objects

You can pass transformation functions to transform the object being built. Transformations are always applied after any value setters.

const scream: Transformation<LogEntry> = entry => ({
    ...entry,
    message: entry.message!.toUpperCase()
});

const logEntry = logEntryBuilder()
    .transform(scream)
    .message(`I'm bored...`)
    .build();

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Packages

No packages published