@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
TypeScript
/**
* 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 {};