···
+
// See: https://github.com/graphql/graphql-js/blob/976d64b/src/language/__tests__/parser-test.ts
+
// Note: Tests regarding reserved keywords have been removed.
+
import { Kind } from 'graphql';
+
import { parse, parseValue, parseType } from '../parser';
+
describe('Parser', () => {
+
it('parse provides errors', () => {
+
expect(() => parse('{')).toThrow();
+
it('parses variable inline values', () => {
+
return parse('{ field(complex: { a: { b: [ $var ] } }) }');
+
it('parses constant default values', () => {
+
return parse('query Foo($x: Complex = { a: { b: [ $var ] } }) { field }');
+
it('parses variable definition directives', () => {
+
return parse('query Foo($x: Boolean = false @bar) { field }');
+
it('does not accept fragments spread of "on"', () => {
+
return parse('{ ...on }');
+
it('parses multi-byte characters', () => {
+
// Note: \u0A0A could be naively interpreted as two line-feed chars.
+
# This comment has a \u0A0A multi-byte character.
+
{ field(arg: "Has a \u0A0A multi-byte character.") }
+
expect(ast).toHaveProperty(
+
'definitions.0.selectionSet.selections.0.arguments.0.value.value',
+
'Has a \u0A0A multi-byte character.'
+
it('parses kitchen sink', () => {
+
expect(() => parse(kitchenSinkQuery)).not.toThrow();
+
it('parses anonymous mutation operations', () => {
+
it('parses anonymous subscription operations', () => {
+
it('parses named mutation operations', () => {
+
it('parses named subscription operations', () => {
+
it('creates ast', () => {
+
expect(result).toMatchObject({
+
kind: Kind.OPERATION_DEFINITION,
+
variableDefinitions: [],
+
kind: Kind.SELECTION_SET,
+
kind: Kind.SELECTION_SET,
+
selectionSet: undefined,
+
selectionSet: undefined,
+
it('creates ast from nameless query without variables', () => {
+
expect(result).toMatchObject({
+
kind: Kind.OPERATION_DEFINITION,
+
variableDefinitions: [],
+
kind: Kind.SELECTION_SET,
+
kind: Kind.SELECTION_SET,
+
selectionSet: undefined,
+
it('allows parsing without source location information', () => {
+
const result = parse('{ id }', { noLocation: true });
+
expect('loc' in result).toBe(false);
+
describe('parseValue', () => {
+
it('parses null value', () => {
+
const result = parseValue('null');
+
expect(result).toEqual({ kind: Kind.NULL });
+
it('parses list values', () => {
+
const result = parseValue('[123 "abc"]');
+
expect(result).toEqual({
+
it('parses block strings', () => {
+
const result = parseValue('["""long""" "short"]');
+
expect(result).toEqual({
+
it('allows variables', () => {
+
const result = parseValue('{ field: $var }');
+
expect(result).toEqual({
+
kind: Kind.OBJECT_FIELD,
+
it('correct message for incomplete variable', () => {
+
return parseValue('$');
+
it('correct message for unexpected token', () => {
+
return parseValue(':');
+
describe('parseType', () => {
+
it('parses well known types', () => {
+
const result = parseType('String');
+
expect(result).toEqual({
+
it('parses custom types', () => {
+
const result = parseType('MyType');
+
expect(result).toEqual({
+
it('parses list types', () => {
+
const result = parseType('[MyType]');
+
expect(result).toEqual({
+
it('parses non-null types', () => {
+
const result = parseType('MyType!');
+
expect(result).toEqual({
+
kind: Kind.NON_NULL_TYPE,
+
it('parses nested types', () => {
+
const result = parseType('[MyType!]');
+
expect(result).toEqual({
+
kind: Kind.NON_NULL_TYPE,
+
const kitchenSinkQuery: string = String.raw`
+
query queryName($foo: ComplexType, $site: Site = MOBILE) @onQuery {
+
whoever123is: node(id: [123, 456]) {
+
... on User @onInlineFragment {
+
alias: field1(first: 10, after: $foo) @include(if: $foo) {
+
...frag @onFragmentSpread
+
... @skip(unless: $foo) {
+
mutation likeStory @onMutation {
+
like(story: 123) @onField {
+
subscription StoryLikeSubscription(
+
$input: StoryLikeSubscribeInput @onVariableDefinition
+
storyLikeSubscribe(input: $input) {
+
fragment frag on Friend @onFragmentDefinition {
+
unnamed(truthy: true, falsy: false, nullish: null)