Skip to content

Commit 867714c

Browse files
committed
fix even MORE bugs
1 parent cf4536b commit 867714c

File tree

8 files changed

+290
-186
lines changed

8 files changed

+290
-186
lines changed

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

Lines changed: 147 additions & 130 deletions
Large diffs are not rendered by default.

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

Lines changed: 53 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,13 @@ describe('project with simple config and graphql files', () => {
116116
...defaultFiles,
117117
],
118118
});
119-
await project.init('query.graphql');
119+
const results = await project.init('query.graphql');
120+
expect(results.diagnostics[0].message).toEqual(
121+
'Cannot query field "bar" on type "Query".',
122+
);
123+
expect(results.diagnostics[1].message).toEqual(
124+
'Fragment "B" cannot be spread here as objects of type "Query" can never be of type "Foo".',
125+
);
120126
const initSchemaDefRequest = await project.lsp.handleDefinitionRequest({
121127
textDocument: { uri: project.uri('schema.graphql') },
122128
position: { character: 19, line: 0 },
@@ -190,11 +196,52 @@ describe('project with simple config and graphql files', () => {
190196
fooLaterTypePosition,
191197
);
192198

199+
// change the file to make the fragment invalid
200+
project.changeFile(
201+
'schema.graphql',
202+
// now Foo has a bad field, the fragment should be invalid
203+
'type Query { foo: Foo, test: Test }\n\n type Test { test: String }\n\n\n\n\n\ntype Foo { bad: Int }',
204+
);
205+
// await project.lsp.handleWatchedFilesChangedNotification({
206+
// changes: [
207+
// {
208+
// type: FileChangeType.Changed,
209+
// uri: project.uri('schema.graphql'),
210+
// },
211+
// ],
212+
// });
213+
await project.lsp.handleDidChangeNotification({
214+
contentChanges: [
215+
{
216+
type: FileChangeType.Changed,
217+
text: 'type Query { foo: Foo, test: Test }\n\n type Test { test: String }\n\n\n\n\n\ntype Foo { bad: Int }',
218+
},
219+
],
220+
textDocument: { uri: project.uri('schema.graphql'), version: 1 },
221+
});
222+
223+
const schemaDefRequest2 = await project.lsp.handleDefinitionRequest({
224+
textDocument: { uri: project.uri('schema.graphql') },
225+
position: { character: 19, line: 0 },
226+
});
227+
228+
const fooLaterTypePosition2 = {
229+
start: { line: 8, character: 0 },
230+
end: { line: 8, character: 21 },
231+
};
232+
expect(schemaDefRequest2.length).toEqual(1);
233+
expect(schemaDefRequest2[0].uri).toEqual(project.uri('schema.graphql'));
234+
expect(serializeRange(schemaDefRequest2[0].range)).toEqual(
235+
fooLaterTypePosition2,
236+
);
237+
193238
// TODO: this fragment should now be invalid
194239
const result = await project.lsp.handleDidOpenOrSaveNotification({
195240
textDocument: { uri: project.uri('fragments.graphql') },
196241
});
197-
expect(result.diagnostics).toEqual([]);
242+
expect(result.diagnostics[0].message).toEqual(
243+
'Cannot query field "bar" on type "Foo". Did you mean "bad"?',
244+
);
198245
const generatedFile = existsSync(join(genSchemaPath));
199246
// this generated file should not exist because the schema is local!
200247
expect(generatedFile).toEqual(false);
@@ -245,7 +292,7 @@ describe('project with simple config and graphql files', () => {
245292
);
246293

247294
expect(serializeRange(schemaDefinitionsAgain[0].range)).toEqual(
248-
fooLaterTypePosition,
295+
fooLaterTypePosition2,
249296
);
250297
expect(project.lsp._logger.error).not.toHaveBeenCalled();
251298
});
@@ -384,7 +431,7 @@ describe('project with simple config and graphql files', () => {
384431
],
385432
[
386433
'a/query.ts',
387-
'\n\n\nexport const query = gql`query { test() { isTest, ...T } }`',
434+
'\n\n\nexport const query = graphql`query { test { isTest ...T } }`',
388435
],
389436

390437
[
@@ -408,8 +455,8 @@ describe('project with simple config and graphql files', () => {
408455
],
409456
});
410457

411-
const initParams = await project.init('a/query.graphql');
412-
expect(initParams.diagnostics).toEqual([]);
458+
const initParams = await project.init('a/query.ts');
459+
expect(initParams.diagnostics[0].message).toEqual('Unknown fragment "T".');
413460

414461
expect(project.lsp._logger.error).not.toHaveBeenCalled();
415462
expect(await project.lsp._graphQLCache.getSchema('a')).toBeDefined();

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

Lines changed: 54 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ describe('MessageProcessor', () => {
4848
logger,
4949
graphqlFileExtensions: ['graphql'],
5050
loadConfigOptions: { rootDir: __dirname },
51+
config: null,
5152
});
5253

5354
const queryPathUri = pathToFileURL(`${__dirname}/__queries__`);
@@ -57,9 +58,10 @@ describe('MessageProcessor', () => {
5758
}
5859
}
5960
`;
60-
61+
let gqlConfig;
6162
beforeEach(async () => {
62-
const gqlConfig = await loadConfig({ rootDir: __dirname, extensions: [] });
63+
gqlConfig = await loadConfig({ rootDir: __dirname, extensions: [] });
64+
6365
// loadConfig.mockRestore();
6466
messageProcessor._settings = { load: {} };
6567
messageProcessor._graphQLCache = new GraphQLCache({
@@ -460,6 +462,35 @@ describe('MessageProcessor', () => {
460462
const result = await messageProcessor.handleHoverRequest(test);
461463
expect(result).toEqual({ contents: [] });
462464
});
465+
it('handles provided config', async () => {
466+
const msgProcessor = new MessageProcessor({
467+
// @ts-ignore
468+
connection: {
469+
workspace: {
470+
getConfiguration() {
471+
return {};
472+
},
473+
},
474+
},
475+
logger,
476+
graphqlFileExtensions: ['graphql'],
477+
loadConfigOptions: { rootDir: __dirname },
478+
config: gqlConfig,
479+
});
480+
expect(msgProcessor._providedConfig).toBeTruthy();
481+
await msgProcessor.handleInitializeRequest(
482+
// @ts-ignore
483+
{
484+
rootPath: __dirname,
485+
},
486+
null,
487+
__dirname,
488+
);
489+
await msgProcessor.handleDidChangeConfiguration({
490+
settings: {},
491+
});
492+
expect(msgProcessor._graphQLCache).toBeTruthy();
493+
});
463494

464495
it('runs workspace symbol requests', async () => {
465496
const msgProcessor = new MessageProcessor({
@@ -554,7 +585,7 @@ describe('MessageProcessor', () => {
554585

555586
beforeEach(() => {
556587
mockReadFileSync.mockReturnValue('');
557-
messageProcessor._updateGraphQLConfig = jest.fn();
588+
messageProcessor._initializeGraphQLCaches = jest.fn();
558589
});
559590

560591
it('loads config if not initialized', async () => {
@@ -563,7 +594,9 @@ describe('MessageProcessor', () => {
563594
const result = await messageProcessor._loadConfigOrSkip(
564595
`${pathToFileURL('.')}/graphql.config.js`,
565596
);
566-
expect(messageProcessor._updateGraphQLConfig).toHaveBeenCalledTimes(1);
597+
expect(messageProcessor._initializeGraphQLCaches).toHaveBeenCalledTimes(
598+
1,
599+
);
567600
// we want to return true here to skip further processing, because it's just a config file change
568601
expect(result).toEqual(true);
569602
});
@@ -574,7 +607,9 @@ describe('MessageProcessor', () => {
574607
const result = await messageProcessor._loadConfigOrSkip(
575608
`${pathToFileURL('.')}/file.ts`,
576609
);
577-
expect(messageProcessor._updateGraphQLConfig).toHaveBeenCalledTimes(1);
610+
expect(messageProcessor._initializeGraphQLCaches).toHaveBeenCalledTimes(
611+
1,
612+
);
578613
// here we have a non-config file, so we don't want to skip, because we need to run diagnostics etc
579614
expect(result).toEqual(false);
580615
});
@@ -583,15 +618,17 @@ describe('MessageProcessor', () => {
583618
const result = await messageProcessor._loadConfigOrSkip(
584619
`${pathToFileURL('.')}/graphql.config.ts`,
585620
);
586-
expect(messageProcessor._updateGraphQLConfig).toHaveBeenCalledTimes(1);
621+
expect(messageProcessor._initializeGraphQLCaches).toHaveBeenCalledTimes(
622+
1,
623+
);
587624
expect(result).toEqual(true);
588625
});
589626
it('skips if the server is already initialized', async () => {
590627
messageProcessor._isInitialized = true;
591628
const result = await messageProcessor._loadConfigOrSkip(
592629
`${pathToFileURL('.')}/myFile.ts`,
593630
);
594-
expect(messageProcessor._updateGraphQLConfig).not.toHaveBeenCalled();
631+
expect(messageProcessor._initializeGraphQLCaches).not.toHaveBeenCalled();
595632
expect(result).toEqual(false);
596633
});
597634
});
@@ -602,7 +639,7 @@ describe('MessageProcessor', () => {
602639

603640
beforeEach(() => {
604641
mockReadFileSync.mockReturnValue('');
605-
messageProcessor._updateGraphQLConfig = jest.fn();
642+
messageProcessor._initializeGraphQLCaches = jest.fn();
606643
messageProcessor._loadConfigOrSkip = jest.fn();
607644
});
608645
it('updates config for standard config filename changes', async () => {
@@ -642,7 +679,7 @@ describe('MessageProcessor', () => {
642679
settings: [],
643680
});
644681

645-
expect(messageProcessor._updateGraphQLConfig).toHaveBeenCalled();
682+
expect(messageProcessor._initializeGraphQLCaches).toHaveBeenCalled();
646683

647684
await messageProcessor.handleDidOpenOrSaveNotification({
648685
textDocument: {
@@ -653,7 +690,7 @@ describe('MessageProcessor', () => {
653690
},
654691
});
655692

656-
expect(messageProcessor._updateGraphQLConfig).toHaveBeenCalled();
693+
expect(messageProcessor._initializeGraphQLCaches).toHaveBeenCalled();
657694
});
658695
});
659696

@@ -664,7 +701,7 @@ describe('MessageProcessor', () => {
664701
uri: 'test',
665702
});
666703

667-
expect(messageProcessor._updateGraphQLConfig).not.toHaveBeenCalled();
704+
expect(messageProcessor._initializeGraphQLCaches).not.toHaveBeenCalled();
668705
expect(logger.error).toHaveBeenCalledWith(
669706
expect.stringContaining('test missing-config'),
670707
);
@@ -675,7 +712,7 @@ describe('MessageProcessor', () => {
675712
uri: 'test',
676713
});
677714

678-
expect(messageProcessor._updateGraphQLConfig).not.toHaveBeenCalled();
715+
expect(messageProcessor._initializeGraphQLCaches).not.toHaveBeenCalled();
679716
expect(logger.error).toHaveBeenCalledWith(
680717
expect.stringContaining('Project not found for this file'),
681718
);
@@ -686,7 +723,7 @@ describe('MessageProcessor', () => {
686723
uri: 'test',
687724
});
688725

689-
expect(messageProcessor._updateGraphQLConfig).not.toHaveBeenCalled();
726+
expect(messageProcessor._initializeGraphQLCaches).not.toHaveBeenCalled();
690727
expect(logger.error).toHaveBeenCalledWith(
691728
expect.stringContaining('Invalid configuration'),
692729
);
@@ -697,7 +734,7 @@ describe('MessageProcessor', () => {
697734
uri: 'test',
698735
});
699736

700-
expect(messageProcessor._updateGraphQLConfig).not.toHaveBeenCalled();
737+
expect(messageProcessor._initializeGraphQLCaches).not.toHaveBeenCalled();
701738
expect(logger.error).toHaveBeenCalledWith(
702739
expect.stringContaining('test loader-error'),
703740
);
@@ -708,7 +745,7 @@ describe('MessageProcessor', () => {
708745
uri: 'test',
709746
});
710747

711-
expect(messageProcessor._updateGraphQLConfig).not.toHaveBeenCalled();
748+
expect(messageProcessor._initializeGraphQLCaches).not.toHaveBeenCalled();
712749
expect(logger.error).toHaveBeenCalledWith(
713750
expect.stringContaining('test loader-error'),
714751
);
@@ -720,7 +757,7 @@ describe('MessageProcessor', () => {
720757

721758
beforeEach(() => {
722759
mockReadFileSync.mockReturnValue(' query { id }');
723-
messageProcessor._updateGraphQLConfig = jest.fn();
760+
messageProcessor._initializeGraphQLCaches = jest.fn();
724761
messageProcessor._updateFragmentDefinition = jest.fn();
725762
messageProcessor._isGraphQLConfigMissing = false;
726763
messageProcessor._isInitialized = true;
@@ -738,7 +775,7 @@ describe('MessageProcessor', () => {
738775
],
739776
});
740777

741-
expect(messageProcessor._updateGraphQLConfig).not.toHaveBeenCalled();
778+
expect(messageProcessor._initializeGraphQLCaches).not.toHaveBeenCalled();
742779
expect(messageProcessor._updateFragmentDefinition).toHaveBeenCalled();
743780
});
744781
});

packages/graphql-language-service-server/src/__tests__/__utils__/MockProject.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,10 @@ export class MockProject {
8686
textDocument: {
8787
uri: this.uri(filename || 'query.graphql'),
8888
version: 1,
89-
text: this.fileCache.get('query.graphql') || fileText,
89+
text:
90+
this.fileCache.get('query.graphql') ||
91+
(filename && this.fileCache.get(filename)) ||
92+
fileText,
9093
},
9194
});
9295
}

packages/graphql-language-service-server/src/parsers/astro.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -41,15 +41,15 @@ function parseAstro(source: string): ParseAstroResult {
4141
return { type: 'error', errors: ['Could not find frontmatter block'] };
4242
}
4343

44-
export const astroParser: SourceParser = (text, uri, logger) => {
44+
export const astroParser: SourceParser = (text, _uri, _logger) => {
4545
const parseAstroResult = parseAstro(text);
4646
if (parseAstroResult.type === 'error') {
47-
logger.error(
48-
`Could not parse the astro file at ${uri} to extract the graphql tags:`,
49-
);
50-
for (const error of parseAstroResult.errors) {
51-
logger.error(String(error));
52-
}
47+
// logger.error(
48+
// `Could not parse the astro file at ${uri} to extract the graphql tags:`,
49+
// );
50+
// for (const error of parseAstroResult.errors) {
51+
// logger.error(String(error));
52+
// }
5353
return null;
5454
}
5555

packages/graphql-language-service-server/src/parsers/babel.ts

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,26 +11,26 @@ export const babelParser = (text: string, plugins?: ParserPlugin[]) => {
1111
return parse(text, PARSER_OPTIONS);
1212
};
1313

14-
export const ecmaParser: SourceParser = (text, uri, logger) => {
14+
export const ecmaParser: SourceParser = (text, _uri, _logger) => {
1515
try {
1616
return { asts: [babelParser(text, ['flow', 'flowComments'])] };
17-
} catch (error) {
18-
logger.error(
19-
`Could not parse the JavaScript file at ${uri} to extract the graphql tags:`,
20-
);
21-
logger.error(String(error));
17+
} catch {
18+
// logger.error(
19+
// `Could not parse the JavaScript file at ${uri} to extract the graphql tags:`,
20+
// );
21+
// logger.error(String(error));
2222
return null;
2323
}
2424
};
2525

26-
export const tsParser: SourceParser = (text, uri, logger) => {
26+
export const tsParser: SourceParser = (text, _uri, _logger) => {
2727
try {
2828
return { asts: [babelParser(text, ['typescript'])] };
29-
} catch (error) {
30-
logger.error(
31-
`Could not parse the TypeScript file at ${uri} to extract the graphql tags:`,
32-
);
33-
logger.error(String(error));
29+
} catch {
30+
// logger.error(
31+
// `Could not parse the TypeScript file at ${uri} to extract the graphql tags:`,
32+
// );
33+
// logger.error(String(error));
3434
return null;
3535
}
3636
};

packages/graphql-language-service-server/src/parsers/svelte.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { SourceMapConsumer } from 'source-map-js';
44
import { Position, Range } from 'graphql-language-service';
55
import type { RangeMapper, SourceParser } from './types';
66

7-
export const svelteParser: SourceParser = (text, uri, logger) => {
7+
export const svelteParser: SourceParser = (text, uri, _logger) => {
88
const svelteResult = svelte2tsx(text, {
99
filename: uri,
1010
});
@@ -35,11 +35,11 @@ export const svelteParser: SourceParser = (text, uri, logger) => {
3535
asts: [babelParser(svelteResult.code, ['typescript'])],
3636
rangeMapper,
3737
};
38-
} catch (error) {
39-
logger.error(
40-
`Could not parse the Svelte file at ${uri} to extract the graphql tags:`,
41-
);
42-
logger.error(String(error));
38+
} catch {
39+
// logger.error(
40+
// `Could not parse the Svelte file at ${uri} to extract the graphql tags:`,
41+
// );
42+
// logger.error(String(error));
4343
return null;
4444
}
4545
};

0 commit comments

Comments
 (0)