Skip to content

Commit aac45ab

Browse files
committed
refactor(tests): drop "global test setup"
Can't do "global beforeAll" because jest sucks.
1 parent 76b5541 commit aac45ab

File tree

9 files changed

+141
-83
lines changed

9 files changed

+141
-83
lines changed

packages/neovim/src/api/Base.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,14 +98,21 @@ export class BaseApi extends EventEmitter {
9898
return this[DO_REQUEST](name, args).catch(err => {
9999
const newError = new Error(err.message);
100100
newError.stack = stack;
101-
this.logger.error(`failed request to "%s": %s: %s`, name, newError.name, newError.message);
101+
this.logger.error(
102+
`failed request to "%s": %s: %s`,
103+
name,
104+
newError.name,
105+
newError.message
106+
);
102107
throw newError;
103108
});
104109
}
105110

106111
request(name: string, args: any[] = []): Promise<any> {
107112
// Dummy error, to get stacktrace.
108-
const error = new Error(`failed request to "${name}" (see $NVIM_NODE_LOG_FILE for details, if it was set)`);
113+
const error = new Error(
114+
`failed request to "${name}" (see $NVIM_NODE_LOG_FILE for details, if it was set)`
115+
);
109116

110117
return this.asyncRequest(name, args, error.stack);
111118
}

packages/neovim/src/api/Buffer.test.ts

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/* eslint-env jest */
2-
import * as testSetup from '../testSetup';
2+
import * as testUtil from '../testUtil';
33

44
function wait(ms: number): Promise<void> {
55
return new Promise(resolve => {
@@ -10,7 +10,7 @@ function wait(ms: number): Promise<void> {
1010
}
1111

1212
describe('Buffer API', () => {
13-
let nvim: ReturnType<typeof testSetup.getNvim>;
13+
let nvim: ReturnType<typeof testUtil.startNvim>[1];
1414

1515
// utility to allow each test to be run in its
1616
// own buffer
@@ -32,7 +32,11 @@ describe('Buffer API', () => {
3232
}
3333

3434
beforeAll(async () => {
35-
nvim = testSetup.getNvim();
35+
[, nvim] = testUtil.startNvim();
36+
});
37+
38+
afterAll(() => {
39+
testUtil.stopNvim();
3640
});
3741

3842
it(
@@ -379,10 +383,14 @@ describe('Buffer API', () => {
379383
});
380384

381385
describe('Buffer event updates', () => {
382-
let nvim: ReturnType<typeof testSetup.getNvim>;
386+
let nvim: ReturnType<typeof testUtil.startNvim>[1];
383387

384388
beforeAll(async () => {
385-
nvim = testSetup.getNvim();
389+
[, nvim] = testUtil.startNvim();
390+
});
391+
392+
afterAll(() => {
393+
testUtil.stopNvim();
386394
});
387395

388396
beforeEach(async () => {

packages/neovim/src/api/Neovim.test.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,17 @@
11
/* eslint-env jest */
22
import * as path from 'node:path';
33
import { Neovim } from './Neovim';
4-
import * as testSetup from '../testSetup';
4+
import * as testUtil from '../testUtil';
55

66
describe('Neovim API', () => {
7-
let nvim: ReturnType<typeof testSetup.getNvim>;
7+
let nvim: ReturnType<typeof testUtil.startNvim>[1];
88

99
beforeAll(async () => {
10-
nvim = testSetup.getNvim();
10+
[, nvim] = testUtil.startNvim();
11+
});
12+
13+
afterAll(() => {
14+
testUtil.stopNvim();
1115
});
1216

1317
it('sets transport when initialized', () => {
@@ -24,7 +28,7 @@ describe('Neovim API', () => {
2428
expect(buffers.length).toBe(1);
2529
buffers[0].name = 'hello.txt';
2630

27-
nvim.command('e! goodbye.txt');
31+
nvim.command('noswapfile e! goodbye.txt');
2832
expect((await nvim.buffers).length).toBe(2);
2933
expect(await nvim.buffer.name).toMatch(/goodbye\.txt$/);
3034

packages/neovim/src/api/Tabpage.test.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
11
/* eslint-env jest */
2-
import * as testSetup from '../testSetup';
2+
import * as testUtil from '../testUtil';
33

44
describe('Tabpage API', () => {
5-
let nvim: ReturnType<typeof testSetup.getNvim>;
5+
let nvim: ReturnType<typeof testUtil.startNvim>[1];
66

77
beforeAll(async () => {
8-
nvim = testSetup.getNvim();
8+
[, nvim] = testUtil.startNvim();
9+
});
10+
11+
afterAll(() => {
12+
testUtil.stopNvim();
913
});
1014

1115
it('gets the current Tabpage', async () => {

packages/neovim/src/api/Window.test.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
11
/* eslint-env jest */
2-
import * as testSetup from '../testSetup';
2+
import * as testUtil from '../testUtil';
33

44
describe('Window API', () => {
5-
let nvim: ReturnType<typeof testSetup.getNvim>;
5+
let nvim: ReturnType<typeof testUtil.startNvim>[1];
66

77
beforeAll(async () => {
8-
nvim = testSetup.getNvim();
8+
[, nvim] = testUtil.startNvim();
9+
});
10+
11+
afterAll(() => {
12+
testUtil.stopNvim();
913
});
1014

1115
it('gets the current Window', async () => {

packages/neovim/src/attach/attach.test.ts

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,15 @@
22
import { attach } from './attach';
33
import { Logger } from '../utils/logger';
44
import * as testUtil from '../testUtil';
5-
import * as testSetup from '../testSetup';
65

76
describe('Nvim API', () => {
8-
let nvim: ReturnType<typeof testSetup.getNvim>;
9-
let requests;
10-
let notifications;
7+
let proc: ReturnType<typeof testUtil.startNvim>[0];
8+
let nvim: ReturnType<typeof testUtil.startNvim>[1];
9+
let requests: { method: string; args: number[] }[];
10+
let notifications: { method: string; args: number[] }[];
1111

1212
beforeAll(async () => {
13-
nvim = testSetup.getNvim();
13+
[proc, nvim] = testUtil.startNvim();
1414

1515
nvim.on('request', (method, args, resp) => {
1616
requests.push({ method, args });
@@ -21,6 +21,10 @@ describe('Nvim API', () => {
2121
});
2222
});
2323

24+
afterAll(() => {
25+
testUtil.stopNvim();
26+
});
27+
2428
beforeEach(() => {
2529
requests = [];
2630
notifications = [];
@@ -48,8 +52,11 @@ describe('Nvim API', () => {
4852
warn: fakeLog,
4953
debug: fakeLog,
5054
error: fakeLog,
51-
} as Logger;
52-
const nvim2 = attach({ proc: proc2, options: { logger: logger2 } });
55+
};
56+
const nvim2 = attach({
57+
proc: proc2,
58+
options: { logger: logger2 as Logger },
59+
});
5360

5461
const spy = jest.spyOn(nvim2.logger, 'info');
5562
// eslint-disable-next-line no-console
@@ -112,16 +119,23 @@ describe('Nvim API', () => {
112119
const buf = await nvim.buffer;
113120
expect(buf instanceof nvim.Buffer).toEqual(true);
114121

115-
const lines = await buf.getLines({ start: 0, end: -1 });
122+
const lines = await buf.getLines({
123+
start: 0,
124+
end: -1,
125+
strictIndexing: true,
126+
});
116127
expect(lines).toEqual([]);
117128

118129
buf.setLines(['line1', 'line2'], { start: 0, end: 1 });
119-
const newLines = await buf.getLines({ start: 0, end: -1 });
130+
const newLines = await buf.getLines({
131+
start: 0,
132+
end: -1,
133+
strictIndexing: true,
134+
});
120135
expect(newLines).toEqual(['line1', 'line2']);
121136
});
122137

123138
it('emits "disconnect" after quit', done => {
124-
const proc = testSetup.getNvimProc();
125139
const disconnectMock = jest.fn();
126140
nvim.on('disconnect', disconnectMock);
127141
nvim.quit();

packages/neovim/src/testSetup.ts

Lines changed: 6 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,12 @@
11
// Global test setup. Runs before each test.
22

33
import * as testUtil from './testUtil';
4-
import * as jest from '@jest/globals'
4+
// import * as jest from '@jest/globals'
55

66
testUtil.findNvimOrFail();
77

8-
let proc: ReturnType<typeof testUtil.startNvim>[0];
9-
let nvim: ReturnType<typeof testUtil.startNvim>[1];
10-
11-
/**
12-
* Gets the current Nvim client being used in the current test.
13-
*/
14-
export function getNvim() {
15-
return nvim!;
16-
}
17-
18-
export function getNvimProc() {
19-
return proc!;
20-
}
21-
22-
jest.beforeAll(() => {
23-
const testName = jest.expect.getState().testPath;
24-
console.log('xxxxxxxxxxxx BEFORE %O', testName);
25-
[proc, nvim] = testUtil.startNvim(true);
26-
});
27-
28-
jest.afterAll(() => {
29-
const testName = jest.expect.getState().currentTestName;
30-
console.log('xxxxxxxxxxxx AFTER %O', testName);
31-
testUtil.stopNvim(proc);
32-
testUtil.stopNvim(nvim);
33-
proc = undefined;
34-
nvim = undefined;
35-
});
8+
// TODO: this doesn't work because jest sucks. use mocha instead.
9+
// jest.beforeAll(() => {
10+
// });
11+
// jest.afterAll(() => {
12+
// });

packages/neovim/src/testUtil.ts

Lines changed: 52 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,78 @@
11
import * as cp from 'node:child_process';
2+
// eslint-disable-next-line import/no-extraneous-dependencies
3+
import * as jest from '@jest/globals';
4+
import * as fs from 'node:fs';
5+
import * as path from 'node:path';
26
import { NeovimClient } from './api/client';
37
import { attach } from './attach';
48
import { findNvim } from './utils/findNvim';
59

6-
export function startNvim(): [cp.ChildProcessWithoutNullStreams, NeovimClient]
7-
export function startNvim(doAttach: false): [cp.ChildProcessWithoutNullStreams, undefined]
8-
export function startNvim(doAttach: true): [cp.ChildProcessWithoutNullStreams, NeovimClient]
10+
export function findNvimOrFail() {
11+
const minVersion = '0.9.5';
12+
const found = findNvim({ minVersion });
13+
if (found.matches.length === 0) {
14+
throw new Error(`nvim ${minVersion} not found`);
15+
}
16+
return found.matches[0].path;
17+
}
18+
19+
const nvimPath = findNvimOrFail();
20+
21+
let proc: cp.ChildProcessWithoutNullStreams;
22+
let nvim: NeovimClient;
23+
24+
export function startNvim(): [cp.ChildProcessWithoutNullStreams, NeovimClient];
25+
export function startNvim(
26+
doAttach: false
27+
): [cp.ChildProcessWithoutNullStreams, undefined];
28+
export function startNvim(
29+
doAttach: true
30+
): [cp.ChildProcessWithoutNullStreams, NeovimClient];
931
export function startNvim(
1032
doAttach: boolean = true
1133
): [cp.ChildProcessWithoutNullStreams, NeovimClient | undefined] {
12-
const proc = cp.spawn('nvim', ['-u', 'NONE', '--embed', '-n', '--noplugin'], {
34+
const testFile = jest.expect.getState().testPath?.replace(/.*[\\/]/, '');
35+
const msg = `startNvim in test: ${testFile}`;
36+
// console.log(msg);
37+
if (process.env.NVIM_NODE_LOG_FILE) {
38+
const logfile = path.resolve(process.env.NVIM_NODE_LOG_FILE);
39+
fs.writeFileSync(logfile, `${msg}\n`, { flag: 'a' });
40+
}
41+
42+
proc = cp.spawn(nvimPath, ['-u', 'NONE', '--embed', '-n', '--noplugin'], {
1343
cwd: __dirname,
1444
});
1545
if (!doAttach) {
1646
return [proc, undefined];
1747
}
18-
const nvim = attach({ proc });
48+
nvim = attach({ proc });
1949
return [proc, nvim];
2050
}
2151

2252
export function stopNvim(
23-
proc_: cp.ChildProcessWithoutNullStreams | NeovimClient
53+
proc_?: cp.ChildProcessWithoutNullStreams | NeovimClient
2454
) {
55+
// Stop all (proc + client).
2556
if (!proc_) {
57+
if (proc) {
58+
stopNvim(proc);
59+
}
60+
if (nvim) {
61+
stopNvim(nvim);
62+
}
2663
return;
27-
} else if (proc_ instanceof NeovimClient) {
64+
}
65+
66+
if (proc_ instanceof NeovimClient) {
2867
proc_.quit();
2968
} else if (proc_ && proc_.connected) {
3069
proc_.disconnect();
3170
}
3271
}
3372

34-
export function findNvimOrFail() {
35-
const minVersion = '0.9.5';
36-
const found = findNvim({ minVersion });
37-
if (found.matches.length === 0) {
38-
throw new Error(`nvim ${minVersion} not found`);
39-
}
40-
return found.matches[0].path;
41-
}
73+
// jest.beforeAll(async () => {
74+
// [proc, nvim] = startNvim();
75+
// });
76+
// jest.afterAll(() => {
77+
// stopNvim();
78+
// });

packages/neovim/src/utils/logger.ts

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,18 +15,21 @@ function setupWinstonLogger(): Logger {
1515
filename: process.env.NVIM_NODE_LOG_FILE,
1616
level,
1717
format: winston.format.combine(
18-
winston.format.splat(),
19-
winston.format.timestamp({
20-
format: 'YYYY-MM-DD HH:mm:ss',
21-
}),
22-
winston.format.errors({ stack: true }),
23-
winston.format.printf(info => {
24-
if (info.raw) {
25-
return info.message
26-
}
27-
const lvl = info.level === 'debug' ? 'DBG' : info.level.slice(0, 3).toUpperCase();
28-
return `${info.timestamp} ${lvl} ${info.message}`
29-
})
18+
winston.format.splat(),
19+
winston.format.timestamp({
20+
format: 'YYYY-MM-DD HH:mm:ss',
21+
}),
22+
winston.format.errors({ stack: true }),
23+
winston.format.printf(info => {
24+
if (info.raw) {
25+
return info.message;
26+
}
27+
const lvl =
28+
info.level === 'debug'
29+
? 'DBG'
30+
: info.level.slice(0, 3).toUpperCase();
31+
return `${info.timestamp} ${lvl} ${info.message}`;
32+
})
3033
),
3134
})
3235
);

0 commit comments

Comments
 (0)