Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ type Options<T = TypeNode> = {
generateLibrary: 'casual' | 'faker';
fieldGeneration?: TypeFieldMap;
enumsAsTypes?: boolean;
useTypeImports?: boolean;
useImplementingTypes: boolean;
defaultNullableToNull: boolean;
nonNull: boolean;
Expand Down Expand Up @@ -319,7 +320,9 @@ const getNamedType = (opts: Options<NamedTypeNode | ObjectTypeDefinitionNode>):
const value = foundType.values ? foundType.values[0] : '';
return handleValueGeneration(opts, undefined, () =>
opts.enumsAsTypes
? `'${value}'`
? opts.useTypeImports
? `('${value}' as ${typenameConverter(foundType.name, opts.enumsPrefix)})`
: `'${value}'`
: `${typenameConverter(foundType.name, opts.enumsPrefix)}.${enumConverter(value)}`,
);
}
Expand Down Expand Up @@ -487,7 +490,7 @@ const getImportTypes = ({
? [enumsPrefix.slice(0, -1)]
: types.filter(({ type }) => type === 'enum').map(({ name }) => typenameConverter(name, enumsPrefix));

if (!enumsAsTypes) {
if (!enumsAsTypes || useTypeImports) {
typeImports.push(...enumTypes);
}

Expand Down Expand Up @@ -587,6 +590,7 @@ export const plugin: PluginFunction<TypescriptMocksPluginConfig> = (schema, docu
const dynamicValues = !!config.dynamicValues;
const generateLibrary = config.generateLibrary || 'casual';
const enumsAsTypes = config.enumsAsTypes ?? false;
const useTypeImports = config.useTypeImports ?? false;
const useImplementingTypes = config.useImplementingTypes ?? false;
const defaultNullableToNull = config.defaultNullableToNull ?? false;

Expand Down Expand Up @@ -667,6 +671,7 @@ export const plugin: PluginFunction<TypescriptMocksPluginConfig> = (schema, docu
generateLibrary,
fieldGeneration: config.fieldGeneration,
enumsAsTypes,
useTypeImports,
useImplementingTypes,
defaultNullableToNull,
nonNull: false,
Expand Down Expand Up @@ -703,6 +708,7 @@ export const plugin: PluginFunction<TypescriptMocksPluginConfig> = (schema, docu
generateLibrary,
fieldGeneration: config.fieldGeneration,
enumsAsTypes,
useTypeImports,
useImplementingTypes,
defaultNullableToNull,
nonNull: false,
Expand Down
159 changes: 159 additions & 0 deletions tests/__snapshots__/typescript-mock-data.spec.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -2227,6 +2227,85 @@ export const aQuery = (overrides?: Partial<Query>): Query => {
"
`;

exports[`should generate mock data with enum values as string union type if enumsAsTypes is true and cast the type if useTypeImports 1`] = `
"
export const anAvatar = (overrides?: Partial<Avatar>): Avatar => {
return {
id: overrides && overrides.hasOwnProperty('id') ? overrides.id! : '0550ff93-dd31-49b4-8c38-ff1cb68bdc38',
url: overrides && overrides.hasOwnProperty('url') ? overrides.url! : 'aliquid',
};
};

export const aUser = (overrides?: Partial<User>): User => {
return {
id: overrides && overrides.hasOwnProperty('id') ? overrides.id! : 'a5756f00-41a6-422a-8a7d-d13ee6a63750',
creationDate: overrides && overrides.hasOwnProperty('creationDate') ? overrides.creationDate! : '1970-01-09T16:33:21.532Z',
login: overrides && overrides.hasOwnProperty('login') ? overrides.login! : 'libero',
avatar: overrides && overrides.hasOwnProperty('avatar') ? overrides.avatar! : anAvatar(),
status: overrides && overrides.hasOwnProperty('status') ? overrides.status! : ('ONLINE' as Status),
customStatus: overrides && overrides.hasOwnProperty('customStatus') ? overrides.customStatus! : ('hasXYZStatus' as AbcStatus),
scalarValue: overrides && overrides.hasOwnProperty('scalarValue') ? overrides.scalarValue! : 'neque',
camelCaseThing: overrides && overrides.hasOwnProperty('camelCaseThing') ? overrides.camelCaseThing! : aCamelCaseThing(),
unionThing: overrides && overrides.hasOwnProperty('unionThing') ? overrides.unionThing! : anAvatar(),
prefixedEnum: overrides && overrides.hasOwnProperty('prefixedEnum') ? overrides.prefixedEnum! : ('PREFIXED_VALUE' as PrefixedEnum),
};
};

export const aWithAvatar = (overrides?: Partial<WithAvatar>): WithAvatar => {
return {
id: overrides && overrides.hasOwnProperty('id') ? overrides.id! : '89f515e7-31e0-461d-a230-c4c7f4dafc5c',
avatar: overrides && overrides.hasOwnProperty('avatar') ? overrides.avatar! : anAvatar(),
};
};

export const aCamelCaseThing = (overrides?: Partial<CamelCaseThing>): CamelCaseThing => {
return {
id: overrides && overrides.hasOwnProperty('id') ? overrides.id! : '345b9cf9-00fa-4974-800f-aeee5ee7fd42',
};
};

export const aPrefixedResponse = (overrides?: Partial<PrefixedResponse>): PrefixedResponse => {
return {
ping: overrides && overrides.hasOwnProperty('ping') ? overrides.ping! : 'sunt',
};
};

export const anAbcType = (overrides?: Partial<AbcType>): AbcType => {
return {
abc: overrides && overrides.hasOwnProperty('abc') ? overrides.abc! : 'sit',
};
};

export const aListType = (overrides?: Partial<ListType>): ListType => {
return {
stringList: overrides && overrides.hasOwnProperty('stringList') ? overrides.stringList! : ['voluptatem'],
nullableStringList: overrides && overrides.hasOwnProperty('nullableStringList') ? overrides.nullableStringList! : ['eum'],
};
};

export const anUpdateUserInput = (overrides?: Partial<UpdateUserInput>): UpdateUserInput => {
return {
id: overrides && overrides.hasOwnProperty('id') ? overrides.id! : '1d6a9360-c92b-4660-8e5f-04155047bddc',
login: overrides && overrides.hasOwnProperty('login') ? overrides.login! : 'qui',
avatar: overrides && overrides.hasOwnProperty('avatar') ? overrides.avatar! : anAvatar(),
};
};

export const aMutation = (overrides?: Partial<Mutation>): Mutation => {
return {
updateUser: overrides && overrides.hasOwnProperty('updateUser') ? overrides.updateUser! : aUser(),
};
};

export const aQuery = (overrides?: Partial<Query>): Query => {
return {
user: overrides && overrides.hasOwnProperty('user') ? overrides.user! : aUser(),
prefixed_query: overrides && overrides.hasOwnProperty('prefixed_query') ? overrides.prefixed_query! : aPrefixedResponse(),
};
};
"
`;

exports[`should generate mock data with typename if addTypename is true 1`] = `
"
export const anAvatar = (overrides?: Partial<Avatar>): { __typename: 'Avatar' } & Avatar => {
Expand Down Expand Up @@ -3113,6 +3192,86 @@ export const aQuery = (overrides?: Partial<Query>): 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, Mutation, Query, AbcStatus, Status, Prefixed_Enum } from './types/graphql';

export const anAvatar = (overrides?: Partial<Avatar>): Avatar => {
return {
id: overrides && overrides.hasOwnProperty('id') ? overrides.id! : '0550ff93-dd31-49b4-8c38-ff1cb68bdc38',
url: overrides && overrides.hasOwnProperty('url') ? overrides.url! : 'aliquid',
};
};

export const aUser = (overrides?: Partial<User>): User => {
return {
id: overrides && overrides.hasOwnProperty('id') ? overrides.id! : 'a5756f00-41a6-422a-8a7d-d13ee6a63750',
creationDate: overrides && overrides.hasOwnProperty('creationDate') ? overrides.creationDate! : '1970-01-09T16:33:21.532Z',
login: overrides && overrides.hasOwnProperty('login') ? overrides.login! : 'libero',
avatar: overrides && overrides.hasOwnProperty('avatar') ? overrides.avatar! : anAvatar(),
status: overrides && overrides.hasOwnProperty('status') ? overrides.status! : ('ONLINE' as Status),
customStatus: overrides && overrides.hasOwnProperty('customStatus') ? overrides.customStatus! : ('hasXYZStatus' as AbcStatus),
scalarValue: overrides && overrides.hasOwnProperty('scalarValue') ? overrides.scalarValue! : 'neque',
camelCaseThing: overrides && overrides.hasOwnProperty('camelCaseThing') ? overrides.camelCaseThing! : aCamelCaseThing(),
unionThing: overrides && overrides.hasOwnProperty('unionThing') ? overrides.unionThing! : anAvatar(),
prefixedEnum: overrides && overrides.hasOwnProperty('prefixedEnum') ? overrides.prefixedEnum! : ('PREFIXED_VALUE' as Prefixed_Enum),
};
};

export const aWithAvatar = (overrides?: Partial<WithAvatar>): WithAvatar => {
return {
id: overrides && overrides.hasOwnProperty('id') ? overrides.id! : '89f515e7-31e0-461d-a230-c4c7f4dafc5c',
avatar: overrides && overrides.hasOwnProperty('avatar') ? overrides.avatar! : anAvatar(),
};
};

export const aCamelCaseThing = (overrides?: Partial<CamelCaseThing>): CamelCaseThing => {
return {
id: overrides && overrides.hasOwnProperty('id') ? overrides.id! : '345b9cf9-00fa-4974-800f-aeee5ee7fd42',
};
};

export const aPrefixed_Response = (overrides?: Partial<Prefixed_Response>): Prefixed_Response => {
return {
ping: overrides && overrides.hasOwnProperty('ping') ? overrides.ping! : 'sunt',
};
};

export const anAbcType = (overrides?: Partial<AbcType>): AbcType => {
return {
abc: overrides && overrides.hasOwnProperty('abc') ? overrides.abc! : 'sit',
};
};

export const aListType = (overrides?: Partial<ListType>): ListType => {
return {
stringList: overrides && overrides.hasOwnProperty('stringList') ? overrides.stringList! : ['voluptatem'],
nullableStringList: overrides && overrides.hasOwnProperty('nullableStringList') ? overrides.nullableStringList! : ['eum'],
};
};

export const anUpdateUserInput = (overrides?: Partial<UpdateUserInput>): UpdateUserInput => {
return {
id: overrides && overrides.hasOwnProperty('id') ? overrides.id! : '1d6a9360-c92b-4660-8e5f-04155047bddc',
login: overrides && overrides.hasOwnProperty('login') ? overrides.login! : 'qui',
avatar: overrides && overrides.hasOwnProperty('avatar') ? overrides.avatar! : anAvatar(),
};
};

export const aMutation = (overrides?: Partial<Mutation>): Mutation => {
return {
updateUser: overrides && overrides.hasOwnProperty('updateUser') ? overrides.updateUser! : aUser(),
};
};

export const aQuery = (overrides?: Partial<Query>): Query => {
return {
user: overrides && overrides.hasOwnProperty('user') ? overrides.user! : aUser(),
prefixed_query: overrides && overrides.hasOwnProperty('prefixed_query') ? overrides.prefixed_query! : aPrefixed_Response(),
};
};
"
`;

exports[`should use relationshipsToOmit argument to terminate circular relationships with terminateCircularRelationships enabled 1`] = `
"
export const anAvatar = (overrides?: Partial<Avatar>, _relationshipsToOmit: Set<string> = new Set()): Avatar => {
Expand Down
15 changes: 15 additions & 0 deletions tests/enumValues/__snapshots__/spec.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,21 @@ export const aMyType = (overrides?: Partial<MyType>): MyType => {
"
`;
exports[`enumValues config having 'keep' value should have no effect if 'transformUnderscore' is false and 'useTypeImports' is true 1`] = `
"
export const aMyType = (overrides?: Partial<MyType>): MyType => {
return {
underscoreEnum: overrides && overrides.hasOwnProperty('underscoreEnum') ? overrides.underscoreEnum! : ('_id' as UnderscoreEnum),
pascalCaseEnum: overrides && overrides.hasOwnProperty('pascalCaseEnum') ? overrides.pascalCaseEnum! : ('PascalCase' as PascalCaseEnum),
camelCaseEnum: overrides && overrides.hasOwnProperty('camelCaseEnum') ? overrides.camelCaseEnum! : ('camelCase' as CamelCaseEnum),
snakeCaseEnum: overrides && overrides.hasOwnProperty('snakeCaseEnum') ? overrides.snakeCaseEnum! : ('snake_case' as SnakeCaseEnum),
screamingSnakeCaseEnum: overrides && overrides.hasOwnProperty('screamingSnakeCaseEnum') ? overrides.screamingSnakeCaseEnum! : ('SCREAMING_SNAKE_CASE' as ScreamingSnakeCaseEnum),
pascalCase_withUnderscore: overrides && overrides.hasOwnProperty('pascalCase_withUnderscore') ? overrides.pascalCase_withUnderscore! : ('other_snake_case' as PascalCase_WithUnderscore),
};
};
"
`;
exports[`enumValues config having 'keep' value should keep case 1`] = `
"
export const aMyType = (overrides?: Partial<MyType>): MyType => {
Expand Down
18 changes: 18 additions & 0 deletions tests/enumValues/spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,24 @@ describe('enumValues config', () => {
expect(result).toContain('other_snake_case');
expect(result).toMatchSnapshot();
});

it(`should have no effect if 'transformUnderscore' is false and 'useTypeImports' is true`, async () => {
const result = await plugin(enumSchema, [], {
enumValues: 'keep',
transformUnderscore: false,
enumsAsTypes: true,
useTypeImports: true,
});

expect(result).toBeDefined();
expect(result).toContain('_id');
expect(result).toContain(`('PascalCase' as PascalCaseEnum)`);
expect(result).toContain(`('camelCase' as CamelCaseEnum)`);
expect(result).toContain(`('snake_case' as SnakeCaseEnum)`);
expect(result).toContain(`('SCREAMING_SNAKE_CASE' as ScreamingSnakeCaseEnum)`);
expect(result).toContain(`('other_snake_case' as PascalCase_WithUnderscore)`);
expect(result).toMatchSnapshot();
});
});

describe(`having default value`, () => {
Expand Down
34 changes: 34 additions & 0 deletions tests/typescript-mock-data.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,19 @@ it('should generate mock data with enum values as string union type if enumsAsTy
expect(result).toMatchSnapshot();
});

it('should generate mock data with enum values as string union type if enumsAsTypes is true and cast the type if useTypeImports', async () => {
const result = await plugin(testSchema, [], { enumsAsTypes: true, useTypeImports: true });

expect(result).toBeDefined();
expect(result).not.toContain('Status.Online');
expect(result).toContain(`('ONLINE' as Status)`);
expect(result).not.toContain('ABCStatus.hasXYZStatus');
expect(result).toContain(`('hasXYZStatus' as AbcStatus)`);
expect(result).not.toContain('Prefixed_Enum.PREFIXED_VALUE');
expect(result).toContain(`('PREFIXED_VALUE' as PrefixedEnum)`);
expect(result).toMatchSnapshot();
});

it('should generate mock data with as-is enum values as string union type if enumsAsTypes is true and enumValues is "keep"', async () => {
const result = await plugin(testSchema, [], { enumsAsTypes: true, enumValues: 'keep' });

Expand Down Expand Up @@ -457,6 +470,27 @@ it('should preserve underscores if transformUnderscore is false and enumsAsTypes
expect(result).toMatchSnapshot();
});

it('should preserve underscores if transformUnderscore is false and enumsAsTypes is true as cast the enum type if useTypeImports is true', async () => {
const result = await plugin(testSchema, [], {
transformUnderscore: false,
typesFile: './types/graphql.ts',
enumsAsTypes: true,
useTypeImports: true,
});

expect(result).toBeDefined();
expect(result).toContain(
"import type { Avatar, User, WithAvatar, CamelCaseThing, Prefixed_Response, AbcType, ListType, UpdateUserInput, Mutation, Query, AbcStatus, Status, Prefixed_Enum } from './types/graphql';",
);
expect(result).toContain(
'export const aPrefixed_Response = (overrides?: Partial<Prefixed_Response>): Prefixed_Response => {',
);
expect(result).toContain(
"prefixedEnum: overrides && overrides.hasOwnProperty('prefixedEnum') ? overrides.prefixedEnum! : ('PREFIXED_VALUE' as Prefixed_Enum),",
);
expect(result).toMatchSnapshot();
});

it('should generate single list element', async () => {
const result = await plugin(testSchema, [], {
typesFile: './types/graphql.ts',
Expand Down