diff --git a/spec/pipeline.spec.ts b/spec/pipeline.spec.ts index ec3af92..068d6f8 100644 --- a/spec/pipeline.spec.ts +++ b/spec/pipeline.spec.ts @@ -74,4 +74,50 @@ describe("pipelines", () => { expect(data.gramps.children[0]).toEqual(data.dad); expect(data.gramps.spouse).toBeNull(); }); + + it("pipelines to async factories", async () => { + const p = Pipe.Pipeline.start() + .addValues({ hello: "kitty", hola: "espanol" }) + .addValues(() => Promise.resolve({ byebye: "birdie" })) + .addValues(v => ({ + corner: `${v.hello} corner`, + golf: v.byebye + })) + .addFactory(childFactory, "kiddo", { grade: 2 }) + .addFactory(parentFactory, "dad", v => + Promise.resolve({ + name: "Dad", + children: [v.kiddo], + spouse: null + }) + ) + .addTxFactory(grandpaFactory, "gramps", v => ({ + name: "Gramps", + children: [v.dad], + spouse: null + })); + + const p_factory = p.toFactory(); + const data = await p_factory.build(); + + expect(data.hello).toEqual("kitty"); + expect(data.hola).toEqual("espanol"); + expect(data.byebye).toEqual("birdie"); + expect(data.corner).toEqual("kitty corner"); + expect(data.golf).toEqual("birdie"); + expect(data.kiddo.grade).toEqual(2); + expect(data.kiddo.name).toEqual("Kid"); + expect(data.dad.name).toEqual("Dad"); + expect(data.dad.birthday.getTime()).toEqual( + new Date("2017/05/03").getTime() + ); + expect(data.dad.children.length).toEqual(1); + expect(data.dad.children[0]).toEqual(data.kiddo); + expect(data.dad.spouse).toBeNull(); + expect(data.gramps.name).toEqual("Gramps"); + expect(data.gramps.spoils).toEqual(true); + expect(data.gramps.children.length).toEqual(1); + expect(data.gramps.children[0]).toEqual(data.dad); + expect(data.gramps.spouse).toBeNull(); + }); }); diff --git a/src/async.ts b/src/async.ts index 99faa42..73f55ef 100644 --- a/src/async.ts +++ b/src/async.ts @@ -15,8 +15,8 @@ export type ListFactoryFunc = keyof T extends K ? (count: number, item?: RecPartial) => Promise : (count: number, item: RecPartial & Omit) => Promise; -function isPromise(t: T | Promise): t is Promise { - return typeof (t as any)["then"] === "function"; +function isPromise(t: T | Promise): t is Promise { + return !!t && typeof (t as any)["then"] === "function"; } export function lift(t: T | Promise): Promise { @@ -57,7 +57,7 @@ export class Factory (this.config && this.config.startingSequenceNumber) || 0; constructor( - readonly builder: Builder, + readonly builder: Builder | Promise>, private readonly config: AsyncFactoryConfig | undefined ) { this.seqNum = this.getStartingSequenceNumber(); @@ -270,13 +270,15 @@ interface BaseBuild { async function buildBase( seqNum: number, - builder: Builder + builder: Builder | Promise> ): Promise> { + const resolvedBuilder = await lift(builder); + const t: { [key: string]: any } = {}; - const keys = Object.getOwnPropertyNames(builder); + const keys = Object.getOwnPropertyNames(resolvedBuilder); const derived: BaseDerived[] = []; for (const key of keys) { - const v = (builder as any)[key]; + const v = (resolvedBuilder as any)[key]; let value = v; if (!!v && typeof v === "object") { if (isPromise(v)) { @@ -299,14 +301,14 @@ async function buildBase( } export function makeFactory( - builder: Builder, + builder: Builder | Promise>, config?: AsyncFactoryConfig ): Factory { return new Factory(builder, config); } export function makeFactoryWithRequired( - builder: Builder>, + builder: Builder> | Promise>>, config?: AsyncFactoryConfig ): Factory> { return new Factory(builder, config); diff --git a/src/pipeline.ts b/src/pipeline.ts index 9a38b1b..8d65c22 100644 --- a/src/pipeline.ts +++ b/src/pipeline.ts @@ -10,8 +10,8 @@ type PipePartialRec = MaybePromiseFunc< RecPartial> & Omit >; -export class Pipeline

implements PromiseLike

{ - constructor(private current: Promise

) {} +export class Pipeline

= {}> implements PromiseLike

{ + constructor(private current: Promise

) { } static start() { return new Pipeline(Promise.resolve({})); @@ -91,4 +91,8 @@ export class Pipeline

implements PromiseLike

{ ): Promise { return this.current.then(onfulfilled, onrejected); } -} + + toFactory(): Async.Factory

{ + return Async.makeFactory(this.current as Promise>); + } +} \ No newline at end of file