Skip to content

Commit 298565a

Browse files
committed
fix: use fetch mock
1 parent 203a2c0 commit 298565a

File tree

20 files changed

+838
-669
lines changed

20 files changed

+838
-669
lines changed

packages/graphql-language-service-server/package.json

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,14 +36,13 @@
3636
"peerDependencies": {
3737
"graphql": "^15.5.0 || ^16.0.0"
3838
},
39-
"COMMENT": "please do not remove depenencies without thorough testing. many dependencies are not imported directly, as they are peer dependencies",
39+
"COMMENT": "please do not remove dependencies without thorough testing. many dependencies are not imported directly, as they are peer dependencies",
4040
"dependencies": {
41-
"@astrojs/compiler": "^2.5.0",
4241
"@babel/parser": "^7.23.6",
4342
"@babel/types": "^7.23.5",
4443
"@graphql-tools/code-file-loader": "8.0.3",
4544
"@vue/compiler-sfc": "^3.4.5",
46-
"astrojs-compiler-sync": "^0.3.5",
45+
"astrojs-compiler-sync": "1.0.0",
4746
"cosmiconfig-toml-loader": "^1.0.0",
4847
"dotenv": "10.0.0",
4948
"fast-glob": "^3.2.7",

packages/graphql-language-service-server/src/GraphQLCache.ts

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -622,7 +622,19 @@ export class GraphQLCache {
622622

623623
try {
624624
// Read from disk
625-
schema = await projectConfig.getSchema();
625+
schema = await projectConfig.loadSchema(
626+
projectConfig.schema,
627+
'GraphQLSchema',
628+
{
629+
assumeValid: true,
630+
assumeValidSDL: true,
631+
experimentalFragmentVariables: true,
632+
sort: false,
633+
includeSources: true,
634+
allowLegacySDLEmptyFields: true,
635+
allowLegacySDLImplementsInterfaces: true,
636+
},
637+
);
626638
} catch {
627639
// // if there is an error reading the schema, just use the last valid schema
628640
schema = this._schemaMap.get(schemaCacheKey);
@@ -794,7 +806,7 @@ export class GraphQLCache {
794806
let queries: CachedContent[] = [];
795807
if (content.trim().length !== 0) {
796808
try {
797-
queries = this._parser(
809+
queries = await this._parser(
798810
content,
799811
filePath,
800812
DEFAULT_SUPPORTED_EXTENSIONS,

packages/graphql-language-service-server/src/MessageProcessor.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ export class MessageProcessor {
128128
private _isGraphQLConfigMissing: boolean | null = null;
129129
private _willShutdown = false;
130130
private _logger: Logger | NoopLogger;
131-
private _parser: (text: string, uri: string) => CachedContent[];
131+
private _parser: (text: string, uri: string) => Promise<CachedContent[]>;
132132
private _tmpDir: string;
133133
private _tmpDirBase: string;
134134
private _loadConfigOptions: LoadConfigOptions;
@@ -160,7 +160,7 @@ export class MessageProcessor {
160160
}
161161
this._connection = connection;
162162
this._logger = logger;
163-
this._parser = (text, uri) => {
163+
this._parser = async (text, uri) => {
164164
const p = parser ?? parseDocument;
165165
return p(text, uri, fileExtensions, graphqlFileExtensions, this._logger);
166166
};
@@ -731,7 +731,7 @@ export class MessageProcessor {
731731
) {
732732
try {
733733
const fileText = text || (await readFile(URI.parse(uri).fsPath, 'utf-8'));
734-
const contents = this._parser(fileText, uri);
734+
const contents = await this._parser(fileText, uri);
735735
const cachedDocument = this._textDocumentCache.get(uri);
736736
const version = cachedDocument ? cachedDocument.version++ : 0;
737737
await this._invalidateCache({ uri, version }, uri, contents);
@@ -1060,7 +1060,7 @@ export class MessageProcessor {
10601060
project?: GraphQLProjectConfig,
10611061
) {
10621062
try {
1063-
const contents = this._parser(text, uri);
1063+
const contents = await this._parser(text, uri);
10641064
if (contents.length > 0) {
10651065
await this._invalidateCache({ version, uri }, uri, contents);
10661066
await this._updateObjectTypeDefinition(uri, contents, project);
@@ -1268,7 +1268,7 @@ export class MessageProcessor {
12681268
const uri = URI.file(filePath).toString();
12691269

12701270
// I would use the already existing graphql-config AST, but there are a few reasons we can't yet
1271-
const contents = this._parser(document.rawSDL, uri);
1271+
const contents = await this._parser(document.rawSDL, uri);
12721272
if (!contents[0]?.query) {
12731273
return;
12741274
}

packages/graphql-language-service-server/src/__tests__/MessageProcessor.spec.ts

Lines changed: 47 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,35 @@ import { serializeRange } from './__utils__/utils';
77
import { readFile } from 'node:fs/promises';
88
import { existsSync } from 'node:fs';
99
import { URI } from 'vscode-uri';
10+
import { GraphQLSchema, introspectionFromSchema } from 'graphql';
11+
import fetchMock from 'fetch-mock';
12+
13+
jest.mock('@whatwg-node/fetch', () => {
14+
const { AbortController } = require('node-abort-controller');
15+
16+
return {
17+
fetch: require('fetch-mock').fetchHandler,
18+
AbortController,
19+
TextDecoder: global.TextDecoder,
20+
};
21+
});
22+
23+
const mockSchema = (schema: GraphQLSchema) => {
24+
const introspectionResult = {
25+
data: introspectionFromSchema(schema, {
26+
descriptions: true,
27+
}),
28+
};
29+
fetchMock.mock({
30+
matcher: '*',
31+
response: {
32+
headers: {
33+
'Content-Type': 'application/json',
34+
},
35+
body: introspectionResult,
36+
},
37+
});
38+
};
1039

1140
const defaultFiles = [
1241
['query.graphql', 'query { bar ...B }'],
@@ -41,6 +70,7 @@ const genSchemaPath =
4170
describe('MessageProcessor with no config', () => {
4271
afterEach(() => {
4372
mockfs.restore();
73+
fetchMock.restore();
4474
});
4575
it('fails to initialize with empty config file', async () => {
4676
const project = new MockProject({
@@ -102,17 +132,17 @@ describe('MessageProcessor with no config', () => {
102132
});
103133

104134
describe('MessageProcessor with config', () => {
105-
let app;
106135
afterEach(() => {
107136
mockfs.restore();
137+
fetchMock.restore();
108138
});
109-
beforeAll(async () => {
110-
app = await import('../../../graphiql/test/e2e-server');
111-
});
112-
afterAll(() => {
113-
app.server.close();
114-
app.wsServer.close();
115-
});
139+
// beforeAll(async () => {
140+
// app = await import('../../../graphiql/test/e2e-server');
141+
// });
142+
// afterAll(() => {
143+
// app.server.close();
144+
// app.wsServer.close();
145+
// });
116146
it('caches files and schema with .graphql file config, and the schema updates with watched file changes', async () => {
117147
const project = new MockProject({
118148
files: [
@@ -324,6 +354,8 @@ describe('MessageProcessor with config', () => {
324354
});
325355

326356
it('caches files and schema with a URL config', async () => {
357+
mockSchema(require('../../../graphiql/test/schema'));
358+
327359
const project = new MockProject({
328360
files: [
329361
['query.graphql', 'query { test { isTest, ...T } }'],
@@ -389,29 +421,29 @@ describe('MessageProcessor with config', () => {
389421

390422
expect(serializeRange(typeDefinitions[0].range)).toEqual({
391423
start: {
392-
line: 10,
424+
line: 11,
393425
character: 0,
394426
},
395427
end: {
396-
line: 98,
428+
line: 102,
397429
character: 1,
398430
},
399431
});
400432

401433
const schemaDefs = await project.lsp.handleDefinitionRequest({
402434
textDocument: { uri: URI.parse(genSchemaPath).toString() },
403-
position: { character: 20, line: 17 },
435+
position: { character: 20, line: 18 },
404436
});
405437
expect(schemaDefs[0].uri).toEqual(URI.parse(genSchemaPath).toString());
406438
// note: if the graphiql test schema changes,
407439
// this might break, please adjust if you see a failure here
408440
expect(serializeRange(schemaDefs[0].range)).toEqual({
409441
start: {
410-
line: 100,
442+
line: 104,
411443
character: 0,
412444
},
413445
end: {
414-
line: 108,
446+
line: 112,
415447
character: 1,
416448
},
417449
});
@@ -456,6 +488,8 @@ describe('MessageProcessor with config', () => {
456488
});
457489

458490
it('caches multiple projects with files and schema with a URL config and a local schema', async () => {
491+
mockSchema(require('../../../graphiql/test/schema'));
492+
459493
const project = new MockProject({
460494
files: [
461495
[

packages/graphql-language-service-server/src/__tests__/parseDocument-test.ts

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { parseDocument } from '../parseDocument';
22

33
describe('parseDocument', () => {
4-
it('parseDocument finds queries in tagged templates', async () => {
4+
it('parseDocument finds queries in tagged templates', () => {
55
const text = `
66
// @flow
77
import {gql} from 'react-apollo';
@@ -32,7 +32,7 @@ describe('parseDocument', () => {
3232
`);
3333
});
3434

35-
it('parseDocument finds queries in tagged templates in leaf', async () => {
35+
it('parseDocument finds queries in tagged templates in leaf', () => {
3636
const text = `
3737
import {gql} from 'react-apollo';
3838
import type {B} from 'B';
@@ -58,7 +58,7 @@ describe('parseDocument', () => {
5858
`);
5959
});
6060

61-
it('parseDocument finds queries in tagged templates using typescript', async () => {
61+
it('parseDocument finds queries in tagged templates using typescript', () => {
6262
const text = `
6363
import {gql} from 'react-apollo';
6464
import {B} from 'B';
@@ -88,7 +88,7 @@ describe('parseDocument', () => {
8888
`);
8989
});
9090

91-
it('parseDocument finds queries in tagged templates using tsx', async () => {
91+
it('parseDocument finds queries in tagged templates using tsx', () => {
9292
const text = `
9393
import {gql} from 'react-apollo';
9494
import {B} from 'B';
@@ -120,7 +120,7 @@ describe('parseDocument', () => {
120120
`);
121121
});
122122

123-
it('parseDocument finds queries in multi-expression tagged templates using tsx', async () => {
123+
it('parseDocument finds queries in multi-expression tagged templates using tsx', () => {
124124
const text = `
125125
import {gql} from 'react-apollo';
126126
import {B} from 'B';
@@ -153,7 +153,7 @@ describe('parseDocument', () => {
153153
}`);
154154
});
155155
// TODO: why an extra line here?
156-
it('parseDocument finds queries in multi-expression tagged template with declarations with using tsx', async () => {
156+
it('parseDocument finds queries in multi-expression tagged template with declarations with using tsx', () => {
157157
const text = `
158158
import {gql} from 'react-apollo';
159159
import {B} from 'B';
@@ -186,7 +186,7 @@ describe('parseDocument', () => {
186186
}`);
187187
});
188188

189-
it('parseDocument finds queries in multi-expression template strings using tsx', async () => {
189+
it('parseDocument finds queries in multi-expression template strings using tsx', () => {
190190
const text = `
191191
import {gql} from 'react-apollo';
192192
import {B} from 'B';
@@ -222,7 +222,7 @@ describe('parseDocument', () => {
222222
`);
223223
});
224224

225-
it('parseDocument finds queries in call expressions with template literals', async () => {
225+
it('parseDocument finds queries in call expressions with template literals', () => {
226226
const text = `
227227
// @flow
228228
import {gql} from 'react-apollo';
@@ -253,7 +253,7 @@ describe('parseDocument', () => {
253253
`);
254254
});
255255

256-
it('parseDocument finds queries in #graphql-annotated templates', async () => {
256+
it('parseDocument finds queries in #graphql-annotated templates', () => {
257257
const text = `
258258
import {gql} from 'react-apollo';
259259
import {B} from 'B';
@@ -283,7 +283,7 @@ describe('parseDocument', () => {
283283
`);
284284
});
285285

286-
it('parseDocument finds queries in /*GraphQL*/-annotated templates', async () => {
286+
it('parseDocument finds queries in /*GraphQL*/-annotated templates', () => {
287287
const text = `
288288
import {gql} from 'react-apollo';
289289
import {B} from 'B';
@@ -314,7 +314,7 @@ describe('parseDocument', () => {
314314
`);
315315
});
316316

317-
it('parseDocument ignores non gql tagged templates', async () => {
317+
it('parseDocument ignores non gql tagged templates', () => {
318318
const text = `
319319
// @flow
320320
import randomThing from 'package';
@@ -337,7 +337,7 @@ describe('parseDocument', () => {
337337
expect(contents.length).toEqual(0);
338338
});
339339

340-
it('parseDocument ignores non gql call expressions with template literals', async () => {
340+
it('parseDocument ignores non gql call expressions with template literals', () => {
341341
const text = `
342342
// @flow
343343
import randomthing from 'package';
@@ -360,7 +360,7 @@ describe('parseDocument', () => {
360360
expect(contents.length).toEqual(0);
361361
});
362362

363-
it('an unparsable JS/TS file does not throw and bring down the server', async () => {
363+
it('an unparsable JS/TS file does not throw and bring down the server', () => {
364364
const text = `
365365
// @flow
366366
import type randomThing fro 'package';
@@ -380,14 +380,14 @@ describe('parseDocument', () => {
380380
expect(contents.length).toEqual(0);
381381
});
382382

383-
it('an empty file is ignored', async () => {
383+
it('an empty file is ignored', () => {
384384
const text = '';
385385

386386
const contents = parseDocument(text, 'test.js');
387387
expect(contents.length).toEqual(0);
388388
});
389389

390-
it('a whitespace only file with empty asts is ignored', async () => {
390+
it('a whitespace only file with empty asts is ignored', () => {
391391
const text = `
392392
393393
`;
@@ -396,7 +396,7 @@ describe('parseDocument', () => {
396396
expect(contents.length).toEqual(0);
397397
});
398398

399-
it('an ignored file is ignored', async () => {
399+
it('an ignored file is ignored', () => {
400400
const text = `
401401
something
402402
`;

packages/graphql-language-service-server/src/__tests__/startServer.spec.ts

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,36 @@
11
import startServer from '../startServer';
22

33
describe('startServer', () => {
4+
let c;
5+
afterEach(async () => {
6+
if (c) {
7+
try {
8+
await c.sendNotification('exit');
9+
} catch {}
10+
}
11+
});
412
it('should start the server', async () => {
5-
await startServer();
13+
c = await startServer();
614
// if the server starts, we're good
715
expect(true).toBe(true);
816
});
917
// this one fails to exit
1018
it('should start the server with stream', async () => {
11-
await startServer({
19+
c = await startServer({
1220
method: 'stream',
1321
});
1422
// if the server starts, we're good
1523
expect(true).toBe(true);
1624
});
1725
it('should start the server with ipc', async () => {
18-
await startServer({
26+
c = await startServer({
1927
method: 'node',
2028
});
2129
// if the server starts, we're good
2230
expect(true).toBe(true);
2331
});
2432
it('should start the server with websockets', async () => {
25-
await startServer({
33+
c = await startServer({
2634
method: 'socket',
2735
port: 4000,
2836
});

0 commit comments

Comments
 (0)