Expose snapshot directory through test.meta

Fixes #1984.

Co-authored-by: Mark Wubben <mark@novemberborn.net>
This commit is contained in:
Oskar Löfgren 2020-04-10 16:22:09 +02:00 committed by GitHub
parent 447d37153b
commit cb5f9f7087
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 87 additions and 34 deletions

View file

@ -267,14 +267,19 @@ test('context is unicorn', t => {
});
```
## Retrieving test meta data
## Retrieving test metadata
Helper files can determine the filename of the test being run by reading `test.meta.file`. This eliminates the need to pass `__filename` from the test to helpers.
Access data about the currently loaded test file run by reading `test.meta`.
Available properties:
* `file`: path to the test file
* `snapshotDirectory`: directory where snapshots are stored
```js
const test = require('ava');
console.log('Test currently being run: ', test.meta.file);
console.log('Test file currently being run:', test.meta.file);
```
## Reusing test logic through macros

3
index.d.ts vendored
View file

@ -760,6 +760,9 @@ export interface TodoDeclaration {
export interface MetaInterface {
/** Path to the test file being executed. */
file: string;
/** Directory where snapshots are stored. */
snapshotDirectory: string;
}
/** Call to declare a test, or chain to declare hooks or test modifiers */

View file

@ -54,7 +54,11 @@ class Runner extends Emittery {
let hasStarted = false;
let scheduledStart = false;
const meta = Object.freeze({
file: options.file
file: options.file,
get snapshotDirectory() {
const {file, snapshotDir: fixedLocation, projectDir} = options;
return snapshotManager.determineSnapshotDir({file, fixedLocation, projectDir});
}
});
this.chain = createChain((metadata, testArgs) => { // eslint-disable-line complexity
if (hasStarted) {

View file

@ -11,6 +11,7 @@ const md5Hex = require('md5-hex');
const convertSourceMap = require('convert-source-map');
const slash = require('slash');
const writeFileAtomic = require('write-file-atomic');
const mem = require('mem');
const concordanceOptions = require('./concordance-options').snapshotManager;
@ -388,26 +389,7 @@ class Manager {
}
}
function determineSnapshotDir({file, fixedLocation, projectDir}) {
const testDir = path.dirname(file);
if (fixedLocation) {
const relativeTestLocation = path.relative(projectDir, testDir);
return path.join(fixedLocation, relativeTestLocation);
}
const parts = new Set(path.relative(projectDir, testDir).split(path.sep));
if (parts.has('__tests__')) {
return path.join(testDir, '__snapshots__');
}
if (parts.has('test') || parts.has('tests')) { // Accept tests, even though it's not in the default test patterns
return path.join(testDir, 'snapshots');
}
return testDir;
}
function resolveSourceFile(file) {
const resolveSourceFile = mem(file => {
const testDir = path.dirname(file);
const buffer = tryRead(file);
if (!buffer) {
@ -423,12 +405,32 @@ function resolveSourceFile(file) {
}
return file;
}
});
const determineSnapshotDir = mem(({file, fixedLocation, projectDir}) => {
const testDir = path.dirname(resolveSourceFile(file));
if (fixedLocation) {
const relativeTestLocation = path.relative(projectDir, testDir);
return path.join(fixedLocation, relativeTestLocation);
}
const parts = new Set(path.relative(projectDir, testDir).split(path.sep));
if (parts.has('__tests__')) {
return path.join(testDir, '__snapshots__');
}
if (parts.has('test') || parts.has('tests')) { // Accept tests, even though it's not in the default test patterns
return path.join(testDir, 'snapshots');
}
return testDir;
}, {cacheKey: ([{file}]) => file});
exports.determineSnapshotDir = determineSnapshotDir;
function load({file, fixedLocation, projectDir, recordNewSnapshots, updating}) {
const sourceFile = resolveSourceFile(file);
const dir = determineSnapshotDir({file: sourceFile, fixedLocation, projectDir});
const relFile = path.relative(projectDir, sourceFile);
const dir = determineSnapshotDir({file, fixedLocation, projectDir});
const relFile = path.relative(projectDir, resolveSourceFile(file));
const name = path.basename(relFile);
const reportFile = `${name}.md`;
const snapFile = `${name}.snap`;

33
package-lock.json generated
View file

@ -5105,6 +5105,15 @@
"integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
"dev": true
},
"map-age-cleaner": {
"version": "0.1.3",
"resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz",
"integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==",
"dev": true,
"requires": {
"p-defer": "^1.0.0"
}
},
"map-cache": {
"version": "0.2.2",
"resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz",
@ -5165,6 +5174,24 @@
"safe-buffer": "^5.1.2"
}
},
"mem": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/mem/-/mem-6.0.1.tgz",
"integrity": "sha512-uIRYASflIsXqvKe+7aXbLrydaRzz4qiK6amqZDQI++eRtW3UoKtnDcGeCAOREgll7YMxO5E4VB9+3B0LFmy96g==",
"dev": true,
"requires": {
"map-age-cleaner": "^0.1.3",
"mimic-fn": "^3.0.0"
},
"dependencies": {
"mimic-fn": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-3.0.0.tgz",
"integrity": "sha512-PiVO95TKvhiwgSwg1IdLYlCTdul38yZxZMIcnDSFIBUm4BNZha2qpQ4GpJ++15bHoKDtrW2D69lMfFwdFYtNZQ==",
"dev": true
}
}
},
"memory-fs": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.2.0.tgz",
@ -5938,6 +5965,12 @@
"resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz",
"integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw=="
},
"p-defer": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz",
"integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=",
"dev": true
},
"p-event": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/p-event/-/p-event-4.1.0.tgz",

View file

@ -116,6 +116,7 @@
"esm": "^3.2.25",
"execa": "^4.0.0",
"get-stream": "^5.1.0",
"mem": "^6.0.1",
"nyc": "^15.0.1",
"p-event": "^4.1.0",
"proxyquire": "^2.1.3",

View file

@ -30,12 +30,12 @@ function apiCreator(options = {}) {
return instance;
}
test('test.meta.file', t => {
const api = apiCreator();
test('test.meta', t => {
const api = apiCreator({snapshotDir: 'snapshot-fixture'});
return api.run({files: [path.join(__dirname, 'fixture/meta.js')]})
return api.run({files: [path.join(__dirname, 'fixture', 'meta.js')]})
.then(runStatus => {
t.is(runStatus.stats.passedTests, 2);
t.is(runStatus.stats.passedTests, 3);
});
});

View file

@ -1,9 +1,14 @@
const {default: test, meta} = require('../..');
test('meta is test.meta', t => {
t.is(meta, test.meta);
});
test('meta.file', t => {
t.is(meta.file, __filename);
});
test('test.meta.file', t => {
t.is(test.meta.file, __filename);
test('meta.snapshotDirectory', t => {
t.regex(meta.snapshotDirectory, /snapshot-fixture/);
});