Skip to content

Restrict modifier chaining #1670

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Feb 4, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 83 additions & 0 deletions docs/recipes/flow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
# Flow

AVA comes bundled with a Flow definition file. This allows developers to leverage Flow for writing tests.

This guide assumes you've already set up Flow for your project. Note that AVA's definition as been tested with version 0.64.

We recommend you use AVA's built-in Babel pipeline to strip Flow type annotations and declarations. AVA automatically applies your project's Babel configuration, so everything may just work without changes. Alternatively install [`@babel/plugin-transform-flow-strip-types`](https://www.npmjs.com/package/@babel/plugin-transform-flow-strip-types) and customize AVA's configuration in the `package.json` file as follows:

```json
{
"ava": {
"babel": {
"testOptions": {
"plugins": ["@babel/plugin-transform-flow-strip-types"]
}
}
}
}
```

See our [Babel documentation](babel.md) for more details.

## Writing tests

Create a `test.js` file.

```js
// @flow
import test from 'ava';

const fn = async () => Promise.resolve('foo');

test(async (t) => {
t.is(await fn(), 'foo');
});
```

## Typing [`t.context`](https://github.com/avajs/ava#test-context)

By default, the type of `t.context` will be the empty object (`{}`). AVA exposes an interface `TestInterface<Context>` which you can use to apply your own type to `t.context`. This can help you catch errors at compile-time:

```js
// @flow
import anyTest from 'ava';
import type {TestInterface} from 'ava';

const test: TestInterface<{foo: string}> = (anyTest: any);

test.beforeEach(t => {
t.context = {foo: 'bar'};
});

test.beforeEach(t => {
t.context.foo = 123; // error: Type '123' is not assignable to type 'string'
});

test.serial.cb.failing('very long chains are properly typed', t => {
t.context.fooo = 'a value'; // error: Property 'fooo' does not exist on type ''
});

test('an actual test', t => {
t.deepEqual(t.context.foo.map(c => c), ['b', 'a', 'r']); // error: Property 'map' does not exist on type 'string'
});
```

Note that, despite the type cast above, when executing `t.context` is an empty object unless it's assigned.

## Using `t.throws()` and `t.notThrows()`

The `t.throws()` and `t.noThrows()` assertions can be called with a function that returns an observable or a promise. You may have to explicitly type functions:

```ts
import test from 'ava';

test('just throws', async t => {
const expected = new Error();
const err = t.throws((): void => { throw expected; });
t.is(err, expected);

const err2 = await t.throws((): Promise<*> => Promise.reject(expected));
t.is(err2, expected);
});
```
95 changes: 51 additions & 44 deletions docs/recipes/typescript.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,7 @@ Translations: [Español](https://github.com/avajs/ava-docs/blob/master/es_ES/doc

AVA comes bundled with a TypeScript definition file. This allows developers to leverage TypeScript for writing tests.


## Setup

First install [TypeScript](https://github.com/Microsoft/TypeScript) (if you already have it installed, make sure you use version 2.1 or greater).

```
$ npm install --save-dev typescript
```

Create a [`tsconfig.json`](http://www.typescriptlang.org/docs/handbook/tsconfig-json.html) file. This file specifies the compiler options required to compile the project or the test file.

```json
{
"compilerOptions": {
"module": "commonjs",
"target": "es2015",
"sourceMap": true
}
}
```
This guide assumes you've already set up TypeScript for your project. Note that AVA's definition has been tested with version 2.7.1.

Add a `test` script in the `package.json` file. It will compile the project first and then run AVA.

Expand All @@ -35,8 +16,9 @@ Add a `test` script in the `package.json` file. It will compile the project firs
}
```

Make sure that AVA runs your built TypeScript files.

## Add tests
## Writing tests

Create a `test.ts` file.

Expand All @@ -50,57 +32,82 @@ test(async (t) => {
});
```

## Working with [macros](https://github.com/avajs/ava#test-macros)
## Using [macros](https://github.com/avajs/ava#test-macros)

In order to be able to assign the `title` property to a macro:
In order to be able to assign the `title` property to a macro you need to type the function:

```ts
import test, { AssertContext, Macro } from 'ava';
import test, {Macro} from 'ava';

const macro: Macro<AssertContext> = (t, input, expected) => {
const macro: Macro = (t, input: string, expected: number) => {
t.is(eval(input), expected);
}

macro.title = (providedTitle, input, expected) => `${providedTitle} ${input} = ${expected}`.trim();
};
macro.title = (providedTitle: string, input: string, expected: number) => `${providedTitle} ${input} = ${expected}`.trim();

test(macro, '2 + 2', 4);
test(macro, '2 * 3', 6);
test('providedTitle', macro, '3 * 3', 9);
```

## Working with [`context`](https://github.com/avajs/ava#test-context)

By default, the type of `t.context` will be [`any`](https://www.typescriptlang.org/docs/handbook/basic-types.html#any). AVA exposes an interface `RegisterContextual<T>` which you can use to apply your own type to `t.context`. This can help you catch errors at compile-time:
You'll need a different type if you're expecting your macro to be used with a callback test:

```ts
import * as ava from 'ava';
import test, {CbMacro} from 'ava';

function contextualize<T>(getContext: () => T): ava.RegisterContextual<T> {
ava.test.beforeEach(t => {
Object.assign(t.context, getContext());
});
const macro: CbMacro = t => {
t.pass();
setTimeout(t.end, 100);
};

return ava.test;
}
test.cb(macro);
```

const test = contextualize(() => ({ foo: 'bar' }));
## Typing [`t.context`](https://github.com/avajs/ava#test-context)

By default, the type of `t.context` will be the empty object (`{}`). AVA exposes an interface `TestInterface<Context>` which you can use to apply your own type to `t.context`. This can help you catch errors at compile-time:

```ts
import anyTest, {TestInterface} from 'ava';

const test: TestInterface<{foo: string}> = anyTest;

test.beforeEach(t => {
t.context = {foo: 'bar'};
});

test.beforeEach(t => {
t.context.foo = 123; // error: Type '123' is not assignable to type 'string'
});

test.after.always.failing.cb.serial('very long chains are properly typed', t => {
t.context.fooo = 'a value'; // error: Property 'fooo' does not exist on type '{ foo: string }'
test.serial.cb.failing('very long chains are properly typed', t => {
t.context.fooo = 'a value'; // error: Property 'fooo' does not exist on type ''
});

test('an actual test', t => {
t.deepEqual(t.context.foo.map(c => c), ['b', 'a', 'r']); // error: Property 'map' does not exist on type 'string'
});
```

You can also type the context when creating macros:

## Execute the tests
```ts
import anyTest, {Macro, TestInterface} from 'ava';

interface Context {
foo: string
}

const test: TestInterface<Context> = anyTest;

const macro: Macro<Context> = (t, expected: string) => {
t.is(t.context.foo, expected);
};

test.beforeEach(t => {
t.context = {foo: 'bar'};
});

test('foo is bar', macro, 'bar');
```
$ npm test
```

Note that, despite the type cast above, when executing `t.context` is an empty object unless it's assigned.
Loading