From f26e1fb911a660bc50d62a72716677d862f2d054 Mon Sep 17 00:00:00 2001 From: Ryan Wilson-Perkin Date: Wed, 2 Feb 2022 14:42:50 -0500 Subject: [PATCH 1/2] Re-export faker from graphql-fixtures Allows consumers to consume the exact faker instance that we're seeding to ensure that they will be consistent with our package. This makes it easier for consumers to use faker in their filler methods so that they don't need to match our exact version in their dependencies. --- packages/graphql-fixtures/README.md | 26 ++++++++++++++++++- packages/graphql-fixtures/src/fill.ts | 2 ++ .../graphql-fixtures/src/tests/fill.test.ts | 10 +++++-- 3 files changed, 35 insertions(+), 3 deletions(-) diff --git a/packages/graphql-fixtures/README.md b/packages/graphql-fixtures/README.md index 088e8cf213..cbb3ad27a3 100644 --- a/packages/graphql-fixtures/README.md +++ b/packages/graphql-fixtures/README.md @@ -57,6 +57,20 @@ If you need to have the filled object immediately, you can invoke `fill` as foll const data = fill(myQuery, data)({query: myQuery}); ``` +#### Using faker + +When using `faker` to provide fake data within your filler function, you should use the `faker` instance that is exported by this library in order to avoid data mismatches. Rather than `import faker from '@faker-js/faker'` instead use: + +```ts +import {createFiller, faker} from 'graphql-fixtures'; + +const fill = createFiller(schema, { + resolvers: { + ID: (_, {parent}) => `gid://${parent.name}/${faker.datatype.number()}`, + }, +}); +``` + #### Interfaces and Unions When attempting to fill data for a union or interface type, the filler will default to selecting a random type that implements the interface/ is a member of the union. If you would like to ensure a particular type is selected, but leave all the other fields to be filled by resolvers, you can provide a `__typename` field in the `data` argument for that field that selects the type you wish to be filled. @@ -89,7 +103,7 @@ query MyQuery { We can create a simpler filler globally, and use it every time we wish to generate a fixture: ```ts -import {createFiller} from 'graphql-fixtures'; +import {createFiller, faker} from 'graphql-fixtures'; import schema from './schema'; import myQuery from './MyQuery.graphql'; @@ -101,6 +115,11 @@ const fillMyQueryOne = fill(myQuery); // will result in {self: {__typename: 'Person', name: 'Chris'}} const fillMyQueryTwo = fill(myQuery, {self: {name: 'Chris'}}); const fillMyQueryThree = fill(myQuery, {self: () => ({name: 'Chris'})}); + +// will result in an object with a random name +const fillMyQueryThree = fill(myQuery, { + self: () => ({name: faker.name.firstName()}), +}); ``` As noted above, individual fields can be a function that takes the current GraphQL request and details about the field, and returns the partial data. You can even do this for the entire partial object, allowing you to completely switch out what partial data is used for an invocation based on things like the variables to the current query: @@ -128,6 +147,11 @@ When a single number is provided as the first argument, an array of that size wi ```ts // assuming `widgets` in a list of Widget objects +import {createFiller, faker} from 'graphql-fixtures'; +import schema from './schema'; +import widgetQuery from './WidgetQuery.graphql'; + +const fill = createFiller(schema); const fixture = fill(widgetQuery, { widgets: list([2, 4], {id: () => faker.datatype.uuid()}), diff --git a/packages/graphql-fixtures/src/fill.ts b/packages/graphql-fixtures/src/fill.ts index dfadf78b64..1d5df027dd 100644 --- a/packages/graphql-fixtures/src/fill.ts +++ b/packages/graphql-fixtures/src/fill.ts @@ -22,6 +22,8 @@ import { import {randomFromArray, chooseNull} from './utilities'; +// Re-export faker so that the exact version can be used by consumers +export {faker}; export interface FieldMetadata { fieldIndex?: number; fieldName: string; diff --git a/packages/graphql-fixtures/src/tests/fill.test.ts b/packages/graphql-fixtures/src/tests/fill.test.ts index 61235e3c9c..d42e61123f 100644 --- a/packages/graphql-fixtures/src/tests/fill.test.ts +++ b/packages/graphql-fixtures/src/tests/fill.test.ts @@ -1,9 +1,9 @@ -import faker from '@faker-js/faker/locale/en'; // eslint-disable-next-line @shopify/typescript/prefer-build-client-schema import {buildSchema} from 'graphql'; import {parse, DocumentNode} from 'graphql-typed'; +import originalFaker from '@faker-js/faker/locale/en'; -import {createFiller, list, Options} from '../fill'; +import {createFiller, list, Options, faker} from '../fill'; jest.mock('../utilities', () => { const utilities = jest.requireActual('../utilities'); @@ -1327,6 +1327,12 @@ describe('createFiller()', () => { }); }); +describe('faker', () => { + it('re-exports faker for use by consumers', () => { + expect(faker).toStrictEqual(originalFaker); + }); +}); + function createFillerForSchema(schema: string, options?: Options) { const filler = createFiller(buildSchema(schema), options); return ( From a69dcb27107a1a58a16e873b8537441e826e94d1 Mon Sep 17 00:00:00 2001 From: Ryan Wilson-Perkin Date: Wed, 2 Feb 2022 14:47:32 -0500 Subject: [PATCH 2/2] Update changelog --- packages/graphql-fixtures/CHANGELOG.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/graphql-fixtures/CHANGELOG.md b/packages/graphql-fixtures/CHANGELOG.md index 38fdd0a6af..2e3f406f7c 100644 --- a/packages/graphql-fixtures/CHANGELOG.md +++ b/packages/graphql-fixtures/CHANGELOG.md @@ -5,7 +5,11 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). - +## Unreleased + +### Changed + +- Re-export the instance of faker used in graphql-fixtures so that it can be leveraged easily by consumers [[#2155]](https://github.com/Shopify/quilt/pull/2155) ## 1.3.0 - 2022-02-01