codemirror-graphql
Version:
GraphQL mode and helpers for CodeMirror.
82 lines (73 loc) • 2.5 kB
text/typescript
/**
* Copyright (c) 2021 GraphQL Contributors
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
import CodeMirror from 'codemirror';
import 'codemirror/addon/lint/lint';
import { readFileSync } from 'node:fs';
import { join } from 'node:path';
import { GraphQLError, OperationDefinitionNode, version } from 'graphql';
import '../lint';
import '../mode';
import { TestSchema } from './testSchema';
function createEditorWithLint(lintConfig?: any) {
return CodeMirror(document.createElement('div'), {
mode: 'graphql',
lint: lintConfig || true,
});
}
function printLintErrors(queryString: string, configOverrides = {}) {
const editor = createEditorWithLint({
schema: TestSchema,
...configOverrides,
});
return new Promise<any[]>(resolve => {
editor.state.lint.options.onUpdateLinting = (errors: any[]) => {
if (errors?.[0] && !errors[0].message.match('Unexpected EOF')) {
resolve(errors);
return;
}
resolve([]);
};
editor.doc.setValue(queryString);
});
}
describe('graphql-lint', () => {
it('attaches a GraphQL lint function with correct mode/lint options', () => {
const editor = createEditorWithLint();
expect(editor.getHelpers(editor.getCursor(), 'lint')).not.toHaveLength(0);
});
const kitchenSink = readFileSync(
join(__dirname, '/kitchen-sink.graphql'),
'utf8',
);
it('returns no syntactic/validation errors after parsing kitchen-sink query', async () => {
const errors = await printLintErrors(kitchenSink);
expect(errors).toHaveLength(0);
});
it('returns a validation error for a invalid query', async () => {
const noMutationOperationRule = (context: any) => ({
OperationDefinition(node: OperationDefinitionNode) {
if (node.operation === 'mutation') {
context.reportError(
new GraphQLError(
'I like turtles.',
// @ts-expect-error
parseInt(version, 10) > 16 ? { nodes: node } : node,
),
);
}
return false;
},
});
const errors = await printLintErrors(kitchenSink, {
validationRules: [noMutationOperationRule],
});
expect(errors.length).toBe(1);
expect(errors[0].message).toBe('I like turtles.');
});
});