Skip to content

Commit 11b73a6

Browse files
authored
Merge pull request #22 from mizdra/build-list
`.buildList()`
2 parents 9a71939 + 0974ede commit 11b73a6

File tree

2 files changed

+83
-0
lines changed

2 files changed

+83
-0
lines changed

src/factory.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,13 @@ export interface TypeFactoryInterface<
3535
build<const T extends InputFieldsResolver<Type & TransientFields>>(
3636
inputFieldsResolver: T,
3737
): Promise<Pick<Merge<ResolvedFields<_DefaultFieldsResolver>, ResolvedFields<T>>, keyof Type>>;
38+
buildList(
39+
count: number,
40+
): Promise<Pick<Merge<ResolvedFields<_DefaultFieldsResolver>, ResolvedFields<{}>>, keyof Type>[]>;
41+
buildList<const T extends InputFieldsResolver<Type & TransientFields>>(
42+
count: number,
43+
inputFieldsResolver: T,
44+
): Promise<Pick<Merge<ResolvedFields<_DefaultFieldsResolver>, ResolvedFields<T>>, keyof Type>[]>;
3845
use<T extends keyof _Traits>(
3946
traitName: T,
4047
): TypeFactoryInterface<Type, TransientFields, Merge<_DefaultFieldsResolver, _Traits[T]['defaultFields']>, _Traits>;
@@ -67,6 +74,22 @@ export function defineTypeFactoryInternal<
6774
inputFieldsResolver ?? ({} as T),
6875
);
6976
},
77+
async buildList<const T extends InputFieldsResolver<Type & TransientFields>>(
78+
count: number,
79+
inputFieldsResolver?: T,
80+
): Promise<Pick<Merge<ResolvedFields<_DefaultFieldsResolver>, ResolvedFields<T>>, keyof Type>[]> {
81+
const array: Pick<Merge<ResolvedFields<_DefaultFieldsResolver>, ResolvedFields<T>>, keyof Type>[] = [];
82+
for (let i = 0; i < count; i++) {
83+
if (inputFieldsResolver) {
84+
// eslint-disable-next-line no-await-in-loop, @typescript-eslint/no-explicit-any
85+
array.push((await this.build(inputFieldsResolver)) as any);
86+
} else {
87+
// eslint-disable-next-line no-await-in-loop, @typescript-eslint/no-explicit-any
88+
array.push((await this.build()) as any);
89+
}
90+
}
91+
return array;
92+
},
7093
use<T extends keyof _Traits>(
7194
traitName: T,
7295
): TypeFactoryInterface<

src/index.test.ts

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -653,6 +653,66 @@ describe('TypeFactoryInterface', () => {
653653
expect(lastNameResolver).toHaveBeenCalledTimes(1);
654654
});
655655
});
656+
describe('buildList', () => {
657+
it('overrides defaultFields', async () => {
658+
const BookFactory = defineBookFactory({
659+
defaultFields: {
660+
id: lazy(({ seq }) => `Book-${seq}`),
661+
title: 'ゆゆ式',
662+
author: undefined,
663+
},
664+
});
665+
// input field is optional
666+
const books1 = await BookFactory.buildList(2);
667+
expect(books1).toStrictEqual([
668+
{
669+
id: 'Book-0',
670+
title: 'ゆゆ式',
671+
author: undefined,
672+
},
673+
{
674+
id: 'Book-1',
675+
title: 'ゆゆ式',
676+
author: undefined,
677+
},
678+
]);
679+
assertType<
680+
{
681+
id: string;
682+
title: string;
683+
author: undefined;
684+
}[]
685+
>(books1);
686+
expectTypeOf(books1).not.toBeNever();
687+
688+
BookFactory.resetSequence();
689+
690+
// Passing input fields allows overriding the default field.
691+
const book2 = await BookFactory.buildList(2, {
692+
title: 'ゆゆ式 100巻',
693+
});
694+
expect(book2).toStrictEqual([
695+
{
696+
id: 'Book-0',
697+
title: 'ゆゆ式 100巻',
698+
author: undefined,
699+
},
700+
{
701+
id: 'Book-1',
702+
title: 'ゆゆ式 100巻',
703+
author: undefined,
704+
},
705+
]);
706+
assertType<
707+
{
708+
id: string;
709+
title: string;
710+
author: undefined;
711+
}[]
712+
>(book2);
713+
expectTypeOf(book2).not.toBeNever();
714+
});
715+
});
656716
describe('resetSequence', () => {
657717
it('resets sequence', async () => {
658718
const BookFactory = defineBookFactory({

0 commit comments

Comments
 (0)