diff --git a/types/factory-girl/factory-girl-tests.ts b/types/factory-girl/factory-girl-tests.ts index e996df56af..bda671c751 100644 --- a/types/factory-girl/factory-girl-tests.ts +++ b/types/factory-girl/factory-girl-tests.ts @@ -1,45 +1,66 @@ import * as factory from "factory-girl"; interface User { - username?: string; - score?: number; - email?: string; - roles?: Role[]; - creditCard?: any; - boss?: User; + username?: string; + score?: number; + email?: string; + roles?: Role[]; + creditCard?: any; + boss?: User; } interface Role { - id?: number; - name?: string; + id?: number; + name?: string; } interface SuperUser extends User { - superpower: string; + superpower: string; } // Testing setAdapter factory.setAdapter("my-adapter", "my-adapter-name"); +// Testing sequence to use it on its own +const scoreSequence = factory.seq('User.score', score => score + 1); + // Testing define with seq, assoc, assocAttrs, assocMany -factory.define("user", {}, { - username: "Bob", - score: factory.seq("User.score", score => score + 1), - email: factory.seq("User.email", num => `email-${1}@users.com`), - roles: factory.assocMany("Role", 3, "id"), - creditCard: factory.assocAttrs("CreditCard", "creditCard", { number: "1234" }), - boss: factory.assoc("User", "boss") -}, { - afterBuild: (model, attrs, options) => {}, - afterCreate: (model, attrs, options) => {} -}); +factory.define( + 'user', + {}, + { + username: () => (Math.random() > 0.5 ? 'Bob' : 'Robert'), + score: scoreSequence, + email: factory.seq('User.email', num => `email-${1}@users.com`), + roles: factory.assocMany('Role', 3, 'id'), + creditCard: factory.assocAttrs('CreditCard', 'creditCard', { number: '1234' }), + boss: factory.assoc('User', 'boss'), + }, + { + afterBuild: (model, attrs, options) => {}, + afterCreate: (model, attrs, options) => {}, + } +); // Testing extend, with and without options factory.extend("user", "superuser", { superpower: "flight" }); -factory.extend("user", "superuser", { superpower: "flight" }, { - afterBuild: (model, attrs, options) => {}, - afterCreate: (model, attrs, options) => {} +factory.extend( + 'user', + 'superuser', + { superpower: 'flight' }, + { + afterBuild: (model, attrs, options) => {}, + afterCreate: (model, attrs, options) => {}, + } +); + +factory.extend('user', 'email-related', () => { + const score = scoreSequence(); + return { + score, + email: factory.seq('User.email', num => `email-${num}-${score}@users.com`), + }; }); // Testing attrs, with and without attributes @@ -55,40 +76,41 @@ factory.build("user").then(user => user.username); factory.build("user", { score: 10 }).then(user => user.username); // Testing buildMany, with and without attributes and options -factory.buildMany("user", 3) - .then(users => users.map(user => user.username)); +factory.buildMany('user', 3).then(users => users.map(user => user.username)); -factory.buildMany("user", 3, { username: "John McClane" }) - .then(users => users.map(user => user.username)); +factory.buildMany('user', 3, { username: 'John McClane' }).then(users => users.map(user => user.username)); // Testing buildMany with a list of attributes -factory.buildMany("user", [ - { username: "Jake Blues" }, - { username: "Elwood Blues" } -]).then(users => users.map(user => user.username)); +factory + .buildMany('user', [{ username: 'Jake Blues' }, { username: 'Elwood Blues' }]) + .then(users => users.map(user => user.username)); // Testing create, with and without attributes factory.create("user").then(user => user.username); factory.create("user", { score: 10 }).then(user => user.username); // Testing createMany, with and without attributes -factory.createMany("user", 3) - .then(users => users.map(user => user.username)); +factory.createMany('user', 3).then(users => users.map(user => user.username)); -factory.createMany("user", 3, { username: "Rocky Balboa" }) - .then(users => users.map(user => user.username)); +factory.createMany('user', 3, { username: 'Rocky Balboa' }).then(users => users.map(user => user.username)); // Testing createMany with options -factory.createMany("user", 3, { username: "John Rambo" }, { - afterBuild: (model, attrs, options) => {}, - afterCreate: (model, attrs, options) => {} -}).then(users => users.map(user => user.username)); +factory + .createMany( + 'user', + 3, + { username: 'John Rambo' }, + { + afterBuild: (model, attrs, options) => {}, + afterCreate: (model, attrs, options) => {}, + } + ) + .then(users => users.map(user => user.username)); // Testing createMany with a list of attributes -factory.createMany("user", [ - { username: "Emmett Brown" }, - { username: "Marty McFly" } -]).then(users => users.map(user => user.username)); +factory + .createMany('user', [{ username: 'Emmett Brown' }, { username: 'Marty McFly' }]) + .then(users => users.map(user => user.username)); // Testing cleanUp factory.cleanUp(); diff --git a/types/factory-girl/index.d.ts b/types/factory-girl/index.d.ts index ebd6583885..01508b5ec0 100644 --- a/types/factory-girl/index.d.ts +++ b/types/factory-girl/index.d.ts @@ -9,86 +9,94 @@ declare const factory: factory.Static; declare namespace factory { - interface Static { - /** - * Associate the factory to other model - */ - assoc(model: string, attributes: string): any; + type Generator = () => T; - /** - * Associate the factory to a model that's not persisted - */ - assocAttrs(name: string, key?: string, attributes?: any): any; + type Definition = T | Generator; - /** - * Associate the factory to multiple other models - */ - assocMany(model: string, num: number, attributes: string): any[]; + type Attributes = Definition<{ + [P in keyof T]: Definition; + }>; - /** - * Generates and returns model attributes as an object hash instead of the model instance - */ - attrs(name: string, attrs?: Partial): Promise; + interface Static { + /** + * Associate the factory to other model + */ + assoc(model: string, attributes: string): any; - /** - * Generates and returns a collection of model attributes as an object hash instead of the model instance - */ - attrsMany(name: string, num: number, attrs?: Array>): Promise; + /** + * Associate the factory to a model that's not persisted + */ + assocAttrs(name: string, key?: string, attributes?: any): any; - /** - * Builds a new model instance that is not persisted - */ - build(name: string, attrs?: Partial): Promise; + /** + * Associate the factory to multiple other models + */ + assocMany(model: string, num: number, attributes: string): any[]; - /** - * Builds an array of model instances that are persisted - */ - buildMany(name: string, num: number, attrs?: Partial): Promise; - buildMany(name: string, attrs?: Array>): Promise; + /** + * Generates and returns model attributes as an object hash instead of the model instance + */ + attrs(name: string, attrs?: Attributes>): Promise; - /** - * Destroys all of the created models - */ - cleanUp(): void; + /** + * Generates and returns a collection of model attributes as an object hash instead of the model instance + */ + attrsMany(name: string, num: number, attrs?: ReadonlyArray>>): Promise; - /** - * Builds a new model instance that is persisted - */ - create(name: string, attrs?: Partial): Promise; + /** + * Builds a new model instance that is not persisted + */ + build(name: string, attrs?: Attributes>): Promise; - /** - * Builds an array of model instances that are persisted - */ - createMany(name: string, num: number, attrs?: Partial, buildOptions?: Options): Promise; - createMany(name: string, attrs?: Array>, buildOptions?: Options): Promise; + /** + * Builds an array of model instances that are persisted + */ + buildMany(name: string, num: number, attrs?: Attributes>): Promise; + buildMany(name: string, attrs?: ReadonlyArray>>): Promise; - /** - * Define a new factory with a set of options - */ - define(name: string, model: any, attrs: T, options?: Options): void; + /** + * Destroys all of the created models + */ + cleanUp(): void; - /** - * Extends a factory - */ - extend(parent: string, name: string, initializer: any, options?: Options): any; + /** + * Builds a new model instance that is persisted + */ + create(name: string, attrs?: Attributes>): Promise; - /** - * Generate values sequentially inside a factory - */ - seq(name: string, fn: (sequence: number) => T): T; + /** + * Builds an array of model instances that are persisted + */ + createMany(name: string, num: number, attrs?: Attributes>, buildOptions?: Options): Promise; + createMany(name: string, attrs?: ReadonlyArray>>, buildOptions?: Options): Promise; - /** - * Register an adapter, either as default or tied to a specific model - */ - setAdapter(adapter: any, name?: string): void; - } + /** + * Define a new factory with a set of options + */ + define(name: string, model: any, attrs: Attributes, options?: Options): void; - interface Options { - afterBuild?: Hook; - afterCreate?: Hook; - } + /** + * Extends a factory + */ + extend(parent: string, name: string, initializer: any, options?: Options): any; - type Hook = (model: any, attrs: T[], options: any) => void; + /** + * Generate values sequentially inside a factory + */ + seq(name: string, fn: (sequence: number) => T): Generator; + + /** + * Register an adapter, either as default or tied to a specific model + */ + setAdapter(adapter: any, name?: string): void; + } + + interface Options { + afterBuild?: Hook; + afterCreate?: Hook; + } + + type Hook = (model: any, attrs: T[], options: any) => void; } export = factory;