Mirror: TypeScript LSP plugin that finds GraphQL documents in your code and provides diagnostics, auto-complete and hover-information.

Add e2e test for renaming an operation name (#43)

* Add e2e test for rename operation

* Update test/e2e/rename.test.ts

Co-authored-by: Jovi De Croock <decroockjovi@gmail.com>

* Poll based expects instead of TSServer response

---------

Co-authored-by: Jovi De Croock <decroockjovi@gmail.com>

Daniel c7924015 89a43ac3

Changed files
+125
test
e2e
fixture-project
fixtures
+9
test/e2e/fixture-project/fixtures/rename.ts
···
+
import { gql } from '@urql/core';
+
+
const PostsQuery = gql`
+
query Posts {
+
posts {
+
title
+
}
+
}
+
`;
+83
test/e2e/rename.test.ts
···
+
import { expect, afterAll, beforeAll, it, describe } from 'vitest';
+
import { TSServer } from './server';
+
import path from 'node:path';
+
import fs from 'node:fs';
+
import url from 'node:url';
+
import ts from 'typescript/lib/tsserverlibrary';
+
import { waitForExpect } from './util';
+
+
const __dirname = path.dirname(url.fileURLToPath(import.meta.url));
+
+
const projectPath = path.resolve(__dirname, 'fixture-project');
+
describe('Operation name', () => {
+
const outFile = path.join(projectPath, 'rename.ts');
+
const genFile = path.join(projectPath, 'rename.generated.ts');
+
+
let server: TSServer;
+
beforeAll(async () => {
+
server = new TSServer(projectPath, { debugLog: false });
+
});
+
+
afterAll(() => {
+
try {
+
fs.unlinkSync(outFile);
+
fs.unlinkSync(genFile);
+
} catch {}
+
});
+
+
it('gets renamed correctly', async () => {
+
server.sendCommand('open', {
+
file: outFile,
+
fileContent: '// empty',
+
scriptKindName: 'TS',
+
} satisfies ts.server.protocol.OpenRequestArgs);
+
+
server.sendCommand('updateOpen', {
+
openFiles: [
+
{
+
file: outFile,
+
fileContent: fs.readFileSync(
+
path.join(projectPath, 'fixtures/rename.ts'),
+
'utf-8'
+
),
+
},
+
],
+
} satisfies ts.server.protocol.UpdateOpenRequestArgs);
+
+
server.sendCommand('saveto', {
+
file: outFile,
+
tmpfile: outFile,
+
} satisfies ts.server.protocol.SavetoRequestArgs);
+
+
await waitForExpect(() => {
+
expect(fs.readFileSync(outFile, 'utf-8')).toContain(
+
`as typeof import('./rename.generated').PostsDocument`
+
);
+
});
+
+
server.sendCommand('updateOpen', {
+
openFiles: [
+
{
+
file: outFile,
+
fileContent: fs
+
.readFileSync(outFile, 'utf-8')
+
.replace('query Posts', 'query PostList'),
+
},
+
],
+
} satisfies ts.server.protocol.UpdateOpenRequestArgs);
+
+
server.sendCommand('saveto', {
+
file: outFile,
+
tmpfile: outFile,
+
} satisfies ts.server.protocol.SavetoRequestArgs);
+
+
await waitForExpect(() => {
+
expect(fs.readFileSync(outFile, 'utf-8')).toContain(
+
`as typeof import('./rename.generated').PostListDocument`
+
);
+
expect(fs.readFileSync(genFile, 'utf-8')).toContain(
+
'export const PostListDocument ='
+
);
+
});
+
}, 12500);
+
});
+33
test/e2e/util.ts
···
+
import { vi } from 'vitest';
+
+
type WaitForExpectOptions = {
+
timeout?: number;
+
interval?: number;
+
};
+
+
export const waitForExpect = async (
+
expectFn: () => void,
+
{ interval = 200, timeout = 10000 }: WaitForExpectOptions = {}
+
) => {
+
// @sinonjs/fake-timers injects `clock` property into setTimeout
+
const usesFakeTimers = 'clock' in setTimeout;
+
+
if (usesFakeTimers) vi.useRealTimers();
+
+
const start = Date.now();
+
+
while (true) {
+
try {
+
expectFn();
+
break;
+
} catch {}
+
+
if (Date.now() - start > timeout) {
+
throw new Error('Timeout');
+
}
+
+
await new Promise(resolve => setTimeout(resolve, interval));
+
}
+
+
if (usesFakeTimers) vi.useFakeTimers();
+
};