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 1 commit
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
Copy link
Member

Choose a reason for hiding this comment

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

Let's do:

// Jest Snapshot v1, https://goo.gl/fbAQLP

which links to our snapshot testing guide.

cc @kentcdodds who will be pleased.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Added the link


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

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

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

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

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

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

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

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

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

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

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

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

exports[`instruments and collects coverage for typescript files 1`] = `
"------------|----------|----------|----------|----------|----------------|
File | % Stmts | % Branch | % Funcs | % Lines |Uncovered Lines |
Expand Down
2 changes: 1 addition & 1 deletion integration_tests/__tests__/transform-test.js
Expand Up @@ -98,7 +98,7 @@ describe('multiple-transformers', () => {
});

it('transforms dependencies using specific transformers', () => {
const {json, stderr} = runJest.json(dir, ['--no-cache']);
const {json, stderr} = runJest.json(dir, ['--no-cache', '-u']);
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Had to add that, so the snapshot version is updated, otherwise it fails.

Copy link
Contributor

Choose a reason for hiding this comment

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

hm. can't you update snapshot in the underlying test directory?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Oh I know what happened, I've updated it manually before this change #2896 (comment), so it wasn't updated. You're totally right and fix is already applied, thanks!


expect(stderr).toMatch(/PASS/);
expect(json.numTotalTests).toBe(1);
Expand Down
@@ -1,3 +1,5 @@
// Jest Snapshot v1

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

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

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

Expand Down
@@ -1,3 +1,5 @@
// Jest Snapshot v1

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

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

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

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

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

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

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

Expand Down
@@ -1,3 +1,5 @@
// Jest Snapshot v1

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

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

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

Expand Down
@@ -1,3 +1,5 @@
// Jest Snapshot v1

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

Expand Down
@@ -1,3 +1,5 @@
// Jest Snapshot v1

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

Expand Down
@@ -1,3 +1,5 @@
// Jest Snapshot v1

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

Expand Down
@@ -1,3 +1,5 @@
// Jest Snapshot v1

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
4 changes: 2 additions & 2 deletions packages/jest-snapshot/src/State.js
Expand Up @@ -48,7 +48,7 @@ class SnapshotState {
) {
this._dirty = false;
this._snapshotPath = snapshotPath || getSnapshotPath(testPath);
this._snapshotData = getSnapshotData(this._snapshotPath);
this._snapshotData = getSnapshotData(this._snapshotPath, update);
this._uncheckedKeys = new Set(Object.keys(this._snapshotData));
this._counters = new Map();
this._index = 0;
Expand Down Expand Up @@ -83,7 +83,7 @@ class SnapshotState {

const isEmpty = Object.keys(this._snapshotData).length === 0;

if ((this._dirty || this._uncheckedKeys.size) && !isEmpty) {
if ((this._dirty || this._uncheckedKeys.size || update) && !isEmpty) {
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This is added because otherwise saveSnapshotFile wouldn't be called (adding a version comment doesn't mark snapshot "dirty")

Copy link
Member

Choose a reason for hiding this comment

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

Can we make this so we only write the file if update is given & the snapshot header is either missing or there is a mismatch? I wanna prevent writes from happening if we don't need them.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Updated. I'm making snapshot "dirty" if it is in update mode and would throw invalid version error. I'm not very happy with returning a tuple from getSnapshotData but it's past midnight here and it seems to work :p

saveSnapshotFile(this._snapshotData, this._snapshotPath);
status.saved = true;
} else if (isEmpty && fileExists(this._snapshotPath)) {
Expand Down
64 changes: 59 additions & 5 deletions packages/jest-snapshot/src/__tests__/utils-test.js
Expand Up @@ -9,17 +9,28 @@
'use strict';

const {
getSnapshotData,
getSnapshotPath,
keyToTestName,
saveSnapshotFile,
testNameToKey,
SNAPSHOT_VERSION,
} = 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 +60,10 @@ 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\n\nexports[`myKey`] = `<div>\n</div>`;\n'
);
});

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

saveSnapshotFile(data, filename);
expect(fs.writeFileSync)
.toBeCalledWith(filename, 'exports[`myKey`] = `<div>\n</div>`;\n');
.toBeCalledWith(
filename,
'// Jest Snapshot v1\n\nexports[`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(
`Stored snapshot version is outdated.\n` +
`Expected: v${SNAPSHOT_VERSION}, but received: v0\n` +
`Update the snapshot to remove this error.`
);
});

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

expect(() => getSnapshotData(filename, update)).toThrowError(
`Stored snapshot version is outdated.\n` +
`Expected: v${SNAPSHOT_VERSION}, but received: v0.99\n` +
`Update the snapshot to remove this error.`
);
});

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\n\nexports[`key`] = `\"'\\\\`;\n");

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