Skip to content

Commit dfd6928

Browse files
test: use tsx for TypeScript test execution
1 parent d131a5e commit dfd6928

6 files changed

Lines changed: 38 additions & 32 deletions

File tree

.github/maintainers_guide.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ Test code should be written in syntax that runs on the oldest supported Node.js
2121

2222
#### Debugging
2323

24-
A useful trick for debugging inside tests is to use the Chrome Debugging Protocol feature of Node.js to set breakpoints and interactively debug. In order to do this you should have already linted the source (`npm run lint`), manually. You can then run a specific test file with Node.js's test runner, for example: `node --inspect-brk --require ts-node/register --require source-map-support/register --test test/unit/{test-name}.spec.ts` (replace `{test-name}` with an actual test file path).
24+
A useful trick for debugging inside tests is to use the Chrome Debugging Protocol feature of Node.js to set breakpoints and interactively debug. In order to do this you should have already linted the source (`npm run lint`), manually. You can then run a specific test file with Node.js's test runner, for example: `node --inspect-brk --import tsx --test test/unit/{test-name}.spec.ts` (replace `{test-name}` with an actual test file path).
2525

2626
#### Local Development
2727

.vscode/launch.json

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,18 +12,15 @@
1212
"stopOnEntry": false,
1313
"args": [
1414
"--inspect-brk",
15-
"--require",
16-
"ts-node/register",
17-
"--require",
18-
"source-map-support/register",
15+
"--import",
16+
"tsx",
1917
"--test",
2018
"test/unit/**/*.spec.ts"
2119
],
2220
"cwd": "${workspaceFolder}",
2321
"env": {
2422
"NODE_ENV": "testing",
25-
"TS_NODE_FILES": "true",
26-
"TS_NODE_PROJECT": "tsconfig.test.json"
23+
"TSX_TSCONFIG_PATH": "tsconfig.test.json"
2724
},
2825
"skipFiles": ["<node_internals>/**"]
2926
}

package.json

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,8 @@
3232
"lint": "npx @biomejs/biome check docs src test examples",
3333
"lint:fix": "npx @biomejs/biome check --write docs src test examples",
3434
"test": "npm run build && npm run lint && npm run test:types && npm run test:coverage",
35-
"test:unit": "TS_NODE_PROJECT=tsconfig.test.json TS_NODE_FILES=true node --require ts-node/register --require source-map-support/register --test test/unit/**/*.spec.ts",
36-
"test:coverage": "TS_NODE_PROJECT=tsconfig.test.json TS_NODE_FILES=true node --experimental-test-coverage --require ts-node/register --require source-map-support/register --test test/unit/**/*.spec.ts",
35+
"test:unit": "TSX_TSCONFIG_PATH=tsconfig.test.json tsx --test test/unit/**/*.spec.ts",
36+
"test:coverage": "TSX_TSCONFIG_PATH=tsconfig.test.json node --experimental-test-coverage --import tsx --test test/unit/**/*.spec.ts",
3737
"test:types": "tsd --files test/types",
3838
"watch": "npx nodemon --watch 'src' --ext 'ts' --exec npm run build"
3939
},
@@ -68,9 +68,8 @@
6868
"proxyquire": "^2.1.3",
6969
"shx": "^0.3.2",
7070
"sinon": "^20.0.0",
71-
"source-map-support": "^0.5.12",
72-
"ts-node": "^10.9.2",
7371
"tsd": "^0.31.2",
72+
"tsx": "^4.20.6",
7473
"typescript": "5.3.3"
7574
},
7675
"peerDependencies": {

test/unit/.mocharc.json

Lines changed: 0 additions & 5 deletions
This file was deleted.

test/unit/receivers/ExpressReceiver.spec.ts

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ import ExpressReceiver, {
1919
verifySignatureAndParseRawBody,
2020
buildBodyParserMiddleware,
2121
} from '../../../src/receivers/ExpressReceiver';
22-
import * as httpFunc from '../../../src/receivers/HTTPModuleFunctions';
2322
import type { ReceiverEvent } from '../../../src/types';
2423
import {
2524
FakeServer,
@@ -30,7 +29,7 @@ import {
3029
withHttpCreateServer,
3130
withHttpsCreateServer,
3231
} from '../helpers';
33-
import { afterEach, beforeEach, after, describe, it } from 'node:test';
32+
import { afterEach, beforeEach, describe, it } from 'node:test';
3433

3534
// Loading the system under test using overrides
3635
function importExpressReceiver(
@@ -318,32 +317,38 @@ describe('ExpressReceiver', () => {
318317
});
319318

320319
describe('#requestHandler()', () => {
321-
const extractRetryNumStub = sinon.stub(httpFunc, 'extractRetryNumFromHTTPRequest');
322-
const extractRetryReasonStub = sinon.stub(httpFunc, 'extractRetryReasonFromHTTPRequest');
323-
const buildNoBodyResponseStub = sinon.stub(httpFunc, 'buildNoBodyResponse');
324-
const buildContentResponseStub = sinon.stub(httpFunc, 'buildContentResponse');
320+
let extractRetryNumStub: sinon.SinonStub;
321+
let extractRetryReasonStub: sinon.SinonStub;
322+
let buildNoBodyResponseStub: sinon.SinonStub;
323+
let buildContentResponseStub: sinon.SinonStub;
325324
const processStub = sinon.stub<[ReceiverEvent]>().resolves({});
326325
const ackStub = function ackStub() {};
327326
ackStub.prototype.bind = function () {
328327
return this;
329328
};
330329
ackStub.prototype.ack = sinon.spy();
331330
beforeEach(() => {
331+
extractRetryNumStub = sinon.stub().returns(undefined);
332+
extractRetryReasonStub = sinon.stub().returns(undefined);
333+
buildNoBodyResponseStub = sinon.stub().returns(undefined);
334+
buildContentResponseStub = sinon.stub().returns(undefined);
332335
overrides = mergeOverrides(
333336
withHttpCreateServer(fakeCreateServer),
334337
withHttpsCreateServer(sinon.fake.throws('Should not be used.')),
335338
{ './HTTPResponseAck': { HTTPResponseAck: ackStub } },
339+
{
340+
'./HTTPModuleFunctions': {
341+
extractRetryNumFromHTTPRequest: extractRetryNumStub,
342+
extractRetryReasonFromHTTPRequest: extractRetryReasonStub,
343+
buildNoBodyResponse: buildNoBodyResponseStub,
344+
buildContentResponse: buildContentResponseStub,
345+
},
346+
},
336347
);
337348
});
338349
afterEach(() => {
339350
sinon.reset();
340351
});
341-
after(() => {
342-
extractRetryNumStub.restore();
343-
extractRetryReasonStub.restore();
344-
buildNoBodyResponseStub.restore();
345-
buildContentResponseStub.restore();
346-
});
347352
it('should not build an HTTP response if processBeforeResponse=false', async () => {
348353
const ER = importExpressReceiver(overrides);
349354
const receiver = new ER({ signingSecret: '' });

test/unit/receivers/HTTPResponseAck.spec.ts

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,19 @@
11
import { IncomingMessage, ServerResponse } from 'node:http';
2+
import path from 'node:path';
23
import assert from 'node:assert/strict';
34
import sinon from 'sinon';
45
import { expectType } from 'tsd';
56
import { ReceiverMultipleAckError } from '../../../src/errors';
6-
import * as HTTPModuleFunctions from '../../../src/receivers/HTTPModuleFunctions';
77
import { HTTPResponseAck } from '../../../src/receivers/HTTPResponseAck';
88
import type { ResponseAck } from '../../../src/types';
9-
import { createFakeLogger } from '../helpers';
9+
import { createFakeLogger, proxyquire } from '../helpers';
1010
import { afterEach, beforeEach, describe, it } from 'node:test';
1111

12+
function importHTTPResponseAck(overrides = {}): typeof import('../../../src/receivers/HTTPResponseAck') {
13+
const absolutePath = path.resolve(__dirname, '../../../src/receivers/HTTPResponseAck');
14+
return proxyquire(absolutePath, overrides);
15+
}
16+
1217
describe('HTTPResponseAck', async () => {
1318
let setTimeoutSpy: sinon.SinonSpy;
1419

@@ -129,10 +134,15 @@ describe('HTTPResponseAck', async () => {
129134
assert.equal(responseAck.storedResponse, '', 'Falsy body passed to bound handler not stored as empty string in Ack instance.');
130135
});
131136
it('should call buildContentResponse with response body if processBeforeResponse=false', async () => {
132-
const stub = sinon.stub(HTTPModuleFunctions, 'buildContentResponse');
137+
const stub = sinon.stub();
138+
const { HTTPResponseAck: HTTPResponseAckWithStub } = importHTTPResponseAck({
139+
'./HTTPModuleFunctions': {
140+
buildContentResponse: stub,
141+
},
142+
});
133143
const httpRequest = sinon.createStubInstance(IncomingMessage) as IncomingMessage;
134144
const httpResponse: ServerResponse = sinon.createStubInstance(ServerResponse) as unknown as ServerResponse;
135-
const responseAck = new HTTPResponseAck({
145+
const responseAck = new HTTPResponseAckWithStub({
136146
logger: createFakeLogger(),
137147
processBeforeResponse: false,
138148
httpRequest,

0 commit comments

Comments
 (0)