Mirror: TypeScript LSP plugin that finds GraphQL documents in your code and provides diagnostics, auto-complete and hover-information.
at main 5.2 kB view raw
1import { expect, afterAll, beforeAll, it, describe } from 'vitest'; 2import { TSServer } from './server'; 3import path from 'node:path'; 4import fs from 'node:fs'; 5import url from 'node:url'; 6import ts from 'typescript/lib/tsserverlibrary'; 7 8const __dirname = path.dirname(url.fileURLToPath(import.meta.url)); 9 10const projectPath = path.resolve(__dirname, 'fixture-project'); 11describe('Fragment + operations', () => { 12 const outfileCombinations = path.join(projectPath, 'Combination.ts'); 13 14 let server: TSServer; 15 beforeAll(async () => { 16 server = new TSServer(projectPath, { debugLog: false }); 17 18 server.sendCommand('open', { 19 file: outfileCombinations, 20 fileContent: '// empty', 21 scriptKindName: 'TS', 22 } satisfies ts.server.protocol.OpenRequestArgs); 23 24 server.sendCommand('updateOpen', { 25 openFiles: [ 26 { 27 file: outfileCombinations, 28 fileContent: fs.readFileSync( 29 path.join(projectPath, 'fixtures/Combination.ts'), 30 'utf-8' 31 ), 32 }, 33 ], 34 } satisfies ts.server.protocol.UpdateOpenRequestArgs); 35 36 server.sendCommand('saveto', { 37 file: outfileCombinations, 38 tmpfile: outfileCombinations, 39 } satisfies ts.server.protocol.SavetoRequestArgs); 40 }); 41 42 afterAll(() => { 43 try { 44 fs.unlinkSync(outfileCombinations); 45 } catch {} 46 }); 47 48 it('gives semantic-diagnostics with preceding fragments', async () => { 49 await server.waitForResponse( 50 e => e.type === 'event' && e.event === 'semanticDiag' 51 ); 52 const res = server.responses 53 .reverse() 54 .find(resp => resp.type === 'event' && resp.event === 'semanticDiag'); 55 expect(res?.body.diagnostics).toMatchInlineSnapshot(` 56 [ 57 { 58 "category": "error", 59 "code": 52001, 60 "end": { 61 "line": 7, 62 "offset": 1, 63 }, 64 "start": { 65 "line": 6, 66 "offset": 5, 67 }, 68 "text": "Cannot query field \\"someUnknownField\\" on type \\"Post\\".", 69 }, 70 { 71 "category": "error", 72 "code": 52001, 73 "end": { 74 "line": 11, 75 "offset": 10, 76 }, 77 "start": { 78 "line": 11, 79 "offset": 3, 80 }, 81 "text": "Cannot query field \\"someUnknownField\\" on type \\"Post\\".", 82 }, 83 { 84 "category": "error", 85 "code": 52001, 86 "end": { 87 "line": 17, 88 "offset": 1, 89 }, 90 "start": { 91 "line": 16, 92 "offset": 7, 93 }, 94 "text": "Cannot query field \\"__typenam\\" on type \\"Post\\".", 95 }, 96 ] 97 `); 98 }, 30000); 99 100 it('gives quick-info with preceding fragments', async () => { 101 server.send({ 102 seq: 9, 103 type: 'request', 104 command: 'quickinfo', 105 arguments: { 106 file: outfileCombinations, 107 line: 14, 108 offset: 7, 109 }, 110 }); 111 112 await server.waitForResponse( 113 response => 114 response.type === 'response' && response.command === 'quickinfo' 115 ); 116 117 const res = server.responses 118 .reverse() 119 .find(resp => resp.type === 'response' && resp.command === 'quickinfo'); 120 121 expect(res).toBeDefined(); 122 expect(typeof res?.body).toEqual('object'); 123 expect(res?.body.documentation).toEqual( 124 `Query.posts: [Post]\n\nList out all posts` 125 ); 126 }, 30000); 127 128 it('gives suggestions with preceding fragments', async () => { 129 server.send({ 130 seq: 10, 131 type: 'request', 132 command: 'completionInfo', 133 arguments: { 134 file: outfileCombinations, 135 line: 15, 136 offset: 7, 137 includeExternalModuleExports: true, 138 includeInsertTextCompletions: true, 139 triggerKind: 1, 140 }, 141 }); 142 143 await server.waitForResponse( 144 response => 145 response.type === 'response' && response.command === 'completionInfo' 146 ); 147 148 const res = server.responses 149 .reverse() 150 .find( 151 resp => resp.type === 'response' && resp.command === 'completionInfo' 152 ); 153 154 expect(res).toBeDefined(); 155 expect(typeof res?.body.entries).toEqual('object'); 156 expect(res?.body.entries).toMatchInlineSnapshot(` 157 [ 158 { 159 "kind": "var", 160 "kindModifiers": "declare", 161 "labelDetails": { 162 "detail": " ID!", 163 }, 164 "name": "id", 165 "sortText": "0id", 166 }, 167 { 168 "kind": "var", 169 "kindModifiers": "declare", 170 "labelDetails": { 171 "detail": " String!", 172 }, 173 "name": "title", 174 "sortText": "1title", 175 }, 176 { 177 "kind": "var", 178 "kindModifiers": "declare", 179 "labelDetails": { 180 "detail": " String!", 181 }, 182 "name": "content", 183 "sortText": "2content", 184 }, 185 { 186 "kind": "var", 187 "kindModifiers": "declare", 188 "labelDetails": { 189 "description": "The name of the current Object type at runtime.", 190 "detail": " String!", 191 }, 192 "name": "__typename", 193 "sortText": "3__typename", 194 }, 195 ] 196 `); 197 }, 30000); 198});