@inquirer/testing 1.0.6 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -52,6 +52,7 @@ The core utility of `@inquirer/testing` is the `render()` function. This `render
52
52
  1. `answer` (`Promise`) This is the promise that'll be resolved once an answer is provided and valid.
53
53
  2. `getScreen` (`({ raw: boolean }) => string`) This function returns the state of what is printed on the command line screen at any given time. You can use its return value to validate your prompt is properly rendered. By default this function will strip the ANSI codes (used for colors.)
54
54
  3. `events` (`{ keypress: (name) => void, type: (string) => void }`) Is the utilities allowing you to interact with the prompt. Use it to trigger keypress events, or typing any input.
55
+ 4. `getFullOutput` (`() => string`) Return a raw dump of everything that got sent on the output stream.
55
56
 
56
57
  You can refer to [the `@inquirer/input` prompt test suite](https://github.com/SBoudrias/Inquirer.js/blob/master/packages/input/test.mts) as a practical example.
57
58
 
package/dist/cjs/index.js CHANGED
@@ -13,36 +13,56 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
13
13
  if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
14
14
  return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
15
15
  };
16
+ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
17
+ if (kind === "m") throw new TypeError("Private method is not writable");
18
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
19
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
20
+ return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
21
+ };
16
22
  var __importDefault = (this && this.__importDefault) || function (mod) {
17
23
  return (mod && mod.__esModule) ? mod : { "default": mod };
18
24
  };
19
- var _BufferedStream__chunks;
25
+ var _BufferedStream__fullOutput, _BufferedStream__chunks, _BufferedStream__rawChunks;
20
26
  Object.defineProperty(exports, "__esModule", { value: true });
21
27
  exports.render = void 0;
22
28
  const mute_stream_1 = __importDefault(require("mute-stream"));
23
29
  const strip_ansi_1 = __importDefault(require("strip-ansi"));
30
+ const ansi_escapes_1 = __importDefault(require("ansi-escapes"));
24
31
  const node_stream_1 = require("node:stream");
32
+ const ignoredAnsi = new Set([ansi_escapes_1.default.cursorHide, ansi_escapes_1.default.cursorShow]);
25
33
  class BufferedStream extends node_stream_1.Stream.Writable {
26
34
  constructor() {
27
35
  super(...arguments);
36
+ _BufferedStream__fullOutput.set(this, '');
28
37
  _BufferedStream__chunks.set(this, []);
38
+ _BufferedStream__rawChunks.set(this, []);
29
39
  }
30
40
  _write(chunk, _encoding, callback) {
31
41
  const str = chunk.toString();
42
+ __classPrivateFieldSet(this, _BufferedStream__fullOutput, __classPrivateFieldGet(this, _BufferedStream__fullOutput, "f") + str, "f");
43
+ // There's some ANSI Inquirer just send to keep state of the terminal clear; we'll ignore those since they're
44
+ // unlikely to be used by end users or part of prompt code.
45
+ if (!ignoredAnsi.has(str)) {
46
+ __classPrivateFieldGet(this, _BufferedStream__rawChunks, "f").push(str);
47
+ }
32
48
  // Stripping the ANSI codes here because Inquirer will push commands ANSI (like cursor move.)
33
49
  // This is probably fine since we don't care about those for testing; but this could become
34
50
  // an issue if we ever want to test for those.
35
51
  if ((0, strip_ansi_1.default)(str).trim().length > 0) {
36
- __classPrivateFieldGet(this, _BufferedStream__chunks, "f").push(chunk.toString());
52
+ __classPrivateFieldGet(this, _BufferedStream__chunks, "f").push(str);
37
53
  }
38
54
  callback();
39
55
  }
40
- getLastChunk() {
41
- const lastChunk = __classPrivateFieldGet(this, _BufferedStream__chunks, "f")[__classPrivateFieldGet(this, _BufferedStream__chunks, "f").length - 1];
56
+ getLastChunk({ raw }) {
57
+ const chunks = raw ? __classPrivateFieldGet(this, _BufferedStream__rawChunks, "f") : __classPrivateFieldGet(this, _BufferedStream__chunks, "f");
58
+ const lastChunk = chunks[chunks.length - 1];
42
59
  return lastChunk !== null && lastChunk !== void 0 ? lastChunk : '';
43
60
  }
61
+ getFullOutput() {
62
+ return __classPrivateFieldGet(this, _BufferedStream__fullOutput, "f");
63
+ }
44
64
  }
45
- _BufferedStream__chunks = new WeakMap();
65
+ _BufferedStream__fullOutput = new WeakMap(), _BufferedStream__chunks = new WeakMap(), _BufferedStream__rawChunks = new WeakMap();
46
66
  function render(prompt, props, options) {
47
67
  return __awaiter(this, void 0, void 0, function* () {
48
68
  const input = new mute_stream_1.default();
@@ -68,9 +88,12 @@ function render(prompt, props, options) {
68
88
  input,
69
89
  events,
70
90
  getScreen({ raw } = {}) {
71
- const lastScreen = output.getLastChunk();
91
+ const lastScreen = output.getLastChunk({ raw });
72
92
  return raw ? lastScreen : (0, strip_ansi_1.default)(lastScreen).trim();
73
93
  },
94
+ getFullOutput() {
95
+ return output.getFullOutput();
96
+ },
74
97
  };
75
98
  });
76
99
  }
@@ -1,7 +1,7 @@
1
1
  import MuteStream from 'mute-stream';
2
2
  import type { Prompt } from '@inquirer/type';
3
3
  export declare function render<TestedPrompt extends Prompt<any, any>>(prompt: TestedPrompt, props: Parameters<TestedPrompt>[0], options?: Parameters<TestedPrompt>[1]): Promise<{
4
- answer: Promise<any>;
4
+ answer: import("@inquirer/type").CancelablePromise<any>;
5
5
  input: MuteStream;
6
6
  events: {
7
7
  keypress(name: string): void;
@@ -10,4 +10,5 @@ export declare function render<TestedPrompt extends Prompt<any, any>>(prompt: Te
10
10
  getScreen({ raw }?: {
11
11
  raw?: boolean | undefined;
12
12
  }): string;
13
+ getFullOutput(): string;
13
14
  }>;
@@ -1,22 +1,36 @@
1
1
  import MuteStream from 'mute-stream';
2
2
  import stripAnsi from 'strip-ansi';
3
+ import ansiEscapes from 'ansi-escapes';
3
4
  import { Stream } from 'node:stream';
5
+ const ignoredAnsi = new Set([ansiEscapes.cursorHide, ansiEscapes.cursorShow]);
4
6
  class BufferedStream extends Stream.Writable {
7
+ #_fullOutput = '';
5
8
  #_chunks = [];
9
+ #_rawChunks = [];
6
10
  _write(chunk, _encoding, callback) {
7
11
  const str = chunk.toString();
12
+ this.#_fullOutput += str;
13
+ // There's some ANSI Inquirer just send to keep state of the terminal clear; we'll ignore those since they're
14
+ // unlikely to be used by end users or part of prompt code.
15
+ if (!ignoredAnsi.has(str)) {
16
+ this.#_rawChunks.push(str);
17
+ }
8
18
  // Stripping the ANSI codes here because Inquirer will push commands ANSI (like cursor move.)
9
19
  // This is probably fine since we don't care about those for testing; but this could become
10
20
  // an issue if we ever want to test for those.
11
21
  if (stripAnsi(str).trim().length > 0) {
12
- this.#_chunks.push(chunk.toString());
22
+ this.#_chunks.push(str);
13
23
  }
14
24
  callback();
15
25
  }
16
- getLastChunk() {
17
- const lastChunk = this.#_chunks[this.#_chunks.length - 1];
26
+ getLastChunk({ raw }) {
27
+ const chunks = raw ? this.#_rawChunks : this.#_chunks;
28
+ const lastChunk = chunks[chunks.length - 1];
18
29
  return lastChunk ?? '';
19
30
  }
31
+ getFullOutput() {
32
+ return this.#_fullOutput;
33
+ }
20
34
  }
21
35
  export async function render(prompt, props, options) {
22
36
  const input = new MuteStream();
@@ -42,8 +56,11 @@ export async function render(prompt, props, options) {
42
56
  input,
43
57
  events,
44
58
  getScreen({ raw } = {}) {
45
- const lastScreen = output.getLastChunk();
59
+ const lastScreen = output.getLastChunk({ raw });
46
60
  return raw ? lastScreen : stripAnsi(lastScreen).trim();
47
61
  },
62
+ getFullOutput() {
63
+ return output.getFullOutput();
64
+ },
48
65
  };
49
66
  }
@@ -1,7 +1,7 @@
1
1
  import MuteStream from 'mute-stream';
2
2
  import type { Prompt } from '@inquirer/type';
3
3
  export declare function render<TestedPrompt extends Prompt<any, any>>(prompt: TestedPrompt, props: Parameters<TestedPrompt>[0], options?: Parameters<TestedPrompt>[1]): Promise<{
4
- answer: Promise<any>;
4
+ answer: import("@inquirer/type").CancelablePromise<any>;
5
5
  input: MuteStream;
6
6
  events: {
7
7
  keypress(name: string): void;
@@ -10,4 +10,5 @@ export declare function render<TestedPrompt extends Prompt<any, any>>(prompt: Te
10
10
  getScreen({ raw }?: {
11
11
  raw?: boolean | undefined;
12
12
  }): string;
13
+ getFullOutput(): string;
13
14
  }>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inquirer/testing",
3
- "version": "1.0.6",
3
+ "version": "2.1.0",
4
4
  "engines": {
5
5
  "node": ">=14.18.0"
6
6
  },
@@ -60,7 +60,8 @@
60
60
  "license": "MIT",
61
61
  "homepage": "https://github.com/SBoudrias/Inquirer.js/blob/master/packages/testing/README.md",
62
62
  "dependencies": {
63
- "@inquirer/type": "^1.0.5",
63
+ "@inquirer/type": "^1.1.0",
64
+ "ansi-escapes": "^4.3.2",
64
65
  "mute-stream": "^1.0.0",
65
66
  "strip-ansi": "^6.0.1"
66
67
  },
@@ -83,5 +84,5 @@
83
84
  }
84
85
  }
85
86
  },
86
- "gitHead": "235c18f13650735b201a8853b28eda001f953d0f"
87
+ "gitHead": "4c139f50414bd538eae1d48e61fd2586581d3e70"
87
88
  }