Skip to content

Commit

Permalink
support additional fields
Browse files Browse the repository at this point in the history
  • Loading branch information
mizdra committed Mar 23, 2024
1 parent efcceff commit 43153e9
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 1 deletion.
45 changes: 45 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,51 @@ expect(await AuthorFactory.build({ bookCount: 3 })).toStrictEqual({
});
```

### Additional Fields

You can add additional fields to the data being built. This is useful when you want to build a fake data for a query that contains [aliases](https://graphql.org/learn/queries/#aliases), such as:

```graphql
query GetAuthorInfo {
author(id: '1') {
id
name
books {
id
title
}
popularBooks: books(popularOnly: true) {
id
title
}
}
}
```

```ts
import { defineAuthorFactory, type OptionalBook, dynamic } from '../__generated__/fabbrica';
const AuthorFactory = defineAuthorFactory.withAdditionalFields<{ popularBooks: OptionalBook[] }>()({
defaultFields: {
id: dynamic(({ seq }) => `Author-${seq}`),
name: 'Komata Mikami',
// Generate a fake data for the `Author.books()` field
books: dynamic(() => BookFactory.buildList(3)),
// Generate a fake data for the `Author.books(popularOnly: true)` field
popularBooks: dynamic(() => BookFactory.buildList(1)),
},
});
expect(await AuthorFactory.build()).toStrictEqual({
id: 'Author-0',
name: 'Komata Mikami',
books: [
{ id: 'Book-0', title: 'Yuyushiki Vol.0' },
{ id: 'Book-1', title: 'Yuyushiki Vol.1' },
{ id: 'Book-2', title: 'Yuyushiki Vol.2' },
],
popularBooks: [{ id: 'Book-3', title: 'Yuyushiki Vol.3' }],
});
```

### Traits

Traits allow you to group the default values of fields and apply them to factories.
Expand Down
36 changes: 35 additions & 1 deletion e2e/esm/index.e2e.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { expect, it, describe, assertType, expectTypeOf, vi } from 'vitest';
import { expect, it, describe, expectTypeOf, vi } from 'vitest';
import {
defineAuthorFactory,
defineBookFactory,
Expand All @@ -16,6 +16,7 @@ import {
defineNullableTest_TypeFactory,
defineInputTest_InputFactory,
defineNonOptionalDefaultFields_OptionalDefaultFieldsTypeFactory,
OptionalBook,
} from './__generated__/1-basic/fabbrica.js';
import { oneOf } from './test/util.js';
import { definePrefixTypeFactory } from './__generated__/2-typesPrefix/fabbrica.js';
Expand Down Expand Up @@ -656,6 +657,39 @@ describe('defineTypeFactory', () => {
expect(book2.id).toBe('Bar-Book');
});
});
it('additionalFields', async () => {
const AuthorFactory = defineAuthorFactory.withAdditionalFields<{ popularBooks: OptionalBook[] }>()({
defaultFields: {
id: dynamic(({ seq }) => `Author-${seq}`),
name: 'Komata Mikami',
books: dynamic(() => BookFactory.buildList(3)),
popularBooks: dynamic(() => BookFactory.buildList(1)),
},
});
const BookFactory = defineBookFactory({
defaultFields: {
id: dynamic(({ seq }) => `Book-${seq}`),
title: dynamic(({ seq }) => `Yuyushiki Vol.${seq}`),
},
});
const author = await AuthorFactory.build();
expect(author).toStrictEqual({
id: 'Author-0',
name: 'Komata Mikami',
books: [
{ id: 'Book-0', title: 'Yuyushiki Vol.0' },
{ id: 'Book-1', title: 'Yuyushiki Vol.1' },
{ id: 'Book-2', title: 'Yuyushiki Vol.2' },
],
popularBooks: [{ id: 'Book-3', title: 'Yuyushiki Vol.3' }],
});
expectTypeOf(author).toEqualTypeOf<{
id: string;
name: string;
books: { id: string; title: string }[];
popularBooks: { id: string; title: string }[];
}>();
});
describe('resetAllSequence', () => {
it('resets all sequence', async () => {
const BookFactory = defineBookFactory({
Expand Down
11 changes: 11 additions & 0 deletions src/helper/factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@ export interface DefineTypeFactoryInterfaceRequired<
withTransientFields<NewTransientFields extends Record<string, unknown>>(
defaultTransientFields: NewTransientFields,
): DefineTypeFactoryInterface<Type, Merge<TransientFields, NewTransientFields>>;
withAdditionalFields<AdditionalFields extends Record<string, unknown>>(): DefineTypeFactoryInterface<
Merge<Type, AdditionalFields>,
TransientFields
>;
}

export interface DefineTypeFactoryInterface<
Expand Down Expand Up @@ -180,5 +184,12 @@ class DefineTypeFactory<
// eslint-disable-next-line @typescript-eslint/no-explicit-any
return new DefineTypeFactory({ ...this._defaultTransientFields, ...defaultTransientFields }) as any;
}
withAdditionalFields<AdditionalFields extends Record<string, unknown>>(): DefineTypeFactoryInterface<
Merge<Type, AdditionalFields>,
TransientFields
> {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
return this as any;
}
}
export const defineTypeFactory = new DefineTypeFactory({}) as unknown as DefineTypeFactoryInterfaceRequired<{}, {}>;

0 comments on commit 43153e9

Please sign in to comment.