UNPKG

data-mock-builder

Version:

🧰 A fluent, type-safe mock object generator for test data creation, seeding, and API mocking.

166 lines (164 loc) • 6.08 kB
type ValueOrFactory<T> = T | (() => T); /** * MockBuilder provides a fluent API to construct mock objects for testing purposes. * * Features: * - Define fields with static values or value factories (functions). * - Support for string, number, boolean, array, and incrementing number fields. * - Repeat object creation to generate arrays of mocks. * - Extend builder with templates or presets for reusable field sets. * - Define and use named presets for common mock structures. * * Example usage: * ``` * const builder = new MockBuilder() * .field("id").increment(1) * .field("name").string("Alice") * .repeat(2); * const result = builder.build(); * // result: [{ id: 1, name: "Alice" }, { id: 2, name: "Alice" }] * ``` */ declare class MockBuilder { private fields; private repeatCount; private static presets; private deepCopyEnabled; private defaultSkipValidation; /** * Creates a new MockBuilder instance. * @param options Optional. { deepCopy?: boolean, skipValidation?: boolean } */ constructor(options?: { deepCopy?: boolean; skipValidation?: boolean; }); /** * Enable or disable deep copy of field values in build(). * By default, deep copy is enabled to prevent mutation between builds. * @param enabled true to enable deep copy, false to disable * @returns The builder instance for chaining. */ deepCopy(enabled: boolean): this; /** * Adds a field to the mock object. * Overloads: * - field(name: string): returns an object with type methods (string, number, etc.) * - field(name: string, value: any | (() => any)): adds the field directly and returns the builder instance. * * @param name The name of the field to add. * @param value (optional) The value or factory for the field. * @returns The builder instance or the type API. */ field<T>(name: string): { string: (val?: ValueOrFactory<string>) => MockBuilder; number: (val?: ValueOrFactory<number>) => MockBuilder; boolean: (val?: ValueOrFactory<boolean>) => MockBuilder; array: <T = any>(val: ValueOrFactory<T[]>) => MockBuilder; object: <T = Record<string, any>>(val: ValueOrFactory<T>) => MockBuilder; /** * Sets an incrementing number for the field, starting from `start` and incrementing by `step`. * @param start The starting value for the increment (default: 1). * @param step The increment step (default: 1). * @returns The builder instance for chaining. */ increment: (start?: number, step?: number) => MockBuilder; }; field<T>(name: string, value: ValueOrFactory<T>): MockBuilder; /** * Adds a field definition to the builder. * * @param name The field name. * @param val The value or value factory for the field. * @returns The builder instance for chaining. * @private */ private addField; /** * Sets the number of objects to generate when build() is called. * * @param n The number of objects to build. * @returns The builder instance for chaining. * * Example: * ``` * builder.repeat(5).build(); // returns an array of 5 objects * ``` */ repeat(n: number): this; /** * Extends the builder with fields from a template object. * Each key-value pair in the template becomes a field. * * @param template An object whose properties are added as fields. * @returns The builder instance for chaining. * * Example: * ``` * builder.extend({ foo: "bar", count: 42 }); * ``` */ extend(template: Record<string, any>): this; /** * Defines a named preset template for reuse in multiple builders. * * Presets are global and can be used in any MockBuilder instance via the `preset` method. * A preset is simply a named object template that can be reused and extended. * * Example: * ``` * // Define a preset named "user" * MockBuilder.definePreset("user", { name: "Alice", age: 30 }); * * // Use the preset in a builder * const builder = new MockBuilder().preset("user"); * const result = builder.build(); * // result: { name: "Alice", age: 30 } * * // You can override fields after applying a preset * const builder2 = new MockBuilder().preset("user").field("age").number(40); * const result2 = builder2.build(); * // result2: { name: "Alice", age: 40 } * ``` * * @param name The name of the preset. * @param template The template object to associate with the preset. */ static definePreset(name: string, template: Record<string, any>): void; /** * Applies a preset template by name to the builder. * Throws an error if the preset does not exist. * * @param name The name of the preset to apply. * @returns The builder instance for chaining. * @throws Error if the preset is not found. * * Example: * ``` * builder.preset("user"); * ``` */ preset(name: string): this; /** * Builds the mock object(s) according to the defined fields and repeat count. * If repeat() was not called or set to 1, returns a single object. * If repeat() was set to n > 1, returns an array of n objects. * * @param options Optional. Options object: * - deepCopy: boolean (overrides the builder's deep copy setting for this build) * - skipValidation: boolean (if true, skips field validation for required fields; default: true) * @returns The built object or array of objects, optionally cast to type T. * * Example: * ``` * interface User { id: number; name: string } * const user = builder.build<User>(); * const users = builder.repeat(2).build<User[]>(); * ``` */ build<T extends object = any>(options?: { deepCopy?: boolean; skipValidation?: boolean; }): T; } export { MockBuilder };