SnapshotInteractiveMode.js 7.3 KB

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