Skip to content

Latest commit

 

History

History
219 lines (172 loc) · 4.75 KB

tutorial.md

File metadata and controls

219 lines (172 loc) · 4.75 KB

Tutorial

Create factory

Before we start generating objects, we need to create the factory itself

Using config

In most cases, a factory can be created using the factoryT(config) function

config is an object that specifies both the type and logic of fields generating for future objects

interface User {
    id: number;
    name: string;
}
const userFactory = factoryT<User>({
    id: fields.index(),
    name: 'Paul',
});
expect(userFactory.item()).toStrictEqual({
    id: 1,
    name: 'Paul',
});

Specify field

By value

Here we just pass value which will be passed to generated object directly

factoryT({
    string: 'string',
    number: 12,
    enum: SomeEnum.Value
    const: 'const-str' as const
    numberArray: [1, 2, 3]
})
By function
factoryT({
    string: (ctx) => `here we have access to ${ctx.index} and ${ctx.options}`,
});
By build-in fields helpers
import { factoryT, fields } from 'factory-t';
factoryT({
    nullableStringNullByDefault: fields.nullable<string>(null),
    nullableStringSomeValueByDefault: fields.nullable('some-value'),
    optionalNumber: fields.optional(12),
    numberGeneratedBySequence: fields.sequence([1, 2, 3]),
    indexField: fields.index(),
});

Factory builder

In some advanced cases a factory is constructed using a builder, such as:

  • one field depends from another(s)
// ../src/tests/tutorial-snippets.test.ts#L21-L39

interface User {
    id: number;
    email: string;
    name: string;
}
const userFactory = factoryTBuilder<User>({
    id: fields.index(),
    email: fields.string(),
    name: fields.string(),
})
    .setFieldFactory('name', (ctx) => `name-${ctx.inject('id')}`)
    .setFieldFactory('email', (ctx) => `${ctx.inject('name')}@g.com`)
    .factory();

expect(userFactory.item({ id: 777 })).toStrictEqual({
    id: 777,
    name: 'name-777',
    email: 'name-777@g.com',
});

Generate data objects

Single item

factory.item();

List

// ../src/tests/tutorial-snippets.test.ts#L45-L68

interface User {
    id: number;
    name: string;
}
const userFactory = factoryT<User>({
    id: fields.index(),
    name: (ctx) => `name-${ctx.index}`,
});

expect(userFactory.list({ count: 2 })).toStrictEqual([
    { id: 1, name: 'name-1' },
    { id: 2, name: 'name-2' },
]);

expect(userFactory.list({ partials: [{ id: 700 }, {}, { id: 900 }] })).toStrictEqual([
    { id: 700, name: 'name-3' },
    { id: 4, name: 'name-4' },
    { id: 900, name: 'name-5' },
]);

expect(userFactory.list({ count: 2, partial: { name: 'custom-name' } })).toStrictEqual([
    { id: 6, name: 'custom-name' },
    { id: 7, name: 'custom-name' },
]);

FAQ

is it possible to somehow reset the index value

// ../src/tests/tutorial-snippets.test.ts#L123-L126

const factory = factoryT({ id: fields.index() });
expect(factory.list({ count: 2 })).toStrictEqual([{ id: 1 }, { id: 2 }]);
factory.resetCount();
expect(factory.list({ count: 2 })).toStrictEqual([{ id: 1 }, { id: 2 }]);

Is it possible to extend factory

// ../src/tests/tutorial-snippets.test.ts#L74-L120

interface BaseTask {
    id: number;
    priority: 'low' | 'middle' | 'high';
}

interface BugTask extends BaseTask {
    type: 'BUG';
    affectedVersion: string;
}

interface EpicTask extends BaseTask {
    type: 'EPIC';
    taskIds: Array<BaseTask['id']>;
}

const baseTaskFactoryBuilder = factoryTBuilder<BaseTask>({
    id: fields.index(),
    priority: 'high',
});

const butTaskFactory = baseTaskFactoryBuilder
    .inheritedBuilder<BugTask>({
        type: 'BUG',
        affectedVersion: '0.0.1',
    })
    .factory();

const epicTaskFactory = baseTaskFactoryBuilder
    .inheritedBuilder<EpicTask>({
        type: 'EPIC',
        taskIds: [100, 500],
    })
    .factory();

expect(butTaskFactory.item()).toStrictEqual<BugTask>({
    id: 1,
    type: 'BUG',
    priority: 'high',
    affectedVersion: '0.0.1',
});

expect(epicTaskFactory.item()).toStrictEqual<EpicTask>({
    id: 1,
    type: 'EPIC',
    priority: 'high',
    taskIds: [100, 500],
});