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

Make snapshots usable again #1317

Merged
merged 2 commits into from
Apr 2, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 11 additions & 60 deletions lib/assert.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,11 @@
const coreAssert = require('core-assert');
const deepEqual = require('lodash.isequal');
const observableToPromise = require('observable-to-promise');
const indentString = require('indent-string');
const isObservable = require('is-observable');
const isPromise = require('is-promise');
const jestSnapshot = require('jest-snapshot');
const jestDiff = require('jest-diff');
const enhanceAssert = require('./enhance-assert');
const formatAssertError = require('./format-assert-error');
const snapshotState = require('./snapshot-state');

class AssertionError extends Error {
constructor(opts) {
Expand Down Expand Up @@ -251,21 +249,21 @@ function wrapAssertions(callbacks) {
}
},

snapshot(actual, optionalMessage) {
const result = snapshot(this, actual, optionalMessage);
snapshot(actual, message) {
const state = this._test.getSnapshotState();
const result = state.match(this.title, actual);
if (result.pass) {
pass(this);
} else {
const diff = formatAssertError.formatDiff(actual, result.expected);
const values = diff ? [diff] : [
formatAssertError.formatWithLabel('Actual:', actual),
formatAssertError.formatWithLabel('Must be deeply equal to:', result.expected)
];

const diff = jestDiff(result.expected.trim(), result.actual.trim(), {expand: true})
// Remove annotation
.split('\n')
.slice(3)
.join('\n');
fail(this, new AssertionError({
assertion: 'snapshot',
message: result.message,
values
message: message || 'Did not match snapshot',
values: [{label: 'Difference:', formatted: diff}]
}));
}
}
Expand Down Expand Up @@ -378,50 +376,3 @@ function wrapAssertions(callbacks) {
return Object.assign(assertions, enhancedAssertions);
}
exports.wrapAssertions = wrapAssertions;

function snapshot(executionContext, tree, optionalMessage, match, snapshotStateGetter) {
// Set defaults - this allows tests to mock deps easily
const toMatchSnapshot = match || jestSnapshot.toMatchSnapshot;
const getState = snapshotStateGetter || snapshotState.get;

const state = getState();

const context = {
dontThrow() {},
currentTestName: executionContext.title,
snapshotState: state
};

// Symbols can't be serialized and saved in a snapshot, that's why tree
// is saved in the `__ava_react_jsx` prop, so that JSX can be detected later
const serializedTree = tree.$$typeof === Symbol.for('react.test.json') ? {__ava_react_jsx: tree} : tree; // eslint-disable-line camelcase
const result = toMatchSnapshot.call(context, JSON.stringify(serializedTree));

let message = 'Please check your code or --update-snapshots';

if (optionalMessage) {
message += '\n\n' + indentString(optionalMessage, 2);
}

state.save();

let expected;

if (result.expected) {
// JSON in a snapshot is surrounded with `"`, because jest-snapshot
// serializes snapshot values too, so it ends up double JSON encoded
expected = JSON.parse(result.expected.slice(1).slice(0, -1));
// Define a `$$typeof` symbol, so that pretty-format detects it as React tree
if (expected.__ava_react_jsx) { // eslint-disable-line camelcase
expected = expected.__ava_react_jsx; // eslint-disable-line camelcase
Object.defineProperty(expected, '$$typeof', {value: Symbol.for('react.test.json')});
}
}

return {
pass: result.pass,
expected,
message
};
}
exports.snapshot = snapshot;
18 changes: 12 additions & 6 deletions lib/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@ const Runner = require('./runner');

const opts = globals.options;
const runner = new Runner({
bail: opts.failFast,
failWithoutAssertions: opts.failWithoutAssertions,
file: opts.file,
match: opts.match,
serial: opts.serial,
bail: opts.failFast,
match: opts.match
updateSnapshots: opts.updateSnapshots
});

worker.setRunner(runner);
Expand Down Expand Up @@ -51,7 +53,7 @@ function exit() {
// Reference the IPC channel now that tests have finished running.
adapter.ipcChannel.ref();

const stats = runner._buildStats();
const stats = runner.buildStats();
adapter.send('results', {stats});
}

Expand All @@ -78,7 +80,11 @@ globals.setImmediate(() => {
adapter.ipcChannel.unref();

runner.run(options)
.then(exit)
.then(() => {
runner.saveSnapshotState();

return exit();
})
.catch(err => {
process.emit('uncaughtException', err);
});
Expand All @@ -89,9 +95,9 @@ globals.setImmediate(() => {
});
});

module.exports = runner.test;
module.exports = runner.chain;

// TypeScript imports the `default` property for
// an ES2015 default import (`import test from 'ava'`)
// See: https://github.com/Microsoft/TypeScript/issues/2242#issuecomment-83694181
module.exports.default = runner.test;
module.exports.default = runner.chain;
Loading