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.
		
		
		
		
		
			
		
			
				
					
					
						
							316 lines
						
					
					
						
							8.4 KiB
						
					
					
				
			
		
		
	
	
							316 lines
						
					
					
						
							8.4 KiB
						
					
					
				'use strict'; | 
						|
 | 
						|
Object.defineProperty(exports, '__esModule', { | 
						|
  value: true | 
						|
}); | 
						|
exports.default = void 0; | 
						|
 | 
						|
var _fs = _interopRequireDefault(require('fs')); | 
						|
 | 
						|
var _jestMessageUtil = require('jest-message-util'); | 
						|
 | 
						|
var _utils = require('./utils'); | 
						|
 | 
						|
var _inline_snapshots = require('./inline_snapshots'); | 
						|
 | 
						|
function _interopRequireDefault(obj) { | 
						|
  return obj && obj.__esModule ? obj : {default: obj}; | 
						|
} | 
						|
 | 
						|
var Symbol = global['jest-symbol-do-not-touch'] || global.Symbol; | 
						|
var Symbol = global['jest-symbol-do-not-touch'] || global.Symbol; | 
						|
 | 
						|
var jestExistsFile = | 
						|
  global[Symbol.for('jest-native-exists-file')] || _fs.default.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-ignore | 
						|
  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, '_getBabelTraverse', void 0); | 
						|
 | 
						|
    _defineProperty(this, '_getPrettier', 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 _getSnapshotData = (0, _utils.getSnapshotData)( | 
						|
        this._snapshotPath, | 
						|
        options.updateSnapshot | 
						|
      ), | 
						|
      data = _getSnapshotData.data, | 
						|
      dirty = _getSnapshotData.dirty; | 
						|
 | 
						|
    this._initialData = data; | 
						|
    this._snapshotData = data; | 
						|
    this._dirty = dirty; | 
						|
    this._getBabelTraverse = options.getBabelTraverse; | 
						|
    this._getPrettier = options.getPrettier; | 
						|
    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; | 
						|
  } | 
						|
 | 
						|
  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)(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) { | 
						|
        const prettier = this._getPrettier(); // Load lazily | 
						|
 | 
						|
        const babelTraverse = this._getBabelTraverse(); // Load lazily | 
						|
 | 
						|
        (0, _inline_snapshots.saveInlineSnapshots)( | 
						|
          this._inlineSnapshots, | 
						|
          prettier, | 
						|
          babelTraverse | 
						|
        ); | 
						|
      } | 
						|
 | 
						|
      status.saved = true; | 
						|
    } else if (!hasExternalSnapshots && jestExistsFile(this._snapshotPath)) { | 
						|
      if (this._updateSnapshot === 'all') { | 
						|
        _fs.default.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, error}) { | 
						|
    this._counters.set(testName, (this._counters.get(testName) || 0) + 1); | 
						|
 | 
						|
    const count = Number(this._counters.get(testName)); | 
						|
    const isInline = inlineSnapshot !== undefined; | 
						|
 | 
						|
    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])) { | 
						|
      this._uncheckedKeys.delete(key); | 
						|
    } | 
						|
 | 
						|
    const receivedSerialized = (0, _utils.serialize)(received); | 
						|
    const expected = isInline ? inlineSnapshot : this._snapshotData[key]; | 
						|
    const pass = expected === receivedSerialized; | 
						|
    const hasSnapshot = isInline | 
						|
      ? inlineSnapshot !== '' | 
						|
      : this._snapshotData[key] !== undefined; | 
						|
 | 
						|
    const snapshotIsPersisted = | 
						|
      isInline || _fs.default.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.unescape)(receivedSerialized), | 
						|
          count, | 
						|
          expected: expected ? (0, _utils.unescape)(expected) : null, | 
						|
          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;
 | 
						|
 |