cli-kiss 0.2.5 → 0.2.6

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.
@@ -2,133 +2,131 @@ import { it } from "@jest/globals";
2
2
  import {
3
3
  command,
4
4
  operation,
5
- optionRepeatable,
6
- positionalVariadics,
7
5
  runAndExit,
8
- type,
6
+ RunColorMode,
9
7
  TypoSupport,
10
8
  usageToStyledLines,
11
9
  } from "../src";
12
10
 
13
11
  const cliName = "my-cli";
12
+ const usageBase = {
13
+ segments: [],
14
+ information: { description: "Description" },
15
+ subcommands: [],
16
+ options: [],
17
+ positionals: [],
18
+ };
19
+ const usageNone = usageToStyledLines({
20
+ cliName,
21
+ usage: usageBase,
22
+ typoSupport: TypoSupport.none(),
23
+ }).join("\n");
24
+ const usageMock = usageToStyledLines({
25
+ cliName,
26
+ usage: usageBase,
27
+ typoSupport: TypoSupport.mock(),
28
+ }).join("\n");
29
+ const usageTty = usageToStyledLines({
30
+ cliName,
31
+ usage: usageBase,
32
+ typoSupport: TypoSupport.tty(),
33
+ }).join("\n");
34
+
35
+ const unexpectedNone = "Error: Unexpected unknown option: --color";
36
+ const unexpectedMock =
37
+ "{{Error:}@darkRed}+ Unexpected unknown option: {{--color}@darkYellow}+";
14
38
 
15
39
  it("run", async function () {
16
- const usage = {
17
- segments: [{ positional: "[string]..." }],
18
- information: { description: "Description" },
19
- subcommands: [],
20
- options: [{ long: "option", label: "<string>", annotation: " [*]" }],
21
- positionals: [{ label: "[string]...", description: "Variadics" }],
22
- };
23
- const usageNone = usageToStyledLines({
24
- cliName,
25
- usage,
26
- typoSupport: TypoSupport.none(),
27
- }).join("\n");
28
- const usageMock = usageToStyledLines({
29
- cliName,
30
- usage,
31
- typoSupport: TypoSupport.mock(),
32
- }).join("\n");
33
- const usageTty = usageToStyledLines({
34
- cliName,
35
- usage,
36
- typoSupport: TypoSupport.tty(),
37
- }).join("\n");
40
+ await withEnv("FORCE_COLOR", "false", async () => {
41
+ if (process.stdout.isTTY) {
42
+ await testAllHelpsSuccesses(usageTty);
43
+ } else {
44
+ await testAllHelpsSuccesses(usageNone);
45
+ }
38
46
 
39
- await testCase("flag", ["--color=auto", "--help"], [usageTty], [], 0);
40
- await testCase("flag", ["--color=always", "--help"], [usageTty], [], 0);
41
- await testCase("flag", ["--color=never", "--help"], [usageNone], [], 0);
42
- await testCase("flag", ["--color=mock", "--help"], [usageMock], [], 0);
43
- await testCase("flag", ["--help"], [usageTty], [], 0);
44
- await testCase("env", ["--help"], [usageTty], [], 0);
45
- await testCase("always", ["--help"], [usageTty], [], 0);
46
- await testCase("never", ["--help"], [usageNone], [], 0);
47
- await testCase("mock", ["--help"], [usageMock], [], 0);
47
+ await withEnv("FORCE_COLOR", "1", async () => {
48
+ await withEnv("NO_COLOR", "1", async () => {
49
+ await testAllHelpsSuccesses(usageNone);
50
+ });
51
+ await withEnv("NO_COLOR", "true", async () => {
52
+ await testAllHelpsSuccesses(usageNone);
53
+ });
54
+ await withEnv("NO_COLOR", "", async () => {
55
+ await testAllHelpsSuccesses(usageTty);
56
+ });
57
+ await withEnv("MOCK_COLOR", "", async () => {
58
+ await testAllHelpsSuccesses(usageTty);
59
+ });
60
+ await withEnv("TERM", "dumb", async () => {
61
+ await testAllHelpsSuccesses(usageTty);
62
+ });
63
+ });
48
64
 
49
- process.env["NO_COLOR"] = "";
50
- await testCase("flag", ["--color=auto", "--help"], [usageNone], [], 0);
51
- await testCase("flag", ["--color=always", "--help"], [usageTty], [], 0);
52
- await testCase("flag", ["--color=never", "--help"], [usageNone], [], 0);
53
- await testCase("flag", ["--color=mock", "--help"], [usageMock], [], 0);
54
- await testCase("flag", ["--help"], [usageNone], [], 0);
55
- await testCase("env", ["--help"], [usageNone], [], 0);
56
- await testCase("always", ["--help"], [usageTty], [], 0);
57
- await testCase("never", ["--help"], [usageNone], [], 0);
58
- await testCase("mock", ["--help"], [usageMock], [], 0);
59
- delete process.env["NO_COLOR"];
65
+ await withEnv("FORCE_COLOR", "2", async () => {
66
+ await testAllHelpsSuccesses(usageTty);
67
+ });
68
+ await withEnv("FORCE_COLOR", "1", async () => {
69
+ await testAllHelpsSuccesses(usageTty);
70
+ });
71
+ await withEnv("FORCE_COLOR", "0", async () => {
72
+ await testAllHelpsSuccesses(usageNone);
73
+ });
74
+ await withEnv("MOCK_COLOR", "true", async () => {
75
+ await testAllHelpsSuccesses(usageMock);
76
+ });
60
77
 
61
- process.env["FORCE_COLOR"] = "";
62
- await testCase("flag", ["--color=auto", "--help"], [usageTty], [], 0);
63
- await testCase("flag", ["--color=always", "--help"], [usageTty], [], 0);
64
- await testCase("flag", ["--color=never", "--help"], [usageNone], [], 0);
65
- await testCase("flag", ["--color=mock", "--help"], [usageMock], [], 0);
66
- await testCase("flag", ["--help"], [usageTty], [], 0);
67
- await testCase("env", ["--help"], [usageTty], [], 0);
68
- await testCase("always", ["--help"], [usageTty], [], 0);
69
- await testCase("never", ["--help"], [usageNone], [], 0);
70
- await testCase("mock", ["--help"], [usageMock], [], 0);
71
- delete process.env["FORCE_COLOR"];
78
+ await withEnv("MOCK_COLOR", "1", async () => {
79
+ await testCase(
80
+ "flag",
81
+ ["--color=42"],
82
+ [],
83
+ [
84
+ usageMock,
85
+ '{{Error:}@darkRed}+ {{--color}@darkCyan}+: {{<color-mode>}@darkBlue}+: Invalid value: {{"42"}@darkYellow}+ (expected one of: {{"auto"}@darkYellow}+ | {{"always"}@darkYellow}+ | {{"never"}@darkYellow}+...)',
86
+ ],
87
+ 1,
88
+ );
89
+ });
72
90
 
73
- process.env["FORCE_COLOR"] = "0";
74
- await testCase("flag", ["--color=auto", "--help"], [usageNone], [], 0);
75
- await testCase("flag", ["--color=always", "--help"], [usageTty], [], 0);
76
- await testCase("flag", ["--color=never", "--help"], [usageNone], [], 0);
77
- await testCase("flag", ["--color=mock", "--help"], [usageMock], [], 0);
78
- await testCase("flag", ["--help"], [usageNone], [], 0);
79
- await testCase("env", ["--help"], [usageNone], [], 0);
80
- await testCase("always", ["--help"], [usageTty], [], 0);
81
- await testCase("never", ["--help"], [usageNone], [], 0);
82
- await testCase("mock", ["--help"], [usageMock], [], 0);
83
- delete process.env["FORCE_COLOR"];
91
+ await withEnv("MOCK_COLOR", "1", async () => {
92
+ await testAllFlagsFailures("env", usageMock, unexpectedMock);
93
+ });
94
+ await withEnv("FORCE_COLOR", "0", async () => {
95
+ await testAllFlagsFailures("env", usageNone, unexpectedNone);
96
+ });
97
+
98
+ await testAllFlagsFailures("mock", usageMock, unexpectedMock);
99
+ await testAllFlagsFailures("never", usageNone, unexpectedNone);
100
+ });
101
+ });
102
+
103
+ async function testAllFlagsFailures(
104
+ colorSetup: "flag" | RunColorMode,
105
+ usageErr: string,
106
+ message: string,
107
+ ) {
108
+ await testCase(colorSetup, ["--color=auto"], [], [usageErr, message], 1);
109
+ await testCase(colorSetup, ["--color=always"], [], [usageErr, message], 1);
110
+ await testCase(colorSetup, ["--color=never"], [], [usageErr, message], 1);
111
+ await testCase(colorSetup, ["--color=mock"], [], [usageErr, message], 1);
112
+ await testCase(colorSetup, ["--color"], [], [usageErr, message], 1);
113
+ }
84
114
 
85
- process.env["MOCK_COLOR"] = "";
86
- await testCase("flag", ["--color=auto", "--help"], [usageMock], [], 0);
115
+ async function testAllHelpsSuccesses(usageFromEnv: string) {
116
+ await testCase("flag", ["--color=auto", "--help"], [usageFromEnv], [], 0);
87
117
  await testCase("flag", ["--color=always", "--help"], [usageTty], [], 0);
88
118
  await testCase("flag", ["--color=never", "--help"], [usageNone], [], 0);
89
119
  await testCase("flag", ["--color=mock", "--help"], [usageMock], [], 0);
90
- await testCase("flag", ["--help"], [usageMock], [], 0);
91
- await testCase("env", ["--help"], [usageMock], [], 0);
120
+ await testCase("flag", ["--color", "--help"], [usageTty], [], 0);
121
+ await testCase("flag", ["--help"], [usageFromEnv], [], 0);
122
+ await testCase("env", ["--help"], [usageFromEnv], [], 0);
92
123
  await testCase("always", ["--help"], [usageTty], [], 0);
93
124
  await testCase("never", ["--help"], [usageNone], [], 0);
94
125
  await testCase("mock", ["--help"], [usageMock], [], 0);
95
- delete process.env["MOCK_COLOR"];
96
-
97
- process.env["MOCK_COLOR"] = "";
98
- await testCase(
99
- "flag",
100
- ["--color=42"],
101
- [],
102
- [
103
- usageMock,
104
- '{{Error:}@darkRed}+ {{--color}@darkCyan}+: {{<color-mode>}@darkBlue}+: Invalid value: {{"42"}@darkYellow}+ (expected one of: {{"auto"}@darkYellow}+ | {{"always"}@darkYellow}+ | {{"never"}@darkYellow}+...)',
105
- ],
106
- 1,
107
- );
108
- delete process.env["MOCK_COLOR"];
109
-
110
- const unexpected1 = "Error: Unexpected unknown option: --color";
111
- await testCase("never", ["--color=auto"], [], [usageNone, unexpected1], 1);
112
- await testCase("never", ["--color=always"], [], [usageNone, unexpected1], 1);
113
- await testCase("never", ["--color=never"], [], [usageNone, unexpected1], 1);
114
- await testCase("never", ["--color=mock"], [], [usageNone, unexpected1], 1);
115
- process.env["FORCE_COLOR"] = "0";
116
- await testCase("env", ["--color=auto"], [], [usageNone, unexpected1], 1);
117
- await testCase("env", ["--color=always"], [], [usageNone, unexpected1], 1);
118
- await testCase("env", ["--color=never"], [], [usageNone, unexpected1], 1);
119
- await testCase("env", ["--color=mock"], [], [usageNone, unexpected1], 1);
120
- delete process.env["FORCE_COLOR"];
121
-
122
- const unexpected2 =
123
- "{{Error:}@darkRed}+ Unexpected unknown option: {{--color}@darkYellow}+";
124
- await testCase("mock", ["--color=auto"], [], [usageMock, unexpected2], 1);
125
- await testCase("mock", ["--color=always"], [], [usageMock, unexpected2], 1);
126
- await testCase("mock", ["--color=never"], [], [usageMock, unexpected2], 1);
127
- await testCase("mock", ["--color=mock"], [], [usageMock, unexpected2], 1);
128
- });
126
+ }
129
127
 
130
128
  async function testCase(
131
- colorSetup: "flag" | "env" | "always" | "never" | "mock",
129
+ colorSetup: "flag" | RunColorMode,
132
130
  cliArgs: Array<string>,
133
131
  expectStdOut: Array<string>,
134
132
  expectStdErr: Array<string>,
@@ -145,21 +143,7 @@ async function testCase(
145
143
  const onExit = makeMocked<number, never>([null as never]);
146
144
  const cmd = command<null, void>(
147
145
  { description: "Description" },
148
- operation(
149
- {
150
- options: {
151
- value: optionRepeatable({ long: "option", type: type() }),
152
- },
153
- positionals: [
154
- positionalVariadics({ type: type(), description: "Variadics" }),
155
- ],
156
- },
157
- async function (_, { options: { value }, positionals: [rest] }) {
158
- console.log(
159
- `Has executed: ${JSON.stringify(value)}, ${JSON.stringify(rest)}`,
160
- );
161
- },
162
- ),
146
+ operation({ options: {}, positionals: [] }, async function () {}),
163
147
  );
164
148
  console.log = onLogStdOut.call;
165
149
  console.error = onLogStdErr.call;
@@ -195,3 +179,21 @@ function makeMocked<P, R>(returns: Array<R>) {
195
179
  },
196
180
  };
197
181
  }
182
+
183
+ async function withEnv(
184
+ envName: string,
185
+ envValue: string,
186
+ callback: () => Promise<void>,
187
+ ) {
188
+ let beforeEnvValue = undefined;
189
+ if (envName in process.env) {
190
+ beforeEnvValue = process.env[envName];
191
+ }
192
+ process.env[envName] = envValue;
193
+ await callback();
194
+ if (beforeEnvValue === undefined) {
195
+ delete process.env[envName];
196
+ } else {
197
+ process.env[envName] = beforeEnvValue;
198
+ }
199
+ }