Skip to content

Commit

Permalink
feat: add lazyattribute and subfactory as options in attribs
Browse files Browse the repository at this point in the history
  • Loading branch information
jorgebodega committed Feb 9, 2022
1 parent 4a2ce08 commit 48a3630
Show file tree
Hide file tree
Showing 7 changed files with 70 additions and 11 deletions.
7 changes: 5 additions & 2 deletions src/factory.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { SaveOptions } from 'typeorm'
import { fetchConnection } from './connection'
import { LazyAttribute } from './lazyAttribute'
import { Subfactory } from './subfactory'
import type { Constructable, FactorizedAttrs } from './types'

export abstract class Factory<T> {
Expand Down Expand Up @@ -72,8 +73,10 @@ export abstract class Factory<T> {
return entity
}

private static resolveValue(value: unknown) {
if (value instanceof Function) {
private static resolveValue(value: unknown, shouldPersist = true) {
if (value instanceof Subfactory) {
return shouldPersist ? value.create() : value.make()
} else if (value instanceof Function) {
return value()
} else {
return value
Expand Down
8 changes: 4 additions & 4 deletions src/lazyAttribute.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import type { FactorizedAttrs, LazyAttributeCallback } from './types'
import type { FactorizedAttr, LazyAttributeCallback } from './types'

export class LazyAttribute<T> {
constructor(private callback: LazyAttributeCallback<T>) {}
export class LazyAttribute<T, V> {
constructor(private callback: LazyAttributeCallback<T, V>) {}

resolve(entity: T): FactorizedAttrs<T> {
resolve(entity: T): FactorizedAttr<V> {
return this.callback(entity)
}
}
39 changes: 39 additions & 0 deletions src/subfactory.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import type { Factory } from './factory'
import type { Constructable, FactorizedAttrs } from './types'

export class Subfactory<T> {
private factoryInstance: Factory<T>
private values?: Partial<FactorizedAttrs<T>>
private count?: number

constructor(factory: Constructable<Factory<T>>)
constructor(factory: Constructable<Factory<T>>, values?: Partial<FactorizedAttrs<T>>)
constructor(factory: Constructable<Factory<T>>, count?: number)
constructor(factory: Constructable<Factory<T>>, values?: Partial<FactorizedAttrs<T>>, count?: number)

constructor(
factory: Constructable<Factory<T>>,
countOrValues?: Partial<FactorizedAttrs<T>> | number,
count?: number,
) {
this.factoryInstance = new factory()
this.values = typeof countOrValues === 'number' ? undefined : countOrValues
this.count = typeof countOrValues === 'number' ? countOrValues : count
}

create() {
if (this.count) {
return this.factoryInstance.createMany(this.count, this.values)
}

return this.factoryInstance.create(this.values)
}

make() {
if (this.count) {
return this.factoryInstance.makeMany(this.count, this.values)
}

return this.factoryInstance.make(this.values)
}
}
8 changes: 5 additions & 3 deletions src/types.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type { ConnectionOptions as TypeORMConnectionOptions } from 'typeorm'
import type { Factory } from './factory'
import type { LazyAttribute } from './lazyAttribute'
import type { Subfactory } from './subfactory'

export type ConnectionOptions = TypeORMConnectionOptions & {
seeders: string[]
Expand All @@ -11,7 +12,8 @@ export type ConnectionConfiguration = {
connection: string
}
export type Constructable<T> = new () => T
export type FactorizedAttr<V> = V | (() => V | Promise<V>) | Subfactory<V>
export type FactorizedAttrs<T> = {
[K in keyof Partial<T>]: T[K] | (() => T[K] | Promise<T[K]>) | Factory<T[K]>
[K in keyof Partial<T>]: FactorizedAttr<T[K]> | LazyAttribute<T, T[K]>
}
export type LazyAttributeCallback<T> = (entity: T) => FactorizedAttrs<T>
export type LazyAttributeCallback<T, V> = (entity: T) => FactorizedAttr<V>
3 changes: 3 additions & 0 deletions test/entities/User.entity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,7 @@ export class User {

@Column()
lastName!: string

@Column()
phone!: number
}
10 changes: 9 additions & 1 deletion test/factories/Pet.factory.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,20 @@
import faker from '@faker-js/faker'
import { Factory } from '../../src/factory'
import { LazyAttribute } from '../../src/lazyAttribute'
import { Subfactory } from '../../src/subfactory'
import { Pet } from '../entities/Pet.entity'
import { UserFactory } from './User.factory'

export class PetFactory extends Factory<Pet> {
protected entity = Pet
protected attrs = {
name: faker.name.findName(),
lastName: async () => faker.name.findName(),
// owner: new UserFactory() as any,
owner: new LazyAttribute(
(instance: Pet) =>
new Subfactory(UserFactory, {
name: `${instance.name} owner`,
}),
),
}
}
6 changes: 5 additions & 1 deletion test/factories/User.factory.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
import faker from '@faker-js/faker'
import { Factory } from '../../src/factory'
import { LazyAttribute } from '../../src/lazyAttribute'
import { Subfactory } from '../../src/subfactory'
import { User } from '../entities/User.entity'
import { PetFactory } from './Pet.factory'

export class UserFactory extends Factory<User> {
protected entity = User
protected attrs = {
name: faker.name.findName(),
lastName: () => faker.name.lastName(),
lastName: new LazyAttribute((instance: User) => faker.name.lastName()),
phone: new LazyAttribute((instance: User) => faker.random.number()),
}
}

0 comments on commit 48a3630

Please sign in to comment.