Skip to content
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

Introducing AVA snapshots v3 #2685

Merged
merged 88 commits into from Mar 13, 2021
Merged
Show file tree
Hide file tree
Changes from 77 commits
Commits
Show all changes
88 commits
Select commit Hold shift + click to select a range
a8b2a4f
Remove associatedTaskIndex
ninevra Feb 9, 2021
207b33d
Remove snapIndex
ninevra Feb 9, 2021
28ea70f
Draft a placeholder snapshot format
ninevra Feb 9, 2021
0fbae43
Update test-tap/assert.js snapshot
ninevra Feb 9, 2021
2b40b78
Update test-tap/try-snapshot.js snapshot
ninevra Feb 9, 2021
b537c46
Update test-tap/integration/snapshots.js snapshots
ninevra Feb 9, 2021
30b02e0
Update test/assertions snapshot
ninevra Feb 9, 2021
3721489
Update test/snapshot-order/randomness.js snapshot
ninevra Feb 9, 2021
3a85c64
Update test/snapshot-updates snapshots
ninevra Feb 12, 2021
2084726
Write reports using blocksByTitle
ninevra Feb 10, 2021
7403619
Collect ordering info from Runner all at once
ninevra Feb 10, 2021
a69ec49
Test regenerating snapshot reports
ninevra Feb 11, 2021
6f80dc4
Allow t.snapshot.skip() with --update-snapshots
ninevra Feb 11, 2021
b7b6fb3
Update existing tests to allow snapshot.skip with -u
ninevra Feb 12, 2021
49204dc
Allow test.skip() with --update-snapshots
ninevra Feb 13, 2021
69e2f62
Update tests to allow test.skip() with -u
ninevra Feb 13, 2021
66fcf02
Generalize Runner lazy-loading snapshot manager
ninevra Feb 14, 2021
6e83431
Allow -u with .only, --match, line number select
ninevra Feb 14, 2021
b668f9d
Update tests to allow -u with test selection
ninevra Feb 14, 2021
7074973
Set up snapshot workflow testing framework
ninevra Feb 14, 2021
b542aca
More snapshot workflow tests
ninevra Feb 14, 2021
6b8ef30
Rename snapshot-updates suite to snapshot-workflow
ninevra Feb 14, 2021
94bdaef
Fix CI-dependent test failure
ninevra Feb 14, 2021
a9222e6
Add more snapshot workflow tests
ninevra Feb 14, 2021
ca071cf
Find fixture's dependencies relative to AVA_PATH
ninevra Feb 15, 2021
90c3c01
Add remaining todo snapshot workflow tests
ninevra Feb 15, 2021
15e226c
Increase test timeout
ninevra Feb 15, 2021
a777048
Further increase test timeout
ninevra Feb 15, 2021
cf43700
Duplicate fixtures rather than use temp dirs
ninevra Feb 16, 2021
8a6d165
Move serial tests to separate files
ninevra Feb 16, 2021
ba8218a
Revert "Further increase test timeout"
ninevra Feb 16, 2021
bc7cec4
Revert "Increase test timeout"
ninevra Feb 16, 2021
6a5fc9a
Refactor tests
ninevra Feb 16, 2021
8e4a5a5
Test t.snapshot.skip with --update-snapshots
ninevra Feb 16, 2021
0bac67f
Fix bug with twice describing skipped snapshots
ninevra Feb 16, 2021
a90c2f9
More tests of --update-snapshots & test selection
ninevra Feb 16, 2021
39adc93
Test edge case involving new t.snapshot.skip()s
ninevra Feb 16, 2021
4d551e3
Fix lint issues
ninevra Feb 16, 2021
98e7123
Add crude profiling for snapshot-removal tests
ninevra Feb 16, 2021
9e7df59
Revert "Add crude profiling for snapshot-removal tests"
ninevra Feb 17, 2021
499d14f
Remove handling for snapshot-error events
ninevra Feb 17, 2021
3af51f7
Test edge cases with skipped snapshots in attempts
ninevra Feb 17, 2021
42ee5fe
Defer skipped snapshots in attempts
ninevra Feb 17, 2021
2df7169
Remove unused "changed" option
ninevra Feb 18, 2021
8ad7ac8
Collect task order info incrementally again
ninevra Feb 18, 2021
272513d
Refactor lazy snapshot manager
ninevra Feb 19, 2021
2787930
Eagerly load the snapshot manager
ninevra Feb 20, 2021
691334b
Refactor path handling in snapshot-manager
ninevra Feb 21, 2021
48e031e
Test that -u updates outdated snapshots
ninevra Feb 21, 2021
9d6e4c8
Avoid creating new blocks in error cases
ninevra Feb 21, 2021
4054903
Test skip() with -u and invalid .snap
ninevra Feb 21, 2021
701a0d3
Make fewer temporary copies when sorting blocks
ninevra Feb 21, 2021
e5d17be
Test edge case: invalid .snap, no snapshot asserts
ninevra Feb 21, 2021
ff9f32f
Only clean snapshots when updating
ninevra Feb 21, 2021
14d1669
Document --update-snapshots allows test selection
ninevra Feb 22, 2021
212a875
Install cbor
ninevra Feb 16, 2021
6ab1156
Implement cbor snapshot format
ninevra Feb 21, 2021
6801ce2
Clarify, minimize remnants of Encoder
ninevra Feb 21, 2021
dec0b4d
Default label to undefined
ninevra Feb 21, 2021
a602cf6
Record blanks when skipping snaps without data
ninevra Feb 21, 2021
dc03ddb
Squash all decoding errors when updating snapshots
ninevra Feb 22, 2021
b5a96e4
Update test snapshots
ninevra Feb 22, 2021
7643307
Use CBOR options to encourage determinism
ninevra Feb 22, 2021
f9e92e3
Experiment with pre-generating fixture templates
ninevra Feb 22, 2021
6d55531
Revert "Experiment with pre-generating fixture templates"
ninevra Feb 24, 2021
c926cb0
Remove unused md5-hex dependency
ninevra Feb 24, 2021
3a416d0
Limit concurrency in snapshot-removal tests
ninevra Feb 27, 2021
a9a7ada
Run slow tests serially
ninevra Feb 27, 2021
c2b5301
Clean up unused macro arg
ninevra Feb 27, 2021
d062f2c
Pregenerate snapshot-removal templates
ninevra Feb 27, 2021
8787fe4
Refactor snapshot-removal macros
ninevra Feb 27, 2021
e3f7f4c
Pregenerate snapshot-workflow templates
ninevra Feb 27, 2021
8ed0a4b
Refactor snapshot-workflow macros
ninevra Feb 27, 2021
2b96059
Use temp fixtures in all snapshot-workflow tests
ninevra Feb 27, 2021
bf68a42
Avoid macro chaining
ninevra Feb 27, 2021
1a66adf
Fix & document fixture initialization
ninevra Feb 27, 2021
b7cf3a0
Refactor for clarity
ninevra Feb 28, 2021
872506b
Update docs/04-snapshot-testing.md
ninevra Mar 2, 2021
819e4e6
Use sha256 instead of md5
ninevra Mar 4, 2021
0ed7a86
Update test snapshots
ninevra Mar 4, 2021
46b17f2
Explicitly remove taskIndex when encoding blocks
ninevra Mar 4, 2021
afc8b01
Separate taskIndices from blocks
ninevra Mar 5, 2021
bb641f5
Touch all non-todo tests at declaration
ninevra Mar 5, 2021
36b98e7
Move snapshot data reformatting into load, save
ninevra Mar 5, 2021
22b4b98
Tweak snapshot manager code
novemberborn Mar 7, 2021
5efbe6a
Merge branch 'main' into snapshot-regenerate
novemberborn Mar 7, 2021
cff4c6a
Snapshot diffs of changed reports
ninevra Mar 12, 2021
30f9f66
Upgrade concordance and rebuild snapshot reports
novemberborn Mar 13, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 4 additions & 2 deletions docs/01-writing-tests.md
Expand Up @@ -118,7 +118,7 @@ You can use the `.only` modifier with all tests. It cannot be used with hooks or

*Note:* The `.only` modifier applies to the test file it's defined in, so if you run multiple test files, tests in other files will still run. If you want to only run the `test.only` test, provide just that test file to AVA.

You cannot update snapshots when using `.only()`.
In AVA 3, you cannot update snapshots when using `.only()`.

## Skipping tests

Expand All @@ -132,7 +132,9 @@ test.skip('will not be run', t => {

You must specify the implementation function. You can use the `.skip` modifier with all tests and hooks, but not with `.todo()`. You can not apply further modifiers to `.skip`.

You cannot update snapshots when using `.skip()`. If the test is likely to be failing for a while, use `.failing()` instead.
If the test is likely to be failing for a while, use `.failing()` instead.

In AVA 3, you cannot update snapshots when using `.skip()`.

## Test placeholders ("todo")

Expand Down
2 changes: 1 addition & 1 deletion docs/03-assertions.md
Expand Up @@ -327,7 +327,7 @@ Compares the `expected` value with a previously recorded snapshot. Snapshots are

AVA 3 supports an `options` object that lets you select a specific snapshot, for instance `{id: 'my snapshot'}`. This is buggy and will be removed in AVA 4.

Snapshot assertions cannot be skipped when snapshots are being updated.
In AVA 3, you cannot update snapshots while using `t.snapshot.skip()`.

### `.try(title?, implementation | macro | macro[], ...args?)`

Expand Down
2 changes: 2 additions & 0 deletions docs/04-snapshot-testing.md
Expand Up @@ -44,6 +44,8 @@ You can then check your code. If the change was intentional you can use the `--u
$ ava --update-snapshots
```

If you need to update snapshots for only a particular test, you can use `--update-snapshots` together with e.g. `--match` or `.only()` to select the test.
ninevra marked this conversation as resolved.
Show resolved Hide resolved

You can specify a fixed location for storing the snapshot files in AVA's [`package.json` configuration](./06-configuration.md):

**`package.json`:**
Expand Down
7 changes: 0 additions & 7 deletions lib/cli.js
Expand Up @@ -199,10 +199,6 @@ exports.run = async () => { // eslint-disable-line complexity
const chalkOptions = {level: combined.color === false ? 0 : require('chalk').level};
const chalk = require('./chalk').set(chalkOptions);

if (combined.updateSnapshots && combined.match) {
exit('Snapshots cannot be updated when matching specific tests.');
}

if (confError) {
if (confError.parent) {
exit(`${confError.message}\n\n${chalk.gray((confError.parent && confError.parent.stack) || confError.parent)}`);
Expand Down Expand Up @@ -379,9 +375,6 @@ exports.run = async () => { // eslint-disable-line complexity
pattern: normalizePattern(path.relative(projectDir, path.resolve(process.cwd(), pattern))),
...rest
}));
if (combined.updateSnapshots && filter.some(condition => condition.lineNumbers !== null)) {
exit('Snapshots cannot be updated when selecting specific tests by their line number.');
}

const api = new Api({
cacheEnabled: combined.cache !== false,
Expand Down
15 changes: 0 additions & 15 deletions lib/reporters/default.js
Expand Up @@ -198,7 +198,6 @@ class Reporter {
this.sharedWorkerErrors = [];
this.uncaughtExceptions = [];
this.unhandledRejections = [];
this.unsavedSnapshots = [];

this.previousFailures = 0;

Expand Down Expand Up @@ -354,10 +353,6 @@ class Reporter {
break;
}

case 'snapshot-error':
this.unsavedSnapshots.push(event);
break;

case 'uncaught-exception': {
this.uncaughtExceptions.push(event);

Expand Down Expand Up @@ -825,16 +820,6 @@ class Reporter {
}
}

if (this.unsavedSnapshots.length > 0) {
this.lineWriter.writeLine(colors.title('Could not update snapshots for the following test files:'));
this.lineWriter.writeLine();
for (const event of this.unsavedSnapshots) {
this.lineWriter.writeLine(`${figures.warning} ${this.relativeFile(event.testFile)}`);
}

this.lineWriter.writeLine();
}

if (this.failFastEnabled && (this.stats.remainingTests > 0 || this.stats.files > this.stats.finishedWorkers)) {
let remaining = '';
if (this.stats.remainingTests > 0) {
Expand Down
3 changes: 0 additions & 3 deletions lib/reporters/tap.js
Expand Up @@ -165,9 +165,6 @@ class TapReporter {
this.writeTest(evt, {passed: false, todo: true, skip: false});
}

break;
case 'snapshot-error':
this.writeComment(evt, {title: 'Could not update snapshots'});
break;
case 'stats':
this.stats = evt.stats;
Expand Down
91 changes: 32 additions & 59 deletions lib/runner.js
Expand Up @@ -23,16 +23,24 @@ class Runner extends Emittery {
this.recordNewSnapshots = options.recordNewSnapshots === true;
this.runOnlyExclusive = options.runOnlyExclusive === true;
this.serial = options.serial === true;
this.skippingTests = false;
this.snapshotDir = options.snapshotDir;
this.updateSnapshots = options.updateSnapshots;

this.activeRunnables = new Set();
this.boundCompareTestSnapshot = this.compareTestSnapshot.bind(this);
this.skippedSnapshots = false;
this.boundSkipSnapshot = this.skipSnapshot.bind(this);
this.interrupted = false;
this.snapshots = null;
this.snapshots = snapshotManager.load({
file: this.file,
fixedLocation: this.snapshotDir,
projectDir: this.projectDir,
recordNewSnapshots: this.recordNewSnapshots,
updating: this.updateSnapshots
});
if (this.snapshots.snapPath !== undefined) {
this.emit('dependency', this.snapshots.snapPath);
}

this.nextTaskIndex = 0;
this.tasks = {
after: [],
Expand Down Expand Up @@ -152,10 +160,6 @@ class Runner extends Emittery {
task.metadata.exclusive = matcher([title], this.match).length === 1;
}

if (task.metadata.skipped) {
this.skippingTests = true;
}

if (task.metadata.exclusive) {
this.runOnlyExclusive = true;
}
Expand Down Expand Up @@ -185,49 +189,15 @@ class Runner extends Emittery {
}

compareTestSnapshot(options) {
if (!this.snapshots) {
this.snapshots = snapshotManager.load({
file: this.file,
fixedLocation: this.snapshotDir,
projectDir: this.projectDir,
recordNewSnapshots: this.recordNewSnapshots,
updating: this.updateSnapshots && !this.runOnlyExclusive && !this.skippingTests
});
this.emit('dependency', this.snapshots.snapPath);
}

return this.snapshots.compare(options);
}

skipSnapshot() {
this.skippedSnapshots = true;
skipSnapshot(options) {
return this.snapshots.skipSnapshot(options);
}

saveSnapshotState() {
if (
this.updateSnapshots &&
(
this.runOnlyExclusive ||
this.skippingTests ||
this.skippedSnapshots
)
) {
return {cannotSave: true};
}

if (this.snapshots) {
return {touchedFiles: this.snapshots.save()};
}

if (this.updateSnapshots) {
return {touchedFiles: snapshotManager.cleanSnapshots({
file: this.file,
fixedLocation: this.snapshotDir,
projectDir: this.projectDir
})};
}

return {};
return {touchedFiles: this.snapshots.save()};
}

onRun(runnable) {
Expand Down Expand Up @@ -301,7 +271,7 @@ class Runner extends Emittery {
return result;
}

async runHooks(tasks, contextRef, {titleSuffix, testPassed, associatedTaskIndex} = {}) {
async runHooks(tasks, contextRef, {titleSuffix, testPassed} = {}) {
const hooks = tasks.map(task => new Runnable({
contextRef,
experiments: this.experiments,
Expand All @@ -312,7 +282,7 @@ class Runner extends Emittery {
compareTestSnapshot: this.boundCompareTestSnapshot,
skipSnapshot: this.boundSkipSnapshot,
updateSnapshots: this.updateSnapshots,
metadata: {...task.metadata, associatedTaskIndex},
metadata: task.metadata,
powerAssert: this.powerAssert,
title: `${task.title}${titleSuffix || ''}`,
isHook: true,
Expand Down Expand Up @@ -347,8 +317,7 @@ class Runner extends Emittery {
this.tasks.beforeEach,
contextRef,
{
titleSuffix: hookSuffix,
associatedTaskIndex: task.metadata.taskIndex
titleSuffix: hookSuffix
}
);

Expand Down Expand Up @@ -388,8 +357,7 @@ class Runner extends Emittery {
contextRef,
{
titleSuffix: hookSuffix,
testPassed: testOk,
associatedTaskIndex: task.metadata.taskIndex
testPassed: testOk
});
} else {
this.emit('stateChange', {
Expand All @@ -409,8 +377,7 @@ class Runner extends Emittery {
contextRef,
{
titleSuffix: hookSuffix,
testPassed: testOk,
associatedTaskIndex: task.metadata.taskIndex
testPassed: testOk
});
return alwaysOk && hooksOk && testOk;
}
Expand All @@ -420,10 +387,12 @@ class Runner extends Emittery {
const serialTests = [];
for (const task of this.tasks.serial) {
if (this.runOnlyExclusive && !task.metadata.exclusive) {
this.snapshots.skipBlock(task.title, task.metadata.taskIndex);
continue;
}

if (this.checkSelectedByLineNumbers && !task.metadata.selected) {
this.snapshots.skipBlock(task.title, task.metadata.taskIndex);
continue;
}

Expand All @@ -435,17 +404,21 @@ class Runner extends Emittery {
todo: false
});

if (!task.metadata.skipped) {
if (task.metadata.skipped) {
this.snapshots.skipBlock(task.title, task.metadata.taskIndex);
} else {
serialTests.push(task);
}
}

for (const task of this.tasks.concurrent) {
if (this.runOnlyExclusive && !task.metadata.exclusive) {
this.snapshots.skipBlock(task.title, task.metadata.taskIndex);
continue;
}

if (this.checkSelectedByLineNumbers && !task.metadata.selected) {
this.snapshots.skipBlock(task.title, task.metadata.taskIndex);
continue;
}

Expand All @@ -457,12 +430,12 @@ class Runner extends Emittery {
todo: false
});

if (!task.metadata.skipped) {
if (this.serial) {
serialTests.push(task);
} else {
concurrentTests.push(task);
}
if (task.metadata.skipped) {
this.snapshots.skipBlock(task.title, task.metadata.taskIndex);
} else if (this.serial) {
serialTests.push(task);
} else {
concurrentTests.push(task);
}
}

Expand Down