Skip to content

Commit 4ee0620

Browse files
committed
add types
1 parent 91a83b6 commit 4ee0620

File tree

14 files changed

+580
-36
lines changed

14 files changed

+580
-36
lines changed

.github/workflows/node-aught.yml

Lines changed: 1 addition & 0 deletions
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

Lines changed: 1 addition & 0 deletions
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

Lines changed: 2 additions & 0 deletions
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

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

index.js

Lines changed: 34 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,32 @@
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
11+
// @ts-expect-error i think old browserify uses `process.browser`
1012
&& typeof process.on === 'function' && 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('.').TestOptions} TestOptions */
20+
/** @typedef {import('.').HarnessEventHandler} HarnessEventHandler */
21+
/** @typedef {import('.').CreateStream} CreateStream */
22+
/** @typedef {import('./lib/results').Result} Result */
23+
1424
module.exports = (function () {
1525
var wait = false;
26+
/** @type {undefined | Harness} */
1627
var harness;
1728

29+
/** @type {(opts?: HarnessConfig) => Harness} */
1830
function getHarness(opts) {
1931
// this override is here since tests fail via nyc if createHarness is moved upwards
2032
if (!harness) {
@@ -24,6 +36,7 @@ module.exports = (function () {
2436
return harness;
2537
}
2638

39+
/** @type {(this: Harness, ...args: Parameters<Tape>) => ReturnType<Tape>} */
2740
function lazyLoad() {
2841
// eslint-disable-next-line no-invalid-this
2942
return getHarness().apply(this, arguments);
@@ -43,11 +56,13 @@ module.exports = (function () {
4356
return getHarness().only.apply(this, arguments);
4457
};
4558

59+
/** @type {CreateStream} */
4660
lazyLoad.createStream = function (opts) {
4761
var options = opts || {};
4862
if (!harness) {
4963
var output = through();
50-
getHarness({ stream: output, objectMode: options.objectMode });
64+
// eslint-disable-next-line no-extra-parens
65+
getHarness({ stream: /** @type {import('stream').Writable} */ (output), objectMode: options.objectMode });
5166
return output;
5267
}
5368
return harness.createStream(options);
@@ -66,21 +81,23 @@ module.exports = (function () {
6681
return lazyLoad;
6782
}());
6883

84+
/** @type {Tape['createHarness']} */
6985
function createHarness(conf_) {
7086
var results = new Results({ todoIsOK: !!(process.env.TODO_IS_OK === '1') });
7187
if (!conf_ || conf_.autoclose !== false) {
7288
results.once('done', function () { results.close(); });
7389
}
7490

91+
/** @type {(name: string, conf: TestOptions, cb: Test.Callback) => Test} */
7592
function test(name, conf, cb) {
7693
var t = new Test(name, conf, cb);
7794
test._tests.push(t);
7895

7996
(function inspectCode(st) {
80-
st.on('test', function sub(st_) {
97+
st.on('test', /** @type {(st: Test) => void} */ function sub(st_) {
8198
inspectCode(st_);
8299
});
83-
st.on('result', function (r) {
100+
st.on('result', /** @type {(r: Result) => void} */ function (r) {
84101
if (!r.todo && !r.ok && typeof r !== 'string') { test._exitCode = 1; }
85102
});
86103
}(t));
@@ -90,21 +107,25 @@ function createHarness(conf_) {
90107
}
91108
test._results = results;
92109

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

112+
/** @type {CreateStream} */
95113
test.createStream = function (opts) {
96114
return results.createStream(opts);
97115
};
98116

117+
/** @type {HarnessEventHandler} */
99118
test.onFinish = function (cb) {
100119
results.on('done', cb);
101120
};
102121

122+
/** @type {HarnessEventHandler} */
103123
test.onFailure = function (cb) {
104124
results.on('fail', cb);
105125
};
106126

107127
var only = false;
128+
/** @type {() => ReturnType<typeof test>} */
108129
test.only = function () {
109130
if (only) { throw new Error('there can only be one only test'); }
110131
if (conf_ && conf_.noOnly) { throw new Error('`only` tests are prohibited'); }
@@ -117,9 +138,12 @@ function createHarness(conf_) {
117138

118139
test.close = function () { results.close(); };
119140

141+
test.run = function () {};
142+
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;
@@ -140,6 +164,7 @@ function createExitHarness(config, wait) {
140164
var es = stream.pipe(cStream || createDefaultStream());
141165
if (canEmitExit && es) { // in node v0.4, `es` is `undefined`
142166
// TODO: use `err` arg?
167+
// @ts-expect-error
143168
// eslint-disable-next-line no-unused-vars
144169
es.on('error', function (err) { harness._exitCode = 1; });
145170
}
@@ -180,6 +205,7 @@ function createExitHarness(config, wait) {
180205
}
181206

182207
module.exports.createHarness = createHarness;
183-
module.exports.Test = Test;
184-
module.exports.test = module.exports; // tap compat
185-
module.exports.test.skip = Test.skip;
208+
var moduleExports = module.exports; // this hack is needed because TS has a bug with seemingly circular exports
209+
moduleExports.Test = Test;
210+
moduleExports.test = module.exports; // tap compat
211+
moduleExports.skip = Test.skip;

lib/default_stream.d.ts

Lines changed: 5 additions & 0 deletions
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

Lines changed: 7 additions & 4 deletions
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

Lines changed: 52 additions & 0 deletions
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)