Skip to content

Commit cd8acc9

Browse files
authored
feat: allow users to specify the prefix of mock builders (#25)
1 parent 1e292c8 commit cd8acc9

File tree

4 files changed

+75
-5
lines changed

4 files changed

+75
-5
lines changed

README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,11 @@ Defines the file path containing all GraphQL types. This file can also be genera
1818

1919
Adds `__typename` property to mock data
2020

21+
### prefix (`string`, defaultValue: `a` for constants & `an` for vowels)
22+
23+
The prefix to add to the mock function name. Cannot be empty since it will clash with the associated
24+
typescript definition from `@graphql-codegen/typescript`
25+
2126
### enumValues (`string`, defaultValue: `pascal-case#pascalCase`)
2227

2328
Changes the case of the enums. Accepts `upper-case#upperCase`, `pascal-case#pascalCase` or `keep`

src/index.ts

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,10 @@ const createNameConverter = (convention: NamingConvention) => (value: string) =>
2020
}
2121
};
2222

23-
const toMockName = (name: string) => {
23+
const toMockName = (name: string, prefix?: string) => {
24+
if (prefix) {
25+
return `${prefix}${name}`;
26+
}
2427
const isVowel = name.match(/^[AEIO]/);
2528
return isVowel ? `an${name}` : `a${name}`;
2629
};
@@ -59,6 +62,7 @@ const getNamedType = (
5962
types: TypeItem[],
6063
typenamesConvention: NamingConvention,
6164
enumValuesConvention: NamingConvention,
65+
prefix?: string,
6266
namedType?: NamedTypeNode,
6367
): string | number | boolean => {
6468
if (!namedType) {
@@ -98,6 +102,7 @@ const getNamedType = (
98102
types,
99103
typenamesConvention,
100104
enumValuesConvention,
105+
prefix,
101106
foundType.types && foundType.types[0],
102107
);
103108
case 'scalar':
@@ -108,7 +113,7 @@ const getNamedType = (
108113
throw `foundType is unknown: ${foundType.name}: ${foundType.type}`;
109114
}
110115
}
111-
return `${toMockName(name)}()`;
116+
return `${toMockName(name, prefix)}()`;
112117
}
113118
}
114119
};
@@ -119,6 +124,7 @@ const generateMockValue = (
119124
types: TypeItem[],
120125
typenamesConvention: NamingConvention,
121126
enumValuesConvention: NamingConvention,
127+
prefix: string | undefined,
122128
currentType: TypeNode,
123129
): string | number | boolean => {
124130
switch (currentType.kind) {
@@ -129,6 +135,7 @@ const generateMockValue = (
129135
types,
130136
typenamesConvention,
131137
enumValuesConvention,
138+
prefix,
132139
currentType as NamedTypeNode,
133140
);
134141
case 'NonNullType':
@@ -138,6 +145,7 @@ const generateMockValue = (
138145
types,
139146
typenamesConvention,
140147
enumValuesConvention,
148+
prefix,
141149
currentType.type,
142150
);
143151
case 'ListType': {
@@ -147,6 +155,7 @@ const generateMockValue = (
147155
types,
148156
typenamesConvention,
149157
enumValuesConvention,
158+
prefix,
150159
currentType.type,
151160
);
152161
return `[${value}]`;
@@ -159,11 +168,12 @@ const getMockString = (
159168
fields: string,
160169
typenamesConvention: NamingConvention,
161170
addTypename = false,
171+
prefix,
162172
) => {
163173
const casedName = createNameConverter(typenamesConvention)(typeName);
164174
const typename = addTypename ? `\n __typename: '${casedName}',` : '';
165175
return `
166-
export const ${toMockName(casedName)} = (overrides?: Partial<${casedName}>): ${casedName} => {
176+
export const ${toMockName(casedName, prefix)} = (overrides?: Partial<${casedName}>): ${casedName} => {
167177
return {${typename}
168178
${fields}
169179
};
@@ -175,6 +185,7 @@ export interface TypescriptMocksPluginConfig {
175185
enumValues?: NamingConvention;
176186
typenames?: NamingConvention;
177187
addTypename?: boolean;
188+
prefix?: string;
178189
}
179190

180191
interface TypeItem {
@@ -230,6 +241,7 @@ export const plugin: PluginFunction<TypescriptMocksPluginConfig> = (schema, docu
230241
types,
231242
typenamesConvention,
232243
enumValuesConvention,
244+
config.prefix,
233245
node.type,
234246
);
235247

@@ -252,6 +264,7 @@ export const plugin: PluginFunction<TypescriptMocksPluginConfig> = (schema, docu
252264
types,
253265
typenamesConvention,
254266
enumValuesConvention,
267+
config.prefix,
255268
field.type,
256269
);
257270

@@ -260,7 +273,7 @@ export const plugin: PluginFunction<TypescriptMocksPluginConfig> = (schema, docu
260273
.join('\n')
261274
: '';
262275

263-
return getMockString(fieldName, mockFields, typenamesConvention, false);
276+
return getMockString(fieldName, mockFields, typenamesConvention, false, config.prefix);
264277
},
265278
};
266279
},
@@ -278,7 +291,13 @@ export const plugin: PluginFunction<TypescriptMocksPluginConfig> = (schema, docu
278291
mockFn: () => {
279292
const mockFields = fields ? fields.map(({ mockFn }: any) => mockFn(typeName)).join('\n') : '';
280293

281-
return getMockString(typeName, mockFields, typenamesConvention, !!config.addTypename);
294+
return getMockString(
295+
typeName,
296+
mockFields,
297+
typenamesConvention,
298+
!!config.addTypename,
299+
config.prefix,
300+
);
282301
},
283302
};
284303
},

tests/__snapshots__/typescript-mock-data.spec.ts.snap

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,42 @@
11
// Jest Snapshot v1, https://goo.gl/fbAQLP
22

3+
exports[`should add custom prefix if the \`prefix\` config option is specified 1`] = `
4+
"
5+
export const mockAbcType = (overrides?: Partial<AbcType>): AbcType => {
6+
return {
7+
abc: overrides && overrides.hasOwnProperty('abc') ? overrides.abc! : 'sit',
8+
};
9+
};
10+
11+
export const mockAvatar = (overrides?: Partial<Avatar>): Avatar => {
12+
return {
13+
id: overrides && overrides.hasOwnProperty('id') ? overrides.id! : '0550ff93-dd31-49b4-8c38-ff1cb68bdc38',
14+
url: overrides && overrides.hasOwnProperty('url') ? overrides.url! : 'aliquid',
15+
};
16+
};
17+
18+
export const mockUpdateUserInput = (overrides?: Partial<UpdateUserInput>): UpdateUserInput => {
19+
return {
20+
id: overrides && overrides.hasOwnProperty('id') ? overrides.id! : '1d6a9360-c92b-4660-8e5f-04155047bddc',
21+
login: overrides && overrides.hasOwnProperty('login') ? overrides.login! : 'qui',
22+
avatar: overrides && overrides.hasOwnProperty('avatar') ? overrides.avatar! : mockAvatar(),
23+
};
24+
};
25+
26+
export const mockUser = (overrides?: Partial<User>): User => {
27+
return {
28+
id: overrides && overrides.hasOwnProperty('id') ? overrides.id! : 'a5756f00-41a6-422a-8a7d-d13ee6a63750',
29+
creationDate: overrides && overrides.hasOwnProperty('creationDate') ? overrides.creationDate! : '1970-01-09T16:33:21.532Z',
30+
login: overrides && overrides.hasOwnProperty('login') ? overrides.login! : 'libero',
31+
avatar: overrides && overrides.hasOwnProperty('avatar') ? overrides.avatar! : mockAvatar(),
32+
status: overrides && overrides.hasOwnProperty('status') ? overrides.status! : Status.Online,
33+
customStatus: overrides && overrides.hasOwnProperty('customStatus') ? overrides.customStatus! : AbcStatus.HasXyzStatus,
34+
scalarValue: overrides && overrides.hasOwnProperty('scalarValue') ? overrides.scalarValue! : 'neque',
35+
};
36+
};
37+
"
38+
`;
39+
340
exports[`should generate mock data functions 1`] = `
441
"
542
export const anAbcType = (overrides?: Partial<AbcType>): AbcType => {

tests/typescript-mock-data.spec.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,3 +168,12 @@ it('should generate mock data with as-is types and enums if typenames is "keep"'
168168
expect(result).not.toMatch(/ABC(TYPE|STATUS)/);
169169
expect(result).toMatchSnapshot();
170170
});
171+
172+
it('should add custom prefix if the `prefix` config option is specified', async () => {
173+
const result = await plugin(testSchema, [], { prefix: 'mock' });
174+
175+
expect(result).toBeDefined();
176+
expect(result).toMatch(/const mockUser/);
177+
expect(result).not.toMatch(/const aUser/);
178+
expect(result).toMatchSnapshot();
179+
});

0 commit comments

Comments
 (0)