State.js 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. 'use strict';
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. var _fs = require('fs');
  6. var _fs2 = _interopRequireDefault(_fs);
  7. var _utils = require('./utils');
  8. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  9. class SnapshotState {
  10. constructor(testPath, options) {
  11. this._snapshotPath = options.snapshotPath || (0, _utils.getSnapshotPath)(testPath);
  12. var _getSnapshotData = (0, _utils.getSnapshotData)(this._snapshotPath, options.updateSnapshot);
  13. const data = _getSnapshotData.data,
  14. dirty = _getSnapshotData.dirty;
  15. this._snapshotData = data;
  16. this._dirty = dirty;
  17. this._uncheckedKeys = new Set(Object.keys(this._snapshotData));
  18. this._counters = new Map();
  19. this._index = 0;
  20. this.expand = options.expand || false;
  21. this.added = 0;
  22. this.matched = 0;
  23. this.unmatched = 0;
  24. this._updateSnapshot = options.updateSnapshot;
  25. this.updated = 0;
  26. }
  27. markSnapshotsAsCheckedForTest(testName) {
  28. this._uncheckedKeys.forEach(uncheckedKey => {
  29. if ((0, _utils.keyToTestName)(uncheckedKey) === testName) {
  30. this._uncheckedKeys.delete(uncheckedKey);
  31. }
  32. });
  33. }
  34. _addSnapshot(key, receivedSerialized) {
  35. this._dirty = true;
  36. this._snapshotData[key] = receivedSerialized;
  37. }
  38. save() {
  39. const isEmpty = Object.keys(this._snapshotData).length === 0;
  40. const status = {
  41. deleted: false,
  42. saved: false
  43. };
  44. if ((this._dirty || this._uncheckedKeys.size) && !isEmpty) {
  45. (0, _utils.saveSnapshotFile)(this._snapshotData, this._snapshotPath);
  46. status.saved = true;
  47. } else if (isEmpty && _fs2.default.existsSync(this._snapshotPath)) {
  48. if (this._updateSnapshot === 'all') {
  49. _fs2.default.unlinkSync(this._snapshotPath);
  50. }
  51. status.deleted = true;
  52. }
  53. return status;
  54. }
  55. getUncheckedCount() {
  56. return this._uncheckedKeys.size || 0;
  57. }
  58. getUncheckedKeys() {
  59. return Array.from(this._uncheckedKeys);
  60. }
  61. removeUncheckedKeys() {
  62. if (this._updateSnapshot === 'all' && this._uncheckedKeys.size) {
  63. this._dirty = true;
  64. this._uncheckedKeys.forEach(key => delete this._snapshotData[key]);
  65. this._uncheckedKeys.clear();
  66. }
  67. }
  68. match(testName, received, key) {
  69. this._counters.set(testName, (this._counters.get(testName) || 0) + 1);
  70. const count = Number(this._counters.get(testName));
  71. if (!key) {
  72. key = (0, _utils.testNameToKey)(testName, count);
  73. }
  74. this._uncheckedKeys.delete(key);
  75. const receivedSerialized = (0, _utils.serialize)(received);
  76. const expected = this._snapshotData[key];
  77. const pass = expected === receivedSerialized;
  78. const hasSnapshot = this._snapshotData[key] !== undefined;
  79. if (pass) {
  80. // Executing a snapshot file as JavaScript and writing the strings back
  81. // when other snapshots have changed loses the proper escaping for some
  82. // characters. Since we check every snapshot in every test, use the newly
  83. // generated formatted string.
  84. // Note that this is only relevant when a snapshot is added and the dirty
  85. // flag is set.
  86. this._snapshotData[key] = receivedSerialized;
  87. }
  88. // These are the conditions on when to write snapshots:
  89. // * There's no snapshot file in a non-CI environment.
  90. // * There is a snapshot file and we decided to update the snapshot.
  91. // * There is a snapshot file, but it doesn't have this snaphsot.
  92. // These are the conditions on when not to write snapshots:
  93. // * The update flag is set to 'none'.
  94. // * There's no snapshot file or a file without this snapshot on a CI environment.
  95. if (hasSnapshot && this._updateSnapshot === 'all' || (!hasSnapshot || !_fs2.default.existsSync(this._snapshotPath)) && (this._updateSnapshot === 'new' || this._updateSnapshot === 'all')) {
  96. if (this._updateSnapshot === 'all') {
  97. if (!pass) {
  98. if (hasSnapshot) {
  99. this.updated++;
  100. } else {
  101. this.added++;
  102. }
  103. this._addSnapshot(key, receivedSerialized);
  104. } else {
  105. this.matched++;
  106. }
  107. } else {
  108. this._addSnapshot(key, receivedSerialized);
  109. this.added++;
  110. }
  111. return {
  112. actual: '',
  113. count,
  114. expected: '',
  115. pass: true
  116. };
  117. } else {
  118. if (!pass) {
  119. this.unmatched++;
  120. return {
  121. actual: (0, _utils.unescape)(receivedSerialized),
  122. count,
  123. expected: expected ? (0, _utils.unescape)(expected) : null,
  124. pass: false
  125. };
  126. } else {
  127. this.matched++;
  128. return {
  129. actual: '',
  130. count,
  131. expected: '',
  132. pass: true
  133. };
  134. }
  135. }
  136. }
  137. }
  138. exports.default = SnapshotState; /**
  139. * Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
  140. *
  141. * This source code is licensed under the MIT license found in the
  142. * LICENSE file in the root directory of this source tree.
  143. *
  144. *
  145. */