Skip to content

Commit 8a8a575

Browse files
committed
Add experimental type definition
This is without macros in anticipation of the next change.
1 parent 9c23a07 commit 8a8a575

File tree

3 files changed

+309
-1
lines changed

3 files changed

+309
-1
lines changed

experimental.d.ts

+201
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,201 @@
1+
export {
2+
AssertAssertion,
3+
AssertionError,
4+
Assertions,
5+
CommitDiscardOptions,
6+
Constructor,
7+
DeepEqualAssertion,
8+
ExecutionContext,
9+
FailAssertion,
10+
FalseAssertion,
11+
FalsyAssertion,
12+
ImplementationResult,
13+
IsAssertion,
14+
LogFn,
15+
MetaInterface,
16+
NotAssertion,
17+
NotDeepEqualAssertion,
18+
NotRegexAssertion,
19+
NotThrowsAssertion,
20+
NotThrowsAsyncAssertion,
21+
PassAssertion,
22+
PlanFn,
23+
RegexAssertion,
24+
SnapshotAssertion,
25+
SnapshotOptions,
26+
Subscribable,
27+
ThrowsAssertion,
28+
ThrowsAsyncAssertion,
29+
ThrowsExpectation,
30+
TimeoutFn,
31+
TrueAssertion,
32+
TruthyAssertion,
33+
TryFn,
34+
TryResult
35+
} from '.';
36+
37+
import {ExecutionContext, ImplementationResult, MetaInterface} from '.';
38+
39+
export type Implementation<Context = unknown> = (t: ExecutionContext<Context>) => ImplementationResult;
40+
export type ImplementationWithArgs<Args extends any[], Context = unknown> = (t: ExecutionContext<Context>, ...args: Args) => ImplementationResult;
41+
42+
export interface TestInterface<Context = unknown> {
43+
/** Declare a concurrent test. */
44+
(title: string, implementation: Implementation<Context>): void;
45+
46+
/** Declare a concurrent test. */
47+
<Args extends any[]> (title: string, implementation: ImplementationWithArgs<Args, Context>, ...args: Args): void;
48+
49+
/** Declare a hook that is run once, after all tests have passed. */
50+
after: AfterInterface<Context>;
51+
52+
/** Declare a hook that is run after each passing test. */
53+
afterEach: AfterInterface<Context>;
54+
55+
/** Declare a hook that is run once, before all tests. */
56+
before: BeforeInterface<Context>;
57+
58+
/** Declare a hook that is run before each test. */
59+
beforeEach: BeforeInterface<Context>;
60+
61+
/** Declare a test that is expected to fail. */
62+
failing: FailingInterface<Context>;
63+
64+
/** Declare tests and hooks that are run serially. */
65+
serial: SerialInterface<Context>;
66+
67+
only: OnlyInterface<Context>;
68+
skip: SkipInterface<Context>;
69+
todo: TodoDeclaration;
70+
meta: MetaInterface;
71+
}
72+
73+
export interface AfterInterface<Context = unknown> {
74+
/** Declare a hook that is run once, after all tests have passed. */
75+
(implementation: Implementation<Context>): void;
76+
77+
/** Declare a hook that is run once, after all tests have passed. */
78+
<Args extends any[]> (implementation: ImplementationWithArgs<Args, Context>, ...args: Args): void;
79+
80+
/** Declare a hook that is run once, after all tests have passed. */
81+
(title: string, implementation: Implementation<Context>): void;
82+
83+
/** Declare a hook that is run once, after all tests have passed. */
84+
<Args extends any[]> (title: string, implementation: ImplementationWithArgs<Args, Context>, ...args: Args): void;
85+
86+
/** Declare a hook that is run once, after all tests are done. */
87+
always: AlwaysInterface<Context>;
88+
89+
skip: HookSkipInterface<Context>;
90+
}
91+
92+
export interface AlwaysInterface<Context = unknown> {
93+
/** Declare a hook that is run once, after all tests are done. */
94+
(implementation: Implementation<Context>): void;
95+
96+
/** Declare a hook that is run once, after all tests are done. */
97+
<Args extends any[]> (implementation: ImplementationWithArgs<Args, Context>, ...args: Args): void;
98+
99+
/** Declare a hook that is run once, after all tests are done. */
100+
(title: string, implementation: Implementation<Context>): void;
101+
102+
/** Declare a hook that is run once, after all tests are done. */
103+
<Args extends any[]> (title: string, implementation: ImplementationWithArgs<Args, Context>, ...args: Args): void;
104+
105+
skip: HookSkipInterface<Context>;
106+
}
107+
108+
export interface BeforeInterface<Context = unknown> {
109+
/** Declare a hook that is run once, before all tests. */
110+
(implementation: Implementation<Context>): void;
111+
112+
/** Declare a hook that is run once, before all tests. */
113+
<Args extends any[]> (implementation: ImplementationWithArgs<Args, Context>, ...args: Args): void;
114+
115+
/** Declare a hook that is run once, before all tests. */
116+
(title: string, implementation: Implementation<Context>): void;
117+
118+
/** Declare a hook that is run once, before all tests. */
119+
<Args extends any[]> (title: string, implementation: ImplementationWithArgs<Args, Context>, ...args: Args): void;
120+
121+
skip: HookSkipInterface<Context>;
122+
}
123+
124+
export interface FailingInterface<Context = unknown> {
125+
/** Declare a concurrent test. The test is expected to fail. */
126+
(title: string, implementation: Implementation<Context>): void;
127+
128+
/** Declare a concurrent test. The test is expected to fail. */
129+
<Args extends any[]> (title: string, implementation: ImplementationWithArgs<Args, Context>, ...args: Args): void;
130+
131+
only: OnlyInterface<Context>;
132+
skip: SkipInterface<Context>;
133+
}
134+
135+
export interface HookSkipInterface<Context = unknown> {
136+
/** Skip this hook. */
137+
(implementation: Implementation<Context>): void;
138+
139+
/** Skip this hook. */
140+
<Args extends any[]> (implementation: ImplementationWithArgs<Args, Context>, ...args: Args): void;
141+
142+
/** Skip this hook. */
143+
(title: string, implementation: Implementation<Context>): void;
144+
145+
/** Skip this hook. */
146+
<Args extends any[]> (title: string, implementation: ImplementationWithArgs<Args, Context>, ...args: Args): void;
147+
}
148+
149+
export interface OnlyInterface<Context = unknown> {
150+
/** Declare a test. Only this test and others declared with `.only()` are run. */
151+
(title: string, implementation: Implementation<Context>): void;
152+
153+
/** Declare a test. Only this test and others declared with `.only()` are run. */
154+
<Args extends any[]> (title: string, implementation: ImplementationWithArgs<Args, Context>, ...args: Args): void;
155+
}
156+
157+
export interface SerialInterface<Context = unknown> {
158+
/** Declare a serial test. */
159+
(title: string, implementation: Implementation<Context>): void;
160+
161+
/** Declare a serial test. */
162+
<Args extends any[]> (title: string, implementation: ImplementationWithArgs<Args, Context>, ...args: Args): void;
163+
164+
/** Declare a serial hook that is run once, after all tests have passed. */
165+
after: AfterInterface<Context>;
166+
167+
/** Declare a serial hook that is run after each passing test. */
168+
afterEach: AfterInterface<Context>;
169+
170+
/** Declare a serial hook that is run once, before all tests. */
171+
before: BeforeInterface<Context>;
172+
173+
/** Declare a serial hook that is run before each test. */
174+
beforeEach: BeforeInterface<Context>;
175+
176+
/** Declare a serial test that is expected to fail. */
177+
failing: FailingInterface<Context>;
178+
179+
only: OnlyInterface<Context>;
180+
skip: SkipInterface<Context>;
181+
todo: TodoDeclaration;
182+
}
183+
184+
export interface SkipInterface<Context = unknown> {
185+
/** Skip this test. */
186+
(title: string, implementation: Implementation<Context>): void;
187+
188+
/** Skip this test. */
189+
<Args extends any[]> (title: string, implementation: ImplementationWithArgs<Args, Context>, ...args: Args): void;
190+
}
191+
192+
export interface TodoDeclaration {
193+
/** Declare a test that should be implemented later. */
194+
(title: string): void;
195+
}
196+
197+
/** Call to declare a test, or chain to declare hooks or test modifiers */
198+
declare const test: TestInterface;
199+
200+
/** Call to declare a test, or chain to declare hooks or test modifiers */
201+
export default test;

package.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@
1616
"lib",
1717
"*.js",
1818
"!*.config.js",
19-
"index.d.ts"
19+
"index.d.ts",
20+
"experimental.d.ts"
2021
],
2122
"keywords": [
2223
"🦄",

test-d/experimental.ts

+106
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
import {expectError} from 'tsd';
2+
import test, {ExecutionContext, Implementation, ImplementationWithArgs} from '../experimental';
3+
4+
test('title', t => t.pass());
5+
6+
expectError(test<[string]>('explicit argument type', t => t.pass(), 42));
7+
8+
expectError(test<[string]>('missing argument', (t: ExecutionContext) => t.pass()));
9+
10+
test<string[]>('optional arguments', t => t.pass());
11+
test<string[]>('optional arguments, with values', t => t.pass(), 'foo', 'bar');
12+
13+
expectError(test('argument type inferred from implementation', (t, string) => t.is(string, 'foo'), 42));
14+
15+
expectError(test('argument type inferred in implementation', (t, string) => t.is(string, 'foo'), 42));
16+
17+
{
18+
const implementation: Implementation = t => t.pass();
19+
expectError(test('unexpected arguments', implementation, 'foo'));
20+
}
21+
22+
{
23+
const implementation: ImplementationWithArgs<[string]> = (t, string) => t.is(string, 'foo');
24+
test('unexpected arguments', implementation, 'foo');
25+
}
26+
27+
test.failing<[string]>('failing test with arguments', (t, string) => t.is(string, 'foo'), 'foo');
28+
test.only<[string]>('only test with arguments', (t, string) => t.is(string, 'foo'), 'foo');
29+
test.skip<[string]>('serial test with arguments', (t, string) => t.is(string, 'foo'), 'foo');
30+
31+
test.after.always.skip<[string]>('after.always hook with args', (t, string) => t.is(string, 'foo'), 'foo');
32+
test.after.always.skip<[string]>((t, string) => t.is(string, 'foo'), 'foo');
33+
test.after.always<[string]>('after.always hook with args', (t, string) => t.is(string, 'foo'), 'foo');
34+
test.after.always<[string]>((t, string) => t.is(string, 'foo'), 'foo');
35+
test.after.skip<[string]>('after hook with args', (t, string) => t.is(string, 'foo'), 'foo');
36+
test.after.skip<[string]>((t, string) => t.is(string, 'foo'), 'foo');
37+
test.after<[string]>('after hook with args', (t, string) => t.is(string, 'foo'), 'foo');
38+
test.after<[string]>((t, string) => t.is(string, 'foo'), 'foo');
39+
test.afterEach.always.skip<[string]>('after.always hook with args', (t, string) => t.is(string, 'foo'), 'foo');
40+
test.afterEach.always.skip<[string]>((t, string) => t.is(string, 'foo'), 'foo');
41+
test.afterEach.always<[string]>('after.always hook with args', (t, string) => t.is(string, 'foo'), 'foo');
42+
test.afterEach.always<[string]>((t, string) => t.is(string, 'foo'), 'foo');
43+
test.afterEach.skip<[string]>('after hook with args', (t, string) => t.is(string, 'foo'), 'foo');
44+
test.afterEach.skip<[string]>((t, string) => t.is(string, 'foo'), 'foo');
45+
test.afterEach<[string]>('after hook with args', (t, string) => t.is(string, 'foo'), 'foo');
46+
test.afterEach<[string]>((t, string) => t.is(string, 'foo'), 'foo');
47+
test.before.skip<[string]>('before hook with args', (t, string) => t.is(string, 'foo'), 'foo');
48+
test.before.skip<[string]>((t, string) => t.is(string, 'foo'), 'foo');
49+
test.before<[string]>('before hook with args', (t, string) => t.is(string, 'foo'), 'foo');
50+
test.before<[string]>((t, string) => t.is(string, 'foo'), 'foo');
51+
test.beforeEach.skip<[string]>('before hook with args', (t, string) => t.is(string, 'foo'), 'foo');
52+
test.beforeEach.skip<[string]>((t, string) => t.is(string, 'foo'), 'foo');
53+
test.beforeEach<[string]>('before hook with args', (t, string) => t.is(string, 'foo'), 'foo');
54+
test.beforeEach<[string]>((t, string) => t.is(string, 'foo'), 'foo');
55+
56+
test.serial('title', t => t.pass());
57+
58+
expectError(test.serial<[string]>('explicit argument type', t => t.pass(), 42));
59+
60+
expectError(test.serial<[string]>('missing argument', (t: ExecutionContext) => t.pass()));
61+
62+
test.serial<string[]>('optional arguments', t => t.pass());
63+
test.serial<string[]>('optional arguments, with values', t => t.pass(), 'foo', 'bar');
64+
65+
expectError(test.serial('argument type inferred from implementation', (t, string) => t.is(string, 'foo'), 42));
66+
67+
expectError(test.serial('argument type inferred in implementation', (t, string) => t.is(string, 'foo'), 42));
68+
69+
{
70+
const implementation: Implementation = t => t.pass();
71+
expectError(test.serial('unexpected arguments', implementation, 'foo'));
72+
}
73+
74+
{
75+
const implementation: ImplementationWithArgs<[string]> = (t, string) => t.is(string, 'foo');
76+
test.serial('unexpected arguments', implementation, 'foo');
77+
}
78+
79+
test.serial.failing<[string]>('failing test with arguments', (t, string) => t.is(string, 'foo'), 'foo');
80+
test.serial.only<[string]>('only test with arguments', (t, string) => t.is(string, 'foo'), 'foo');
81+
test.serial.skip<[string]>('serial test with arguments', (t, string) => t.is(string, 'foo'), 'foo');
82+
83+
test.serial.after.always.skip<[string]>('after.always hook with args', (t, string) => t.is(string, 'foo'), 'foo');
84+
test.serial.after.always.skip<[string]>((t, string) => t.is(string, 'foo'), 'foo');
85+
test.serial.after.always<[string]>('after.always hook with args', (t, string) => t.is(string, 'foo'), 'foo');
86+
test.serial.after.always<[string]>((t, string) => t.is(string, 'foo'), 'foo');
87+
test.serial.after.skip<[string]>('after hook with args', (t, string) => t.is(string, 'foo'), 'foo');
88+
test.serial.after.skip<[string]>((t, string) => t.is(string, 'foo'), 'foo');
89+
test.serial.after<[string]>('after hook with args', (t, string) => t.is(string, 'foo'), 'foo');
90+
test.serial.after<[string]>((t, string) => t.is(string, 'foo'), 'foo');
91+
test.serial.afterEach.always.skip<[string]>('after.always hook with args', (t, string) => t.is(string, 'foo'), 'foo');
92+
test.serial.afterEach.always.skip<[string]>((t, string) => t.is(string, 'foo'), 'foo');
93+
test.serial.afterEach.always<[string]>('after.always hook with args', (t, string) => t.is(string, 'foo'), 'foo');
94+
test.serial.afterEach.always<[string]>((t, string) => t.is(string, 'foo'), 'foo');
95+
test.serial.afterEach.skip<[string]>('after hook with args', (t, string) => t.is(string, 'foo'), 'foo');
96+
test.serial.afterEach.skip<[string]>((t, string) => t.is(string, 'foo'), 'foo');
97+
test.serial.afterEach<[string]>('after hook with args', (t, string) => t.is(string, 'foo'), 'foo');
98+
test.serial.afterEach<[string]>((t, string) => t.is(string, 'foo'), 'foo');
99+
test.serial.before.skip<[string]>('before hook with args', (t, string) => t.is(string, 'foo'), 'foo');
100+
test.serial.before.skip<[string]>((t, string) => t.is(string, 'foo'), 'foo');
101+
test.serial.before<[string]>('before hook with args', (t, string) => t.is(string, 'foo'), 'foo');
102+
test.serial.before<[string]>((t, string) => t.is(string, 'foo'), 'foo');
103+
test.serial.beforeEach.skip<[string]>('before hook with args', (t, string) => t.is(string, 'foo'), 'foo');
104+
test.serial.beforeEach.skip<[string]>((t, string) => t.is(string, 'foo'), 'foo');
105+
test.serial.beforeEach<[string]>('before hook with args', (t, string) => t.is(string, 'foo'), 'foo');
106+
test.serial.beforeEach<[string]>((t, string) => t.is(string, 'foo'), 'foo');

0 commit comments

Comments
 (0)