Mirror: The spec-compliant minimum of client-side GraphQL.
1import { describe, it, expect } from 'vitest';
2import { readFileSync } from 'fs';
3
4import { parse, print as graphql_print } from 'graphql';
5import { print } from '../printer';
6
7function dedentString(string) {
8 const trimmedStr = string
9 .replace(/^\n*/m, '') // remove leading newline
10 .replace(/[ \t\n]*$/, ''); // remove trailing spaces and tabs
11 // fixes indentation by removing leading spaces and tabs from each line
12 let indent = '';
13 for (const char of trimmedStr) {
14 if (char !== ' ' && char !== '\t') {
15 break;
16 }
17 indent += char;
18 }
19
20 return trimmedStr.replace(RegExp('^' + indent, 'mg'), ''); // remove indent
21}
22
23function dedent(strings, ...values) {
24 let str = strings[0];
25 for (let i = 1; i < strings.length; ++i) str += values[i - 1] + strings[i]; // interpolation
26 return dedentString(str);
27}
28
29describe('print', () => {
30 it('prints the kitchen sink document like graphql.js does', () => {
31 const sink = JSON.parse(readFileSync(__dirname + '/kitchen_sink.json', { encoding: 'utf8' }));
32 const doc = print(sink);
33 expect(doc).toMatchSnapshot();
34 expect(doc).toEqual(graphql_print(sink));
35 });
36
37 it('prints minimal ast', () => {
38 const ast = {
39 kind: 'Field',
40 name: { kind: 'Name', value: 'foo' },
41 };
42 expect(print(ast as any)).toBe('foo');
43 });
44
45 // NOTE: The shim won't throw for invalid AST nodes
46 it('returns empty strings for invalid AST', () => {
47 const badAST = { random: 'Data' };
48 expect(print(badAST as any)).toBe('');
49 });
50
51 it('correctly prints non-query operations without name', () => {
52 const queryASTShorthanded = parse('query { id, name }');
53 expect(print(queryASTShorthanded)).toBe(dedent`
54 {
55 id
56 name
57 }
58 `);
59
60 const mutationAST = parse('mutation { id, name }');
61 expect(print(mutationAST)).toBe(dedent`
62 mutation {
63 id
64 name
65 }
66 `);
67
68 const queryASTWithArtifacts = parse('query ($foo: TestType) @testDirective { id, name }');
69 expect(print(queryASTWithArtifacts)).toBe(dedent`
70 query ($foo: TestType) @testDirective {
71 id
72 name
73 }
74 `);
75
76 const mutationASTWithArtifacts = parse('mutation ($foo: TestType) @testDirective { id, name }');
77 expect(print(mutationASTWithArtifacts)).toBe(dedent`
78 mutation ($foo: TestType) @testDirective {
79 id
80 name
81 }
82 `);
83 });
84
85 it('prints query with variable directives', () => {
86 const queryASTWithVariableDirective = parse(
87 'query ($foo: TestType = {a: 123} @testDirective(if: true) @test) { id }'
88 );
89 expect(print(queryASTWithVariableDirective)).toBe(dedent`
90 query ($foo: TestType = {a: 123} @testDirective(if: true) @test) {
91 id
92 }
93 `);
94 });
95
96 it('keeps arguments on one line if line is short (<= 80 chars)', () => {
97 const printed = print(parse('{trip(wheelchair:false arriveBy:false){dateTime}}'));
98
99 expect(printed).toBe(
100 dedent`
101 {
102 trip(wheelchair: false, arriveBy: false) {
103 dateTime
104 }
105 }
106 `
107 );
108 });
109});