graphql-language-service-utils
Version:
Utilities to support the GraphQL Language Service
261 lines (242 loc) • 7.51 kB
text/typescript
/**
* Copyright (c) 2021 GraphQL Contributors
* All rights reserved.
*
* This source code is licensed under the license found in the
* LICENSE file in the root directory of this source tree.
*/
import { readFileSync } from 'fs';
import { buildSchema, GraphQLSchema, parse } from 'graphql';
import { join } from 'path';
import { collectVariables } from '../collectVariables';
import { getVariablesJSONSchema } from '../getVariablesJSONSchema';
describe('getVariablesJSONSchema', () => {
let schema: GraphQLSchema;
beforeEach(() => {
const schemaPath = join(__dirname, '__schema__', 'StarWarsSchema.graphql');
schema = buildSchema(readFileSync(schemaPath, 'utf8'));
});
it('should handle scalar types', () => {
const variableToType = collectVariables(
schema,
parse(`query($id: ID, $string: String!, $boolean: Boolean, $number: Int!, $price: Float) {
characters{
name
}
}`),
);
const jsonSchema = getVariablesJSONSchema(variableToType);
expect(jsonSchema.required).toEqual(['string', 'number']);
expect(jsonSchema.properties).toEqual({
boolean: {
type: 'boolean',
description: 'Boolean',
},
string: {
type: 'string',
description: 'String!',
},
number: {
type: 'integer',
description: 'Int!',
},
price: {
description: 'Float',
type: 'number',
},
});
});
it('should handle input object types', () => {
const variableToType = collectVariables(
schema,
parse(`query($input: InputType!, $anotherInput: InputType) {
characters {
name
}
}`),
);
const jsonSchema = getVariablesJSONSchema(variableToType);
expect(jsonSchema.required).toEqual(['input']);
expect(jsonSchema.properties).toEqual({
input: {
$ref: '#/definitions/InputType',
description: 'InputType!',
},
anotherInput: {
$ref: '#/definitions/InputType',
description: 'example input type\nInputType',
},
});
expect(jsonSchema.definitions).toEqual({
InputType: {
type: 'object',
description: 'example input type\nInputType',
properties: {
key: {
description: 'example key\nString!',
type: 'string',
},
value: {
description: 'example value\nInt',
type: 'integer',
default: 42,
},
exampleObject: {
$ref: '#/definitions/ChildInputType',
description: 'nesting a whole object!\nChildInputType!',
},
exampleList: {
type: 'array',
items: {
$ref: '#/definitions/ChildInputType',
},
description: 'list type with default\n[ChildInputType]',
default: [
{
isChild: false,
favoriteBook: 'Binti',
},
],
},
exampleScalarList: {
type: 'array',
description: '[String]!',
items: {
type: 'string',
description: 'String',
},
default: ['something'],
},
},
required: ['key', 'exampleObject', 'exampleScalarList'],
},
ChildInputType: {
type: 'object',
description: 'ChildInputType',
properties: {
isChild: {
type: 'boolean',
description: 'Boolean!',
default: true,
},
favoriteBook: {
type: 'string',
description: 'favorite book\nString',
default: 'Where the wild things are',
},
},
required: ['isChild'],
},
});
});
const mdTicks = (name: string) => `\`\`\`graphql\n${name}\n\`\`\``;
it('should handle input object types with markdown', () => {
const variableToType = collectVariables(
schema,
parse(`query($input: InputType!, $anotherInput: InputType, $episode: Episode) {
characters {
name
}
}`),
);
const jsonSchema = getVariablesJSONSchema(variableToType, {
useMarkdownDescription: true,
});
expect(jsonSchema.required).toEqual(['input']);
expect(jsonSchema.properties).toEqual({
input: {
$ref: '#/definitions/InputType',
description: 'InputType!',
markdownDescription: mdTicks('InputType!'),
},
anotherInput: {
$ref: '#/definitions/InputType',
// description: 'example input type',
// TODO: fix this for non-nulls?
description: 'example input type\nInputType',
markdownDescription: 'example input type\n```graphql\nInputType\n```',
},
episode: {
enum: ['NEWHOPE', 'EMPIRE', 'JEDI'],
description: 'Episode',
type: 'string',
markdownDescription: mdTicks('Episode'),
},
});
expect(jsonSchema.definitions).toEqual({
InputType: {
type: 'object',
description: 'example input type\nInputType',
markdownDescription: `example input type\n${mdTicks('InputType')}`,
properties: {
key: {
description: 'example key\nString!',
markdownDescription: `example key\n${mdTicks('String!')}`,
type: 'string',
},
value: {
description: 'example value\nInt',
markdownDescription: `example value\n${mdTicks('Int')}`,
type: 'integer',
default: 42,
},
exampleObject: {
description: 'nesting a whole object!\nChildInputType!',
markdownDescription: `nesting a whole object!\n${mdTicks(
'ChildInputType!',
)}`,
$ref: '#/definitions/ChildInputType',
},
exampleList: {
type: 'array',
items: {
$ref: '#/definitions/ChildInputType',
},
description: `list type with default\n[ChildInputType]`,
markdownDescription: `list type with default\n${mdTicks(
'[ChildInputType]',
)}`,
default: [
{
isChild: false,
favoriteBook: 'Binti',
},
],
},
exampleScalarList: {
type: 'array',
description: '[String]!',
markdownDescription: mdTicks('[String]!'),
items: {
type: 'string',
description: 'String',
markdownDescription: mdTicks('String'),
},
default: ['something'],
},
},
required: ['key', 'exampleObject', 'exampleScalarList'],
},
ChildInputType: {
description: 'ChildInputType',
markdownDescription: `${mdTicks('ChildInputType')}`,
properties: {
favoriteBook: {
default: 'Where the wild things are',
description: 'favorite book\nString',
markdownDescription: 'favorite book\n```graphql\nString\n```',
type: 'string',
},
isChild: {
default: true,
description: 'Boolean!',
markdownDescription: '```graphql\nBoolean!\n```',
type: 'boolean',
},
},
required: ['isChild'],
type: 'object',
},
});
});
});