You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
389 lines
10 KiB
389 lines
10 KiB
'use strict'; |
|
|
|
var global = (function () { |
|
if (typeof globalThis !== 'undefined') { |
|
return globalThis; |
|
} else if (typeof global !== 'undefined') { |
|
return global; |
|
} else if (typeof self !== 'undefined') { |
|
return self; |
|
} else if (typeof window !== 'undefined') { |
|
return window; |
|
} else { |
|
return Function('return this')(); |
|
} |
|
})(); |
|
|
|
var Symbol = global['jest-symbol-do-not-touch'] || global.Symbol; |
|
Object.defineProperty(exports, '__esModule', { |
|
value: true |
|
}); |
|
exports.default = void 0; |
|
|
|
var fs = _interopRequireWildcard(require('graceful-fs')); |
|
|
|
var _jestMessageUtil = require('jest-message-util'); |
|
|
|
var _InlineSnapshots = require('./InlineSnapshots'); |
|
|
|
var _utils = require('./utils'); |
|
|
|
function _getRequireWildcardCache(nodeInterop) { |
|
if (typeof WeakMap !== 'function') return null; |
|
var cacheBabelInterop = new WeakMap(); |
|
var cacheNodeInterop = new WeakMap(); |
|
return (_getRequireWildcardCache = function (nodeInterop) { |
|
return nodeInterop ? cacheNodeInterop : cacheBabelInterop; |
|
})(nodeInterop); |
|
} |
|
|
|
function _interopRequireWildcard(obj, nodeInterop) { |
|
if (!nodeInterop && obj && obj.__esModule) { |
|
return obj; |
|
} |
|
if (obj === null || (typeof obj !== 'object' && typeof obj !== 'function')) { |
|
return {default: obj}; |
|
} |
|
var cache = _getRequireWildcardCache(nodeInterop); |
|
if (cache && cache.has(obj)) { |
|
return cache.get(obj); |
|
} |
|
var newObj = {}; |
|
var hasPropertyDescriptor = |
|
Object.defineProperty && Object.getOwnPropertyDescriptor; |
|
for (var key in obj) { |
|
if (key !== 'default' && Object.prototype.hasOwnProperty.call(obj, key)) { |
|
var desc = hasPropertyDescriptor |
|
? Object.getOwnPropertyDescriptor(obj, key) |
|
: null; |
|
if (desc && (desc.get || desc.set)) { |
|
Object.defineProperty(newObj, key, desc); |
|
} else { |
|
newObj[key] = obj[key]; |
|
} |
|
} |
|
} |
|
newObj.default = obj; |
|
if (cache) { |
|
cache.set(obj, newObj); |
|
} |
|
return newObj; |
|
} |
|
|
|
var global = (function () { |
|
if (typeof globalThis !== 'undefined') { |
|
return globalThis; |
|
} else if (typeof global !== 'undefined') { |
|
return global; |
|
} else if (typeof self !== 'undefined') { |
|
return self; |
|
} else if (typeof window !== 'undefined') { |
|
return window; |
|
} else { |
|
return Function('return this')(); |
|
} |
|
})(); |
|
|
|
var Symbol = global['jest-symbol-do-not-touch'] || global.Symbol; |
|
|
|
var global = (function () { |
|
if (typeof globalThis !== 'undefined') { |
|
return globalThis; |
|
} else if (typeof global !== 'undefined') { |
|
return global; |
|
} else if (typeof self !== 'undefined') { |
|
return self; |
|
} else if (typeof window !== 'undefined') { |
|
return window; |
|
} else { |
|
return Function('return this')(); |
|
} |
|
})(); |
|
|
|
var jestExistsFile = |
|
global[Symbol.for('jest-native-exists-file')] || fs.existsSync; |
|
|
|
function _defineProperty(obj, key, value) { |
|
if (key in obj) { |
|
Object.defineProperty(obj, key, { |
|
value: value, |
|
enumerable: true, |
|
configurable: true, |
|
writable: true |
|
}); |
|
} else { |
|
obj[key] = value; |
|
} |
|
return obj; |
|
} |
|
|
|
class SnapshotState { |
|
// @ts-expect-error |
|
constructor(snapshotPath, options) { |
|
_defineProperty(this, '_counters', void 0); |
|
|
|
_defineProperty(this, '_dirty', void 0); |
|
|
|
_defineProperty(this, '_index', void 0); |
|
|
|
_defineProperty(this, '_updateSnapshot', void 0); |
|
|
|
_defineProperty(this, '_snapshotData', void 0); |
|
|
|
_defineProperty(this, '_initialData', void 0); |
|
|
|
_defineProperty(this, '_snapshotPath', void 0); |
|
|
|
_defineProperty(this, '_inlineSnapshots', void 0); |
|
|
|
_defineProperty(this, '_uncheckedKeys', void 0); |
|
|
|
_defineProperty(this, '_prettierPath', void 0); |
|
|
|
_defineProperty(this, '_snapshotFormat', void 0); |
|
|
|
_defineProperty(this, 'added', void 0); |
|
|
|
_defineProperty(this, 'expand', void 0); |
|
|
|
_defineProperty(this, 'matched', void 0); |
|
|
|
_defineProperty(this, 'unmatched', void 0); |
|
|
|
_defineProperty(this, 'updated', void 0); |
|
|
|
this._snapshotPath = snapshotPath; |
|
const {data, dirty} = (0, _utils.getSnapshotData)( |
|
this._snapshotPath, |
|
options.updateSnapshot |
|
); |
|
this._initialData = data; |
|
this._snapshotData = data; |
|
this._dirty = dirty; |
|
this._prettierPath = options.prettierPath; |
|
this._inlineSnapshots = []; |
|
this._uncheckedKeys = new Set(Object.keys(this._snapshotData)); |
|
this._counters = new Map(); |
|
this._index = 0; |
|
this.expand = options.expand || false; |
|
this.added = 0; |
|
this.matched = 0; |
|
this.unmatched = 0; |
|
this._updateSnapshot = options.updateSnapshot; |
|
this.updated = 0; |
|
this._snapshotFormat = options.snapshotFormat; |
|
} |
|
|
|
markSnapshotsAsCheckedForTest(testName) { |
|
this._uncheckedKeys.forEach(uncheckedKey => { |
|
if ((0, _utils.keyToTestName)(uncheckedKey) === testName) { |
|
this._uncheckedKeys.delete(uncheckedKey); |
|
} |
|
}); |
|
} |
|
|
|
_addSnapshot(key, receivedSerialized, options) { |
|
this._dirty = true; |
|
|
|
if (options.isInline) { |
|
const error = options.error || new Error(); |
|
const lines = (0, _jestMessageUtil.getStackTraceLines)( |
|
(0, _utils.removeLinesBeforeExternalMatcherTrap)(error.stack || '') |
|
); |
|
const frame = (0, _jestMessageUtil.getTopFrame)(lines); |
|
|
|
if (!frame) { |
|
throw new Error( |
|
"Jest: Couldn't infer stack frame for inline snapshot." |
|
); |
|
} |
|
|
|
this._inlineSnapshots.push({ |
|
frame, |
|
snapshot: receivedSerialized |
|
}); |
|
} else { |
|
this._snapshotData[key] = receivedSerialized; |
|
} |
|
} |
|
|
|
clear() { |
|
this._snapshotData = this._initialData; |
|
this._inlineSnapshots = []; |
|
this._counters = new Map(); |
|
this._index = 0; |
|
this.added = 0; |
|
this.matched = 0; |
|
this.unmatched = 0; |
|
this.updated = 0; |
|
} |
|
|
|
save() { |
|
const hasExternalSnapshots = Object.keys(this._snapshotData).length; |
|
const hasInlineSnapshots = this._inlineSnapshots.length; |
|
const isEmpty = !hasExternalSnapshots && !hasInlineSnapshots; |
|
const status = { |
|
deleted: false, |
|
saved: false |
|
}; |
|
|
|
if ((this._dirty || this._uncheckedKeys.size) && !isEmpty) { |
|
if (hasExternalSnapshots) { |
|
(0, _utils.saveSnapshotFile)(this._snapshotData, this._snapshotPath); |
|
} |
|
|
|
if (hasInlineSnapshots) { |
|
(0, _InlineSnapshots.saveInlineSnapshots)( |
|
this._inlineSnapshots, |
|
this._prettierPath |
|
); |
|
} |
|
|
|
status.saved = true; |
|
} else if (!hasExternalSnapshots && jestExistsFile(this._snapshotPath)) { |
|
if (this._updateSnapshot === 'all') { |
|
fs.unlinkSync(this._snapshotPath); |
|
} |
|
|
|
status.deleted = true; |
|
} |
|
|
|
return status; |
|
} |
|
|
|
getUncheckedCount() { |
|
return this._uncheckedKeys.size || 0; |
|
} |
|
|
|
getUncheckedKeys() { |
|
return Array.from(this._uncheckedKeys); |
|
} |
|
|
|
removeUncheckedKeys() { |
|
if (this._updateSnapshot === 'all' && this._uncheckedKeys.size) { |
|
this._dirty = true; |
|
|
|
this._uncheckedKeys.forEach(key => delete this._snapshotData[key]); |
|
|
|
this._uncheckedKeys.clear(); |
|
} |
|
} |
|
|
|
match({testName, received, key, inlineSnapshot, isInline, error}) { |
|
this._counters.set(testName, (this._counters.get(testName) || 0) + 1); |
|
|
|
const count = Number(this._counters.get(testName)); |
|
|
|
if (!key) { |
|
key = (0, _utils.testNameToKey)(testName, count); |
|
} // Do not mark the snapshot as "checked" if the snapshot is inline and |
|
// there's an external snapshot. This way the external snapshot can be |
|
// removed with `--updateSnapshot`. |
|
|
|
if (!(isInline && this._snapshotData[key] !== undefined)) { |
|
this._uncheckedKeys.delete(key); |
|
} |
|
|
|
const receivedSerialized = (0, _utils.addExtraLineBreaks)( |
|
(0, _utils.serialize)(received, undefined, this._snapshotFormat) |
|
); |
|
const expected = isInline ? inlineSnapshot : this._snapshotData[key]; |
|
const pass = expected === receivedSerialized; |
|
const hasSnapshot = expected !== undefined; |
|
const snapshotIsPersisted = isInline || fs.existsSync(this._snapshotPath); |
|
|
|
if (pass && !isInline) { |
|
// Executing a snapshot file as JavaScript and writing the strings back |
|
// when other snapshots have changed loses the proper escaping for some |
|
// characters. Since we check every snapshot in every test, use the newly |
|
// generated formatted string. |
|
// Note that this is only relevant when a snapshot is added and the dirty |
|
// flag is set. |
|
this._snapshotData[key] = receivedSerialized; |
|
} // These are the conditions on when to write snapshots: |
|
// * There's no snapshot file in a non-CI environment. |
|
// * There is a snapshot file and we decided to update the snapshot. |
|
// * There is a snapshot file, but it doesn't have this snaphsot. |
|
// These are the conditions on when not to write snapshots: |
|
// * The update flag is set to 'none'. |
|
// * There's no snapshot file or a file without this snapshot on a CI environment. |
|
|
|
if ( |
|
(hasSnapshot && this._updateSnapshot === 'all') || |
|
((!hasSnapshot || !snapshotIsPersisted) && |
|
(this._updateSnapshot === 'new' || this._updateSnapshot === 'all')) |
|
) { |
|
if (this._updateSnapshot === 'all') { |
|
if (!pass) { |
|
if (hasSnapshot) { |
|
this.updated++; |
|
} else { |
|
this.added++; |
|
} |
|
|
|
this._addSnapshot(key, receivedSerialized, { |
|
error, |
|
isInline |
|
}); |
|
} else { |
|
this.matched++; |
|
} |
|
} else { |
|
this._addSnapshot(key, receivedSerialized, { |
|
error, |
|
isInline |
|
}); |
|
|
|
this.added++; |
|
} |
|
|
|
return { |
|
actual: '', |
|
count, |
|
expected: '', |
|
key, |
|
pass: true |
|
}; |
|
} else { |
|
if (!pass) { |
|
this.unmatched++; |
|
return { |
|
actual: (0, _utils.removeExtraLineBreaks)(receivedSerialized), |
|
count, |
|
expected: |
|
expected !== undefined |
|
? (0, _utils.removeExtraLineBreaks)(expected) |
|
: undefined, |
|
key, |
|
pass: false |
|
}; |
|
} else { |
|
this.matched++; |
|
return { |
|
actual: '', |
|
count, |
|
expected: '', |
|
key, |
|
pass: true |
|
}; |
|
} |
|
} |
|
} |
|
|
|
fail(testName, _received, key) { |
|
this._counters.set(testName, (this._counters.get(testName) || 0) + 1); |
|
|
|
const count = Number(this._counters.get(testName)); |
|
|
|
if (!key) { |
|
key = (0, _utils.testNameToKey)(testName, count); |
|
} |
|
|
|
this._uncheckedKeys.delete(key); |
|
|
|
this.unmatched++; |
|
return key; |
|
} |
|
} |
|
|
|
exports.default = SnapshotState;
|
|
|