Test AVA using AVA

This commit is contained in:
Mark Wubben 2020-04-27 15:09:58 +02:00
parent a5385a4168
commit c8f31a39ca
18 changed files with 259 additions and 5 deletions

View file

@ -1,7 +1,7 @@
{
"all": true,
"exclude": [
"{coverage,media,test-d,test-tap}/**",
"{coverage,media,test,test-d,test-tap}/**",
"*.config.js",
"index.d.ts"
],

View file

@ -59,7 +59,7 @@ Try and avoid making breaking changes. Those take more time to ship. Instead mak
Non-experimental features should be accompanied with tests and documentation.
Don't include unrelated changes in your pull request. Make sure tests pass on your machine by running `npm test`. You can run specific test files as well using `npx tap test-tap/{file}.js`.
Don't include unrelated changes in your pull request. Make sure tests pass on your machine by running `npm test`. You can run specific test files as well using `npx tap test-tap/{file}.js` or `npx test-ava test/{file}.js`.
When you make a pull request please use a clear and descriptive title. Be specific about what's changed and why.

7
.gitignore vendored
View file

@ -1,2 +1,5 @@
node_modules
coverage
/coverage
/media/**/node_modules/
/node_modules/
/test-tap/**/node_modules/
/test/**/fixtures/**/node_modules/*/

4
ava.config.js Normal file
View file

@ -0,0 +1,4 @@
export default {
files: ['test/**', '!test/**/{fixtures,helpers}/**'],
ignoredByWatcher: ['{coverage,docs,media,test-d,test-tap}/**']
};

View file

@ -410,6 +410,19 @@ exports.run = async () => { // eslint-disable-line complexity
api.on('run', plan => {
reporter.startRun(plan);
if (process.env.AVA_EMIT_RUN_STATUS_OVER_IPC === 'I\'ll find a payphone baby / Take some time to talk to you') {
if (process.versions.node >= '12.16.0') {
plan.status.on('stateChange', evt => {
process.send(evt);
});
} else {
const v8 = require('v8');
plan.status.on('stateChange', evt => {
process.send([...v8.serialize(evt)]);
});
}
}
plan.status.on('stateChange', evt => {
if (evt.type === 'interrupt') {
reporter.endRun();

View file

@ -8,6 +8,7 @@
* `npm test`: Lint the code and run the entire test suite with coverage.
* `npx tap test-tap/fork.js --bail`: Run a specific test file and bail on the first failure (useful when hunting bugs).
* `npx test-ava test/{file}.js`: Run self-hosted tests.
## CI

71
package-lock.json generated
View file

@ -47,6 +47,77 @@
"integrity": "sha512-N7w4g+P/SUL8SF+HC4Z4e/ctV6nQ5AERC90K90r4xZQ8WVrJux9albvfyYAzygyU47CSqMWh6yJwFs8DYaeWmg==",
"dev": true
},
"@ava/test": {
"version": "github:avajs/test#46dbf16d19cccfdb5b599fb80ec3baf97ceb9605",
"from": "github:avajs/test",
"dev": true,
"requires": {
"@ava/v3": "npm:ava@^3.8.1"
}
},
"@ava/v3": {
"version": "npm:ava@3.8.1",
"resolved": "https://registry.npmjs.org/ava/-/ava-3.8.1.tgz",
"integrity": "sha512-OPWrTxcf1EbtAaGGFQPLbx4AaVqPrFMumKOKn2SzIRo+RTKb33lF2aoVnWqBeZaJ68uSc9R6jqIE7qkG6O33uQ==",
"dev": true,
"requires": {
"@concordance/react": "^2.0.0",
"acorn": "^7.1.1",
"acorn-walk": "^7.1.1",
"ansi-styles": "^4.2.1",
"arrgv": "^1.0.2",
"arrify": "^2.0.1",
"callsites": "^3.1.0",
"chalk": "^4.0.0",
"chokidar": "^3.4.0",
"chunkd": "^2.0.1",
"ci-info": "^2.0.0",
"ci-parallel-vars": "^1.0.0",
"clean-yaml-object": "^0.1.0",
"cli-cursor": "^3.1.0",
"cli-truncate": "^2.1.0",
"code-excerpt": "^2.1.1",
"common-path-prefix": "^3.0.0",
"concordance": "^4.0.0",
"convert-source-map": "^1.7.0",
"currently-unhandled": "^0.4.1",
"debug": "^4.1.1",
"del": "^5.1.0",
"emittery": "^0.6.0",
"equal-length": "^1.0.0",
"figures": "^3.2.0",
"globby": "^11.0.0",
"ignore-by-default": "^1.0.0",
"import-local": "^3.0.2",
"indent-string": "^4.0.0",
"is-error": "^2.2.2",
"is-plain-object": "^3.0.0",
"is-promise": "^3.0.0",
"lodash": "^4.17.15",
"matcher": "^3.0.0",
"md5-hex": "^3.0.1",
"mem": "^6.1.0",
"ms": "^2.1.2",
"ora": "^4.0.4",
"p-map": "^4.0.0",
"picomatch": "^2.2.2",
"pkg-conf": "^3.1.0",
"plur": "^4.0.0",
"pretty-ms": "^6.0.1",
"read-pkg": "^5.2.0",
"resolve-cwd": "^3.0.0",
"slash": "^3.0.0",
"source-map-support": "^0.5.19",
"stack-utils": "^2.0.1",
"strip-ansi": "^6.0.0",
"supertap": "^1.0.0",
"temp-dir": "^2.0.0",
"trim-off-newlines": "^1.0.1",
"update-notifier": "^4.1.0",
"write-file-atomic": "^3.0.3",
"yargs": "^15.3.1"
}
},
"@babel/code-frame": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz",

View file

@ -10,7 +10,7 @@
"node": ">=10.18.0 <11 || >=12.14.0 <13 || >=13.5.0 <14 || >=14.0.0"
},
"scripts": {
"test": "xo && tsd && c8 tap"
"test": "xo && tsd && c8 --report=none tap && c8 --report=none --no-clean test-ava && c8 report"
},
"files": [
"lib",
@ -113,6 +113,7 @@
},
"devDependencies": {
"@ava/babel": "^1.0.1",
"@ava/test": "github:avajs/test",
"@babel/plugin-proposal-do-expressions": "^7.8.3",
"@sinonjs/fake-timers": "^6.0.1",
"ansi-escapes": "^4.3.1",

7
test/README.md Normal file
View file

@ -0,0 +1,7 @@
# Self-hosted tests
This directory contains tests that are run using a stable version of AVA. You can run them using `npx test-ava`.
Tests should be placed in their own directory, grouped by area of responsibility. Use the `exec.fixture()` helper to launch the AVA version that is in the repository to run tests. Place these in a nested `fixtures` directory. Add a relative dependency in `package.json`. You can then import from `ava`.
Prefer snapshotting the test results.

View file

@ -0,0 +1,29 @@
const test = require('ava');
const passes = async (t, assertion, ...args) => {
await t[assertion](...args);
};
passes.title = (_, assertion, ...args) => `t.${assertion}(${args.map(v => JSON.stringify(v)).join(', ')}) passes`;
test(passes, 'pass');
test(passes, 'is', 1, 1);
test(passes, 'not', 1, 2);
test(passes, 'deepEqual', {foo: 'bar'}, {foo: 'bar'});
test(passes, 'notDeepEqual', {foo: 'bar'}, {foo: 'baz'});
test(passes, 'throws', () => {
throw new Error('error');
});
test(passes, 'throwsAsync', async () => {
throw new Error('error');
});
test(passes, 'notThrows', () => {});
test(passes, 'notThrowsAsync', async () => {});
test(passes, 'snapshot', {foo: 'bar'});
test(passes, 'truthy', 1);
test(passes, 'falsy', '');
test(passes, 'true', true);
test(passes, 'false', false);
test(passes, 'regex', 'foo', /foo/);
test(passes, 'notRegex', 'bar', /foo/);
test(passes, 'assert', 1);

View file

@ -0,0 +1,13 @@
# Snapshot report for `happy-path.js`
The actual snapshot is saved in `happy-path.js.snap`.
Generated by [AVA](https://avajs.dev).
## t.snapshot({"foo":"bar"}) passes
> Snapshot 1
{
foo: 'bar',
}

Binary file not shown.

View file

@ -0,0 +1,10 @@
{
"ava": {
"files": [
"*.js"
]
},
"dependencies": {
"ava": "file:../../.."
}
}

View file

@ -0,0 +1,29 @@
# Snapshot report for `test/assertions/test.js`
The actual snapshot is saved in `test.js.snap`.
Generated by [AVA](https://avajs.dev).
## happy path
> Snapshot 1
[
't.assert(1) passes',
't.deepEqual({"foo":"bar"}, {"foo":"bar"}) passes',
't.false(false) passes',
't.falsy("") passes',
't.is(1, 1) passes',
't.not(1, 2) passes',
't.notDeepEqual({"foo":"bar"}, {"foo":"baz"}) passes',
't.notRegex("bar", {}) passes',
't.notThrows() passes',
't.notThrowsAsync() passes',
't.pass() passes',
't.regex("foo", {}) passes',
't.snapshot({"foo":"bar"}) passes',
't.throws() passes',
't.throwsAsync() passes',
't.true(true) passes',
't.truthy(1) passes',
]

Binary file not shown.

7
test/assertions/test.js Normal file
View file

@ -0,0 +1,7 @@
const test = require('@ava/test');
const exec = require('../helpers/exec');
test('happy path', async t => {
const result = await exec.fixture('happy-path.js');
t.snapshot(result.stats.passed.map(({title}) => title));
});

65
test/helpers/exec.js Normal file
View file

@ -0,0 +1,65 @@
const path = require('path');
const v8 = require('v8');
const test = require('@ava/test');
const execa = require('execa');
const cliPath = path.resolve(__dirname, '../../cli.js');
const serialization = process.versions.node >= '12.16.0' ? 'advanced' : 'json';
exports.fixture = async (...args) => {
const cwd = path.join(path.dirname(test.meta.file), 'fixtures');
const running = execa.node(cliPath, args, {
env: {
AVA_EMIT_RUN_STATUS_OVER_IPC: 'I\'ll find a payphone baby / Take some time to talk to you'
},
cwd,
serialization
});
const stats = {
passed: []
};
running.on('message', message => {
if (serialization === 'json') {
message = v8.deserialize(Uint8Array.from(message));
}
switch (message.type) {
case 'test-passed': {
const {title, testFile} = message;
stats.passed.push({title, file: path.posix.relative(cwd, testFile)});
break;
}
default:
break;
}
});
try {
return {
stats,
...await running
};
} catch (error) {
throw Object.assign(error, {stats});
} finally {
stats.passed.sort((a, b) => {
if (a.file < b.file) {
return -1;
}
if (a.file > b.file) {
return 1;
}
if (a.title < b.title) {
return -1;
}
return 1;
});
}
};

1
test/node_modules/ava generated vendored Symbolic link
View file

@ -0,0 +1 @@
../../