Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: avajs/ava
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v3.5.2
Choose a base ref
...
head repository: avajs/ava
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: v3.6.0
Choose a head ref
  • 7 commits
  • 19 files changed
  • 3 contributors

Commits on Apr 4, 2020

  1. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    ede4f32 View commit details
  2. Add t.passed to execution contexts

    In `afterEach` hooks, consult `t.passed` to determine whether the test passed.
    
    Fixes #840.
    
    Co-authored-by: Mark Wubben <mark@novemberborn.net>
    bunysae and novemberborn authored Apr 4, 2020

    Partially verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    We cannot verify signatures from co-authors, and some of the co-authors attributed to this commit require their commits to be signed.
    Copy the full SHA
    8f312c0 View commit details
  3. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    4bf64d0 View commit details
  4. Unverified

    This commit is not signed, but one or more authors requires that any commit attributed to them is signed.
    Copy the full SHA
    489b13e View commit details

Commits on Apr 5, 2020

  1. Dependency updates

    * Remove ts-node related tests
    
    * Remove unused lolex dependency
    
    * Update dev dependencies
    
    * Update dependencies
    novemberborn authored Apr 5, 2020

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    1f59b05 View commit details
  2. Rebuild lockfile

    novemberborn authored Apr 5, 2020

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    886b4d7 View commit details
  3. 3.6.0

    novemberborn committed Apr 5, 2020

    Verified

    This commit was signed with the committer’s verified signature.
    novemberborn Mark Wubben
    Copy the full SHA
    447d371 View commit details
4 changes: 4 additions & 0 deletions docs/02-execution-context.md
Original file line number Diff line number Diff line change
@@ -22,6 +22,10 @@ The test title.

Contains shared state from hooks.

## `t.passed`

Whether a test has passed. This value is only accurate in the `test.afterEach()` and `test.afterEach.always()` hooks.

## `t.plan(count)`

Plan how many assertion there are in the test. The test will fail if the actual assertion count doesn't match the number of planned assertions. See [assertion planning](./03-assertions.md#assertion-planning).
2 changes: 1 addition & 1 deletion docs/recipes/endpoint-testing.md
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@

Translations: [Español](https://github.com/avajs/ava-docs/blob/master/es_ES/docs/recipes/endpoint-testing.md), [Français](https://github.com/avajs/ava-docs/blob/master/fr_FR/docs/recipes/endpoint-testing.md), [Italiano](https://github.com/avajs/ava-docs/blob/master/it_IT/docs/recipes/endpoint-testing.md), [日本語](https://github.com/avajs/ava-docs/blob/master/ja_JP/docs/recipes/endpoint-testing.md), [Português](https://github.com/avajs/ava-docs/blob/master/pt_BR/docs/recipes/endpoint-testing.md), [Русский](https://github.com/avajs/ava-docs/blob/master/ru_RU/docs/recipes/endpoint-testing.md), [简体中文](https://github.com/avajs/ava-docs/blob/master/zh_CN/docs/recipes/endpoint-testing.md)

AVA doesn't have a built-in method for testing endpoints, but you can use any HTTP client of your choosing, for example [`got`](https://github.com/sindresorhus/got). You'll also need to start an HTTP server, preferrably on a unique port so that you can run tests in parallel. For that we recommend [`test-listen`](https://github.com/zeit/test-listen).
AVA doesn't have a built-in method for testing endpoints, but you can use any HTTP client of your choosing, for example [`got`](https://github.com/sindresorhus/got). You'll also need to start an HTTP server, preferably on a unique port so that you can run tests in parallel. For that we recommend [`test-listen`](https://github.com/zeit/test-listen).

Since tests run concurrently, it's best to create a fresh server instance at least for each test file, but perhaps even for each test. This can be accomplished with `test.before()` and `test.beforeEach()` hooks and `t.context`. If you start your server using a `test.before()` hook you should make sure to execute your tests serially.

19 changes: 11 additions & 8 deletions index.d.ts
Original file line number Diff line number Diff line change
@@ -308,6 +308,9 @@ export interface ExecutionContext<Context = unknown> extends Assertions {
/** Title of the test or hook. */
readonly title: string;

/** Whether the test has passed. Only accurate in afterEach hooks. */
readonly passed: boolean;

log: LogFn;
plan: PlanFn;
timeout: TimeoutFn;
@@ -343,29 +346,29 @@ export interface TimeoutFn {

export interface TryFn<Context = unknown> {
/**
* Requires opt-in. Attempt to run some assertions. The result must be explicitly committed or discarded or else
* Attempt to run some assertions. The result must be explicitly committed or discarded or else
* the test will fail. A macro may be provided. The title may help distinguish attempts from
* one another.
*/
<Args extends any[]>(title: string, fn: EitherMacro<Args, Context>, ...args: Args): Promise<TryResult>;

/**
* Requires opt-in. Attempt to run some assertions. The result must be explicitly committed or discarded or else
* Attempt to run some assertions. The result must be explicitly committed or discarded or else
* the test will fail. A macro may be provided. The title may help distinguish attempts from
* one another.
*/
<Args extends any[]>(title: string, fn: [EitherMacro<Args, Context>, ...Array<EitherMacro<Args, Context>>], ...args: Args): Promise<TryResult[]>;

/**
* Requires opt-in. Attempt to run some assertions. The result must be explicitly committed or discarded or else
* the test will fail. A macro may be provided.
*/
* Attempt to run some assertions. The result must be explicitly committed or discarded or else
* the test will fail. A macro may be provided.
*/
<Args extends any[]>(fn: EitherMacro<Args, Context>, ...args: Args): Promise<TryResult>;

/**
* Requires opt-in. Attempt to run some assertions. The result must be explicitly committed or discarded or else
* the test will fail. A macro may be provided.
*/
* Attempt to run some assertions. The result must be explicitly committed or discarded or else
* the test will fail. A macro may be provided.
*/
<Args extends any[]>(fn: [EitherMacro<Args, Context>, ...Array<EitherMacro<Args, Context>>], ...args: Args): Promise<TryResult[]>;
}

23 changes: 14 additions & 9 deletions lib/runner.js
Original file line number Diff line number Diff line change
@@ -266,7 +266,7 @@ class Runner extends Emittery {
return result;
}

async runHooks(tasks, contextRef, titleSuffix) {
async runHooks(tasks, contextRef, titleSuffix, testPassed) {
const hooks = tasks.map(task => new Runnable({
contextRef,
experiments: this.experiments,
@@ -278,7 +278,8 @@ class Runner extends Emittery {
updateSnapshots: this.updateSnapshots,
metadata: task.metadata,
powerAssert: this.powerAssert,
title: `${task.title}${titleSuffix || ''}`
title: `${task.title}${titleSuffix || ''}`,
testPassed
}));
const outcome = await this.runMultiple(hooks, this.serial);
for (const result of outcome.storedResults) {
@@ -304,10 +305,11 @@ class Runner extends Emittery {
}

async runTest(task, contextRef) {
let hooksAndTestOk = false;

const hookSuffix = ` for ${task.title}`;
if (await this.runHooks(this.tasks.beforeEach, contextRef, hookSuffix)) {
let hooksOk = await this.runHooks(this.tasks.beforeEach, contextRef, hookSuffix);

let testOk = false;
if (hooksOk) {
// Only run the test if all `beforeEach` hooks passed.
const test = new Runnable({
contextRef,
@@ -325,15 +327,18 @@ class Runner extends Emittery {
});

const result = await this.runSingle(test);
if (result.passed) {
testOk = result.passed;

if (testOk) {
this.emit('stateChange', {
type: 'test-passed',
title: result.title,
duration: result.duration,
knownFailing: result.metadata.failing,
logs: result.logs
});
hooksAndTestOk = await this.runHooks(this.tasks.afterEach, contextRef, hookSuffix);

hooksOk = await this.runHooks(this.tasks.afterEach, contextRef, hookSuffix, testOk);
} else {
this.emit('stateChange', {
type: 'test-failed',
@@ -347,8 +352,8 @@ class Runner extends Emittery {
}
}

const alwaysOk = await this.runHooks(this.tasks.afterEachAlways, contextRef, hookSuffix);
return hooksAndTestOk && alwaysOk;
const alwaysOk = await this.runHooks(this.tasks.afterEachAlways, contextRef, hookSuffix, testOk);
return alwaysOk && hooksOk && testOk;
}

async start() {
5 changes: 5 additions & 0 deletions lib/test.js
Original file line number Diff line number Diff line change
@@ -174,6 +174,10 @@ class ExecutionContext extends assert.Assertions {
testMap.get(this).contextRef.set(context);
}

get passed() {
return testMap.get(this).testPassed;
}

_throwsArgStart(assertion, file, line) {
testMap.get(this).trackThrows({assertion, file, line});
}
@@ -192,6 +196,7 @@ class Test {
this.metadata = options.metadata;
this.powerAssert = options.powerAssert;
this.title = options.title;
this.testPassed = options.testPassed;
this.registerUniqueTitle = options.registerUniqueTitle;
this.logs = [];

1,316 changes: 730 additions & 586 deletions package-lock.json

Large diffs are not rendered by default.

38 changes: 18 additions & 20 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "ava",
"version": "3.5.2",
"version": "3.6.0",
"description": "Testing can be a drag. AVA helps you get it done.",
"license": "MIT",
"repository": "avajs/ava",
@@ -59,7 +59,7 @@
"ansi-styles": "^4.2.1",
"arrgv": "^1.0.2",
"arrify": "^2.0.1",
"chalk": "^3.0.0",
"chalk": "^4.0.0",
"chokidar": "^3.3.1",
"chunkd": "^2.0.1",
"ci-info": "^2.0.0",
@@ -75,9 +75,9 @@
"currently-unhandled": "^0.4.1",
"debug": "^4.1.1",
"del": "^5.1.0",
"emittery": "^0.5.1",
"emittery": "^0.6.0",
"equal-length": "^1.0.0",
"figures": "^3.1.0",
"figures": "^3.2.0",
"globby": "^11.0.0",
"ignore-by-default": "^1.0.0",
"import-local": "^3.0.2",
@@ -90,11 +90,11 @@
"md5-hex": "^3.0.1",
"ms": "^2.1.2",
"ora": "^4.0.3",
"p-map": "^3.0.0",
"picomatch": "^2.2.1",
"p-map": "^4.0.0",
"picomatch": "^2.2.2",
"pkg-conf": "^3.1.0",
"plur": "^4.0.0",
"pretty-ms": "^6.0.0",
"pretty-ms": "^6.0.1",
"read-pkg": "^5.2.0",
"resolve-cwd": "^3.0.0",
"slash": "^3.0.0",
@@ -105,34 +105,32 @@
"temp-dir": "^2.0.0",
"trim-off-newlines": "^1.0.1",
"update-notifier": "^4.1.0",
"write-file-atomic": "^3.0.1",
"yargs": "^15.1.0"
"write-file-atomic": "^3.0.3",
"yargs": "^15.3.1"
},
"devDependencies": {
"@ava/babel": "^1.0.1",
"@sinonjs/fake-timers": "^6.0.0",
"ansi-escapes": "^4.3.0",
"@sinonjs/fake-timers": "^6.0.1",
"ansi-escapes": "^4.3.1",
"delay": "^4.3.0",
"esm": "^3.2.25",
"execa": "^4.0.0",
"get-stream": "^5.1.0",
"lolex": "^5.1.2",
"nyc": "^15.0.0",
"nyc": "^15.0.1",
"p-event": "^4.1.0",
"proxyquire": "^2.1.3",
"react": "^16.12.0",
"react-test-renderer": "^16.12.0",
"react": "^16.13.1",
"react-test-renderer": "^16.13.1",
"replace-string": "^3.0.0",
"sinon": "^8.1.1",
"sinon": "^9.0.1",
"source-map-fixtures": "^2.1.0",
"tap": "^14.10.6",
"tap": "^14.10.7",
"temp-write": "^4.0.0",
"tempy": "^0.4.0",
"tempy": "^0.5.0",
"touch": "^3.1.0",
"ts-node": "^8.6.2",
"tsd": "^0.11.0",
"typescript": "^3.7.5",
"xo": "^0.28.1",
"xo": "^0.28.2",
"zen-observable": "^0.8.15"
},
"xo": {
1 change: 0 additions & 1 deletion readme.md
Original file line number Diff line number Diff line change
@@ -156,7 +156,6 @@ We have a growing list of [common pitfalls](docs/08-common-pitfalls.md) you may
- [Passing arguments to your test files](docs/recipes/passing-arguments-to-your-test-files.md)
- [Testing React components](docs/recipes/react.md)
- [Testing Vue.js components](docs/recipes/vue.md)
- [JSPM and SystemJS](docs/recipes/jspm-systemjs.md)
- [Debugging tests with Chrome DevTools](docs/recipes/debugging-with-chrome-devtools.md)
- [Debugging tests with VSCode](docs/recipes/debugging-with-vscode.md)
- [Debugging tests with WebStorm](docs/recipes/debugging-with-webstorm.md)
2 changes: 0 additions & 2 deletions test-tap/fixture/report/typescript/build-error.ts

This file was deleted.

1 change: 0 additions & 1 deletion test-tap/fixture/report/typescript/package.json

This file was deleted.

5 changes: 0 additions & 5 deletions test-tap/fixture/report/typescript/tsconfig.json

This file was deleted.

6 changes: 0 additions & 6 deletions test-tap/fixture/ts-node/package.json

This file was deleted.

5 changes: 0 additions & 5 deletions test-tap/fixture/ts-node/test.ts

This file was deleted.

10 changes: 1 addition & 9 deletions test-tap/helper/report.js
Original file line number Diff line number Diff line change
@@ -94,20 +94,13 @@ const run = (type, reporter, match = []) => {
snapshotDir: false,
chalkOptions: {level: 1}
};
let pattern = '*.js';

if (type === 'typescript') {
options.extensions.push('ts');
options.require = ['ts-node/register'];
pattern = '*.ts';
}

options.globs = normalizeGlobs({extensions: options.extensions, providers: []});

const api = createApi(options);
api.on('run', plan => reporter.startRun(plan));

const files = globby.sync(pattern, {
const files = globby.sync('*.js', {
absolute: true,
brace: true,
case: false,
@@ -149,5 +142,4 @@ exports.timeoutInSingleFile = reporter => run('timeoutInSingleFile', reporter);
exports.timeoutInMultipleFiles = reporter => run('timeoutInMultipleFiles', reporter);
exports.timeoutWithMatch = reporter => run('timeoutWithMatch', reporter, ['*needle*']);
exports.watch = reporter => run('watch', reporter);
exports.typescript = reporter => run('typescript', reporter);
exports.edgeCases = reporter => run('edgeCases', reporter);
84 changes: 84 additions & 0 deletions test-tap/hooks.js
Original file line number Diff line number Diff line change
@@ -371,6 +371,90 @@ test('afterEach.always run even if beforeEach failed', t => {
});
});

test('afterEach: property `passed` of execution-context is false when test failed and true when test passed', t => {
t.plan(1);

const passed = [];
let i;
return promiseEnd(new Runner(), runner => {
runner.chain.afterEach(a => {
passed[i] = a.passed;
});

runner.chain('failure', () => {
i = 0;
throw new Error('something went wrong');
});
runner.chain('pass', a => {
i = 1;
a.pass();
});
}).then(() => {
t.strictDeepEqual(passed, [undefined, true]);
});
});

test('afterEach.always: property `passed` of execution-context is false when test failed and true when test passed', t => {
t.plan(1);

const passed = [];
let i;
return promiseEnd(new Runner(), runner => {
runner.chain.afterEach.always(a => {
passed[i] = a.passed;
});

runner.chain('failure', () => {
i = 0;
throw new Error('something went wrong');
});
runner.chain('pass', a => {
i = 1;
a.pass();
});
}).then(() => {
t.strictDeepEqual(passed, [false, true]);
});
});

test('afterEach.always: property `passed` of execution-context is false when before hook failed', t => {
t.plan(1);

let passed;
return promiseEnd(new Runner(), runner => {
runner.chain.before(() => {
throw new Error('something went wrong');
});
runner.chain.afterEach.always(a => {
passed = a.passed;
});
runner.chain('pass', a => {
a.pass();
});
}).then(() => {
t.false(passed);
});
});

test('afterEach.always: property `passed` of execution-context is true when test passed and afterEach hook failed', t => {
t.plan(1);

let passed;
return promiseEnd(new Runner(), runner => {
runner.chain.afterEach(() => {
throw new Error('something went wrong');
});
runner.chain.afterEach.always(a => {
passed = a.passed;
});
runner.chain('pass', a => {
a.pass();
});
}).then(() => {
t.true(passed);
});
});

test('ensure hooks run only around tests', t => {
t.plan(1);

1 change: 0 additions & 1 deletion test-tap/reporters/mini.js
Original file line number Diff line number Diff line change
@@ -46,5 +46,4 @@ test('mini reporter - failFast run', run('failFast'));
test('mini reporter - second failFast run', run('failFast2'));
test('mini reporter - only run', run('only'));
test('mini reporter - watch mode run', run('watch'));
test('mini reporter - typescript', run('typescript', [report.sanitizers.lineEndings]));
test('mini reporter - edge cases', run('edgeCases'));
16 changes: 0 additions & 16 deletions test-tap/reporters/mini.typescript.log

This file was deleted.

1 change: 0 additions & 1 deletion test-tap/reporters/verbose.js
Original file line number Diff line number Diff line change
@@ -35,7 +35,6 @@ test('verbose reporter - failFast run', run('failFast'));
test('verbose reporter - second failFast run', run('failFast2'));
test('verbose reporter - only run', run('only'));
test('verbose reporter - watch mode run', run('watch'));
test('verbose reporter - typescript', run('typescript', [report.sanitizers.lineEndings]));
test('verbose reporter - edge cases', run('edgeCases'));

test('verbose reporter - timeout', t => {
14 changes: 0 additions & 14 deletions test-tap/reporters/verbose.typescript.log

This file was deleted.