Skip to content

Commit 4b986a0

Browse files
committed
add types
1 parent e52bb18 commit 4b986a0

14 files changed

+612
-48
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
@@ -95,6 +95,7 @@ var hasImport = require('has-dynamic-import');
9595

9696
var tape = require('../');
9797

98+
/** @type {(hasSupport: boolean) => Promise<void> | void} */
9899
function importFiles(hasSupport) {
99100
if (!hasSupport) {
100101
return files.forEach(function (x) { require(x); });
@@ -104,6 +105,7 @@ function importFiles(hasSupport) {
104105

105106
tape.wait();
106107

108+
/** @type {null | undefined | Promise<unknown>} */
107109
var filesPromise = files.reduce(function (promise, file) {
108110
return promise ? promise.then(function () {
109111
return importOrRequire(file);

index.d.ts

+82
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
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: ThisType<Test>, name: string, opts: tape.TestOptions, cb: tape.TestCase): Test;
7+
declare function harnessFunction(this: ThisType<Test>, name: string, opts: tape.TestOptions): Test;
8+
declare function harnessFunction(this: ThisType<Test>, name: string, cb: tape.TestCase): Test;
9+
declare function harnessFunction(this: ThisType<Test>, name: string): Test;
10+
declare function harnessFunction(this: ThisType<Test>, opts: tape.TestOptions, cb: tape.TestCase): Test;
11+
declare function harnessFunction(this: ThisType<Test>, opts: tape.TestOptions): Test;
12+
declare function harnessFunction(this: ThisType<Test>, cb: tape.TestCase): 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 TestCase {
32+
(test: Test): void | Promise<void>;
33+
}
34+
35+
export interface StreamOptions {
36+
objectMode?: boolean | undefined;
37+
}
38+
39+
function createStream(opts?: StreamOptions): ThroughStream;
40+
41+
export type CreateStream = typeof createStream;
42+
43+
export type HarnessEventHandler = (cb: Test.SyncCallback, ...rest: unknown[]) => void;
44+
45+
function only(name: string, cb: tape.TestCase): void;
46+
function only(name: string, opts: tape.TestOptions, cb: tape.TestCase): void;
47+
function only(cb: tape.TestCase): void;
48+
function only(opts: tape.TestOptions, cb: tape.TestCase): void;
49+
50+
export type HarnessCallSignatures = typeof harnessFunction;
51+
52+
export interface Harness extends HarnessCallSignatures {
53+
run?: () => void;
54+
only: typeof only;
55+
_exitCode: number;
56+
_results: Results;
57+
_tests: Test[];
58+
close: () => void;
59+
createStream: CreateStream;
60+
onFailure: HarnessEventHandler;
61+
onFinish: HarnessEventHandler;
62+
}
63+
64+
export type HarnessConfig = {
65+
autoclose?: boolean;
66+
noOnly?: boolean;
67+
stream?: NodeJS.WritableStream | ThroughStream;
68+
exit?: boolean;
69+
} & StreamOptions;
70+
71+
function createHarness(conf_?: HarnessConfig): Harness;
72+
const Test: Test;
73+
const test: typeof tape;
74+
const skip: Test['skip'];
75+
}
76+
77+
declare function tape(this: tape.Harness, name: string, opts: tape.TestOptions, cb: tape.TestCase): Test;
78+
declare function tape(this: tape.Harness, name: string, cb: tape.TestCase): Test;
79+
declare function tape(this: tape.Harness, opts?: tape.TestOptions): Test;
80+
declare function tape(this: tape.Harness, opts: tape.TestOptions, cb: tape.TestCase): Test;
81+
82+
export = tape;

index.js

+38-10
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,36 @@
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

16+
/** @typedef {import('.')} Tape */
17+
/** @typedef {import('.').Harness} Harness */
18+
/** @typedef {import('.').HarnessConfig} HarnessConfig */
19+
/** @typedef {import('.').HarnessCallSignatures} HarnessCallSignatures */
20+
/** @typedef {import('.').TestOptions} TestOptions */
21+
/** @typedef {import('.').HarnessEventHandler} HarnessEventHandler */
22+
/** @typedef {import('.').CreateStream} CreateStream */
23+
/** @typedef {import('.').createHarness} CreateHarness */
24+
/** @typedef {import('./lib/results').Result} Result */
25+
/** @typedef {import('stream').Writable} WritableStream */
26+
/** @typedef {import('.').TestCase} TestCase */
27+
1428
module.exports = (function () {
1529
var wait = false;
30+
/** @type {undefined | Harness} */
1631
var harness;
1732

33+
/** @type {(opts?: HarnessConfig) => Harness} */
1834
function getHarness(opts) {
1935
// this override is here since tests fail via nyc if createHarness is moved upwards
2036
if (!harness) {
@@ -24,6 +40,7 @@ module.exports = (function () {
2440
return harness;
2541
}
2642

43+
/** @type {(this: Harness, ...args: Parameters<Tape>) => ReturnType<Tape>} */
2744
function lazyLoad() {
2845
// eslint-disable-next-line no-invalid-this
2946
return getHarness().apply(this, arguments);
@@ -43,6 +60,7 @@ module.exports = (function () {
4360
return getHarness().only.apply(this, arguments);
4461
};
4562

63+
/** @type {CreateStream} */
4664
lazyLoad.createStream = function (opts) {
4765
var options = opts || {};
4866
if (!harness) {
@@ -66,21 +84,23 @@ module.exports = (function () {
6684
return lazyLoad;
6785
}());
6886

87+
/** @type {CreateHarness} */
6988
function createHarness(conf_) {
7089
var results = new Results({ todoIsOK: !!(process.env.TODO_IS_OK === '1') });
7190
if (!conf_ || conf_.autoclose !== false) {
7291
results.once('done', function () { results.close(); });
7392
}
7493

94+
/** @type {(name: string, conf: TestOptions, cb: TestCase) => Test} */
7595
function test(name, conf, cb) {
7696
var t = new Test(name, conf, cb);
7797
test._tests.push(t);
7898

7999
(function inspectCode(st) {
80-
st.on('test', function sub(st_) {
100+
st.on('test', /** @type {(st: Test) => void} */ function sub(st_) {
81101
inspectCode(st_);
82102
});
83-
st.on('result', function (r) {
103+
st.on('result', /** @type {(r: Result) => void} */ function (r) {
84104
if (!r.todo && !r.ok && typeof r !== 'string') { test._exitCode = 1; }
85105
});
86106
}(t));
@@ -90,21 +110,25 @@ function createHarness(conf_) {
90110
}
91111
test._results = results;
92112

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

115+
/** @type {CreateStream} */
95116
test.createStream = function (opts) {
96117
return results.createStream(opts);
97118
};
98119

120+
/** @type {HarnessEventHandler} */
99121
test.onFinish = function (cb) {
100122
results.on('done', cb);
101123
};
102124

125+
/** @type {HarnessEventHandler} */
103126
test.onFailure = function (cb) {
104127
results.on('fail', cb);
105128
};
106129

107130
var only = false;
131+
/** @type {() => Test} */
108132
test.only = function () {
109133
if (only) { throw new Error('there can only be one only test'); }
110134
if (conf_ && conf_.noOnly) { throw new Error('`only` tests are prohibited'); }
@@ -117,9 +141,11 @@ function createHarness(conf_) {
117141

118142
test.close = function () { results.close(); };
119143

144+
// @ts-expect-error TODO FIXME: why is `test` not assignable to `Harness`???
120145
return test;
121146
}
122147

148+
/** @type {(conf: Omit<HarnessConfig, 'autoclose'>, wait?: boolean) => Harness} */
123149
function createExitHarness(config, wait) {
124150
var noOnly = config.noOnly;
125151
var objectMode = config.objectMode;
@@ -137,11 +163,12 @@ function createExitHarness(config, wait) {
137163
if (running) { return; }
138164
running = true;
139165
var stream = harness.createStream({ objectMode: objectMode });
140-
var es = stream.pipe(cStream || createDefaultStream());
166+
// eslint-disable-next-line no-extra-parens
167+
var es = stream.pipe(/** @type {WritableStream} */ (cStream || createDefaultStream()));
141168
if (canEmitExit && es) { // in node v0.4, `es` is `undefined`
142169
// TODO: use `err` arg?
143170
// eslint-disable-next-line no-unused-vars
144-
es.on('error', function (err) { harness._exitCode = 1; });
171+
es.on('error', function (_) { harness._exitCode = 1; });
145172
}
146173
stream.on('end', function () { ended = true; });
147174
}
@@ -180,6 +207,7 @@ function createExitHarness(config, wait) {
180207
}
181208

182209
module.exports.createHarness = createHarness;
183-
module.exports.Test = Test;
184-
module.exports.test = module.exports; // tap compat
185-
module.exports.test.skip = Test.skip;
210+
var moduleExports = module.exports; // this hack is needed because TS has a bug with seemingly circular exports
211+
moduleExports.Test = Test;
212+
moduleExports.test = module.exports; // tap compat
213+
moduleExports.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)