Skip to content

Commit 9af9ce2

Browse files
authored
Split ts-resolvers test into smaller chunks to make it easier to target (#10011)
1 parent 808ada5 commit 9af9ce2

File tree

6 files changed

+386
-370
lines changed

6 files changed

+386
-370
lines changed

packages/plugins/typescript/resolvers/tests/federation.spec.ts renamed to packages/plugins/typescript/resolvers/tests/ts-resolvers.federation.spec.ts

File renamed without changes.
Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
import { resolversTestingSchema } from '@graphql-codegen/testing';
2+
import { buildSchema } from 'graphql';
3+
import { plugin } from '../src/index.js';
4+
5+
describe('TypeScript Resolvers Plugin - Interfaces', () => {
6+
it('should generate ResolversInterfaceTypes', async () => {
7+
const content = await plugin(resolversTestingSchema, [], {}, { outputFile: 'graphql.ts' });
8+
9+
expect(content.content).toBeSimilarStringTo(`
10+
export type ResolversInterfaceTypes<_RefType extends Record<string, unknown>> = {
11+
Node: ( SomeNode );
12+
AnotherNode: ( Omit<AnotherNodeWithChild, 'unionChild' | 'interfaceChild'> & { unionChild?: Maybe<_RefType['ChildUnion']>, interfaceChild?: Maybe<_RefType['Node']> } ) | ( Omit<AnotherNodeWithAll, 'unionChild' | 'unionChildren' | 'interfaceChild' | 'interfaceChildren'> & { unionChild?: Maybe<_RefType['ChildUnion']>, unionChildren: Array<_RefType['ChildUnion']>, interfaceChild?: Maybe<_RefType['Node']>, interfaceChildren: Array<_RefType['Node']> } );
13+
WithChild: ( Omit<AnotherNodeWithChild, 'unionChild' | 'interfaceChild'> & { unionChild?: Maybe<_RefType['ChildUnion']>, interfaceChild?: Maybe<_RefType['Node']> } ) | ( Omit<AnotherNodeWithAll, 'unionChild' | 'unionChildren' | 'interfaceChild' | 'interfaceChildren'> & { unionChild?: Maybe<_RefType['ChildUnion']>, unionChildren: Array<_RefType['ChildUnion']>, interfaceChild?: Maybe<_RefType['Node']>, interfaceChildren: Array<_RefType['Node']> } );
14+
WithChildren: ( Omit<AnotherNodeWithAll, 'unionChild' | 'unionChildren' | 'interfaceChild' | 'interfaceChildren'> & { unionChild?: Maybe<_RefType['ChildUnion']>, unionChildren: Array<_RefType['ChildUnion']>, interfaceChild?: Maybe<_RefType['Node']>, interfaceChildren: Array<_RefType['Node']> } );
15+
};
16+
`);
17+
18+
expect(content.content).toBeSimilarStringTo(`
19+
export type ResolversTypes = {
20+
MyType: ResolverTypeWrapper<Omit<MyType, 'unionChild'> & { unionChild?: Maybe<ResolversTypes['ChildUnion']> }>;
21+
String: ResolverTypeWrapper<Scalars['String']['output']>;
22+
Child: ResolverTypeWrapper<Child>;
23+
MyOtherType: ResolverTypeWrapper<MyOtherType>;
24+
ChildUnion: ResolverTypeWrapper<ResolversUnionTypes<ResolversTypes>['ChildUnion']>;
25+
Query: ResolverTypeWrapper<{}>;
26+
Subscription: ResolverTypeWrapper<{}>;
27+
Node: ResolverTypeWrapper<ResolversInterfaceTypes<ResolversTypes>['Node']>;
28+
ID: ResolverTypeWrapper<Scalars['ID']['output']>;
29+
SomeNode: ResolverTypeWrapper<SomeNode>;
30+
AnotherNode: ResolverTypeWrapper<ResolversInterfaceTypes<ResolversTypes>['AnotherNode']>;
31+
WithChild: ResolverTypeWrapper<ResolversInterfaceTypes<ResolversTypes>['WithChild']>;
32+
WithChildren: ResolverTypeWrapper<ResolversInterfaceTypes<ResolversTypes>['WithChildren']>;
33+
AnotherNodeWithChild: ResolverTypeWrapper<Omit<AnotherNodeWithChild, 'unionChild' | 'interfaceChild'> & { unionChild?: Maybe<ResolversTypes['ChildUnion']>, interfaceChild?: Maybe<ResolversTypes['Node']> }>;
34+
AnotherNodeWithAll: ResolverTypeWrapper<Omit<AnotherNodeWithAll, 'unionChild' | 'unionChildren' | 'interfaceChild' | 'interfaceChildren'> & { unionChild?: Maybe<ResolversTypes['ChildUnion']>, unionChildren: Array<ResolversTypes['ChildUnion']>, interfaceChild?: Maybe<ResolversTypes['Node']>, interfaceChildren: Array<ResolversTypes['Node']> }>;
35+
MyUnion: ResolverTypeWrapper<ResolversUnionTypes<ResolversTypes>['MyUnion']>;
36+
MyScalar: ResolverTypeWrapper<Scalars['MyScalar']['output']>;
37+
Int: ResolverTypeWrapper<Scalars['Int']['output']>;
38+
Boolean: ResolverTypeWrapper<Scalars['Boolean']['output']>;
39+
};
40+
`);
41+
42+
expect(content.content).toBeSimilarStringTo(`
43+
export type ResolversParentTypes = {
44+
MyType: Omit<MyType, 'unionChild'> & { unionChild?: Maybe<ResolversParentTypes['ChildUnion']> };
45+
String: Scalars['String']['output'];
46+
Child: Child;
47+
MyOtherType: MyOtherType;
48+
ChildUnion: ResolversUnionTypes<ResolversParentTypes>['ChildUnion'];
49+
Query: {};
50+
Subscription: {};
51+
Node: ResolversInterfaceTypes<ResolversParentTypes>['Node'];
52+
ID: Scalars['ID']['output'];
53+
SomeNode: SomeNode;
54+
AnotherNode: ResolversInterfaceTypes<ResolversParentTypes>['AnotherNode'];
55+
WithChild: ResolversInterfaceTypes<ResolversParentTypes>['WithChild'];
56+
WithChildren: ResolversInterfaceTypes<ResolversParentTypes>['WithChildren'];
57+
AnotherNodeWithChild: Omit<AnotherNodeWithChild, 'unionChild' | 'interfaceChild'> & { unionChild?: Maybe<ResolversParentTypes['ChildUnion']>, interfaceChild?: Maybe<ResolversParentTypes['Node']> };
58+
AnotherNodeWithAll: Omit<AnotherNodeWithAll, 'unionChild' | 'unionChildren' | 'interfaceChild' | 'interfaceChildren'> & { unionChild?: Maybe<ResolversParentTypes['ChildUnion']>, unionChildren: Array<ResolversParentTypes['ChildUnion']>, interfaceChild?: Maybe<ResolversParentTypes['Node']>, interfaceChildren: Array<ResolversParentTypes['Node']> };
59+
MyUnion: ResolversUnionTypes<ResolversParentTypes>['MyUnion'];
60+
MyScalar: Scalars['MyScalar']['output'];
61+
Int: Scalars['Int']['output'];
62+
Boolean: Scalars['Boolean']['output'];
63+
};
64+
`);
65+
});
66+
67+
it('should generate ResolversInterfaceTypes with transformed type names correctly', async () => {
68+
const content = await plugin(
69+
resolversTestingSchema,
70+
[],
71+
{ typesPrefix: 'I_', typesSuffix: '_Types' },
72+
{ outputFile: 'graphql.ts' }
73+
);
74+
75+
expect(content.content).toBeSimilarStringTo(`
76+
export type I_ResolversInterfaceTypes_Types<_RefType extends Record<string, unknown>> = {
77+
Node: ( I_SomeNode_Types );
78+
AnotherNode: ( Omit<I_AnotherNodeWithChild_Types, 'unionChild' | 'interfaceChild'> & { unionChild?: Maybe<_RefType['ChildUnion']>, interfaceChild?: Maybe<_RefType['Node']> } ) | ( Omit<I_AnotherNodeWithAll_Types, 'unionChild' | 'unionChildren' | 'interfaceChild' | 'interfaceChildren'> & { unionChild?: Maybe<_RefType['ChildUnion']>, unionChildren: Array<_RefType['ChildUnion']>, interfaceChild?: Maybe<_RefType['Node']>, interfaceChildren: Array<_RefType['Node']> } );
79+
WithChild: ( Omit<I_AnotherNodeWithChild_Types, 'unionChild' | 'interfaceChild'> & { unionChild?: Maybe<_RefType['ChildUnion']>, interfaceChild?: Maybe<_RefType['Node']> } ) | ( Omit<I_AnotherNodeWithAll_Types, 'unionChild' | 'unionChildren' | 'interfaceChild' | 'interfaceChildren'> & { unionChild?: Maybe<_RefType['ChildUnion']>, unionChildren: Array<_RefType['ChildUnion']>, interfaceChild?: Maybe<_RefType['Node']>, interfaceChildren: Array<_RefType['Node']> } );
80+
WithChildren: ( Omit<I_AnotherNodeWithAll_Types, 'unionChild' | 'unionChildren' | 'interfaceChild' | 'interfaceChildren'> & { unionChild?: Maybe<_RefType['ChildUnion']>, unionChildren: Array<_RefType['ChildUnion']>, interfaceChild?: Maybe<_RefType['Node']>, interfaceChildren: Array<_RefType['Node']> } );
81+
};
82+
`);
83+
84+
expect(content.content).toBeSimilarStringTo(`
85+
export type I_ResolversTypes_Types = {
86+
MyType: ResolverTypeWrapper<Omit<I_MyType_Types, 'unionChild'> & { unionChild?: Maybe<I_ResolversTypes_Types['ChildUnion']> }>;
87+
String: ResolverTypeWrapper<Scalars['String']['output']>;
88+
Child: ResolverTypeWrapper<I_Child_Types>;
89+
MyOtherType: ResolverTypeWrapper<I_MyOtherType_Types>;
90+
ChildUnion: ResolverTypeWrapper<I_ResolversUnionTypes_Types<I_ResolversTypes_Types>['ChildUnion']>;
91+
Query: ResolverTypeWrapper<{}>;
92+
Subscription: ResolverTypeWrapper<{}>;
93+
Node: ResolverTypeWrapper<I_ResolversInterfaceTypes_Types<I_ResolversTypes_Types>['Node']>;
94+
ID: ResolverTypeWrapper<Scalars['ID']['output']>;
95+
SomeNode: ResolverTypeWrapper<I_SomeNode_Types>;
96+
AnotherNode: ResolverTypeWrapper<I_ResolversInterfaceTypes_Types<I_ResolversTypes_Types>['AnotherNode']>;
97+
WithChild: ResolverTypeWrapper<I_ResolversInterfaceTypes_Types<I_ResolversTypes_Types>['WithChild']>;
98+
WithChildren: ResolverTypeWrapper<I_ResolversInterfaceTypes_Types<I_ResolversTypes_Types>['WithChildren']>;
99+
AnotherNodeWithChild: ResolverTypeWrapper<Omit<I_AnotherNodeWithChild_Types, 'unionChild' | 'interfaceChild'> & { unionChild?: Maybe<I_ResolversTypes_Types['ChildUnion']>, interfaceChild?: Maybe<I_ResolversTypes_Types['Node']> }>;
100+
AnotherNodeWithAll: ResolverTypeWrapper<Omit<I_AnotherNodeWithAll_Types, 'unionChild' | 'unionChildren' | 'interfaceChild' | 'interfaceChildren'> & { unionChild?: Maybe<I_ResolversTypes_Types['ChildUnion']>, unionChildren: Array<I_ResolversTypes_Types['ChildUnion']>, interfaceChild?: Maybe<I_ResolversTypes_Types['Node']>, interfaceChildren: Array<I_ResolversTypes_Types['Node']> }>;
101+
MyUnion: ResolverTypeWrapper<I_ResolversUnionTypes_Types<I_ResolversTypes_Types>['MyUnion']>;
102+
MyScalar: ResolverTypeWrapper<Scalars['MyScalar']['output']>;
103+
Int: ResolverTypeWrapper<Scalars['Int']['output']>;
104+
Boolean: ResolverTypeWrapper<Scalars['Boolean']['output']>;
105+
};
106+
`);
107+
108+
expect(content.content).toBeSimilarStringTo(`
109+
export type I_ResolversParentTypes_Types = {
110+
MyType: Omit<I_MyType_Types, 'unionChild'> & { unionChild?: Maybe<I_ResolversParentTypes_Types['ChildUnion']> };
111+
String: Scalars['String']['output'];
112+
Child: I_Child_Types;
113+
MyOtherType: I_MyOtherType_Types;
114+
ChildUnion: I_ResolversUnionTypes_Types<I_ResolversParentTypes_Types>['ChildUnion'];
115+
Query: {};
116+
Subscription: {};
117+
Node: I_ResolversInterfaceTypes_Types<I_ResolversParentTypes_Types>['Node'];
118+
ID: Scalars['ID']['output'];
119+
SomeNode: I_SomeNode_Types;
120+
AnotherNode: I_ResolversInterfaceTypes_Types<I_ResolversParentTypes_Types>['AnotherNode'];
121+
WithChild: I_ResolversInterfaceTypes_Types<I_ResolversParentTypes_Types>['WithChild'];
122+
WithChildren: I_ResolversInterfaceTypes_Types<I_ResolversParentTypes_Types>['WithChildren'];
123+
AnotherNodeWithChild: Omit<I_AnotherNodeWithChild_Types, 'unionChild' | 'interfaceChild'> & { unionChild?: Maybe<I_ResolversParentTypes_Types['ChildUnion']>, interfaceChild?: Maybe<I_ResolversParentTypes_Types['Node']> };
124+
AnotherNodeWithAll: Omit<I_AnotherNodeWithAll_Types, 'unionChild' | 'unionChildren' | 'interfaceChild' | 'interfaceChildren'> & { unionChild?: Maybe<I_ResolversParentTypes_Types['ChildUnion']>, unionChildren: Array<I_ResolversParentTypes_Types['ChildUnion']>, interfaceChild?: Maybe<I_ResolversParentTypes_Types['Node']>, interfaceChildren: Array<I_ResolversParentTypes_Types['Node']> };
125+
MyUnion: I_ResolversUnionTypes_Types<I_ResolversParentTypes_Types>['MyUnion'];
126+
MyScalar: Scalars['MyScalar']['output'];
127+
Int: Scalars['Int']['output'];
128+
Boolean: Scalars['Boolean']['output'];
129+
};
130+
`);
131+
});
132+
133+
it('should NOT generate ResolversInterfaceTypes if there is no Interface', async () => {
134+
const testSchema = buildSchema(/* GraphQL */ `
135+
type Query {
136+
user(id: ID!): User
137+
}
138+
139+
type User {
140+
id: ID!
141+
fullName: String!
142+
}
143+
`);
144+
const content = await plugin(testSchema, [], {}, { outputFile: 'graphql.ts' });
145+
146+
expect(content.content).not.toBeSimilarStringTo(`export type ResolversInterfaceTypes`);
147+
});
148+
149+
it('Should generate valid types even when there are no implementers for an interface', async () => {
150+
const schemaWithNoImplementors = buildSchema(/* GraphQL */ `
151+
interface Node {
152+
id: ID!
153+
}
154+
155+
type Query {
156+
node: Node!
157+
}
158+
`);
159+
160+
const result = await plugin(schemaWithNoImplementors, [], {}, { outputFile: '' });
161+
162+
expect(result.content).toBeSimilarStringTo(`
163+
export type NodeResolvers<ContextType = any, ParentType extends ResolversParentTypes['Node'] = ResolversParentTypes['Node']> = {
164+
__resolveType: TypeResolveFn<null, ParentType, ContextType>;
165+
id?: Resolver<ResolversTypes['ID'], ParentType, ContextType>;
166+
};
167+
`);
168+
});
169+
});

packages/plugins/typescript/resolvers/tests/mapping.spec.ts renamed to packages/plugins/typescript/resolvers/tests/ts-resolvers.mapping.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { resolversTestingSchema, resolversTestingValidate } from '@graphql-codeg
33
import { buildSchema } from 'graphql';
44
import { plugin } from '../src/index.js';
55

6-
describe('ResolversTypes', () => {
6+
describe('TypeScript Resolvers Plugin - Mapping', () => {
77
it('Should build ResolversTypes object when there are no mappers', async () => {
88
const result = await plugin(resolversTestingSchema, [], {}, { outputFile: '' });
99

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
import '@graphql-codegen/testing';
2+
import { plugin } from '../src/index.js';
3+
import { buildSchema } from 'graphql';
4+
5+
describe('TypeScript Resolvers Plugin - Meta', () => {
6+
it('generates meta correctly', async () => {
7+
const result = await plugin(
8+
buildSchema(/* GraphQL */ `
9+
type Query {
10+
user(id: ID!): User
11+
post(id: ID!): Post
12+
}
13+
14+
type Mutation {
15+
createUser(name: String!): CreateUserPayload!
16+
}
17+
18+
interface Node {
19+
id: ID!
20+
}
21+
type Post implements Node {
22+
id: ID!
23+
author: User
24+
}
25+
type User implements Node {
26+
id: ID!
27+
name: String
28+
}
29+
30+
type CreateUserOk {
31+
user: User!
32+
}
33+
34+
type CreateUserError {
35+
error: ErrorType!
36+
}
37+
38+
union CreateUserPayload = CreateUserOk | CreateUserError
39+
40+
enum ErrorType {
41+
FORBIDDEN_ERROR
42+
INTERNAL_ERROR
43+
}
44+
`),
45+
[],
46+
{
47+
namingConvention: 'change-case-all#snakeCase',
48+
enumValues: {
49+
ErrorType: {
50+
FORBIDDEN_ERROR: '403',
51+
INTERNAL_ERROR: '500',
52+
},
53+
},
54+
},
55+
{ outputFile: '' }
56+
);
57+
58+
expect(result.content).toBeSimilarStringTo(`
59+
export type resolvers<ContextType = any> = {
60+
Query?: query_resolvers<ContextType>;
61+
Mutation?: mutation_resolvers<ContextType>;
62+
Node?: node_resolvers<ContextType>;
63+
Post?: post_resolvers<ContextType>;
64+
User?: user_resolvers<ContextType>;
65+
CreateUserOk?: create_user_ok_resolvers<ContextType>;
66+
CreateUserError?: create_user_error_resolvers<ContextType>;
67+
CreateUserPayload?: create_user_payload_resolvers<ContextType>;
68+
ErrorType?: error_type_resolvers;
69+
};`);
70+
expect(result.content).toContain(`export type create_user_error_resolvers`);
71+
expect(result.content).toContain(`export type create_user_ok_resolvers`);
72+
expect(result.content).toContain(`export type create_user_payload_resolvers`);
73+
expect(result.content).toContain(`export type error_type_resolvers`);
74+
expect(result.content).toContain(`export type mutation_resolvers`);
75+
expect(result.content).toContain(`export type node_resolvers`);
76+
expect(result.content).toContain(`export type post_resolvers`);
77+
expect(result.content).toContain(`export type query_resolvers`);
78+
expect(result.content).toContain(`export type user_resolvers`);
79+
80+
expect(result.meta).toMatchInlineSnapshot(`
81+
Object {
82+
"generatedResolverTypes": Object {
83+
"resolversMap": Object {
84+
"name": "resolvers",
85+
},
86+
"userDefined": Object {
87+
"CreateUserError": Object {
88+
"name": "create_user_error_resolvers",
89+
},
90+
"CreateUserOk": Object {
91+
"name": "create_user_ok_resolvers",
92+
},
93+
"CreateUserPayload": Object {
94+
"name": "create_user_payload_resolvers",
95+
},
96+
"ErrorType": Object {
97+
"name": "error_type_resolvers",
98+
},
99+
"Mutation": Object {
100+
"name": "mutation_resolvers",
101+
},
102+
"Node": Object {
103+
"name": "node_resolvers",
104+
},
105+
"Post": Object {
106+
"name": "post_resolvers",
107+
},
108+
"Query": Object {
109+
"name": "query_resolvers",
110+
},
111+
"User": Object {
112+
"name": "user_resolvers",
113+
},
114+
},
115+
},
116+
}
117+
`);
118+
});
119+
});

0 commit comments

Comments
 (0)