UNPKG

data-mock-builder

Version:

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

216 lines (214 loc) • 7.89 kB
type ValueOrFactory<T> = T | ((obj?: any, index?: number, options?: { deepCopy?: boolean; skipValidation?: boolean; }) => T); type FieldValidator = (value: any, fieldName: string) => { success: boolean; errorMsg?: string; }; /** * 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; private currentFieldName; /** * 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; /** * Sets a field validator function that will be used to validate the field's value * during build. * * @param validator A function that validates the field value. * Should return an object with { success: boolean, errorMsg?: string }. * @returns The builder instance for chaining. */ validator: (validator: FieldValidator) => MockBuilder; }; field<T>(name: string, value: ValueOrFactory<T>): MockBuilder; /** * Adds a validator to the last defined field. * * @param name The field name. * @param validator The validator function. * @returns The builder instance for chaining. * @private */ private addValidator; /** * 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; /** * Sets a custom validator for a field. * The validator function should return an object with { success: boolean, errorMsg?: string }. * * @param fieldName The name of the field to validate. * @param validator The validator function. * @returns The builder instance for chaining. * * Example: * ``` * builder * .field("age").number(25) * .validator("age", (value) => ({ * success: value >= 18, * errorMsg: value >= 18 ? undefined : "Age must be at least 18" * })) * .field("email").string("user@example.com") * .validator("email", (value) => ({ * success: /^.+@.+\..+$/.test(value), * errorMsg: /^.+@.+\..+$/.test(value) ? undefined : "Invalid email format" * })); * ``` */ validator(fieldName: string, validator: FieldValidator): 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 };