Mirror: The highly customizable and versatile GraphQL client with which you add on features like normalized caching as you grow.
at main 5.2 kB view raw
1import { describe, it, expect } from 'vitest'; 2import { 3 TypedDocumentNode, 4 FormattedNode, 5 formatDocument, 6 gql, 7} from '@urql/core'; 8import { FieldNode } from '@0no-co/graphql.web'; 9 10import { SelectionIterator, deferRef } from './shared'; 11import { SelectionSet } from '../ast'; 12 13const selectionOfDocument = ( 14 doc: TypedDocumentNode 15): FormattedNode<SelectionSet> => { 16 for (const definition of formatDocument(doc).definitions) 17 if (definition.kind === 'OperationDefinition') 18 return definition.selectionSet.selections as FormattedNode<SelectionSet>; 19 return []; 20}; 21 22const ctx = {} as any; 23 24describe('SelectionIterator', () => { 25 it('emits all fields', () => { 26 const selection = selectionOfDocument(gql` 27 { 28 a 29 b 30 c 31 } 32 `); 33 const iterate = new SelectionIterator( 34 'Query', 35 'Query', 36 false, 37 undefined, 38 selection, 39 ctx 40 ); 41 const result: FieldNode[] = []; 42 43 let node: FieldNode | void; 44 while ((node = iterate.next())) result.push(node); 45 46 expect(result).toMatchInlineSnapshot(` 47 [ 48 { 49 "alias": undefined, 50 "arguments": undefined, 51 "directives": undefined, 52 "kind": "Field", 53 "name": { 54 "kind": "Name", 55 "value": "a", 56 }, 57 "selectionSet": undefined, 58 }, 59 { 60 "alias": undefined, 61 "arguments": undefined, 62 "directives": undefined, 63 "kind": "Field", 64 "name": { 65 "kind": "Name", 66 "value": "b", 67 }, 68 "selectionSet": undefined, 69 }, 70 { 71 "alias": undefined, 72 "arguments": undefined, 73 "directives": undefined, 74 "kind": "Field", 75 "name": { 76 "kind": "Name", 77 "value": "c", 78 }, 79 "selectionSet": undefined, 80 }, 81 ] 82 `); 83 }); 84 85 it('skips fields that are skipped or not included', () => { 86 const selection = selectionOfDocument(gql` 87 { 88 a @skip(if: true) 89 b @include(if: false) 90 } 91 `); 92 93 const iterate = new SelectionIterator( 94 'Query', 95 'Query', 96 false, 97 undefined, 98 selection, 99 ctx 100 ); 101 const result: FieldNode[] = []; 102 103 let node: FieldNode | void; 104 while ((node = iterate.next())) result.push(node); 105 106 expect(result).toMatchInlineSnapshot('[]'); 107 }); 108 109 it('processes fragments', () => { 110 const selection = selectionOfDocument(gql` 111 { 112 a 113 ... { 114 b 115 } 116 ... { 117 ... { 118 c 119 } 120 } 121 } 122 `); 123 124 const iterate = new SelectionIterator( 125 'Query', 126 'Query', 127 false, 128 undefined, 129 selection, 130 ctx 131 ); 132 const result: FieldNode[] = []; 133 134 let node: FieldNode | void; 135 while ((node = iterate.next())) result.push(node); 136 137 expect(result).toMatchInlineSnapshot(` 138 [ 139 { 140 "alias": undefined, 141 "arguments": undefined, 142 "directives": undefined, 143 "kind": "Field", 144 "name": { 145 "kind": "Name", 146 "value": "a", 147 }, 148 "selectionSet": undefined, 149 }, 150 { 151 "alias": undefined, 152 "arguments": undefined, 153 "directives": undefined, 154 "kind": "Field", 155 "name": { 156 "kind": "Name", 157 "value": "b", 158 }, 159 "selectionSet": undefined, 160 }, 161 { 162 "alias": undefined, 163 "arguments": undefined, 164 "directives": undefined, 165 "kind": "Field", 166 "name": { 167 "kind": "Name", 168 "value": "c", 169 }, 170 "selectionSet": undefined, 171 }, 172 ] 173 `); 174 }); 175 176 it('updates deferred state as needed', () => { 177 const selection = selectionOfDocument(gql` 178 { 179 a 180 ... @defer { 181 b 182 } 183 ... { 184 ... @defer { 185 c 186 } 187 } 188 ... { 189 ... { 190 d 191 } 192 } 193 ... @defer { 194 ... { 195 e 196 } 197 } 198 ... { 199 ... { 200 f 201 } 202 } 203 ... { 204 g 205 } 206 h 207 } 208 `); 209 210 const iterate = new SelectionIterator( 211 'Query', 212 'Query', 213 false, 214 undefined, 215 selection, 216 ctx 217 ); 218 219 const deferred: boolean[] = []; 220 while (iterate.next()) deferred.push(deferRef); 221 expect(deferred).toEqual([ 222 false, // a 223 true, // b 224 true, // c 225 false, // d 226 true, // e 227 false, // f 228 false, // g 229 false, // h 230 ]); 231 }); 232 233 it('applies the parent’s defer state if needed', () => { 234 const selection = selectionOfDocument(gql` 235 { 236 a 237 ... @defer { 238 b 239 } 240 ... { 241 c 242 } 243 } 244 `); 245 246 const iterate = new SelectionIterator( 247 'Query', 248 'Query', 249 true, 250 undefined, 251 selection, 252 ctx 253 ); 254 255 const deferred: boolean[] = []; 256 while (iterate.next()) deferred.push(deferRef); 257 expect(deferred).toEqual([true, true, true]); 258 }); 259});