Mirror: The highly customizable and versatile GraphQL client with which you add on features like normalized caching as you grow.
at main 4.0 kB view raw
1import { Kind, parse, print } from '@0no-co/graphql.web'; 2import { describe, it, expect } from 'vitest'; 3import { createRequest } from './request'; 4import { formatDocument } from './formatDocument'; 5 6const formatTypeNames = (query: string) => { 7 const typedNode = formatDocument(parse(query)); 8 return print(typedNode); 9}; 10 11describe('formatDocument', () => { 12 it('creates a new instance when adding typenames', () => { 13 const doc = parse(`{ id todos { id } }`) as any; 14 const newDoc = formatDocument(doc) as any; 15 expect(doc).not.toBe(newDoc); 16 expect(doc.definitions).not.toBe(newDoc.definitions); 17 expect(doc.definitions[0]).not.toBe(newDoc.definitions[0]); 18 expect(doc.definitions[0].selectionSet).not.toBe( 19 newDoc.definitions[0].selectionSet 20 ); 21 expect(doc.definitions[0].selectionSet.selections).not.toBe( 22 newDoc.definitions[0].selectionSet.selections 23 ); 24 // Here we're equal again: 25 expect(doc.definitions[0].selectionSet.selections[0]).toBe( 26 newDoc.definitions[0].selectionSet.selections[0] 27 ); 28 // Not equal again: 29 expect(doc.definitions[0].selectionSet.selections[1]).not.toBe( 30 newDoc.definitions[0].selectionSet.selections[1] 31 ); 32 expect(doc.definitions[0].selectionSet.selections[1].selectionSet).not.toBe( 33 newDoc.definitions[0].selectionSet.selections[1].selectionSet 34 ); 35 // Equal again: 36 expect( 37 doc.definitions[0].selectionSet.selections[1].selectionSet.selections[0] 38 ).toBe( 39 newDoc.definitions[0].selectionSet.selections[1].selectionSet 40 .selections[0] 41 ); 42 }); 43 44 it('preserves the hashed key of the resulting query', () => { 45 const doc = parse(`{ id todos { id } }`) as any; 46 const expectedKey = createRequest(doc, undefined).key; 47 const formattedDoc = formatDocument(doc); 48 expect(formattedDoc).not.toBe(doc); 49 const actualKey = createRequest(formattedDoc, undefined).key; 50 expect(expectedKey).toBe(actualKey); 51 }); 52 53 it('does not preserve the referential integrity with a cloned object', () => { 54 const doc = parse(`{ id todos { id } }`); 55 const formattedDoc = formatDocument(doc); 56 expect(formattedDoc).not.toBe(doc); 57 const query = { ...formattedDoc }; 58 const reformattedDoc = formatDocument(query); 59 expect(reformattedDoc).not.toBe(doc); 60 }); 61 62 it('preserves custom properties', () => { 63 const doc = parse(`{ todos { id } }`) as any; 64 doc.documentId = '123'; 65 expect((formatDocument(doc) as any).documentId).toBe(doc.documentId); 66 }); 67 68 it('adds typenames to a query string', () => { 69 expect(formatTypeNames(`{ todos { id } }`)).toMatchInlineSnapshot(` 70 "{ 71 todos { 72 id 73 __typename 74 } 75 }" 76 `); 77 }); 78 79 it('does not duplicate typenames', () => { 80 expect( 81 formatTypeNames(`{ 82 todos { 83 id 84 __typename 85 } 86 }`) 87 ).toMatchInlineSnapshot(` 88 "{ 89 todos { 90 id 91 __typename 92 } 93 }" 94 `); 95 }); 96 97 it('does add typenames when it is aliased', () => { 98 expect( 99 formatTypeNames(`{ 100 todos { 101 id 102 typename: __typename 103 } 104 }`) 105 ).toMatchInlineSnapshot(` 106 "{ 107 todos { 108 id 109 typename: __typename 110 __typename 111 } 112 }" 113 `); 114 }); 115 116 it('processes directives', () => { 117 const document = ` 118 { 119 todos @skip { 120 id @_test 121 } 122 } 123 `; 124 125 const node = formatDocument(parse(document)); 126 127 expect(node).toHaveProperty( 128 'definitions.0.selectionSet.selections.0.selectionSet.selections.0._directives', 129 { 130 test: { 131 kind: Kind.DIRECTIVE, 132 arguments: undefined, 133 name: { 134 kind: Kind.NAME, 135 value: '_test', 136 }, 137 }, 138 } 139 ); 140 141 expect(formatTypeNames(document)).toMatchInlineSnapshot(` 142 "{ 143 todos @skip { 144 id 145 __typename 146 } 147 }" 148 `); 149 }); 150});