Skip to content

Commit e67315b

Browse files
committed
[New] add types
1 parent be106fd commit e67315b

14 files changed

+611
-49
lines changed

.github/workflows/node-aught.yml

+1
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,4 @@ jobs:
99
range: '< 10'
1010
type: minors
1111
command: npm run tests-only
12+
skip-ls-check: true

bin/import-or-require.js

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ const { extname: extnamePath } = require('path');
44
const { pathToFileURL } = require('url');
55
const getPackageType = require('get-package-type');
66

7+
/** @type {(file: string) => undefined | Promise<unknown>} */
78
// eslint-disable-next-line consistent-return
89
module.exports = function importOrRequire(file) {
910
const ext = extnamePath(file);

bin/tape

+2
Original file line numberDiff line numberDiff line change
@@ -100,9 +100,11 @@ var hasImport = require('has-dynamic-import');
100100

101101
var tape = require('../');
102102

103+
/** @type {(hasSupport: boolean) => Promise<void> | void} */
103104
function importFiles(hasSupport) {
104105
tape.wait();
105106

107+
/** @type {null | undefined | Promise<unknown>} */
106108
var filesPromise;
107109
if (hasSupport) {
108110
var importOrRequire = require('./import-or-require');

index.d.ts

+76
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
import type { ThroughStream } from '@ljharb/through';
2+
3+
import type Test from './lib/test';
4+
import type Results from './lib/results';
5+
6+
declare function harnessFunction(this: Test, name: string, opts: tape.TestOptions, cb: Test.Callback): Test;
7+
declare function harnessFunction(this: Test, name: string, opts: tape.TestOptions): Test;
8+
declare function harnessFunction(this: Test, name: string, cb: Test.Callback): Test;
9+
declare function harnessFunction(this: Test, name: string): Test;
10+
declare function harnessFunction(this: Test, opts: tape.TestOptions, cb: Test.Callback): Test;
11+
declare function harnessFunction(this: Test, opts: tape.TestOptions): Test;
12+
declare function harnessFunction(this: Test, cb: Test.Callback): Test;
13+
14+
declare namespace tape {
15+
export type TestOptions = {
16+
objectPrintDepth?: number | undefined;
17+
skip?: boolean | undefined;
18+
timeout?: number | undefined;
19+
todo?: boolean | undefined;
20+
};
21+
22+
export interface AssertOptions {
23+
skip?: boolean | string | undefined;
24+
todo?: boolean | string | undefined;
25+
message?: string | undefined;
26+
actual?: unknown;
27+
expected?: unknown;
28+
exiting?: boolean;
29+
}
30+
31+
export interface StreamOptions {
32+
objectMode?: boolean | undefined;
33+
}
34+
35+
function createStream(opts?: StreamOptions): ThroughStream;
36+
37+
export type CreateStream = typeof createStream;
38+
39+
export type HarnessEventHandler = (cb: Test.SyncCallback, ...rest: unknown[]) => void;
40+
41+
function only(name: string, cb: Test.Callback): void;
42+
function only(name: string, opts: tape.TestOptions, cb: Test.Callback): void;
43+
function only(cb: Test.Callback): void;
44+
function only(opts: tape.TestOptions, cb: Test.Callback): void;
45+
46+
export type Harness = typeof harnessFunction & {
47+
run?: () => void;
48+
only: typeof only;
49+
_exitCode: number;
50+
_results: Results;
51+
_tests: Test[];
52+
close: () => void;
53+
createStream: CreateStream;
54+
onFailure: HarnessEventHandler;
55+
onFinish: HarnessEventHandler;
56+
}
57+
58+
export type HarnessConfig = {
59+
autoclose?: boolean;
60+
noOnly?: boolean;
61+
stream?: NodeJS.WritableStream | ThroughStream;
62+
exit?: boolean;
63+
} & StreamOptions;
64+
65+
function createHarness(conf_?: HarnessConfig): Harness;
66+
const Test: Test;
67+
const test: typeof tape;
68+
const skip: Test['skip'];
69+
}
70+
71+
declare function tape(this: tape.Harness, name: string, opts: tape.TestOptions, cb: Test.Callback): Test;
72+
declare function tape(this: tape.Harness, name: string, cb: Test.Callback): Test;
73+
declare function tape(this: tape.Harness, opts?: tape.TestOptions): Test;
74+
declare function tape(this: tape.Harness, opts: tape.TestOptions, cb: Test.Callback): Test;
75+
76+
export = tape;

index.js

+37-10
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,34 @@
11
'use strict';
22

33
var defined = require('defined');
4+
var through = require('@ljharb/through');
5+
46
var createDefaultStream = require('./lib/default_stream');
57
var Test = require('./lib/test');
68
var Results = require('./lib/results');
7-
var through = require('@ljharb/through');
89

910
var canEmitExit = typeof process !== 'undefined' && process
10-
&& typeof process.on === 'function' && process.browser !== true;
11+
// eslint-disable-next-line no-extra-parens
12+
&& typeof process.on === 'function' && /** @type {{ browser?: boolean }} */ (process).browser !== true;
1113
var canExit = typeof process !== 'undefined' && process
1214
&& typeof process.exit === 'function';
1315

14-
module.exports = (function () {
16+
/** @typedef {import('.')} Tape */
17+
/** @typedef {import('.').Harness} Harness */
18+
/** @typedef {import('.').HarnessConfig} HarnessConfig */
19+
/** @typedef {import('.').TestOptions} TestOptions */
20+
/** @typedef {import('.').HarnessEventHandler} HarnessEventHandler */
21+
/** @typedef {import('.').CreateStream} CreateStream */
22+
/** @typedef {import('.').createHarness} CreateHarness */
23+
/** @typedef {import('./lib/results').Result} Result */
24+
/** @typedef {import('stream').Writable} WritableStream */
25+
26+
var tape = (function () {
1527
var wait = false;
28+
/** @type {undefined | Harness} */
1629
var harness;
1730

31+
/** @type {(opts?: HarnessConfig) => Harness} */
1832
function getHarness(opts) {
1933
// this override is here since tests fail via nyc if createHarness is moved upwards
2034
if (!harness) {
@@ -24,6 +38,7 @@ module.exports = (function () {
2438
return harness;
2539
}
2640

41+
/** @type {(this: Harness, ...args: Parameters<Tape>) => ReturnType<Tape>} */
2742
function lazyLoad() {
2843
// eslint-disable-next-line no-invalid-this
2944
return getHarness().apply(this, arguments);
@@ -43,6 +58,7 @@ module.exports = (function () {
4358
return getHarness().only.apply(this, arguments);
4459
};
4560

61+
/** @type {CreateStream} */
4662
lazyLoad.createStream = function (opts) {
4763
var options = opts || {};
4864
if (!harness) {
@@ -66,21 +82,23 @@ module.exports = (function () {
6682
return lazyLoad;
6783
}());
6884

85+
/** @type {CreateHarness} */
6986
function createHarness(conf_) {
7087
var results = new Results({ todoIsOK: !!(process.env.TODO_IS_OK === '1') });
7188
if (!conf_ || conf_.autoclose !== false) {
7289
results.once('done', function () { results.close(); });
7390
}
7491

92+
/** @type {(name: string, conf: TestOptions, cb: Test.Callback) => Test} */
7593
function test(name, conf, cb) {
7694
var t = new Test(name, conf, cb);
7795
test._tests.push(t);
7896

7997
(function inspectCode(st) {
80-
st.on('test', function sub(st_) {
98+
st.on('test', /** @type {(st: Test) => void} */ function sub(st_) {
8199
inspectCode(st_);
82100
});
83-
st.on('result', function (r) {
101+
st.on('result', /** @type {(r: Result) => void} */ function (r) {
84102
if (!r.todo && !r.ok && typeof r !== 'string') { test._exitCode = 1; }
85103
});
86104
}(t));
@@ -90,21 +108,25 @@ function createHarness(conf_) {
90108
}
91109
test._results = results;
92110

93-
test._tests = [];
111+
/** @type {Test[]} */ test._tests = [];
94112

113+
/** @type {CreateStream} */
95114
test.createStream = function (opts) {
96115
return results.createStream(opts);
97116
};
98117

118+
/** @type {HarnessEventHandler} */
99119
test.onFinish = function (cb) {
100120
results.on('done', cb);
101121
};
102122

123+
/** @type {HarnessEventHandler} */
103124
test.onFailure = function (cb) {
104125
results.on('fail', cb);
105126
};
106127

107128
var only = false;
129+
/** @type {() => Test} */
108130
test.only = function () {
109131
if (only) { throw new Error('there can only be one only test'); }
110132
if (conf_ && conf_.noOnly) { throw new Error('`only` tests are prohibited'); }
@@ -117,9 +139,11 @@ function createHarness(conf_) {
117139

118140
test.close = function () { results.close(); };
119141

142+
// @ts-expect-error TODO FIXME: why is `test` not assignable to `Harness`???
120143
return test;
121144
}
122145

146+
/** @type {(conf: Omit<HarnessConfig, 'autoclose'>, wait?: boolean) => Harness} */
123147
function createExitHarness(config, wait) {
124148
var noOnly = config.noOnly;
125149
var objectMode = config.objectMode;
@@ -137,11 +161,12 @@ function createExitHarness(config, wait) {
137161
if (running) { return; }
138162
running = true;
139163
var stream = harness.createStream({ objectMode: objectMode });
140-
var es = stream.pipe(cStream || createDefaultStream());
164+
// eslint-disable-next-line no-extra-parens
165+
var es = stream.pipe(/** @type {WritableStream} */ (cStream || createDefaultStream()));
141166
if (canEmitExit && es) { // in node v0.4, `es` is `undefined`
142167
// TODO: use `err` arg?
143168
// eslint-disable-next-line no-unused-vars
144-
es.on('error', function (err) { harness._exitCode = 1; });
169+
es.on('error', function (_) { harness._exitCode = 1; });
145170
}
146171
stream.on('end', function () { ended = true; });
147172
}
@@ -179,7 +204,9 @@ function createExitHarness(config, wait) {
179204
return harness;
180205
}
181206

207+
module.exports = tape;
208+
182209
module.exports.createHarness = createHarness;
183210
module.exports.Test = Test;
184-
module.exports.test = module.exports; // tap compat
185-
module.exports.test.skip = Test.skip;
211+
module.exports.test = tape; // tap compat
212+
module.exports.skip = Test.skip;

lib/default_stream.d.ts

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import type { ThroughStream } from "@ljharb/through";
2+
3+
declare function defaultStream(): ThroughStream;
4+
5+
export = defaultStream;

lib/default_stream.js

+7-4
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,13 @@
33
var through = require('@ljharb/through');
44
var fs = require('fs');
55

6+
/** @type {import('./default_stream')} */
67
module.exports = function () {
78
var line = '';
89
var stream = through(write, flush);
910
return stream;
1011

12+
/** @type {(buf: unknown) => void} */
1113
function write(buf) {
1214
if (
1315
buf == null // eslint-disable-line eqeqeq
@@ -16,10 +18,11 @@ module.exports = function () {
1618
flush();
1719
return;
1820
}
19-
for (var i = 0; i < buf.length; i++) {
20-
var c = typeof buf === 'string'
21-
? buf.charAt(i)
22-
: String.fromCharCode(buf[i]);
21+
var b = /** @type {string | ArrayLike<number>} */ (buf); // eslint-disable-line no-extra-parens
22+
for (var i = 0; i < b.length; i++) {
23+
var c = typeof b === 'string'
24+
? b.charAt(i)
25+
: String.fromCharCode(b[i]);
2326
if (c === '\n') {
2427
flush();
2528
} else {

lib/results.d.ts

+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import through from '@ljharb/through';
2+
import type { EventEmitter } from 'events';
3+
4+
import type { StreamOptions } from '../';
5+
import Test = require('./test');
6+
7+
declare class Results extends EventEmitter {
8+
constructor(options?: { todoIsOK?: boolean });
9+
10+
count: number;
11+
fail: number;
12+
pass: number;
13+
tests: Test[];
14+
todo: number;
15+
todoIsOK: boolean;
16+
closed?: boolean;
17+
18+
_isRunning: boolean;
19+
_only: Test | null;
20+
_stream: through.ThroughStream;
21+
22+
close(this: Results): void;
23+
createStream(this: Results, opts?: StreamOptions): through.ThroughStream;
24+
only(this: Results, t: Test): void;
25+
push(this: Results, t: Test): void;
26+
27+
_watch(this: Results, t: Test): void;
28+
}
29+
30+
declare namespace Results {
31+
export type Operator = string;
32+
33+
export type Result = {
34+
id: number;
35+
ok: boolean;
36+
skip: unknown;
37+
todo: unknown;
38+
name?: string;
39+
operator: undefined | Operator;
40+
objectPrintDepth?: number;
41+
actual?: unknown;
42+
expected?: unknown;
43+
error?: unknown;
44+
functionName?: string;
45+
file?: string;
46+
line?: number;
47+
column?: number;
48+
at?: string;
49+
};
50+
}
51+
52+
export = Results;

0 commit comments

Comments
 (0)