Mirror: The small sibling of the graphql package, slimmed down for client-side libraries.
at v16.6.0-4 5.5 kB view raw
1// See: https://github.com/graphql/graphql-js/blob/976d64b/src/language/__tests__/printer-test.ts 2 3import { describe, it, expect } from 'vitest'; 4import { parse } from '../parser'; 5import { print } from '../printer'; 6 7describe('Printer: Query document', () => { 8 it('prints minimal ast', () => { 9 const ast = { 10 kind: 'Field', 11 name: { kind: 'Name', value: 'foo' }, 12 }; 13 expect(print(ast)).toBe('foo'); 14 }); 15 16 // NOTE: The shim won't throw for invalid AST nodes 17 it('returns empty strings for invalid AST', () => { 18 const badAST = { random: 'Data' }; 19 expect(print(badAST)).toBe(''); 20 }); 21 22 it('correctly prints non-query operations without name', () => { 23 const queryASTShorthanded = parse('query { id, name }'); 24 expect(print(queryASTShorthanded)).toBe(dedent` 25 { 26 id 27 name 28 }`); 29 30 const mutationAST = parse('mutation { id, name }'); 31 expect(print(mutationAST)).toBe(dedent` 32 mutation { 33 id 34 name 35 }`); 36 37 const queryASTWithArtifacts = parse('query ($foo: TestType) @testDirective { id, name }'); 38 expect(print(queryASTWithArtifacts)).toBe(dedent` 39 query ($foo: TestType) @testDirective { 40 id 41 name 42 }`); 43 44 const mutationASTWithArtifacts = parse('mutation ($foo: TestType) @testDirective { id, name }'); 45 expect(print(mutationASTWithArtifacts)).toBe(dedent` 46 mutation ($foo: TestType) @testDirective { 47 id 48 name 49 } 50 `); 51 }); 52 53 it('prints query with variable directives', () => { 54 const queryASTWithVariableDirective = parse( 55 'query ($foo: TestType = {a: 123} @testDirective(if: true) @test) { id }' 56 ); 57 expect(print(queryASTWithVariableDirective)).toBe(dedent` 58 query ($foo: TestType = {a: 123} @testDirective(if: true) @test) { 59 id 60 } 61 `); 62 }); 63 64 it('keeps arguments on one line if line is short (<= 80 chars)', () => { 65 const printed = print(parse('{trip(wheelchair:false arriveBy:false){dateTime}}')); 66 67 expect(printed).toBe( 68 dedent` 69 { 70 trip(wheelchair: false, arriveBy: false) { 71 dateTime 72 } 73 }` 74 ); 75 }); 76 77 it('prints kitchen sink without altering ast', () => { 78 const ast = parse(kitchenSinkQuery, { noLocation: true }); 79 80 const astBeforePrintCall = JSON.stringify(ast); 81 const printed = print(ast); 82 const printedAST = parse(printed, { noLocation: true }); 83 84 expect(printedAST).toEqual(ast); 85 expect(JSON.stringify(ast)).toBe(astBeforePrintCall); 86 87 expect(printed).toBe( 88 dedentString(String.raw` 89 query queryName($foo: ComplexType, $site: Site = MOBILE) @onQuery { 90 whoever123is: node(id: [123, 456]) { 91 id 92 ... on User @onInlineFragment { 93 field2 { 94 id 95 alias: field1(first: 10, after: $foo) @include(if: $foo) { 96 id 97 ...frag @onFragmentSpread 98 } 99 } 100 } 101 ... @skip(unless: $foo) { 102 id 103 } 104 ... { 105 id 106 } 107 } 108 } 109 110 mutation likeStory @onMutation { 111 like(story: 123) @onField { 112 story { 113 id @onField 114 } 115 } 116 } 117 118 subscription StoryLikeSubscription($input: StoryLikeSubscribeInput @onVariableDefinition) @onSubscription { 119 storyLikeSubscribe(input: $input) { 120 story { 121 likers { 122 count 123 } 124 likeSentence { 125 text 126 } 127 } 128 } 129 } 130 131 fragment frag on Friend @onFragmentDefinition { 132 foo(size: $size, bar: $b, obj: {key: "value"}) 133 } 134 135 { 136 unnamed(truthy: true, falsy: false, nullish: null) 137 query 138 } 139 140 { 141 __typename 142 }`) 143 ); 144 }); 145}); 146 147const kitchenSinkQuery = String.raw` 148query queryName($foo: ComplexType, $site: Site = MOBILE) @onQuery { 149 whoever123is: node(id: [123, 456]) { 150 id 151 ... on User @onInlineFragment { 152 field2 { 153 id 154 alias: field1(first: 10, after: $foo) @include(if: $foo) { 155 id 156 ...frag @onFragmentSpread 157 } 158 } 159 } 160 ... @skip(unless: $foo) { 161 id 162 } 163 ... { 164 id 165 } 166 } 167} 168mutation likeStory @onMutation { 169 like(story: 123) @onField { 170 story { 171 id @onField 172 } 173 } 174} 175subscription StoryLikeSubscription( 176 $input: StoryLikeSubscribeInput @onVariableDefinition 177) 178 @onSubscription { 179 storyLikeSubscribe(input: $input) { 180 story { 181 likers { 182 count 183 } 184 likeSentence { 185 text 186 } 187 } 188 } 189} 190fragment frag on Friend @onFragmentDefinition { 191 foo( 192 size: $size 193 bar: $b 194 obj: { key: "value" } 195 ) 196} 197{ 198 unnamed(truthy: true, falsy: false, nullish: null) 199 query 200} 201query { 202 __typename 203} 204`; 205 206function dedentString(string) { 207 const trimmedStr = string 208 .replace(/^\n*/m, '') // remove leading newline 209 .replace(/[ \t\n]*$/, ''); // remove trailing spaces and tabs 210 // fixes indentation by removing leading spaces and tabs from each line 211 let indent = ''; 212 for (const char of trimmedStr) { 213 if (char !== ' ' && char !== '\t') { 214 break; 215 } 216 indent += char; 217 } 218 219 return trimmedStr.replace(RegExp('^' + indent, 'mg'), ''); // remove indent 220} 221 222function dedent(strings, ...values) { 223 let str = strings[0]; 224 for (let i = 1; i < strings.length; ++i) str += values[i - 1] + strings[i]; // interpolation 225 return dedentString(str); 226}