Type additional arguments used by macros
Co-authored-by: Nikita Volodin [Никита Володин] <volodin.n@gmail.com>
This commit is contained in:
parent
a82fee56ff
commit
6f54db8419
4 changed files with 210 additions and 75 deletions
|
|
@ -58,15 +58,27 @@ test(async t => {
|
|||
|
||||
## Using [macros](../01-writing-tests.md#reusing-test-logic-through-macros)
|
||||
|
||||
Macros can receive additional arguments. AVA can infer these to ensure you're using the macro correctly:
|
||||
|
||||
```ts
|
||||
import test, {ExecutionContext} from 'ava';
|
||||
|
||||
const hasLength = (t: ExecutionContext, input: string, expected: number) => {
|
||||
t.is(input.length, expected);
|
||||
};
|
||||
|
||||
test('bar has length 3', hasLength, 'bar', 3);
|
||||
```
|
||||
|
||||
In order to be able to assign the `title` property to a macro you need to type the function:
|
||||
|
||||
```ts
|
||||
import test, {Macro} from 'ava';
|
||||
|
||||
const macro: Macro = (t, input: string, expected: number) => {
|
||||
const macro: Macro<[string, number]> = (t, input, expected) => {
|
||||
t.is(eval(input), expected);
|
||||
};
|
||||
macro.title = (providedTitle = '', input: string, expected: number) => `${providedTitle} ${input} = ${expected}`.trim();
|
||||
macro.title = (providedTitle = '', input, expected) => `${providedTitle} ${input} = ${expected}`.trim();
|
||||
|
||||
test(macro, '2 + 2', 4);
|
||||
test(macro, '2 * 3', 6);
|
||||
|
|
@ -78,7 +90,7 @@ You'll need a different type if you're expecting your macro to be used with a ca
|
|||
```ts
|
||||
import test, {CbMacro} from 'ava';
|
||||
|
||||
const macro: CbMacro = t => {
|
||||
const macro: CbMacro<[]> = t => {
|
||||
t.pass();
|
||||
setTimeout(t.end, 100);
|
||||
};
|
||||
|
|
@ -123,7 +135,7 @@ interface Context {
|
|||
|
||||
const test = anyTest as TestInterface<Context>;
|
||||
|
||||
const macro: Macro<Context> = (t, expected: string) => {
|
||||
const macro: Macro<[string], Context> = (t, expected: string) => {
|
||||
t.is(t.context.foo, expected);
|
||||
};
|
||||
|
||||
|
|
|
|||
199
index.d.ts
vendored
199
index.d.ts
vendored
|
|
@ -383,34 +383,66 @@ export type Implementation<Context = {}> = (t: ExecutionContext<Context>) => Imp
|
|||
export type CbImplementation<Context = {}> = (t: CbExecutionContext<Context>) => ImplementationResult;
|
||||
|
||||
/** A reusable test or hook implementation. */
|
||||
export interface Macro<Context = {}> {
|
||||
(t: ExecutionContext<Context>, ...args: Array<any>): ImplementationResult;
|
||||
export interface Macro<Args extends any[], Context = {}> {
|
||||
(t: ExecutionContext<Context>, ...args: Args): ImplementationResult;
|
||||
|
||||
/**
|
||||
* Implement this function to generate a test (or hook) title whenever this macro is used. `providedTitle` contains
|
||||
* the title provided when the test or hook was declared. Also receives the remaining test arguments.
|
||||
*/
|
||||
title?: (providedTitle: string | undefined, ...args: Array<any>) => string;
|
||||
title?: (providedTitle: string | undefined, ...args: Args) => string;
|
||||
}
|
||||
|
||||
/** Alias for a single macro, or an array of macros. */
|
||||
export type OneOrMoreMacros<Args extends any[], Context> = Macro<Args, Context> | [Macro<Args, Context>, ...Macro<Args, Context>[]];
|
||||
|
||||
/** A reusable test or hook implementation, for tests & hooks declared with the `.cb` modifier. */
|
||||
export interface CbMacro<Context = {}> {
|
||||
(t: CbExecutionContext<Context>, ...args: Array<any>): ImplementationResult;
|
||||
title?: (providedTitle: string | undefined, ...args: Array<any>) => string;
|
||||
export interface CbMacro<Args extends any[], Context = {}> {
|
||||
(t: CbExecutionContext<Context>, ...args: Args): ImplementationResult;
|
||||
title?: (providedTitle: string | undefined, ...args: Args) => string;
|
||||
}
|
||||
|
||||
/** Alias for a single macro, or an array of macros, used for tests & hooks declared with the `.cb` modifier. */
|
||||
export type OneOrMoreCbMacros<Args extends any[], Context> = CbMacro<Args, Context> | [CbMacro<Args, Context>, ...CbMacro<Args, Context>[]];
|
||||
|
||||
/** Infers the types of the additional arguments the macro implementations should be called with. */
|
||||
export type InferArgs<OneOrMore> =
|
||||
OneOrMore extends Macro<infer Args, any> ? Args :
|
||||
OneOrMore extends Macro<infer Args, any>[] ? Args :
|
||||
OneOrMore extends CbMacro<infer Args, any> ? Args :
|
||||
OneOrMore extends CbMacro<infer Args, any>[] ? Args :
|
||||
never;
|
||||
|
||||
export type TitleOrMacro<Context> = string | OneOrMoreMacros<any, Context>
|
||||
|
||||
export type MacroOrFirstArg<TitleOrMacro, Context> =
|
||||
TitleOrMacro extends string ? OneOrMoreMacros<any, Context> :
|
||||
TitleOrMacro extends OneOrMoreMacros<any, Context> ? InferArgs<TitleOrMacro>[0] :
|
||||
never
|
||||
|
||||
export type TitleOrCbMacro<Context> = string | OneOrMoreCbMacros<any, Context>
|
||||
|
||||
export type CbMacroOrFirstArg<TitleOrMacro, Context> =
|
||||
TitleOrMacro extends string ? OneOrMoreCbMacros<any, Context> :
|
||||
TitleOrMacro extends OneOrMoreCbMacros<any, Context> ? InferArgs<TitleOrMacro>[0] :
|
||||
never
|
||||
|
||||
export type RestArgs<TitleOrMacro, MacroOrFirstArg, Context> =
|
||||
MacroOrFirstArg extends OneOrMoreMacros<any, Context> ? InferArgs<MacroOrFirstArg> :
|
||||
MacroOrFirstArg extends OneOrMoreCbMacros<any, Context> ? InferArgs<MacroOrFirstArg> :
|
||||
TitleOrMacro extends OneOrMoreMacros<any, Context> ? Tail<InferArgs<TitleOrMacro>> :
|
||||
TitleOrMacro extends OneOrMoreCbMacros<any, Context> ? Tail<InferArgs<TitleOrMacro>> :
|
||||
never
|
||||
|
||||
export interface TestInterface<Context = {}> {
|
||||
/** Declare a concurrent test. */
|
||||
(title: string, implementation: Implementation<Context>): void;
|
||||
|
||||
/** Declare a concurrent test that uses one or more macros. Additional arguments are passed to the macro. */
|
||||
(title: string, macro: Macro<Context> | Macro<Context>[], ...args: Array<any>): void;
|
||||
<ToM extends TitleOrMacro<Context>, MoA extends MacroOrFirstArg<ToM, Context>>(titleOrMacro: ToM, macroOrArg: MoA, ...rest: RestArgs<ToM, MoA, Context>): void;
|
||||
|
||||
/**
|
||||
* Declare a concurrent test that uses one or more macros. Additional arguments are passed to the macro. The macro
|
||||
* is responsible for generating a unique test title.
|
||||
*/
|
||||
(macro: Macro<Context> | Macro<Context>[], ...args: Array<any>): void;
|
||||
/** Declare a concurrent test that uses one or more macros. The macro is responsible for generating a unique test title. */
|
||||
(macro: OneOrMoreMacros<[], Context>): void
|
||||
|
||||
/** Declare a hook that is run once, after all tests have passed. */
|
||||
after: AfterInterface<Context>;
|
||||
|
|
@ -442,14 +474,14 @@ export interface AfterInterface<Context = {}> {
|
|||
/** Declare a hook that is run once, after all tests have passed. */
|
||||
(implementation: Implementation<Context>): void;
|
||||
|
||||
/** Declare a hook that is run once, after all tests have passed. Additional argumens are passed to the macro. */
|
||||
(macro: Macro<Context> | Macro<Context>[], ...args: Array<any>): void;
|
||||
|
||||
/** Declare a hook that is run once, after all tests have passed. */
|
||||
(title: string, implementation: Implementation<Context>): void;
|
||||
|
||||
/** Declare a hook that is run once, after all tests have passed. Additional argumens are passed to the macro. */
|
||||
(title: string, macro: Macro<Context> | Macro<Context>[], ...args: Array<any>): void;
|
||||
/** Declare a hook that is run once, after all tests have passed. Additional arguments are passed to the macro. */
|
||||
<ToM extends TitleOrMacro<Context>, MoA extends MacroOrFirstArg<ToM, Context>>(titleOrMacro: ToM, macroOrArg: MoA, ...rest: RestArgs<ToM, MoA, Context>): void;
|
||||
|
||||
/** Declare a hook that is run once, after all tests have passed. */
|
||||
(macro: OneOrMoreMacros<[], Context>): void
|
||||
|
||||
/** Declare a hook that is run once, after all tests are done. */
|
||||
always: AlwaysInterface<Context>;
|
||||
|
|
@ -464,14 +496,14 @@ export interface AlwaysInterface<Context = {}> {
|
|||
/** Declare a hook that is run once, after all tests are done. */
|
||||
(implementation: Implementation<Context>): void;
|
||||
|
||||
/** Declare a hook that is run once, after all tests are done. Additional argumens are passed to the macro. */
|
||||
(macro: Macro<Context> | Macro<Context>[], ...args: Array<any>): void;
|
||||
|
||||
/** Declare a hook that is run once, after all tests are done. */
|
||||
(title: string, implementation: Implementation<Context>): void;
|
||||
|
||||
/** Declare a hook that is run once, after all tests are done. Additional argumens are passed to the macro. */
|
||||
(title: string, macro: Macro<Context> | Macro<Context>[], ...args: Array<any>): void;
|
||||
/** Declare a hook that is run once, after all tests are done. Additional arguments are passed to the macro. */
|
||||
<ToM extends TitleOrMacro<Context>, MoA extends MacroOrFirstArg<ToM, Context>>(titleOrMacro: ToM, macroOrArg: MoA, ...rest: RestArgs<ToM, MoA, Context>): void;
|
||||
|
||||
/** Declare a hook that is run once, after all tests are done. */
|
||||
(macro: OneOrMoreMacros<[], Context>): void
|
||||
|
||||
/** Declare a hook that must call `t.end()` when it's done. */
|
||||
cb: HookCbInterface<Context>;
|
||||
|
|
@ -483,14 +515,14 @@ export interface BeforeInterface<Context = {}> {
|
|||
/** Declare a hook that is run once, before all tests. */
|
||||
(implementation: Implementation<Context>): void;
|
||||
|
||||
/** Declare a hook that is run once, before all tests. Additional argumens are passed to the macro. */
|
||||
(macro: Macro<Context> | Macro<Context>[], ...args: Array<any>): void;
|
||||
|
||||
/** Declare a hook that is run once, before all tests. */
|
||||
(title: string, implementation: Implementation<Context>): void;
|
||||
|
||||
/** Declare a hook that is run once, before all tests. Additional argumens are passed to the macro. */
|
||||
(title: string, macro: Macro<Context> | Macro<Context>[], ...args: Array<any>): void;
|
||||
/** Declare a hook that is run once, before all tests. Additional arguments are passed to the macro. */
|
||||
<ToM extends TitleOrMacro<Context>, MoA extends MacroOrFirstArg<ToM, Context>>(titleOrMacro: ToM, macroOrArg: MoA, ...rest: RestArgs<ToM, MoA, Context>): void;
|
||||
|
||||
/** Declare a hook that is run once, before all tests. */
|
||||
(macro: OneOrMoreMacros<[], Context>): void
|
||||
|
||||
/** Declare a hook that must call `t.end()` when it's done. */
|
||||
cb: HookCbInterface<Context>;
|
||||
|
|
@ -503,16 +535,16 @@ export interface CbInterface<Context = {}> {
|
|||
(title: string, implementation: CbImplementation<Context>): void;
|
||||
|
||||
/**
|
||||
* Declare a test that uses one or more macros. The macros must call `t.end()` when they're done.
|
||||
* Declare a concurrent test that uses one or more macros. The macros must call `t.end()` when they're done.
|
||||
* Additional arguments are passed to the macro.
|
||||
*/
|
||||
(title: string, macro: CbMacro<Context> | CbMacro<Context>[], ...args: Array<any>): void;
|
||||
<ToM extends TitleOrCbMacro<Context>, MoA extends CbMacroOrFirstArg<ToM, Context>>(titleOrMacro: ToM, macroOrArg: MoA, ...rest: RestArgs<ToM, MoA, Context>): void;
|
||||
|
||||
/**
|
||||
* Declare a test that uses one or more macros. The macros must call `t.end()` when they're done.
|
||||
* Additional arguments are passed to the macro. The macro is responsible for generating a unique test title.
|
||||
* Declare a concurrent test that uses one or more macros. The macros must call `t.end()` when they're done.
|
||||
* The macro is responsible for generating a unique test title.
|
||||
*/
|
||||
(macro: CbMacro<Context> | CbMacro<Context>[], ...args: Array<any>): void;
|
||||
(macro: OneOrMoreCbMacros<[], Context>): void
|
||||
|
||||
/** Declare a test that is expected to fail. */
|
||||
failing: CbFailingInterface<Context>;
|
||||
|
|
@ -529,14 +561,13 @@ export interface CbFailingInterface<Context = {}> {
|
|||
* Declare a test that uses one or more macros. The macros must call `t.end()` when they're done.
|
||||
* Additional arguments are passed to the macro. The test is expected to fail.
|
||||
*/
|
||||
(title: string, macro: CbMacro<Context> | CbMacro<Context>[], ...args: Array<any>): void;
|
||||
<ToM extends TitleOrCbMacro<Context>, MoA extends CbMacroOrFirstArg<ToM, Context>>(titleOrMacro: ToM, macroOrArg: MoA, ...rest: RestArgs<ToM, MoA, Context>): void;
|
||||
|
||||
/**
|
||||
* Declare a test that uses one or more macros. The macros must call `t.end()` when they're done.
|
||||
* Additional arguments are passed to the macro. The macro is responsible for generating a unique test title.
|
||||
* The test is expected to fail.
|
||||
*/
|
||||
(macro: CbMacro<Context> | CbMacro<Context>[], ...args: Array<any>): void;
|
||||
(macro: OneOrMoreCbMacros<[], Context>): void
|
||||
|
||||
only: CbOnlyInterface<Context>;
|
||||
skip: CbSkipInterface<Context>;
|
||||
|
|
@ -552,14 +583,13 @@ export interface CbOnlyInterface<Context = {}> {
|
|||
* Declare a test that uses one or more macros. The macros must call `t.end()` when they're done.
|
||||
* Additional arguments are passed to the macro. Only this test and others declared with `.only()` are run.
|
||||
*/
|
||||
(title: string, macro: CbMacro<Context> | CbMacro<Context>[], ...args: Array<any>): void;
|
||||
<ToM extends TitleOrCbMacro<Context>, MoA extends CbMacroOrFirstArg<ToM, Context>>(titleOrMacro: ToM, macroOrArg: MoA, ...rest: RestArgs<ToM, MoA, Context>): void;
|
||||
|
||||
/**
|
||||
* Declare a test that uses one or more macros. The macros must call `t.end()` when they're done.
|
||||
* Additional arguments are passed to the macro. The macro is responsible for generating a unique test title.
|
||||
* Only this test and others declared with `.only()` are run.
|
||||
* Additional arguments are passed to the macro. Only this test and others declared with `.only()` are run.
|
||||
*/
|
||||
(macro: CbMacro<Context> | CbMacro<Context>[], ...args: Array<any>): void;
|
||||
(macro: OneOrMoreCbMacros<[], Context>): void
|
||||
}
|
||||
|
||||
export interface CbSkipInterface<Context = {}> {
|
||||
|
|
@ -567,10 +597,10 @@ export interface CbSkipInterface<Context = {}> {
|
|||
(title: string, implementation: CbImplementation<Context>): void;
|
||||
|
||||
/** Skip this test. */
|
||||
(title: string, macro: CbMacro<Context> | CbMacro<Context>[], ...args: Array<any>): void;
|
||||
<ToM extends TitleOrCbMacro<Context>, MoA extends CbMacroOrFirstArg<ToM, Context>>(titleOrMacro: ToM, macroOrArg: MoA, ...rest: RestArgs<ToM, MoA, Context>): void;
|
||||
|
||||
/** Skip this test. */
|
||||
(macro: CbMacro<Context> | CbMacro<Context>[], ...args: Array<any>): void;
|
||||
(macro: OneOrMoreCbMacros<[], Context>): void
|
||||
}
|
||||
|
||||
export interface FailingInterface<Context = {}> {
|
||||
|
|
@ -581,13 +611,13 @@ export interface FailingInterface<Context = {}> {
|
|||
* Declare a concurrent test that uses one or more macros. Additional arguments are passed to the macro.
|
||||
* The test is expected to fail.
|
||||
*/
|
||||
(title: string, macro: Macro<Context> | Macro<Context>[], ...args: Array<any>): void;
|
||||
<ToM extends TitleOrMacro<Context>, MoA extends MacroOrFirstArg<ToM, Context>>(titleOrMacro: ToM, macroOrArg: MoA, ...rest: RestArgs<ToM, MoA, Context>): void;
|
||||
|
||||
/**
|
||||
* Declare a concurrent test that uses one or more macros. Additional arguments are passed to the macro. The macro
|
||||
* is responsible for generating a unique test title. The test is expected to fail.
|
||||
* Declare a concurrent test that uses one or more macros. The macro is responsible for generating a unique test title.
|
||||
* The test is expected to fail.
|
||||
*/
|
||||
(macro: Macro<Context> | Macro<Context>[], ...args: Array<any>): void;
|
||||
(macro: OneOrMoreMacros<[], Context>): void
|
||||
|
||||
only: OnlyInterface<Context>;
|
||||
skip: SkipInterface<Context>;
|
||||
|
|
@ -597,12 +627,6 @@ export interface HookCbInterface<Context = {}> {
|
|||
/** Declare a hook that must call `t.end()` when it's done. */
|
||||
(implementation: CbImplementation<Context>): void;
|
||||
|
||||
/**
|
||||
* Declare a hook that uses one or more macros. The macros must call `t.end()` when they're done.
|
||||
* Additional arguments are passed to the macro.
|
||||
*/
|
||||
(macro: CbMacro<Context> | CbMacro<Context>[], ...args: Array<any>): void;
|
||||
|
||||
/** Declare a hook that must call `t.end()` when it's done. */
|
||||
(title: string, implementation: CbImplementation<Context>): void;
|
||||
|
||||
|
|
@ -610,7 +634,12 @@ export interface HookCbInterface<Context = {}> {
|
|||
* Declare a hook that uses one or more macros. The macros must call `t.end()` when they're done.
|
||||
* Additional arguments are passed to the macro.
|
||||
*/
|
||||
(title: string, macro: CbMacro<Context> | CbMacro<Context>[], ...args: Array<any>): void;
|
||||
<ToM extends TitleOrCbMacro<Context>, MoA extends CbMacroOrFirstArg<ToM, Context>>(titleOrMacro: ToM, macroOrArg: MoA, ...rest: RestArgs<ToM, MoA, Context>): void;
|
||||
|
||||
/**
|
||||
* Declare a hook that uses one or more macros. The macros must call `t.end()` when they're done.
|
||||
*/
|
||||
(macro: OneOrMoreCbMacros<[], Context>): void
|
||||
|
||||
skip: HookCbSkipInterface<Context>;
|
||||
}
|
||||
|
|
@ -619,28 +648,28 @@ export interface HookCbSkipInterface<Context = {}> {
|
|||
/** Skip this hook. */
|
||||
(implementation: CbImplementation<Context>): void;
|
||||
|
||||
/** Skip this hook. */
|
||||
(macro: CbMacro<Context> | CbMacro<Context>[], ...args: Array<any>): void;
|
||||
|
||||
/** Skip this hook. */
|
||||
(title: string, implementation: CbImplementation<Context>): void;
|
||||
|
||||
/** Skip this hook. */
|
||||
(title: string, macro: CbMacro<Context> | CbMacro<Context>[], ...args: Array<any>): void;
|
||||
<ToM extends TitleOrCbMacro<Context>, MoA extends CbMacroOrFirstArg<ToM, Context>>(titleOrMacro: ToM, macroOrArg: MoA, ...rest: RestArgs<ToM, MoA, Context>): void;
|
||||
|
||||
/** Skip this hook. */
|
||||
(macro: OneOrMoreCbMacros<[], Context>): void
|
||||
}
|
||||
|
||||
export interface HookSkipInterface<Context = {}> {
|
||||
/** Skip this hook. */
|
||||
(implementation: Implementation<Context>): void;
|
||||
|
||||
/** Skip this hook. */
|
||||
(macro: Macro<Context> | Macro<Context>[], ...args: Array<any>): void;
|
||||
|
||||
/** Skip this hook. */
|
||||
(title: string, implementation: Implementation<Context>): void;
|
||||
|
||||
/** Skip this hook. */
|
||||
(title: string, macro: Macro<Context> | Macro<Context>[], ...args: Array<any>): void;
|
||||
<ToM extends TitleOrMacro<Context>, MoA extends MacroOrFirstArg<ToM, Context>>(titleOrMacro: ToM, macroOrArg: MoA, ...rest: RestArgs<ToM, MoA, Context>): void;
|
||||
|
||||
/** Skip this hook. */
|
||||
(macro: OneOrMoreMacros<[], Context>): void
|
||||
}
|
||||
|
||||
export interface OnlyInterface<Context = {}> {
|
||||
|
|
@ -651,13 +680,13 @@ export interface OnlyInterface<Context = {}> {
|
|||
* Declare a test that uses one or more macros. Additional arguments are passed to the macro.
|
||||
* Only this test and others declared with `.only()` are run.
|
||||
*/
|
||||
(title: string, macro: Macro<Context> | Macro<Context>[], ...args: Array<any>): void;
|
||||
<ToM extends TitleOrMacro<Context>, MoA extends MacroOrFirstArg<ToM, Context>>(titleOrMacro: ToM, macroOrArg: MoA, ...rest: RestArgs<ToM, MoA, Context>): void;
|
||||
|
||||
/**
|
||||
* Declare a test that uses one or more macros. Additional arguments are passed to the macro. The macro
|
||||
* is responsible for generating a unique test title. Only this test and others declared with `.only()` are run.
|
||||
* Declare a test that uses one or more macros. The macro is responsible for generating a unique test title.
|
||||
* Only this test and others declared with `.only()` are run.
|
||||
*/
|
||||
(macro: Macro<Context> | Macro<Context>[], ...args: Array<any>): void;
|
||||
(macro: OneOrMoreMacros<[], Context>): void
|
||||
}
|
||||
|
||||
export interface SerialInterface<Context = {}> {
|
||||
|
|
@ -665,13 +694,12 @@ export interface SerialInterface<Context = {}> {
|
|||
(title: string, implementation: Implementation<Context>): void;
|
||||
|
||||
/** Declare a serial test that uses one or more macros. Additional arguments are passed to the macro. */
|
||||
(title: string, macro: Macro<Context> | Macro<Context>[], ...args: Array<any>): void;
|
||||
<ToM extends TitleOrMacro<Context>, MoA extends MacroOrFirstArg<ToM, Context>>(titleOrMacro: ToM, macroOrArg: MoA, ...rest: RestArgs<ToM, MoA, Context>): void;
|
||||
|
||||
/**
|
||||
* Declare a serial test that uses one or more macros. Additional arguments are passed to the macro. The macro
|
||||
* is responsible for generating a unique test title.
|
||||
* Declare a serial test that uses one or more macros. The macro is responsible for generating a unique test title.
|
||||
*/
|
||||
(macro: Macro<Context> | Macro<Context>[], ...args: Array<any>): void;
|
||||
(macro: OneOrMoreMacros<[], Context>): void
|
||||
|
||||
/** Declare a serial hook that is run once, after all tests have passed. */
|
||||
after: AfterInterface<Context>;
|
||||
|
|
@ -701,10 +729,10 @@ export interface SkipInterface<Context = {}> {
|
|||
(title: string, implementation: Implementation<Context>): void;
|
||||
|
||||
/** Skip this test. */
|
||||
(title: string, macro: Macro<Context> | Macro<Context>[], ...args: Array<any>): void;
|
||||
<ToM extends TitleOrMacro<Context>, MoA extends MacroOrFirstArg<ToM, Context>>(titleOrMacro: ToM, macroOrArg: MoA, ...rest: RestArgs<ToM, MoA, Context>): void;
|
||||
|
||||
/** Skip this test. */
|
||||
(macro: Macro<Context> | Macro<Context>[], ...args: Array<any>): void;
|
||||
(macro: OneOrMoreMacros<[], Context>): void
|
||||
}
|
||||
|
||||
export interface TodoDeclaration {
|
||||
|
|
@ -747,3 +775,34 @@ export const skip: SkipInterface;
|
|||
|
||||
/** Declare a test that should be implemented later. */
|
||||
export const todo: TodoDeclaration;
|
||||
|
||||
|
||||
/*
|
||||
Tail type from <https://github.com/tycho01/typical/blob/25f11ed92c960aab1ebbf47fd6ead9e0ae51d947/src/array/Tail.ts>.
|
||||
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2017 Thomas Crockett
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
/** Get all but the first element of a tuple. */
|
||||
export type Tail<T extends any[]> =
|
||||
((...args: T) => any) extends ((head: any, ...tail: infer R) => any) ? R : never;
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ interface Context {
|
|||
|
||||
const test = anyTest as TestInterface<Context>;
|
||||
|
||||
const macro: Macro<Context> = (t, expected: string) => {
|
||||
const macro: Macro<[string], Context> = (t, expected) => {
|
||||
t.is(t.context.foo, expected);
|
||||
};
|
||||
|
||||
|
|
|
|||
64
test/ts-types/macros.ts
Normal file
64
test/ts-types/macros.ts
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
import test, {ExecutionContext, Macro} from '../..';
|
||||
|
||||
// Explicitly type as a macro.
|
||||
{
|
||||
const hasLength: Macro<[string, number]> = (t, input, expected) => {
|
||||
t.is(input.length, expected);
|
||||
};
|
||||
|
||||
test('bar has length 3', hasLength, 'bar', 3);
|
||||
test('bar has length 3', [hasLength], 'bar', 3);
|
||||
}
|
||||
|
||||
// Infer macro
|
||||
{
|
||||
const hasLength = (t: ExecutionContext, input: string, expected: number) => {
|
||||
t.is(input.length, expected);
|
||||
};
|
||||
|
||||
test('bar has length 3', hasLength, 'bar', 3);
|
||||
test('bar has length 3', [hasLength], 'bar', 3);
|
||||
}
|
||||
|
||||
// Multiple macros
|
||||
{
|
||||
const hasLength = (t: ExecutionContext, input: string, expected: number) => {
|
||||
t.is(input.length, expected);
|
||||
};
|
||||
const hasCodePoints = (t: ExecutionContext, input: string, expected: number) => {
|
||||
t.is(Array.from(input).length, expected);
|
||||
};
|
||||
|
||||
test('bar has length 3', [hasLength, hasCodePoints], 'bar', 3);
|
||||
}
|
||||
|
||||
// No title
|
||||
{
|
||||
const hasLength: Macro<[string, number]> = (t, input, expected) => {
|
||||
t.is(input.length, expected);
|
||||
};
|
||||
const hasCodePoints: Macro<[string, number]> = (t, input, expected) => {
|
||||
t.is(Array.from(input).length, expected);
|
||||
};
|
||||
|
||||
test(hasLength, 'bar', 3);
|
||||
test([hasLength, hasCodePoints], 'bar', 3);
|
||||
}
|
||||
|
||||
// No arguments
|
||||
{
|
||||
const pass: Macro<[]> = t => t.pass()
|
||||
pass.title = () => 'pass'
|
||||
test(pass)
|
||||
}
|
||||
|
||||
// Inline
|
||||
{
|
||||
test('has length 3', (t: ExecutionContext, input: string, expected: number) => {
|
||||
t.is(input.length, expected)
|
||||
}, 'bar', 3)
|
||||
|
||||
test((t: ExecutionContext, input: string, expected: number) => {
|
||||
t.is(input.length, expected)
|
||||
}, 'bar', 3)
|
||||
}
|
||||
Loading…
Reference in a new issue