UNPKG

@makerx/ts-dossier

Version:

A support library to facilitate the easy creation of builders for use with an Object-Mother test pattern in TypeScript

65 lines (64 loc) 2.38 kB
/** * Data builder is an abstract class builders can inherit to make working with the {@linkplain dossierProxy} easier. * * ```typescript * export class ShapeBuilder extends DataBuilder<Shape> { * constructor() { * super({ * name: randomString(10, 20), * sides: randomNumberBetween(1, 4), * colour: randomElement(['Blue', 'Red', 'Yellow', 'Green']), * }) * } * * public withName(name: string) { * return this.with('name', name + ' Intercepted') * } * } * * export const shapeBuilder = dossierProxy<ShapeBuilder, Shape>(ShapeBuilder) * ``` */ export declare abstract class DataBuilder<T> { protected thing: T; protected constructor(thing: T); with<K extends keyof T>(key: K, value: T[K]): this; build(): T; clone(): this; } type WithMethods<T extends object, TBuilder> = CoerceIntellisense<{ [K in keyof T as K extends string ? `with${Capitalize<K>}` : never]-?: (d: T[K]) => WithMethods<T, TBuilder> & TBuilder; } & TBuilder>; export type CoerceIntellisense<T> = T extends infer O ? { [K in keyof O]: O[K]; } : never; type DynamicDataBuilder<TDataBuilder, TData extends object> = TDataBuilder & WithMethods<TData, TDataBuilder>; /** * The proxy builder allows one to easily create a builder and have a [proxy]{@link https://developer.mozilla.org/en-US/docs/web/javascript/reference/global_objects/proxy/proxy} * instance handle any with* methods not specifically declared by the builder itself. * * ```typescript * class ShapeBuilder extends DataBuilder<Shape> { * constructor() { * super({ * name: randomString(10, 20), * sides: randomNumberBetween(1, 4), * colour: randomElement(['Blue', 'Red', 'Yellow', 'Green']), * }) * } * * public withName(name: string) { * return this.with('name', name + ' Intercepted') * } * } * * const shapeBuilder = dossierProxy<ShapeBuilder, Shape>(ShapeBuilder) * * const shape = shapeBuilder().withName('Square').withSides(4).withColour('Red').build() * * console.log(shape) // Outputs { name: 'Square Intercepted', sides: 4, colour: 'Red' } * ``` * @param builder The constructor to call to create a new instance of the builder. */ export declare function dossierProxy<TDataBuilder, TData extends object>(builder: new () => TDataBuilder): () => DynamicDataBuilder<TDataBuilder, TData>; export {};