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

Add snapshot version support #2896

Merged
merged 9 commits into from Feb 16, 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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
@@ -1,3 +1,5 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`renders correctly 1`] = `
<View
style={
Expand Down
@@ -1,3 +1,5 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`renders correctly 1`] = `
<p>
1482363367.071
Expand Down
@@ -1,3 +1,5 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`changes the class when hovered 1`] = `
<a
className="normal"
Expand Down
@@ -1,3 +1,5 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`console printing 1`] = `
" PASS __tests__/console-test.js
● Console
Expand Down
@@ -1,3 +1,5 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`collects coverage only from specified files 1`] = `
"----------|----------|----------|----------|----------|----------------|
File | % Stmts | % Branch | % Funcs | % Lines |Uncovered Lines |
Expand Down
@@ -1,3 +1,5 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`throwing not Error objects 1`] = `
Object {
"rest": " FAIL __tests__/throw-number-test.js
Expand Down
@@ -1,3 +1,5 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`basic test constructs 1`] = `
" PASS __tests__/basic-test-constructs-test.js
✓ it
Expand Down
@@ -1,3 +1,5 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Snapshot serializers renders snapshot 1`] = `
Object {
"snapshot serializers works with default serializers 1": "
Expand Down
@@ -1,3 +1,5 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Snapshot Validation deletes a snapshot when a test does removes all the snapshots 1`] = `
"Test Suites: 3 passed, 3 total
Tests: 7 passed, 7 total
Expand Down
@@ -1,3 +1,5 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Stack Trace does not print a stack trace for errors when --noStackTrace is given 1`] = `
"Test Suites: 1 failed, 1 total
Tests: 3 failed, 3 total
Expand Down
@@ -1,3 +1,5 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`testNamePattern 1`] = `
"Test Suites: 1 passed, 1 total
Tests: 2 skipped, 2 passed, 4 total
Expand Down
@@ -1,3 +1,5 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`babel-jest instruments only specific files and collects coverage 1`] = `
"------------|----------|----------|----------|----------|----------------|
File | % Stmts | % Branch | % Funcs | % Lines |Uncovered Lines |
Expand Down
@@ -1,3 +1,5 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`instruments and collects coverage for typescript files 1`] = `
"------------|----------|----------|----------|----------|----------------|
File | % Stmts | % Branch | % Funcs | % Lines |Uncovered Lines |
Expand Down
@@ -1,3 +1,5 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`generates a snapshot with correctly transformed dependencies 1`] = `
<div
className="App-root"
Expand Down
@@ -1,3 +1,5 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`generates an empty coverage object for a file without running it 1`] = `
Object {
"b": Object {
Expand Down
@@ -1,3 +1,5 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Watch mode flows Pressing "P" enters pattern mode 1`] = `
"

Expand Down
@@ -1,3 +1,5 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Watch mode flows Pressing "T" enters pattern mode 1`] = `
"

Expand Down
@@ -1,3 +1,5 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Watch mode flows Runs Jest once by default and shows usage 1`] = `
Array [
"
Expand Down
@@ -1,3 +1,5 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`for multiline test name returns test name with highlighted pattern and replaced line breaks 1`] = `"should⏎ name the ⏎function you at..."`;

exports[`for multiline test name returns test name with highlighted pattern and replaced line breaks 2`] = `"should⏎ name the ⏎function you at..."`;
Expand Down
@@ -1,3 +1,5 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`dims everything when there is no match 1`] = `"jest-cli/__tests__/watch-test.js"`;

exports[`dims everything when there is no match 2`] = `"...t-cli/__tests__/watch-test.js"`;
Expand Down
@@ -1,3 +1,5 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`trimAndFormatPath() does not trim anything 1`] = `"1234567890/1234567890/1234.js"`;

exports[`trimAndFormatPath() split at the path.sep index 1`] = `".../1234.js"`;
Expand All @@ -8,9 +10,9 @@ exports[`trimAndFormatPath() trims dirname 1`] = `"...234567890/123

exports[`trimAndFormatPath() trims dirname and basename 1`] = `"...1234.js"`;

exports[`wrapAnsiString() returns the string unaltered if given a terminal width of zero 1`] = `"This string shouldn\'t cause you any trouble"`;
exports[`wrapAnsiString() returns the string unaltered if given a terminal width of zero 1`] = `"This string shouldn't cause you any trouble"`;
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this be fixed?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

omg yes. Not sure what is going on here?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you remove this snapshot and run the test again and use the result of that?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wait, actually this is correct now. I don't understand why it wasn't updated before. cc @vjeux.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe because before it was checking the unserialized state so they were both the same and therefore didn't needed an update? idk


exports[`wrapAnsiString() returns the string unaltered if given a terminal width of zero 2`] = `"This string shouldn\'t cause you any trouble"`;
exports[`wrapAnsiString() returns the string unaltered if given a terminal width of zero 2`] = `"This string shouldn't cause you any trouble"`;

exports[`wrapAnsiString() wraps a long string containing ansi chars 1`] = `
"abcde red-
Expand Down
@@ -1,3 +1,5 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Upgrade help logs a warning when \`scriptPreprocessor\` and/or \`preprocessorIgnorePatterns\` are used 1`] = `
"● Deprecation Warning:

Expand Down
@@ -1,3 +1,5 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`collapses big diffs to patch format 1`] = `
"- Expected
+ Received
Expand Down
@@ -1,3 +1,5 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`HasteMap throws on duplicate module ids if "throwOnModuleCollision" is set to true 1`] = `
[Error: jest-haste-map: @providesModule naming collision:
Duplicate module name: Strawberry
Expand All @@ -8,7 +10,7 @@ This error is caused by a @providesModule declaration with the same name across

exports[`HasteMap tries to crawl using node as a fallback 1`] = `
"jest-haste-map: Watchman crawl failed. Retrying once with node crawler.
Usually this happens when watchman isn\'t running. Create an empty \`.watchmanconfig\` file in your project\'s root folder or initialize a git or hg repository in your project.
Usually this happens when watchman isn't running. Create an empty \`.watchmanconfig\` file in your project's root folder or initialize a git or hg repository in your project.
Error: watchman error"
`;

Expand Down
@@ -1,3 +1,5 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`matchers proxies matchers to jest-matchers 1`] = `
"expect(received).toBe(expected)

Expand Down
@@ -1,3 +1,5 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`.stringify() reduces maxDepth if stringifying very large objects 1`] = `"{\\"a\\": 1, \\"b\\": [Object]}"`;

exports[`.stringify() reduces maxDepth if stringifying very large objects 2`] = `"{\\"a\\": 1, \\"b\\": {\\"0\\": \\"test\\", \\"1\\": \\"test\\", \\"2\\": \\"test\\", \\"3\\": \\"test\\", \\"4\\": \\"test\\", \\"5\\": \\"test\\", \\"6\\": \\"test\\", \\"7\\": \\"test\\", \\"8\\": \\"test\\", \\"9\\": \\"test\\"}}"`;
Expand Down
@@ -1,3 +1,5 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`is available globally 1`] = `"expected 15 to be divisible by 2"`;

exports[`is ok if there is no message specified 1`] = `"No message was specified for this matcher."`;
@@ -1,3 +1,5 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`.toBe() does not crash on circular references 1`] = `
"expect(received).toBe(expected)

Expand Down
@@ -1,3 +1,5 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`lastCalledWith works only on spies or jest.fn 1`] = `
"expect(jest.fn())[.not].lastCalledWith()

Expand Down
@@ -1,3 +1,5 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`.toThrow() error class did not throw at all 1`] = `
"expect(function).toThrow(type)

Expand Down
@@ -1,3 +1,5 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`should exclude jasmine from stack trace for windows paths 1`] = `
" ● windows test

Expand Down
@@ -1,3 +1,5 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`transform transforms a file properly 1`] = `
"({\\"Object.<anonymous>\\":function(module,exports,require,__dirname,__filename,global,jest){/* istanbul ignore next */var cov_25u22311x4 = function () {var path = \\"/fruits/banana.js\\",hash = \\"04636d4ae73b4b3e24bf6fba39e08c946fd0afb5\\",global = new Function('return this')(),gcv = \\"__coverage__\\",coverageData = { path: \\"/fruits/banana.js\\", statementMap: { \\"0\\": { start: { line: 1, column: 0 }, end: { line: 1, column: 26 } } }, fnMap: {}, branchMap: {}, s: { \\"0\\": 0 }, f: {}, b: {}, _coverageSchema: \\"332fd63041d2c1bcb487cc26dd0d5f7d97098a6c\\" },coverage = global[gcv] || (global[gcv] = {});if (coverage[path] && coverage[path].hash === hash) {return coverage[path];}coverageData.hash = hash;return coverage[path] = coverageData;}();++cov_25u22311x4.s[0];module.exports = \\"banana\\";
}});"
Expand Down
5 changes: 3 additions & 2 deletions packages/jest-snapshot/src/State.js
Expand Up @@ -46,9 +46,10 @@ class SnapshotState {
snapshotPath?: string,
expand?: boolean,
) {
this._dirty = false;
this._snapshotPath = snapshotPath || getSnapshotPath(testPath);
this._snapshotData = getSnapshotData(this._snapshotPath);
const {data, dirty} = getSnapshotData(this._snapshotPath, update);
this._snapshotData = data;
this._dirty = dirty;
this._uncheckedKeys = new Set(Object.keys(this._snapshotData));
this._counters = new Map();
this._index = 0;
Expand Down
97 changes: 92 additions & 5 deletions packages/jest-snapshot/src/__tests__/utils-test.js
Expand Up @@ -9,17 +9,30 @@
'use strict';

const {
getSnapshotData,
getSnapshotPath,
keyToTestName,
saveSnapshotFile,
testNameToKey,
SNAPSHOT_GUIDE_LINK,
SNAPSHOT_VERSION,
SNAPSHOT_VERSION_WARNING,
} = require('../utils');
const fs = require('fs');
const path = require('path');

const writeFileSync = fs.writeFileSync;
beforeEach(() => fs.writeFileSync = jest.fn());
afterEach(() => fs.writeFileSync = writeFileSync);
const readFileSync = fs.readFileSync;
beforeEach(() => {
fs.writeFileSync = jest.fn();
fs.readFileSync = jest.fn();
});
afterEach(() => {
fs.writeFileSync = writeFileSync;
fs.readFileSync = readFileSync;
});

jest.mock('jest-file-exists', () => () => true);

test('keyToTestName()', () => {
expect(keyToTestName('abc cde 12')).toBe('abc cde');
Expand Down Expand Up @@ -49,7 +62,11 @@ test('saveSnapshotFile() works with \r\n', () => {

saveSnapshotFile(data, filename);
expect(fs.writeFileSync)
.toBeCalledWith(filename, 'exports[`myKey`] = `<div>\n</div>`;\n');
.toBeCalledWith(
filename,
`// Jest Snapshot v1, ${SNAPSHOT_GUIDE_LINK}\n\n` +
'exports[`myKey`] = `<div>\n</div>`;\n'
);
});

test('saveSnapshotFile() works with \r', () => {
Expand All @@ -60,15 +77,85 @@ test('saveSnapshotFile() works with \r', () => {

saveSnapshotFile(data, filename);
expect(fs.writeFileSync)
.toBeCalledWith(filename, 'exports[`myKey`] = `<div>\n</div>`;\n');
.toBeCalledWith(
filename,
`// Jest Snapshot v1, ${SNAPSHOT_GUIDE_LINK}\n\n` +
'exports[`myKey`] = `<div>\n</div>`;\n'
);
});

test('getSnapshotData() throws when no snapshot version', () => {
const filename = path.join(__dirname, 'old-snapshot.snap');
fs.readFileSync = jest.fn(() => 'exports[`myKey`] = `<div>\n</div>`;\n');
const update = false;

expect(() => getSnapshotData(filename, update)).toThrowError(
`Outdated snapshot: No snapshot header found. ` +
`Jest 19 introduced versioned snapshots to ensure all people on ` +
`a project are using the same version of Jest. ` +
`Please update all snapshots during this upgrade of Jest.\n\n` +
SNAPSHOT_VERSION_WARNING
);
});

test('getSnapshotData() throws for older snapshot version', () => {
const filename = path.join(__dirname, 'old-snapshot.snap');
fs.readFileSync = jest.fn(() =>
`// Jest Snapshot v0.99, ${SNAPSHOT_GUIDE_LINK}\n\n` +
'exports[`myKey`] = `<div>\n</div>`;\n'
);
const update = false;

expect(() => getSnapshotData(filename, update)).toThrowError(
`Outdated snapshot: The version of the snapshot file associated ` +
`with this test is outdated. The snapshot file version ensures that ` +
`all people on a project are using the same version of Jest. ` +
`Please update all snapshots during this upgrade of Jest.\n\n` +
`Expected: v${SNAPSHOT_VERSION}\n` +
`Received: v0.99\n\n` +
SNAPSHOT_VERSION_WARNING
);
});

test('getSnapshotData() throws for newer snapshot version', () => {
const filename = path.join(__dirname, 'old-snapshot.snap');
fs.readFileSync = jest.fn(() =>
`// Jest Snapshot v2, ${SNAPSHOT_GUIDE_LINK}\n\n` +
'exports[`myKey`] = `<div>\n</div>`;\n'
);
const update = false;

expect(() => getSnapshotData(filename, update)).toThrowError(
`Outdated Jest version: the version of this snapshot file indicates ` +
`that this project is meant to be used with a newer version of Jest. ` +
`The snapshot file version ensures that all people on a project ` +
`are using the same version of Jest. ` +
`Please update your version of Jest and re-run the tests.\n\n` +
`Expected: v${SNAPSHOT_VERSION}\n` +
`Received: v2`
);
});

test('getSnapshotData() does not throw for when updating', () => {
const filename = path.join(__dirname, 'old-snapshot.snap');
fs.readFileSync = jest.fn(() =>
'exports[`myKey`] = `<div>\n</div>`;\n'
);
const update = true;

expect(() => getSnapshotData(filename, update)).not.toThrow();
});

test('escaping', () => {
const filename = path.join(__dirname, 'escaping.snap');
const data = '"\'\\';
saveSnapshotFile({key: data}, filename);
const writtenData = fs.writeFileSync.mock.calls[0][1];
expect(writtenData).toBe("exports[`key`] = `\"'\\\\`;\n");
expect(writtenData)
.toBe(
`// Jest Snapshot v1, ${SNAPSHOT_GUIDE_LINK}\n\n` +
"exports[`key`] = `\"'\\\\`;\n"
);

// eslint-disable-next-line no-unused-vars
const exports = {};
Expand Down