Skip to content

Commit ebd572a

Browse files
committed
Determine snapshot directory by where the test is located
Tests inside a `__tests__` directory have their snapshots written to a `__snapshots__` directory. Tests inside a `test` or `tests` directory have their snapshots written to a `snapshots` directory. All other tests have their snapshots colocated.
1 parent dbc78dc commit ebd572a

File tree

11 files changed

+111
-39
lines changed

11 files changed

+111
-39
lines changed

lib/runner.js

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -182,12 +182,13 @@ class Runner extends EventEmitter {
182182

183183
compareTestSnapshot(options) {
184184
if (!this.snapshots) {
185-
const name = path.basename(this.file);
186-
// TODO: Only use __snapshots__ directory name if file is inside a
187-
// __tests__ directory (relative to the project root).
188-
const dir = path.join(path.dirname(this.file), '__snapshots__');
189-
const relFile = path.relative(this.projectDir, this.file);
190-
this.snapshots = snapshotManager.load(dir, name, relFile, this.updateSnapshots);
185+
this.snapshots = snapshotManager.load({
186+
name: path.basename(this.file),
187+
projectDir: this.projectDir,
188+
relFile: path.relative(this.projectDir, this.file),
189+
testDir: path.dirname(this.file),
190+
updating: this.updateSnapshots
191+
});
191192
this.emit('dependency', this.snapshots.snapPath);
192193
}
193194

lib/snapshot-manager.js

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -354,15 +354,26 @@ class Manager {
354354
}
355355
}
356356

357-
function load(dir, name, relFile, updating) {
358-
const reportFile = `${name}.md`;
359-
const snapFile = `${name}.snap`;
357+
function determineSnapshotDir(projectDir, testDir) {
358+
const parts = new Set(path.relative(projectDir, testDir).split(path.sep));
359+
if (parts.has('__tests__')) {
360+
return path.join(testDir, '__snapshots__');
361+
} else if (parts.has('test') || parts.has('tests')) { // Accept tests, even though it's not in the default test patterns
362+
return path.join(testDir, 'snapshots');
363+
}
364+
return testDir;
365+
}
366+
367+
function load(options) {
368+
const dir = determineSnapshotDir(options.projectDir, options.testDir);
369+
const reportFile = `${options.name}.md`;
370+
const snapFile = `${options.name}.snap`;
360371
const snapPath = path.join(dir, snapFile);
361372

362-
let appendOnly = !updating;
373+
let appendOnly = !options.updating;
363374
let snapshotsByHash;
364375

365-
if (!updating) {
376+
if (!options.updating) {
366377
const buffer = tryRead(snapPath);
367378
if (buffer) {
368379
snapshotsByHash = decodeSnapshots(buffer, snapPath);
@@ -374,7 +385,7 @@ function load(dir, name, relFile, updating) {
374385
return new Manager({
375386
appendOnly,
376387
dir,
377-
relFile,
388+
relFile: options.relFile,
378389
reportFile,
379390
snapFile,
380391
snapPath,

test/assert.js

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -736,9 +736,16 @@ test('.snapshot()', t => {
736736
// "$(npm bin)"/tap --no-cov -R spec test/assert.js
737737
//
738738
// Ignore errors and make sure not to run tests with the `-b` (bail) option.
739-
const update = false;
739+
const updating = false;
740740

741-
const manager = snapshotManager.load(path.join(__dirname, 'fixture'), 'assert.js', 'test/assert.js', update);
741+
const projectDir = path.join(__dirname, 'fixture');
742+
const manager = snapshotManager.load({
743+
projectDir,
744+
testDir: projectDir,
745+
name: 'assert.js',
746+
relFile: 'test/assert.js',
747+
updating
748+
});
742749
const setup = title => {
743750
const fauxTest = new Test({
744751
title,
@@ -760,7 +767,7 @@ test('.snapshot()', t => {
760767

761768
{
762769
const executionContext = setup('fails');
763-
if (update) {
770+
if (updating) {
764771
assertions.snapshot.call(executionContext, {foo: 'bar'});
765772
} else {
766773
failsWith(t, () => {
@@ -784,7 +791,7 @@ test('.snapshot()', t => {
784791

785792
{
786793
const executionContext = setup('fails');
787-
if (update) {
794+
if (updating) {
788795
assertions.snapshot.call(executionContext, {foo: 'bar'}, 'my message');
789796
} else {
790797
failsWith(t, () => {
@@ -799,7 +806,7 @@ test('.snapshot()', t => {
799806

800807
{
801808
const executionContext = setup('rendered comparison');
802-
if (update) {
809+
if (updating) {
803810
assertions.snapshot.call(executionContext, renderer.create(React.createElement(HelloMessage, {name: 'Sindre'})).toJSON());
804811
} else {
805812
passes(t, () => {
@@ -810,7 +817,7 @@ test('.snapshot()', t => {
810817

811818
{
812819
const executionContext = setup('rendered comparison');
813-
if (update) {
820+
if (updating) {
814821
assertions.snapshot.call(executionContext, renderer.create(React.createElement(HelloMessage, {name: 'Sindre'})).toJSON());
815822
} else {
816823
failsWith(t, () => {
@@ -825,7 +832,7 @@ test('.snapshot()', t => {
825832

826833
{
827834
const executionContext = setup('element comparison');
828-
if (update) {
835+
if (updating) {
829836
assertions.snapshot.call(executionContext, React.createElement(HelloMessage, {name: 'Sindre'}));
830837
} else {
831838
failsWith(t, () => {

test/cli.js

Lines changed: 30 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -354,7 +354,7 @@ test('watcher reruns test files when snapshot dependencies change', t => {
354354
} else {
355355
passedFirst = true;
356356
setTimeout(() => {
357-
touch.sync(path.join(__dirname, 'fixture/snapshots/__snapshots__/test.js.snap'));
357+
touch.sync(path.join(__dirname, 'fixture/snapshots/test.js.snap'));
358358
}, 500);
359359
}
360360
}
@@ -556,29 +556,39 @@ test('promise tests fail if event loop empties before they\'re resolved', t => {
556556
});
557557
});
558558

559-
test('snapshots work', t => {
560-
try {
561-
fs.unlinkSync(path.join(__dirname, 'fixture', 'snapshots', '__snapshots__', 'test.js.snap'));
562-
} catch (err) {
563-
if (err.code !== 'ENOENT') {
564-
throw err;
559+
for (const obj of [
560+
{type: 'colocated', rel: '', dir: ''},
561+
{type: '__tests__', rel: '__tests__-dir', dir: '__tests__/__snapshots__'},
562+
{type: 'test', rel: 'test-dir', dir: 'test/snapshots'},
563+
{type: 'tests', rel: 'tests-dir', dir: 'tests/snapshots'}
564+
]) {
565+
test(`snapshots work (${obj.type})`, t => {
566+
const snapPath = path.join(__dirname, 'fixture', 'snapshots', obj.rel, obj.dir, 'test.js.snap');
567+
try {
568+
fs.unlinkSync(snapPath);
569+
} catch (err) {
570+
if (err.code !== 'ENOENT') {
571+
throw err;
572+
}
565573
}
566-
}
567574

568-
// Test should pass, and a snapshot gets written
569-
execCli(['--update-snapshots', 'test.js'], {dirname: 'fixture/snapshots'}, err => {
570-
t.ifError(err);
571-
572-
// Test should pass, and the snapshot gets used
573-
execCli(['test.js'], {dirname: 'fixture/snapshots'}, err => {
575+
const dirname = path.join('fixture/snapshots', obj.rel);
576+
// Test should pass, and a snapshot gets written
577+
execCli(['--update-snapshots'], {dirname}, err => {
574578
t.ifError(err);
575-
t.end();
579+
t.true(fs.existsSync(snapPath));
580+
581+
// Test should pass, and the snapshot gets used
582+
execCli([], {dirname}, err => {
583+
t.ifError(err);
584+
t.end();
585+
});
576586
});
577587
});
578-
});
588+
}
579589

580590
test('outdated snapshot version is reported to the console', t => {
581-
const snapPath = path.join(__dirname, 'fixture', 'snapshots', '__snapshots__', 'test.js.snap');
591+
const snapPath = path.join(__dirname, 'fixture', 'snapshots', 'test.js.snap');
582592
fs.writeFileSync(snapPath, Buffer.from([0x0A, 0x00, 0x00]));
583593

584594
execCli(['test.js'], {dirname: 'fixture/snapshots'}, (err, stdout, stderr) => {
@@ -592,7 +602,7 @@ test('outdated snapshot version is reported to the console', t => {
592602
});
593603

594604
test('newer snapshot version is reported to the console', t => {
595-
const snapPath = path.join(__dirname, 'fixture', 'snapshots', '__snapshots__', 'test.js.snap');
605+
const snapPath = path.join(__dirname, 'fixture', 'snapshots', 'test.js.snap');
596606
fs.writeFileSync(snapPath, Buffer.from([0x0A, 0xFF, 0xFF]));
597607

598608
execCli(['test.js'], {dirname: 'fixture/snapshots'}, (err, stdout, stderr) => {
@@ -606,7 +616,7 @@ test('newer snapshot version is reported to the console', t => {
606616
});
607617

608618
test('snapshot corruption is reported to the console', t => {
609-
const snapPath = path.join(__dirname, 'fixture', 'snapshots', '__snapshots__', 'test.js.snap');
619+
const snapPath = path.join(__dirname, 'fixture', 'snapshots', 'test.js.snap');
610620
fs.writeFileSync(snapPath, Buffer.from([0x0A, 0x01, 0x00]));
611621

612622
execCli(['test.js'], {dirname: 'fixture/snapshots'}, (err, stdout, stderr) => {
@@ -620,7 +630,7 @@ test('snapshot corruption is reported to the console', t => {
620630
});
621631

622632
test('legacy snapshot files are reported to the console', t => {
623-
const snapPath = path.join(__dirname, 'fixture', 'snapshots', '__snapshots__', 'test.js.snap');
633+
const snapPath = path.join(__dirname, 'fixture', 'snapshots', 'test.js.snap');
624634
fs.writeFileSync(snapPath, Buffer.from('// Jest Snapshot v1, https://goo.gl/fbAQLP\n'));
625635

626636
execCli(['test.js'], {dirname: 'fixture/snapshots'}, (err, stdout, stderr) => {

test/fixture/snapshots/.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,4 @@
1+
*.snap
2+
*.md
3+
snapshots
14
__snapshots__
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import test from '../../../../..';
2+
3+
test('test title', t => {
4+
t.snapshot({foo: 'bar'});
5+
6+
t.snapshot({answer: 42});
7+
});
8+
9+
test('another test', t => {
10+
t.snapshot(new Map());
11+
});
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import test from '../../../../..';
2+
3+
test('test title', t => {
4+
t.snapshot({foo: 'bar'});
5+
6+
t.snapshot({answer: 42});
7+
});
8+
9+
test('another test', t => {
10+
t.snapshot(new Map());
11+
});
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"ava": {
3+
"files": "tests"
4+
}
5+
}

0 commit comments

Comments
 (0)