SnapshotInteractiveMode.js 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327
  1. 'use strict';
  2. Object.defineProperty(exports, '__esModule', {
  3. value: true
  4. });
  5. exports.default = void 0;
  6. function _ansiEscapes() {
  7. const data = _interopRequireDefault(require('ansi-escapes'));
  8. _ansiEscapes = function () {
  9. return data;
  10. };
  11. return data;
  12. }
  13. function _chalk() {
  14. const data = _interopRequireDefault(require('chalk'));
  15. _chalk = function () {
  16. return data;
  17. };
  18. return data;
  19. }
  20. function _jestUtil() {
  21. const data = require('jest-util');
  22. _jestUtil = function () {
  23. return data;
  24. };
  25. return data;
  26. }
  27. function _jestWatcher() {
  28. const data = require('jest-watcher');
  29. _jestWatcher = function () {
  30. return data;
  31. };
  32. return data;
  33. }
  34. function _interopRequireDefault(obj) {
  35. return obj && obj.__esModule ? obj : {default: obj};
  36. }
  37. function _defineProperty(obj, key, value) {
  38. if (key in obj) {
  39. Object.defineProperty(obj, key, {
  40. value: value,
  41. enumerable: true,
  42. configurable: true,
  43. writable: true
  44. });
  45. } else {
  46. obj[key] = value;
  47. }
  48. return obj;
  49. }
  50. const {ARROW, CLEAR} = _jestUtil().specialChars;
  51. class SnapshotInteractiveMode {
  52. constructor(pipe) {
  53. _defineProperty(this, '_pipe', void 0);
  54. _defineProperty(this, '_isActive', void 0);
  55. _defineProperty(this, '_updateTestRunnerConfig', void 0);
  56. _defineProperty(this, '_testAssertions', void 0);
  57. _defineProperty(this, '_countPaths', void 0);
  58. _defineProperty(this, '_skippedNum', void 0);
  59. this._pipe = pipe;
  60. this._isActive = false;
  61. this._skippedNum = 0;
  62. }
  63. isActive() {
  64. return this._isActive;
  65. }
  66. getSkippedNum() {
  67. return this._skippedNum;
  68. }
  69. _clearTestSummary() {
  70. this._pipe.write(_ansiEscapes().default.cursorUp(6));
  71. this._pipe.write(_ansiEscapes().default.eraseDown);
  72. }
  73. _drawUIProgress() {
  74. this._clearTestSummary();
  75. const numPass = this._countPaths - this._testAssertions.length;
  76. const numRemaining = this._countPaths - numPass - this._skippedNum;
  77. let stats = _chalk().default.bold.dim(
  78. (0, _jestUtil().pluralize)('snapshot', numRemaining) + ' remaining'
  79. );
  80. if (numPass) {
  81. stats +=
  82. ', ' +
  83. _chalk().default.bold.green(
  84. (0, _jestUtil().pluralize)('snapshot', numPass) + ' updated'
  85. );
  86. }
  87. if (this._skippedNum) {
  88. stats +=
  89. ', ' +
  90. _chalk().default.bold.yellow(
  91. (0, _jestUtil().pluralize)('snapshot', this._skippedNum) + ' skipped'
  92. );
  93. }
  94. const messages = [
  95. '\n' + _chalk().default.bold('Interactive Snapshot Progress'),
  96. ARROW + stats,
  97. '\n' + _chalk().default.bold('Watch Usage'),
  98. _chalk().default.dim(ARROW + 'Press ') +
  99. 'u' +
  100. _chalk().default.dim(' to update failing snapshots for this test.'),
  101. _chalk().default.dim(ARROW + 'Press ') +
  102. 's' +
  103. _chalk().default.dim(' to skip the current test.'),
  104. _chalk().default.dim(ARROW + 'Press ') +
  105. 'q' +
  106. _chalk().default.dim(' to quit Interactive Snapshot Mode.'),
  107. _chalk().default.dim(ARROW + 'Press ') +
  108. 'Enter' +
  109. _chalk().default.dim(' to trigger a test run.')
  110. ];
  111. this._pipe.write(messages.filter(Boolean).join('\n') + '\n');
  112. }
  113. _drawUIDoneWithSkipped() {
  114. this._pipe.write(CLEAR);
  115. const numPass = this._countPaths - this._testAssertions.length;
  116. let stats = _chalk().default.bold.dim(
  117. (0, _jestUtil().pluralize)('snapshot', this._countPaths) + ' reviewed'
  118. );
  119. if (numPass) {
  120. stats +=
  121. ', ' +
  122. _chalk().default.bold.green(
  123. (0, _jestUtil().pluralize)('snapshot', numPass) + ' updated'
  124. );
  125. }
  126. if (this._skippedNum) {
  127. stats +=
  128. ', ' +
  129. _chalk().default.bold.yellow(
  130. (0, _jestUtil().pluralize)('snapshot', this._skippedNum) + ' skipped'
  131. );
  132. }
  133. const messages = [
  134. '\n' + _chalk().default.bold('Interactive Snapshot Result'),
  135. ARROW + stats,
  136. '\n' + _chalk().default.bold('Watch Usage'),
  137. _chalk().default.dim(ARROW + 'Press ') +
  138. 'r' +
  139. _chalk().default.dim(' to restart Interactive Snapshot Mode.'),
  140. _chalk().default.dim(ARROW + 'Press ') +
  141. 'q' +
  142. _chalk().default.dim(' to quit Interactive Snapshot Mode.')
  143. ];
  144. this._pipe.write(messages.filter(Boolean).join('\n') + '\n');
  145. }
  146. _drawUIDone() {
  147. this._pipe.write(CLEAR);
  148. const numPass = this._countPaths - this._testAssertions.length;
  149. let stats = _chalk().default.bold.dim(
  150. (0, _jestUtil().pluralize)('snapshot', this._countPaths) + ' reviewed'
  151. );
  152. if (numPass) {
  153. stats +=
  154. ', ' +
  155. _chalk().default.bold.green(
  156. (0, _jestUtil().pluralize)('snapshot', numPass) + ' updated'
  157. );
  158. }
  159. const messages = [
  160. '\n' + _chalk().default.bold('Interactive Snapshot Result'),
  161. ARROW + stats,
  162. '\n' + _chalk().default.bold('Watch Usage'),
  163. _chalk().default.dim(ARROW + 'Press ') +
  164. 'Enter' +
  165. _chalk().default.dim(' to return to watch mode.')
  166. ];
  167. this._pipe.write(messages.filter(Boolean).join('\n') + '\n');
  168. }
  169. _drawUIOverlay() {
  170. if (this._testAssertions.length === 0) {
  171. return this._drawUIDone();
  172. }
  173. if (this._testAssertions.length - this._skippedNum === 0) {
  174. return this._drawUIDoneWithSkipped();
  175. }
  176. return this._drawUIProgress();
  177. }
  178. put(key) {
  179. switch (key) {
  180. case 's':
  181. if (this._skippedNum === this._testAssertions.length) break;
  182. this._skippedNum += 1; // move skipped test to the end
  183. this._testAssertions.push(this._testAssertions.shift());
  184. if (this._testAssertions.length - this._skippedNum > 0) {
  185. this._run(false);
  186. } else {
  187. this._drawUIDoneWithSkipped();
  188. }
  189. break;
  190. case 'u':
  191. this._run(true);
  192. break;
  193. case 'q':
  194. case _jestWatcher().KEYS.ESCAPE:
  195. this.abort();
  196. break;
  197. case 'r':
  198. this.restart();
  199. break;
  200. case _jestWatcher().KEYS.ENTER:
  201. if (this._testAssertions.length === 0) {
  202. this.abort();
  203. } else {
  204. this._run(false);
  205. }
  206. break;
  207. default:
  208. break;
  209. }
  210. }
  211. abort() {
  212. this._isActive = false;
  213. this._skippedNum = 0;
  214. this._updateTestRunnerConfig(null, false);
  215. }
  216. restart() {
  217. this._skippedNum = 0;
  218. this._countPaths = this._testAssertions.length;
  219. this._run(false);
  220. }
  221. updateWithResults(results) {
  222. const hasSnapshotFailure = !!results.snapshot.failure;
  223. if (hasSnapshotFailure) {
  224. this._drawUIOverlay();
  225. return;
  226. }
  227. this._testAssertions.shift();
  228. if (this._testAssertions.length - this._skippedNum === 0) {
  229. this._drawUIOverlay();
  230. return;
  231. } // Go to the next test
  232. this._run(false);
  233. }
  234. _run(shouldUpdateSnapshot) {
  235. const testAssertion = this._testAssertions[0];
  236. this._updateTestRunnerConfig(testAssertion, shouldUpdateSnapshot);
  237. }
  238. run(failedSnapshotTestAssertions, onConfigChange) {
  239. if (!failedSnapshotTestAssertions.length) {
  240. return;
  241. }
  242. this._testAssertions = [...failedSnapshotTestAssertions];
  243. this._countPaths = this._testAssertions.length;
  244. this._updateTestRunnerConfig = onConfigChange;
  245. this._isActive = true;
  246. this._run(false);
  247. }
  248. }
  249. exports.default = SnapshotInteractiveMode;