From 0e592ed8bc0e9bab7c2dea6566c2d6310d3d8f00 Mon Sep 17 00:00:00 2001 From: Daniel Playfair Cal Date: Thu, 7 Aug 2025 16:47:44 +1000 Subject: [PATCH 1/4] test: add input type with a field which is a oneOf type --- .../typescript-mock-data.spec.ts.snap | 278 +++++++++++++++++- tests/typescript-mock-data.spec.ts | 18 +- 2 files changed, 277 insertions(+), 19 deletions(-) diff --git a/tests/__snapshots__/typescript-mock-data.spec.ts.snap b/tests/__snapshots__/typescript-mock-data.spec.ts.snap index e58554c..8095af4 100644 --- a/tests/__snapshots__/typescript-mock-data.spec.ts.snap +++ b/tests/__snapshots__/typescript-mock-data.spec.ts.snap @@ -70,6 +70,12 @@ export const aOneOfInput = (override?: OneOfInput): OneOfInput => { }; }; +export const aContainsOneOfInput = (overrides?: Partial): ContainsOneOfInput => { + return { + field: overrides && overrides.hasOwnProperty('field') ? overrides.field! : null, + }; +}; + export const aMutation = (overrides?: Partial): Mutation => { return { updateUser: overrides && overrides.hasOwnProperty('updateUser') ? overrides.updateUser! : null, @@ -155,6 +161,12 @@ export const aOneOfInput = (override?: OneOfInput): OneOfInput => { }; }; +export const aContainsOneOfInput = (overrides?: Partial): ContainsOneOfInput => { + return { + field: overrides && overrides.hasOwnProperty('field') ? overrides.field! : null, + }; +}; + export const aMutation = (overrides?: Partial): Mutation => { return { updateUser: overrides && overrides.hasOwnProperty('updateUser') ? overrides.updateUser! : null, @@ -240,6 +252,12 @@ export const mockOneOfInput = (override?: OneOfInput): OneOfInput => { }; }; +export const mockContainsOneOfInput = (overrides?: Partial): ContainsOneOfInput => { + return { + field: overrides && overrides.hasOwnProperty('field') ? overrides.field! : mockOneOfInput(), + }; +}; + export const mockMutation = (overrides?: Partial): Mutation => { return { updateUser: overrides && overrides.hasOwnProperty('updateUser') ? overrides.updateUser! : mockUser(), @@ -325,6 +343,12 @@ export const aOneOfInput = (override?: OneOfInput): OneOfInput => { }; }; +export const aContainsOneOfInput = (overrides?: Partial): ContainsOneOfInput => { + return { + field: overrides && overrides.hasOwnProperty('field') ? overrides.field! : aOneOfInput(), + }; +}; + export const aMutation = (overrides?: Partial): Mutation => { return { updateUser: overrides && overrides.hasOwnProperty('updateUser') ? overrides.updateUser! : aUser(), @@ -341,7 +365,7 @@ export const aQuery = (overrides?: Partial): Query => { `; exports[`should add enumsPrefix to imports 1`] = ` -"import { Avatar, User, WithAvatar, CamelCaseThing, PrefixedResponse, AbcType, ListType, UpdateUserInput, OneOfInput, Mutation, Query, Api } from './types/graphql'; +"import { Avatar, User, WithAvatar, CamelCaseThing, PrefixedResponse, AbcType, ListType, UpdateUserInput, OneOfInput, ContainsOneOfInput, Mutation, Query, Api } from './types/graphql'; export const anAvatar = (overrides?: Partial): Avatar => { return { @@ -411,6 +435,12 @@ export const aOneOfInput = (override?: OneOfInput): OneOfInput => { }; }; +export const aContainsOneOfInput = (overrides?: Partial): ContainsOneOfInput => { + return { + field: overrides && overrides.hasOwnProperty('field') ? overrides.field! : aOneOfInput(), + }; +}; + export const aMutation = (overrides?: Partial): Mutation => { return { updateUser: overrides && overrides.hasOwnProperty('updateUser') ? overrides.updateUser! : aUser(), @@ -497,6 +527,12 @@ export const aOneOfInput = (override?: Api.OneOfInput): Api.OneOfInput => { }; }; +export const aContainsOneOfInput = (overrides?: Partial): Api.ContainsOneOfInput => { + return { + field: overrides && overrides.hasOwnProperty('field') ? overrides.field! : aOneOfInput(), + }; +}; + export const aMutation = (overrides?: Partial): Api.Mutation => { return { updateUser: overrides && overrides.hasOwnProperty('updateUser') ? overrides.updateUser! : aUser(), @@ -582,6 +618,12 @@ export const aOneOfInput = (override?: Api.OneOfInput): Api.OneOfInput => { }; }; +export const aContainsOneOfInput = (overrides?: Partial): Api.ContainsOneOfInput => { + return { + field: overrides && overrides.hasOwnProperty('field') ? overrides.field! : aOneOfInput(), + }; +}; + export const aMutation = (overrides?: Partial): Api.Mutation => { return { updateUser: overrides && overrides.hasOwnProperty('updateUser') ? overrides.updateUser! : aUser(), @@ -668,6 +710,12 @@ export const aOneOfInput = (override?: Api.OneOfInput): Api.OneOfInput => { }; }; +export const aContainsOneOfInput = (overrides?: Partial): Api.ContainsOneOfInput => { + return { + field: overrides && overrides.hasOwnProperty('field') ? overrides.field! : aOneOfInput(), + }; +}; + export const aMutation = (overrides?: Partial): Api.Mutation => { return { updateUser: overrides && overrides.hasOwnProperty('updateUser') ? overrides.updateUser! : aUser(), @@ -753,6 +801,12 @@ export const aOneOfInput = (override?: OneOfInput): OneOfInput => { }; }; +export const aContainsOneOfInput = (overrides?: Partial): ContainsOneOfInput => { + return { + field: overrides && overrides.hasOwnProperty('field') ? overrides.field! : aOneOfInput(), + }; +}; + export const aMutation = (overrides?: Partial): Mutation => { return { updateUser: overrides && overrides.hasOwnProperty('updateUser') ? overrides.updateUser! : aUser(), @@ -838,6 +892,12 @@ export const aOneOfInput = (override?: OneOfInput): OneOfInput => { }; }; +export const aContainsOneOfInput = (overrides?: Partial): ContainsOneOfInput => { + return { + field: overrides && overrides.hasOwnProperty('field') ? overrides.field! : aOneOfInput(), + }; +}; + export const aMutation = (overrides?: Partial): Mutation => { return { updateUser: overrides && overrides.hasOwnProperty('updateUser') ? overrides.updateUser! : aUser(), @@ -923,6 +983,12 @@ export const aOneOfInput = (override?: OneOfInput): OneOfInput => { }; }; +export const aContainsOneOfInput = (overrides?: Partial): ContainsOneOfInput => { + return { + field: overrides && overrides.hasOwnProperty('field') ? overrides.field! : aOneOfInput(), + }; +}; + export const aMutation = (overrides?: Partial): Mutation => { return { updateUser: overrides && overrides.hasOwnProperty('updateUser') ? overrides.updateUser! : aUser(), @@ -1008,6 +1074,12 @@ export const aOneOfInput = (override?: OneOfInput): OneOfInput => { }; }; +export const aContainsOneOfInput = (overrides?: Partial): ContainsOneOfInput => { + return { + field: overrides && overrides.hasOwnProperty('field') ? overrides.field! : aOneOfInput(), + }; +}; + export const aMutation = (overrides?: Partial): Mutation => { return { updateUser: overrides && overrides.hasOwnProperty('updateUser') ? overrides.updateUser! : aUser(), @@ -1093,6 +1165,12 @@ export const aOneOfInput = (override?: OneOfInput): OneOfInput => { }; }; +export const aContainsOneOfInput = (overrides?: Partial): ContainsOneOfInput => { + return { + field: overrides && overrides.hasOwnProperty('field') ? overrides.field! : aOneOfInput(), + }; +}; + export const aMutation = (overrides?: Partial): Mutation => { return { updateUser: overrides && overrides.hasOwnProperty('updateUser') ? overrides.updateUser! : aUser(), @@ -1181,6 +1259,12 @@ export const aOneOfInput = (override?: OneOfInput): OneOfInput => { }; }; +export const aContainsOneOfInput = (overrides?: Partial): ContainsOneOfInput => { + return { + field: overrides && overrides.hasOwnProperty('field') ? overrides.field! : aOneOfInput(), + }; +}; + export const aMutation = (overrides?: Partial): Mutation => { return { updateUser: overrides && overrides.hasOwnProperty('updateUser') ? overrides.updateUser! : aUser(), @@ -1271,6 +1355,12 @@ export const aOneOfInput = (override?: OneOfInput): OneOfInput => { }; }; +export const aContainsOneOfInput = (overrides?: Partial): ContainsOneOfInput => { + return { + field: overrides && overrides.hasOwnProperty('field') ? overrides.field! : aOneOfInput(), + }; +}; + export const aMutation = (overrides?: Partial): Mutation => { return { updateUser: overrides && overrides.hasOwnProperty('updateUser') ? overrides.updateUser! : aUser(), @@ -1358,6 +1448,12 @@ export const aOneOfInput = (override?: OneOfInput): OneOfInput => { }; }; +export const aContainsOneOfInput = (overrides?: Partial): ContainsOneOfInput => { + return { + field: overrides && overrides.hasOwnProperty('field') ? overrides.field! : aOneOfInput(), + }; +}; + export const aMutation = (overrides?: Partial): Mutation => { return { updateUser: overrides && overrides.hasOwnProperty('updateUser') ? overrides.updateUser! : aUser(), @@ -1443,6 +1539,12 @@ export const aOneOfInput = (override?: OneOfInput): OneOfInput => { }; }; +export const aContainsOneOfInput = (overrides?: Partial): ContainsOneOfInput => { + return { + field: overrides && overrides.hasOwnProperty('field') ? overrides.field! : aOneOfInput(), + }; +}; + export const aMutation = (overrides?: Partial): Mutation => { return { updateUser: overrides && overrides.hasOwnProperty('updateUser') ? overrides.updateUser! : aUser(), @@ -1459,7 +1561,7 @@ export const aQuery = (overrides?: Partial): Query => { `; exports[`should generate mock data functions with external types file import 1`] = ` -"import { Avatar, User, WithAvatar, CamelCaseThing, PrefixedResponse, AbcType, ListType, UpdateUserInput, OneOfInput, Mutation, Query, AbcStatus, Status, PrefixedEnum } from './types/graphql'; +"import { Avatar, User, WithAvatar, CamelCaseThing, PrefixedResponse, AbcType, ListType, UpdateUserInput, OneOfInput, ContainsOneOfInput, Mutation, Query, AbcStatus, Status, PrefixedEnum } from './types/graphql'; export const anAvatar = (overrides?: Partial): Avatar => { return { @@ -1529,6 +1631,12 @@ export const aOneOfInput = (override?: OneOfInput): OneOfInput => { }; }; +export const aContainsOneOfInput = (overrides?: Partial): ContainsOneOfInput => { + return { + field: overrides && overrides.hasOwnProperty('field') ? overrides.field! : aOneOfInput(), + }; +}; + export const aMutation = (overrides?: Partial): Mutation => { return { updateUser: overrides && overrides.hasOwnProperty('updateUser') ? overrides.updateUser! : aUser(), @@ -1614,6 +1722,12 @@ export const aOneOfInput = (override?: OneOfInput): OneOfInput => { }; }; +export const aContainsOneOfInput = (overrides?: Partial): ContainsOneOfInput => { + return { + field: overrides && overrides.hasOwnProperty('field') ? overrides.field! : aOneOfInput(), + }; +}; + export const aMutation = (overrides?: Partial): Mutation => { return { updateUser: overrides && overrides.hasOwnProperty('updateUser') ? overrides.updateUser! : aUser(), @@ -1699,6 +1813,12 @@ export const aOneOfInput = (override?: OneOfInput): OneOfInput => { }; }; +export const aContainsOneOfInput = (overrides?: Partial): ContainsOneOfInput => { + return { + field: overrides && overrides.hasOwnProperty('field') ? overrides.field! : aOneOfInput(), + }; +}; + export const aMutation = (overrides?: Partial): Mutation => { return { updateUser: overrides && overrides.hasOwnProperty('updateUser') ? overrides.updateUser! : aUser(), @@ -1810,6 +1930,12 @@ export const aOneOfInput = (override?: OneOfInput): OneOfInput => { }; }; +export const aContainsOneOfInput = (overrides?: Partial): ContainsOneOfInput => { + return { + field: overrides && overrides.hasOwnProperty('field') ? overrides.field! : aOneOfInput(), + }; +}; + export const aMutation = (overrides?: Partial): Mutation => { return { updateUser: overrides && overrides.hasOwnProperty('updateUser') ? overrides.updateUser! : aUser(), @@ -1895,6 +2021,12 @@ export const aOneOfInput = (override?: OneOfInput): OneOfInput => { }; }; +export const aContainsOneOfInput = (overrides?: Partial): ContainsOneOfInput => { + return { + field: overrides && overrides.hasOwnProperty('field') ? overrides.field! : aOneOfInput(), + }; +}; + export const aMutation = (overrides?: Partial): Mutation => { return { updateUser: overrides && overrides.hasOwnProperty('updateUser') ? overrides.updateUser! : aUser(), @@ -1980,6 +2112,12 @@ export const aOneOfInput = (override?: OneOfInput): OneOfInput => { }; }; +export const aContainsOneOfInput = (overrides?: Partial): ContainsOneOfInput => { + return { + field: overrides && overrides.hasOwnProperty('field') ? overrides.field! : aOneOfInput(), + }; +}; + export const aMutation = (overrides?: Partial): Mutation => { return { updateUser: overrides && overrides.hasOwnProperty('updateUser') ? overrides.updateUser! : aUser(), @@ -1996,7 +2134,7 @@ export const aQuery = (overrides?: Partial): Query => { `; exports[`should generate mock data with PascalCase types and enums by default 1`] = ` -"import { Avatar, User, WithAvatar, CamelCaseThing, PrefixedResponse, AbcType, ListType, UpdateUserInput, OneOfInput, Mutation, Query, AbcStatus, Status, PrefixedEnum } from './types/graphql'; +"import { Avatar, User, WithAvatar, CamelCaseThing, PrefixedResponse, AbcType, ListType, UpdateUserInput, OneOfInput, ContainsOneOfInput, Mutation, Query, AbcStatus, Status, PrefixedEnum } from './types/graphql'; export const anAvatar = (overrides?: Partial): Avatar => { return { @@ -2066,6 +2204,12 @@ export const aOneOfInput = (override?: OneOfInput): OneOfInput => { }; }; +export const aContainsOneOfInput = (overrides?: Partial): ContainsOneOfInput => { + return { + field: overrides && overrides.hasOwnProperty('field') ? overrides.field! : aOneOfInput(), + }; +}; + export const aMutation = (overrides?: Partial): Mutation => { return { updateUser: overrides && overrides.hasOwnProperty('updateUser') ? overrides.updateUser! : aUser(), @@ -2151,6 +2295,12 @@ export const aOneOfInput = (override?: OneOfInput): OneOfInput => { }; }; +export const aContainsOneOfInput = (overrides?: Partial): ContainsOneOfInput => { + return { + field: overrides && overrides.hasOwnProperty('field') ? overrides.field! : aOneOfInput(), + }; +}; + export const aMutation = (overrides?: Partial): Mutation => { return { updateUser: overrides && overrides.hasOwnProperty('updateUser') ? overrides.updateUser! : aUser(), @@ -2236,6 +2386,12 @@ export const aOneOfInput = (override?: OneOfInput): OneOfInput => { }; }; +export const aContainsOneOfInput = (overrides?: Partial): ContainsOneOfInput => { + return { + field: overrides && overrides.hasOwnProperty('field') ? overrides.field! : aOneOfInput(), + }; +}; + export const aMutation = (overrides?: Partial): Mutation => { return { updateUser: overrides && overrides.hasOwnProperty('updateUser') ? overrides.updateUser! : aUser(), @@ -2321,6 +2477,12 @@ export const aOneOfInput = (override?: OneOfInput): OneOfInput => { }; }; +export const aContainsOneOfInput = (overrides?: Partial): ContainsOneOfInput => { + return { + field: overrides && overrides.hasOwnProperty('field') ? overrides.field! : aOneOfInput(), + }; +}; + export const aMutation = (overrides?: Partial): Mutation => { return { updateUser: overrides && overrides.hasOwnProperty('updateUser') ? overrides.updateUser! : aUser(), @@ -2406,6 +2568,12 @@ export const aOneOfInput = (override?: OneOfInput): OneOfInput => { }; }; +export const aContainsOneOfInput = (overrides?: Partial): ContainsOneOfInput => { + return { + field: overrides && overrides.hasOwnProperty('field') ? overrides.field! : aOneOfInput(), + }; +}; + export const aMutation = (overrides?: Partial): Mutation => { return { updateUser: overrides && overrides.hasOwnProperty('updateUser') ? overrides.updateUser! : aUser(), @@ -2491,6 +2659,12 @@ export const aOneOfInput = (override?: OneOfInput): OneOfInput => { }; }; +export const aContainsOneOfInput = (overrides?: Partial): ContainsOneOfInput => { + return { + field: overrides && overrides.hasOwnProperty('field') ? overrides.field! : aOneOfInput(), + }; +}; + export const aMutation = (overrides?: Partial): Mutation => { return { updateUser: overrides && overrides.hasOwnProperty('updateUser') ? overrides.updateUser! : aUser(), @@ -2583,6 +2757,12 @@ export const aOneOfInput = (override?: OneOfInput): OneOfInput => { }; }; +export const aContainsOneOfInput = (overrides?: Partial): ContainsOneOfInput => { + return { + field: overrides && overrides.hasOwnProperty('field') ? overrides.field! : aOneOfInput(), + }; +}; + export const aMutation = (overrides?: Partial): { __typename: 'Mutation' } & Mutation => { return { __typename: 'Mutation', @@ -2670,6 +2850,12 @@ export const aOneOfInput = (override?: OneOfInput): OneOfInput => { }; }; +export const aContainsOneOfInput = (overrides?: Partial): ContainsOneOfInput => { + return { + field: overrides && overrides.hasOwnProperty('field') ? overrides.field! : aOneOfInput(), + }; +}; + export const aMutation = (overrides?: Partial): Mutation => { return { updateUser: overrides && overrides.hasOwnProperty('updateUser') ? overrides.updateUser! : aUser(), @@ -2755,6 +2941,12 @@ export const aONEOFINPUT = (override?: ONEOFINPUT): ONEOFINPUT => { }; }; +export const aCONTAINSONEOFINPUT = (overrides?: Partial): CONTAINSONEOFINPUT => { + return { + field: overrides && overrides.hasOwnProperty('field') ? overrides.field! : aONEOFINPUT(), + }; +}; + export const aMUTATION = (overrides?: Partial): MUTATION => { return { updateUser: overrides && overrides.hasOwnProperty('updateUser') ? overrides.updateUser! : aUSER(), @@ -2771,7 +2963,7 @@ export const aQUERY = (overrides?: Partial): QUERY => { `; exports[`should generate mock data with upperCase types and imports if typeNames is "upper-case#upperCase" 1`] = ` -"import { AVATAR, USER, WITHAVATAR, CAMELCASETHING, PREFIXED_RESPONSE, ABCTYPE, LISTTYPE, UPDATEUSERINPUT, ONEOFINPUT, MUTATION, QUERY, ABCSTATUS, STATUS, PREFIXED_ENUM } from './types/graphql'; +"import { AVATAR, USER, WITHAVATAR, CAMELCASETHING, PREFIXED_RESPONSE, ABCTYPE, LISTTYPE, UPDATEUSERINPUT, ONEOFINPUT, CONTAINSONEOFINPUT, MUTATION, QUERY, ABCSTATUS, STATUS, PREFIXED_ENUM } from './types/graphql'; export const anAVATAR = (overrides?: Partial): AVATAR => { return { @@ -2841,6 +3033,12 @@ export const aONEOFINPUT = (override?: ONEOFINPUT): ONEOFINPUT => { }; }; +export const aCONTAINSONEOFINPUT = (overrides?: Partial): CONTAINSONEOFINPUT => { + return { + field: overrides && overrides.hasOwnProperty('field') ? overrides.field! : aONEOFINPUT(), + }; +}; + export const aMUTATION = (overrides?: Partial): MUTATION => { return { updateUser: overrides && overrides.hasOwnProperty('updateUser') ? overrides.updateUser! : aUSER(), @@ -2857,7 +3055,7 @@ export const aQUERY = (overrides?: Partial): QUERY => { `; exports[`should generate multiple list elements 1`] = ` -"import { Avatar, User, WithAvatar, CamelCaseThing, PrefixedResponse, AbcType, ListType, UpdateUserInput, OneOfInput, Mutation, Query, AbcStatus, Status, PrefixedEnum } from './types/graphql'; +"import { Avatar, User, WithAvatar, CamelCaseThing, PrefixedResponse, AbcType, ListType, UpdateUserInput, OneOfInput, ContainsOneOfInput, Mutation, Query, AbcStatus, Status, PrefixedEnum } from './types/graphql'; export const anAvatar = (overrides?: Partial): Avatar => { return { @@ -2927,6 +3125,12 @@ export const aOneOfInput = (override?: OneOfInput): OneOfInput => { }; }; +export const aContainsOneOfInput = (overrides?: Partial): ContainsOneOfInput => { + return { + field: overrides && overrides.hasOwnProperty('field') ? overrides.field! : aOneOfInput(), + }; +}; + export const aMutation = (overrides?: Partial): Mutation => { return { updateUser: overrides && overrides.hasOwnProperty('updateUser') ? overrides.updateUser! : aUser(), @@ -2943,7 +3147,7 @@ export const aQuery = (overrides?: Partial): Query => { `; exports[`should generate no list elements when listElementCount is 0 1`] = ` -"import { Avatar, User, WithAvatar, CamelCaseThing, PrefixedResponse, AbcType, ListType, UpdateUserInput, OneOfInput, Mutation, Query, AbcStatus, Status, PrefixedEnum } from './types/graphql'; +"import { Avatar, User, WithAvatar, CamelCaseThing, PrefixedResponse, AbcType, ListType, UpdateUserInput, OneOfInput, ContainsOneOfInput, Mutation, Query, AbcStatus, Status, PrefixedEnum } from './types/graphql'; export const anAvatar = (overrides?: Partial): Avatar => { return { @@ -3013,6 +3217,12 @@ export const aOneOfInput = (override?: OneOfInput): OneOfInput => { }; }; +export const aContainsOneOfInput = (overrides?: Partial): ContainsOneOfInput => { + return { + field: overrides && overrides.hasOwnProperty('field') ? overrides.field! : aOneOfInput(), + }; +}; + export const aMutation = (overrides?: Partial): Mutation => { return { updateUser: overrides && overrides.hasOwnProperty('updateUser') ? overrides.updateUser! : aUser(), @@ -3029,7 +3239,7 @@ export const aQuery = (overrides?: Partial): Query => { `; exports[`should generate single list element 1`] = ` -"import { Avatar, User, WithAvatar, CamelCaseThing, PrefixedResponse, AbcType, ListType, UpdateUserInput, OneOfInput, Mutation, Query, AbcStatus, Status, PrefixedEnum } from './types/graphql'; +"import { Avatar, User, WithAvatar, CamelCaseThing, PrefixedResponse, AbcType, ListType, UpdateUserInput, OneOfInput, ContainsOneOfInput, Mutation, Query, AbcStatus, Status, PrefixedEnum } from './types/graphql'; export const anAvatar = (overrides?: Partial): Avatar => { return { @@ -3099,6 +3309,12 @@ export const aOneOfInput = (override?: OneOfInput): OneOfInput => { }; }; +export const aContainsOneOfInput = (overrides?: Partial): ContainsOneOfInput => { + return { + field: overrides && overrides.hasOwnProperty('field') ? overrides.field! : aOneOfInput(), + }; +}; + export const aMutation = (overrides?: Partial): Mutation => { return { updateUser: overrides && overrides.hasOwnProperty('updateUser') ? overrides.updateUser! : aUser(), @@ -3115,7 +3331,7 @@ export const aQuery = (overrides?: Partial): Query => { `; exports[`should not merge imports into one if enumsPrefix does not contain dots 1`] = ` -"import { Avatar, User, WithAvatar, CamelCaseThing, PrefixedResponse, AbcType, ListType, UpdateUserInput, OneOfInput, Mutation, Query, ApiAbcStatus, ApiStatus, ApiPrefixedEnum } from './types/graphql'; +"import { Avatar, User, WithAvatar, CamelCaseThing, PrefixedResponse, AbcType, ListType, UpdateUserInput, OneOfInput, ContainsOneOfInput, Mutation, Query, ApiAbcStatus, ApiStatus, ApiPrefixedEnum } from './types/graphql'; export const anAvatar = (overrides?: Partial): Avatar => { return { @@ -3185,6 +3401,12 @@ export const aOneOfInput = (override?: OneOfInput): OneOfInput => { }; }; +export const aContainsOneOfInput = (overrides?: Partial): ContainsOneOfInput => { + return { + field: overrides && overrides.hasOwnProperty('field') ? overrides.field! : aOneOfInput(), + }; +}; + export const aMutation = (overrides?: Partial): Mutation => { return { updateUser: overrides && overrides.hasOwnProperty('updateUser') ? overrides.updateUser! : aUser(), @@ -3201,7 +3423,7 @@ export const aQuery = (overrides?: Partial): Query => { `; exports[`should not merge imports into one if typesPrefix does not contain dots 1`] = ` -"import { ApiAvatar, ApiUser, ApiWithAvatar, ApiCamelCaseThing, ApiPrefixedResponse, ApiAbcType, ApiListType, ApiUpdateUserInput, ApiOneOfInput, ApiMutation, ApiQuery, AbcStatus, Status, PrefixedEnum } from './types/graphql'; +"import { ApiAvatar, ApiUser, ApiWithAvatar, ApiCamelCaseThing, ApiPrefixedResponse, ApiAbcType, ApiListType, ApiUpdateUserInput, ApiOneOfInput, ApiContainsOneOfInput, ApiMutation, ApiQuery, AbcStatus, Status, PrefixedEnum } from './types/graphql'; export const anAvatar = (overrides?: Partial): ApiAvatar => { return { @@ -3271,6 +3493,12 @@ export const aOneOfInput = (override?: ApiOneOfInput): ApiOneOfInput => { }; }; +export const aContainsOneOfInput = (overrides?: Partial): ApiContainsOneOfInput => { + return { + field: overrides && overrides.hasOwnProperty('field') ? overrides.field! : aOneOfInput(), + }; +}; + export const aMutation = (overrides?: Partial): ApiMutation => { return { updateUser: overrides && overrides.hasOwnProperty('updateUser') ? overrides.updateUser! : aUser(), @@ -3287,7 +3515,7 @@ export const aQuery = (overrides?: Partial): ApiQuery => { `; exports[`should preserve underscores if transformUnderscore is false 1`] = ` -"import { Avatar, User, WithAvatar, CamelCaseThing, Prefixed_Response, AbcType, ListType, UpdateUserInput, OneOfInput, Mutation, Query, AbcStatus, Status, Prefixed_Enum } from './types/graphql'; +"import { Avatar, User, WithAvatar, CamelCaseThing, Prefixed_Response, AbcType, ListType, UpdateUserInput, OneOfInput, ContainsOneOfInput, Mutation, Query, AbcStatus, Status, Prefixed_Enum } from './types/graphql'; export const anAvatar = (overrides?: Partial): Avatar => { return { @@ -3357,6 +3585,12 @@ export const aOneOfInput = (override?: OneOfInput): OneOfInput => { }; }; +export const aContainsOneOfInput = (overrides?: Partial): ContainsOneOfInput => { + return { + field: overrides && overrides.hasOwnProperty('field') ? overrides.field! : aOneOfInput(), + }; +}; + export const aMutation = (overrides?: Partial): Mutation => { return { updateUser: overrides && overrides.hasOwnProperty('updateUser') ? overrides.updateUser! : aUser(), @@ -3373,7 +3607,7 @@ export const aQuery = (overrides?: Partial): Query => { `; exports[`should preserve underscores if transformUnderscore is false and enumsAsTypes is true 1`] = ` -"import { Avatar, User, WithAvatar, CamelCaseThing, Prefixed_Response, AbcType, ListType, UpdateUserInput, OneOfInput, Mutation, Query } from './types/graphql'; +"import { Avatar, User, WithAvatar, CamelCaseThing, Prefixed_Response, AbcType, ListType, UpdateUserInput, OneOfInput, ContainsOneOfInput, Mutation, Query } from './types/graphql'; export const anAvatar = (overrides?: Partial): Avatar => { return { @@ -3443,6 +3677,12 @@ export const aOneOfInput = (override?: OneOfInput): OneOfInput => { }; }; +export const aContainsOneOfInput = (overrides?: Partial): ContainsOneOfInput => { + return { + field: overrides && overrides.hasOwnProperty('field') ? overrides.field! : aOneOfInput(), + }; +}; + export const aMutation = (overrides?: Partial): Mutation => { return { updateUser: overrides && overrides.hasOwnProperty('updateUser') ? overrides.updateUser! : aUser(), @@ -3459,7 +3699,7 @@ export const aQuery = (overrides?: Partial): Query => { `; exports[`should preserve underscores if transformUnderscore is false and enumsAsTypes is true as cast the enum type if useTypeImports is true 1`] = ` -"import type { Avatar, User, WithAvatar, CamelCaseThing, Prefixed_Response, AbcType, ListType, UpdateUserInput, OneOfInput, Mutation, Query, AbcStatus, Status, Prefixed_Enum } from './types/graphql'; +"import type { Avatar, User, WithAvatar, CamelCaseThing, Prefixed_Response, AbcType, ListType, UpdateUserInput, OneOfInput, ContainsOneOfInput, Mutation, Query, AbcStatus, Status, Prefixed_Enum } from './types/graphql'; export const anAvatar = (overrides?: Partial): Avatar => { return { @@ -3529,6 +3769,12 @@ export const aOneOfInput = (override?: OneOfInput): OneOfInput => { }; }; +export const aContainsOneOfInput = (overrides?: Partial): ContainsOneOfInput => { + return { + field: overrides && overrides.hasOwnProperty('field') ? overrides.field! : aOneOfInput(), + }; +}; + export const aMutation = (overrides?: Partial): Mutation => { return { updateUser: overrides && overrides.hasOwnProperty('updateUser') ? overrides.updateUser! : aUser(), @@ -3632,6 +3878,14 @@ export const aOneOfInput = (override?: OneOfInput, _relationshipsToOmit: Set, _relationshipsToOmit: Set = new Set()): ContainsOneOfInput => { + const relationshipsToOmit: Set = new Set(_relationshipsToOmit); + relationshipsToOmit.add('ContainsOneOfInput'); + return { + field: overrides && overrides.hasOwnProperty('field') ? overrides.field! : relationshipsToOmit.has('OneOfInput') ? {} as OneOfInput : aOneOfInput({}, relationshipsToOmit), + }; +}; + export const aMutation = (overrides?: Partial, _relationshipsToOmit: Set = new Set()): Mutation => { const relationshipsToOmit: Set = new Set(_relationshipsToOmit); relationshipsToOmit.add('Mutation'); diff --git a/tests/typescript-mock-data.spec.ts b/tests/typescript-mock-data.spec.ts index 6fec492..94da072 100644 --- a/tests/typescript-mock-data.spec.ts +++ b/tests/typescript-mock-data.spec.ts @@ -60,6 +60,10 @@ const testSchema = buildSchema(/* GraphQL */ ` oneOfFieldB: String } + input ContainsOneOfInput { + field: OneOfInput + } + enum ABCStatus { hasXYZStatus } @@ -136,7 +140,7 @@ it('should generate mock data functions with external types file import', async expect(result).toBeDefined(); expect(result).toContain( - "import { Avatar, User, WithAvatar, CamelCaseThing, PrefixedResponse, AbcType, ListType, UpdateUserInput, OneOfInput, Mutation, Query, AbcStatus, Status, PrefixedEnum } from './types/graphql';", + "import { Avatar, User, WithAvatar, CamelCaseThing, PrefixedResponse, AbcType, ListType, UpdateUserInput, OneOfInput, ContainsOneOfInput, Mutation, Query, AbcStatus, Status, PrefixedEnum } from './types/graphql';", ); expect(result).toMatchSnapshot(); }); @@ -394,7 +398,7 @@ it('should add enumsPrefix to imports', async () => { expect(result).toBeDefined(); expect(result).toContain( - "import { Avatar, User, WithAvatar, CamelCaseThing, PrefixedResponse, AbcType, ListType, UpdateUserInput, OneOfInput, Mutation, Query, Api } from './types/graphql';", + "import { Avatar, User, WithAvatar, CamelCaseThing, PrefixedResponse, AbcType, ListType, UpdateUserInput, OneOfInput, ContainsOneOfInput, Mutation, Query, Api } from './types/graphql';", ); expect(result).toMatchSnapshot(); }); @@ -419,7 +423,7 @@ it('should not merge imports into one if typesPrefix does not contain dots', asy expect(result).toBeDefined(); expect(result).toContain( - "import { ApiAvatar, ApiUser, ApiWithAvatar, ApiCamelCaseThing, ApiPrefixedResponse, ApiAbcType, ApiListType, ApiUpdateUserInput, ApiOneOfInput, ApiMutation, ApiQuery, AbcStatus, Status, PrefixedEnum } from './types/graphql';", + "import { ApiAvatar, ApiUser, ApiWithAvatar, ApiCamelCaseThing, ApiPrefixedResponse, ApiAbcType, ApiListType, ApiUpdateUserInput, ApiOneOfInput, ApiContainsOneOfInput, ApiMutation, ApiQuery, AbcStatus, Status, PrefixedEnum } from './types/graphql';", ); expect(result).toMatchSnapshot(); }); @@ -432,7 +436,7 @@ it('should not merge imports into one if enumsPrefix does not contain dots', asy expect(result).toBeDefined(); expect(result).toContain( - "import { Avatar, User, WithAvatar, CamelCaseThing, PrefixedResponse, AbcType, ListType, UpdateUserInput, OneOfInput, Mutation, Query, ApiAbcStatus, ApiStatus, ApiPrefixedEnum } from './types/graphql';", + "import { Avatar, User, WithAvatar, CamelCaseThing, PrefixedResponse, AbcType, ListType, UpdateUserInput, OneOfInput, ContainsOneOfInput, Mutation, Query, ApiAbcStatus, ApiStatus, ApiPrefixedEnum } from './types/graphql';", ); expect(result).toMatchSnapshot(); }); @@ -456,7 +460,7 @@ it('should preserve underscores if transformUnderscore is false', async () => { expect(result).toBeDefined(); expect(result).toContain( - "import { Avatar, User, WithAvatar, CamelCaseThing, Prefixed_Response, AbcType, ListType, UpdateUserInput, OneOfInput, Mutation, Query, AbcStatus, Status, Prefixed_Enum } from './types/graphql';", + "import { Avatar, User, WithAvatar, CamelCaseThing, Prefixed_Response, AbcType, ListType, UpdateUserInput, OneOfInput, ContainsOneOfInput, Mutation, Query, AbcStatus, Status, Prefixed_Enum } from './types/graphql';", ); expect(result).toContain( 'export const aPrefixed_Response = (overrides?: Partial): Prefixed_Response => {', @@ -476,7 +480,7 @@ it('should preserve underscores if transformUnderscore is false and enumsAsTypes expect(result).toBeDefined(); expect(result).toContain( - "import { Avatar, User, WithAvatar, CamelCaseThing, Prefixed_Response, AbcType, ListType, UpdateUserInput, OneOfInput, Mutation, Query } from './types/graphql';", + "import { Avatar, User, WithAvatar, CamelCaseThing, Prefixed_Response, AbcType, ListType, UpdateUserInput, OneOfInput, ContainsOneOfInput, Mutation, Query } from './types/graphql';", ); expect(result).toContain( 'export const aPrefixed_Response = (overrides?: Partial): Prefixed_Response => {', @@ -497,7 +501,7 @@ it('should preserve underscores if transformUnderscore is false and enumsAsTypes expect(result).toBeDefined(); expect(result).toContain( - "import type { Avatar, User, WithAvatar, CamelCaseThing, Prefixed_Response, AbcType, ListType, UpdateUserInput, OneOfInput, Mutation, Query, AbcStatus, Status, Prefixed_Enum } from './types/graphql';", + "import type { Avatar, User, WithAvatar, CamelCaseThing, Prefixed_Response, AbcType, ListType, UpdateUserInput, OneOfInput, ContainsOneOfInput, Mutation, Query, AbcStatus, Status, Prefixed_Enum } from './types/graphql';", ); expect(result).toContain( 'export const aPrefixed_Response = (overrides?: Partial): Prefixed_Response => {', From 9b0d2aa16ef620d58d33b9e385f122ea6c19dd9e Mon Sep 17 00:00:00 2001 From: Daniel Playfair Cal Date: Thu, 7 Aug 2025 18:38:42 +1000 Subject: [PATCH 2/4] fix input types containing fields which are input objects with oneOf directive --- src/index.ts | 19 ++- .../typescript-mock-data.spec.ts.snap | 117 +++++++++++++++++- tests/typescript-mock-data.spec.ts | 10 ++ 3 files changed, 144 insertions(+), 2 deletions(-) diff --git a/src/index.ts b/src/index.ts index 4811c19..2e23fe5 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,4 +1,4 @@ -import { parse, TypeNode, ASTKindToNode, ListTypeNode, NamedTypeNode, ObjectTypeDefinitionNode } from 'graphql'; +import { parse, TypeNode, ASTKindToNode, ListTypeNode, NamedTypeNode, ObjectTypeDefinitionNode, Kind } from 'graphql'; import * as allFakerLocales from '@faker-js/faker'; import casual from 'casual'; import { oldVisit, PluginFunction, resolveExternalModuleAndFn } from '@graphql-codegen/plugin-helpers'; @@ -409,6 +409,7 @@ const getNamedType = (opts: Options): throw `foundType is unknown: ${foundType.name}: ${foundType.type}`; } } + if (opts.terminateCircularRelationships) { return handleValueGeneration(opts, null, () => { if (opts.typesPrefix) { @@ -801,12 +802,28 @@ export const plugin: PluginFunction = (schema, docu } else if (node.fields) { mockFieldsString = node.fields .map((field) => { + const typeName = field.type.kind === Kind.NAMED_TYPE ? field.type.name.value : null; + const fieldIsOneOfType = Boolean( + typeName && + astNode.definitions.find( + (definition) => + definition.kind === Kind.INPUT_OBJECT_TYPE_DEFINITION && + definition.name.value === typeName && + definition.directives.some( + (directive) => directive.name.value === 'oneOf', + ), + ), + ); + const value = generateMockValue({ typeName: fieldName, fieldName: field.name.value, currentType: field.type, generatorMode: 'input', ...sharedGenerateMockOpts, + terminateCircularRelationships: fieldIsOneOfType + ? false + : sharedGenerateMockOpts.terminateCircularRelationships, }); const valueWithOverride = `overrides && overrides.hasOwnProperty('${field.name.value}') ? overrides.${field.name.value}! : ${value}`; diff --git a/tests/__snapshots__/typescript-mock-data.spec.ts.snap b/tests/__snapshots__/typescript-mock-data.spec.ts.snap index 8095af4..fcb83ce 100644 --- a/tests/__snapshots__/typescript-mock-data.spec.ts.snap +++ b/tests/__snapshots__/typescript-mock-data.spec.ts.snap @@ -1378,6 +1378,121 @@ export const seedMocks = (seed: number) => casual.seed(seed); " `; +exports[`should generate mock data for an input type containing a field with a oneOf directive 1`] = ` +" +export const anAvatar = (overrides?: Partial, _relationshipsToOmit: Set = new Set()): Avatar => { + const relationshipsToOmit: Set = _relationshipsToOmit; + relationshipsToOmit.add('Avatar'); + return { + id: overrides && overrides.hasOwnProperty('id') ? overrides.id! : '15f9c394-c8fc-46bc-a882-b3b853f28c03', + url: overrides && overrides.hasOwnProperty('url') ? overrides.url! : 'consectetur', + }; +}; + +export const aUser = (overrides?: Partial, _relationshipsToOmit: Set = new Set()): User => { + const relationshipsToOmit: Set = _relationshipsToOmit; + relationshipsToOmit.add('User'); + return { + id: overrides && overrides.hasOwnProperty('id') ? overrides.id! : 'b7605a2a-ad1e-4667-801e-5e47e5de933b', + creationDate: overrides && overrides.hasOwnProperty('creationDate') ? overrides.creationDate! : '2021-07-07T09:30:34.236Z', + login: overrides && overrides.hasOwnProperty('login') ? overrides.login! : 'sordeo', + avatar: overrides && overrides.hasOwnProperty('avatar') ? overrides.avatar! : relationshipsToOmit.has('Avatar') ? {} as Avatar : anAvatar({}, relationshipsToOmit), + status: overrides && overrides.hasOwnProperty('status') ? overrides.status! : Status.Online, + customStatus: overrides && overrides.hasOwnProperty('customStatus') ? overrides.customStatus! : AbcStatus.HasXyzStatus, + scalarValue: overrides && overrides.hasOwnProperty('scalarValue') ? overrides.scalarValue! : 'arx', + camelCaseThing: overrides && overrides.hasOwnProperty('camelCaseThing') ? overrides.camelCaseThing! : relationshipsToOmit.has('CamelCaseThing') ? {} as CamelCaseThing : aCamelCaseThing({}, relationshipsToOmit), + unionThing: overrides && overrides.hasOwnProperty('unionThing') ? overrides.unionThing! : relationshipsToOmit.has('Avatar') ? {} as Avatar : anAvatar({}, relationshipsToOmit), + prefixedEnum: overrides && overrides.hasOwnProperty('prefixedEnum') ? overrides.prefixedEnum! : PrefixedEnum.PrefixedValue, + }; +}; + +export const aWithAvatar = (overrides?: Partial, _relationshipsToOmit: Set = new Set()): WithAvatar => { + const relationshipsToOmit: Set = _relationshipsToOmit; + relationshipsToOmit.add('WithAvatar'); + return { + id: overrides && overrides.hasOwnProperty('id') ? overrides.id! : '9f1e2e6d-2047-44ac-ac43-58f18eff5255', + avatar: overrides && overrides.hasOwnProperty('avatar') ? overrides.avatar! : relationshipsToOmit.has('Avatar') ? {} as Avatar : anAvatar({}, relationshipsToOmit), + }; +}; + +export const aCamelCaseThing = (overrides?: Partial, _relationshipsToOmit: Set = new Set()): CamelCaseThing => { + const relationshipsToOmit: Set = _relationshipsToOmit; + relationshipsToOmit.add('CamelCaseThing'); + return { + id: overrides && overrides.hasOwnProperty('id') ? overrides.id! : '259f1f94-0fee-4e7d-8280-96dd5d8d9177', + }; +}; + +export const aPrefixedResponse = (overrides?: Partial, _relationshipsToOmit: Set = new Set()): PrefixedResponse => { + const relationshipsToOmit: Set = _relationshipsToOmit; + relationshipsToOmit.add('PrefixedResponse'); + return { + ping: overrides && overrides.hasOwnProperty('ping') ? overrides.ping! : 'nam', + }; +}; + +export const anAbcType = (overrides?: Partial, _relationshipsToOmit: Set = new Set()): AbcType => { + const relationshipsToOmit: Set = _relationshipsToOmit; + relationshipsToOmit.add('AbcType'); + return { + abc: overrides && overrides.hasOwnProperty('abc') ? overrides.abc! : 'accommodo', + }; +}; + +export const aListType = (overrides?: Partial, _relationshipsToOmit: Set = new Set()): ListType => { + const relationshipsToOmit: Set = _relationshipsToOmit; + relationshipsToOmit.add('ListType'); + return { + stringList: overrides && overrides.hasOwnProperty('stringList') ? overrides.stringList! : ['accusator'], + nullableStringList: overrides && overrides.hasOwnProperty('nullableStringList') ? overrides.nullableStringList! : ['tricesimus'], + }; +}; + +export const anUpdateUserInput = (overrides?: Partial, _relationshipsToOmit: Set = new Set()): UpdateUserInput => { + const relationshipsToOmit: Set = _relationshipsToOmit; + relationshipsToOmit.add('UpdateUserInput'); + return { + id: overrides && overrides.hasOwnProperty('id') ? overrides.id! : '0696d260-ef45-407d-ac64-e375cbd7e441', + login: overrides && overrides.hasOwnProperty('login') ? overrides.login! : 'apud', + avatar: overrides && overrides.hasOwnProperty('avatar') ? overrides.avatar! : relationshipsToOmit.has('Avatar') ? {} as Avatar : anAvatar({}, relationshipsToOmit), + }; +}; + +export const aOneOfInput = (override?: OneOfInput, _relationshipsToOmit: Set = new Set()): OneOfInput => { + const relationshipsToOmit: Set = _relationshipsToOmit; + relationshipsToOmit.add('OneOfInput'); + return { + ...(override ? override : {oneOfFieldA : 'tibi'}), + }; +}; + +export const aContainsOneOfInput = (overrides?: Partial, _relationshipsToOmit: Set = new Set()): ContainsOneOfInput => { + const relationshipsToOmit: Set = _relationshipsToOmit; + relationshipsToOmit.add('ContainsOneOfInput'); + return { + field: overrides && overrides.hasOwnProperty('field') ? overrides.field! : aOneOfInput(), + }; +}; + +export const aMutation = (overrides?: Partial, _relationshipsToOmit: Set = new Set()): Mutation => { + const relationshipsToOmit: Set = _relationshipsToOmit; + relationshipsToOmit.add('Mutation'); + return { + updateUser: overrides && overrides.hasOwnProperty('updateUser') ? overrides.updateUser! : relationshipsToOmit.has('User') ? {} as User : aUser({}, relationshipsToOmit), + }; +}; + +export const aQuery = (overrides?: Partial, _relationshipsToOmit: Set = new Set()): Query => { + const relationshipsToOmit: Set = _relationshipsToOmit; + relationshipsToOmit.add('Query'); + return { + user: overrides && overrides.hasOwnProperty('user') ? overrides.user! : relationshipsToOmit.has('User') ? {} as User : aUser({}, relationshipsToOmit), + prefixed_query: overrides && overrides.hasOwnProperty('prefixed_query') ? overrides.prefixed_query! : relationshipsToOmit.has('PrefixedResponse') ? {} as PrefixedResponse : aPrefixedResponse({}, relationshipsToOmit), + }; +}; +" +`; + exports[`should generate mock data functions 1`] = ` " export const anAvatar = (overrides?: Partial): Avatar => { @@ -3882,7 +3997,7 @@ export const aContainsOneOfInput = (overrides?: Partial, _re const relationshipsToOmit: Set = new Set(_relationshipsToOmit); relationshipsToOmit.add('ContainsOneOfInput'); return { - field: overrides && overrides.hasOwnProperty('field') ? overrides.field! : relationshipsToOmit.has('OneOfInput') ? {} as OneOfInput : aOneOfInput({}, relationshipsToOmit), + field: overrides && overrides.hasOwnProperty('field') ? overrides.field! : aOneOfInput(), }; }; diff --git a/tests/typescript-mock-data.spec.ts b/tests/typescript-mock-data.spec.ts index 94da072..305805b 100644 --- a/tests/typescript-mock-data.spec.ts +++ b/tests/typescript-mock-data.spec.ts @@ -135,6 +135,16 @@ it('should generate mock data for an input type with a oneOf directive', async ( expect(result).toContain(`...(override ? override : {oneOfFieldA : 'tibi'}),`); }); +it('should generate mock data for an input type containing a field with a oneOf directive', async () => { + const result = await plugin(testSchema, [], { + terminateCircularRelationships: 'immediate', + }); + + expect(result).toBeDefined(); + + expect(result).toMatchSnapshot(); +}); + it('should generate mock data functions with external types file import', async () => { const result = await plugin(testSchema, [], { typesFile: './types/graphql.ts' }); From a5eaefe03a3e5adc5fe367db729db31d91350798 Mon Sep 17 00:00:00 2001 From: Daniel Playfair Cal Date: Fri, 8 Aug 2025 11:35:40 +1000 Subject: [PATCH 3/4] simplify implementation --- src/index.ts | 28 ++++++++++------------------ 1 file changed, 10 insertions(+), 18 deletions(-) diff --git a/src/index.ts b/src/index.ts index 2e23fe5..9efb6e5 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,4 +1,4 @@ -import { parse, TypeNode, ASTKindToNode, ListTypeNode, NamedTypeNode, ObjectTypeDefinitionNode, Kind } from 'graphql'; +import { parse, TypeNode, ASTKindToNode, ListTypeNode, NamedTypeNode, ObjectTypeDefinitionNode } from 'graphql'; import * as allFakerLocales from '@faker-js/faker'; import casual from 'casual'; import { oldVisit, PluginFunction, resolveExternalModuleAndFn } from '@graphql-codegen/plugin-helpers'; @@ -34,6 +34,7 @@ type Options = { defaultNullableToNull: boolean; nonNull: boolean; typeNamesMapping?: Record; + inputOneOfTypes: Set; }; const getTerminateCircularRelationshipsConfig = ({ terminateCircularRelationships }: TypescriptMocksPluginConfig) => @@ -410,7 +411,7 @@ const getNamedType = (opts: Options): } } - if (opts.terminateCircularRelationships) { + if (opts.terminateCircularRelationships && !opts.inputOneOfTypes.has(opts.currentType.name.value)) { return handleValueGeneration(opts, null, () => { if (opts.typesPrefix) { const typeNameConverter = createNameConverter( @@ -688,6 +689,7 @@ export const plugin: PluginFunction = (schema, docu // List of types that are enums const types: TypeItem[] = []; + const inputOneOfTypes: Set = new Set(); const typeVisitor: VisitorType = { EnumTypeDefinition: (node) => { const name = node.name.value; @@ -724,6 +726,11 @@ export const plugin: PluginFunction = (schema, docu } } }, + InputObjectTypeDefinition: (node) => { + if (node.directives.some((directive) => directive.name.value === 'oneOf')) { + inputOneOfTypes.add(node.name.value); + } + }, ScalarTypeDefinition: (node) => { const name = node.name.value; if (!types.find((scalarType) => scalarType.name === name)) { @@ -756,6 +763,7 @@ export const plugin: PluginFunction = (schema, docu typesPrefix: config.typesPrefix, useImplementingTypes, useTypeImports, + inputOneOfTypes, }; const visitor: VisitorType = { @@ -802,28 +810,12 @@ export const plugin: PluginFunction = (schema, docu } else if (node.fields) { mockFieldsString = node.fields .map((field) => { - const typeName = field.type.kind === Kind.NAMED_TYPE ? field.type.name.value : null; - const fieldIsOneOfType = Boolean( - typeName && - astNode.definitions.find( - (definition) => - definition.kind === Kind.INPUT_OBJECT_TYPE_DEFINITION && - definition.name.value === typeName && - definition.directives.some( - (directive) => directive.name.value === 'oneOf', - ), - ), - ); - const value = generateMockValue({ typeName: fieldName, fieldName: field.name.value, currentType: field.type, generatorMode: 'input', ...sharedGenerateMockOpts, - terminateCircularRelationships: fieldIsOneOfType - ? false - : sharedGenerateMockOpts.terminateCircularRelationships, }); const valueWithOverride = `overrides && overrides.hasOwnProperty('${field.name.value}') ? overrides.${field.name.value}! : ${value}`; From 633536366aa1dc1f8e322c6ca4e4e9be3aa718ef Mon Sep 17 00:00:00 2001 From: Daniel Playfair Cal Date: Fri, 8 Aug 2025 11:49:51 +1000 Subject: [PATCH 4/4] add assertion in test --- tests/typescript-mock-data.spec.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/typescript-mock-data.spec.ts b/tests/typescript-mock-data.spec.ts index 305805b..5050937 100644 --- a/tests/typescript-mock-data.spec.ts +++ b/tests/typescript-mock-data.spec.ts @@ -141,7 +141,9 @@ it('should generate mock data for an input type containing a field with a oneOf }); expect(result).toBeDefined(); - + expect(result).toContain( + `field: overrides && overrides.hasOwnProperty('field') ? overrides.field! : aOneOfInput(),`, + ); expect(result).toMatchSnapshot(); });