cli-kiss 0.2.7 → 0.2.9

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.
Files changed (42) hide show
  1. package/README.md +8 -3
  2. package/dist/index.d.ts +200 -190
  3. package/dist/index.js +2 -2
  4. package/dist/index.js.map +1 -1
  5. package/docs/.vitepress/config.mts +1 -1
  6. package/docs/.vitepress/theme/Layout.vue +16 -0
  7. package/docs/.vitepress/theme/index.ts +5 -1
  8. package/docs/.vitepress/theme/style.css +5 -1
  9. package/docs/guide/01_getting_started.md +2 -2
  10. package/docs/guide/02_commands.md +3 -3
  11. package/docs/guide/03_options.md +11 -11
  12. package/docs/guide/04_positionals.md +9 -9
  13. package/docs/guide/05_input_types.md +17 -16
  14. package/docs/guide/06_run_as_cli.md +1 -1
  15. package/docs/index.md +2 -2
  16. package/docs/public/favicon.ico +0 -0
  17. package/docs/public/logo.png +0 -0
  18. package/package.json +1 -1
  19. package/src/index.ts +1 -1
  20. package/src/lib/Command.ts +51 -40
  21. package/src/lib/Operation.ts +41 -25
  22. package/src/lib/Option.ts +198 -127
  23. package/src/lib/Positional.ts +51 -25
  24. package/src/lib/Reader.ts +188 -226
  25. package/src/lib/Run.ts +20 -9
  26. package/src/lib/Suggest.ts +78 -0
  27. package/src/lib/Type.ts +178 -154
  28. package/src/lib/Typo.ts +58 -55
  29. package/src/lib/Usage.ts +12 -12
  30. package/tests/unit.Reader.commons.ts +86 -123
  31. package/tests/unit.Reader.parsings.ts +14 -26
  32. package/tests/unit.Reader.shortBig.ts +75 -101
  33. package/tests/unit.command.aliases.ts +88 -0
  34. package/tests/unit.command.execute.ts +6 -6
  35. package/tests/unit.command.usage.ts +19 -13
  36. package/tests/unit.fuzzed.alternatives.ts +35 -26
  37. package/tests/unit.runner.colors.ts +8 -33
  38. package/tests/unit.runner.cycle.ts +141 -156
  39. package/tests/unit.runner.errors.ts +25 -22
  40. package/docs/public/hero.png +0 -0
  41. package/src/lib/Similarity.ts +0 -41
  42. package/tests/unit.Reader.aliases.ts +0 -62
@@ -1,5 +1,5 @@
1
1
  import { expect, it } from "@jest/globals";
2
- import { ReaderArgs, ReaderOptionParsing } from "../src";
2
+ import { ReaderArgs, ReaderOptionNextGuard } from "../src";
3
3
 
4
4
  it("run", async function () {
5
5
  const stream = new ReaderArgs([
@@ -19,136 +19,110 @@ it("run", async function () {
19
19
 
20
20
  expect(stream.consumePositional()).toStrictEqual("positional-0");
21
21
 
22
- const kSofUnset = stream.registerOption({
23
- longs: [],
24
- shorts: ["sof-unset"],
25
- parsing: optionFlagParsing,
22
+ const kSofUnset = stream.registerOptionShort({
23
+ key: "sof-unset",
24
+ nextGuard: optionFlagNextGuard,
25
+ consumeGroupRestAsValue: false,
26
26
  });
27
- const kSofNormal = stream.registerOption({
28
- shorts: ["sof-normal"],
29
- longs: [],
30
- parsing: optionFlagParsing,
27
+ const kSofNormal = stream.registerOptionShort({
28
+ key: "sof-normal",
29
+ nextGuard: optionFlagNextGuard,
30
+ consumeGroupRestAsValue: false,
31
31
  });
32
- const kSofPositive = stream.registerOption({
33
- longs: [],
34
- shorts: ["sof-positive"],
35
- parsing: optionFlagParsing,
32
+ const kSofPositive = stream.registerOptionShort({
33
+ key: "sof-positive",
34
+ nextGuard: optionFlagNextGuard,
35
+ consumeGroupRestAsValue: false,
36
36
  });
37
- const kSofNegative = stream.registerOption({
38
- longs: [],
39
- shorts: ["sof-negative"],
40
- parsing: optionFlagParsing,
37
+ const kSofNegative = stream.registerOptionShort({
38
+ key: "sof-negative",
39
+ nextGuard: optionFlagNextGuard,
40
+ consumeGroupRestAsValue: false,
41
41
  });
42
42
 
43
- const kAa = stream.registerOption({
44
- longs: [],
45
- shorts: ["aa"],
46
- parsing: optionFlagParsing,
43
+ const kAa = stream.registerOptionShort({
44
+ key: "aa",
45
+ nextGuard: optionFlagNextGuard,
46
+ consumeGroupRestAsValue: false,
47
47
  });
48
- const kBb = stream.registerOption({
49
- longs: [],
50
- shorts: ["bb"],
51
- parsing: optionFlagParsing,
48
+ const kBb = stream.registerOptionShort({
49
+ key: "bb",
50
+ nextGuard: optionFlagNextGuard,
51
+ consumeGroupRestAsValue: false,
52
52
  });
53
- const kCc = stream.registerOption({
54
- longs: [],
55
- shorts: ["cc"],
56
- parsing: optionFlagParsing,
53
+ const kCc = stream.registerOptionShort({
54
+ key: "cc",
55
+ nextGuard: optionFlagNextGuard,
56
+ consumeGroupRestAsValue: false,
57
57
  });
58
58
 
59
59
  expect(stream.consumePositional()).toStrictEqual("positional-1");
60
60
 
61
- const kSovSplit = stream.registerOption({
62
- longs: [],
63
- shorts: ["sov-split"],
64
- parsing: optionValueFixedUniqueParsing,
61
+ const kSovSplit = stream.registerOptionShort({
62
+ key: "sov-split",
63
+ nextGuard: optionValuedNextGuard,
64
+ consumeGroupRestAsValue: true,
65
65
  });
66
- const kSovJoin = stream.registerOption({
67
- longs: [],
68
- shorts: ["sov-join"],
69
- parsing: optionValueFixedUniqueParsing,
66
+ const kSovJoin = stream.registerOptionShort({
67
+ key: "sov-join",
68
+ nextGuard: optionValuedNextGuard,
69
+ consumeGroupRestAsValue: true,
70
70
  });
71
- const kSovUnset = stream.registerOption({
72
- longs: [],
73
- shorts: ["sov-unset"],
74
- parsing: optionValueFixedUniqueParsing,
71
+ const kSovUnset = stream.registerOptionShort({
72
+ key: "sov-unset",
73
+ nextGuard: optionValuedNextGuard,
74
+ consumeGroupRestAsValue: true,
75
75
  });
76
76
 
77
- const kDd = stream.registerOption({
78
- longs: [],
79
- shorts: ["dd"],
80
- parsing: optionFlagParsing,
77
+ const kDd = stream.registerOptionShort({
78
+ key: "dd",
79
+ nextGuard: optionFlagNextGuard,
80
+ consumeGroupRestAsValue: false,
81
81
  });
82
- const kEe = stream.registerOption({
83
- longs: [],
84
- shorts: ["ee"],
85
- parsing: optionFlagParsing,
82
+ const kEe = stream.registerOptionShort({
83
+ key: "ee",
84
+ nextGuard: optionFlagNextGuard,
85
+ consumeGroupRestAsValue: false,
86
86
  });
87
- const kFf = stream.registerOption({
88
- longs: [],
89
- shorts: ["ff"],
90
- parsing: optionFlagParsing,
87
+
88
+ const kFf = stream.registerOptionShort({
89
+ key: "ff",
90
+ nextGuard: optionFlagNextGuard,
91
+ consumeGroupRestAsValue: false,
91
92
  });
92
- const kGg = stream.registerOption({
93
- longs: [],
94
- shorts: ["gg"],
95
- parsing: optionFlagParsing,
93
+ const kGg = stream.registerOptionShort({
94
+ key: "gg",
95
+ nextGuard: optionFlagNextGuard,
96
+ consumeGroupRestAsValue: false,
96
97
  });
97
98
 
98
99
  expect(stream.consumePositional()).toStrictEqual("positional-2");
99
100
 
100
- expect(stream.getOptionValues(kSofUnset)).toStrictEqual([]);
101
- expect(stream.getOptionValues(kSofNormal)).toStrictEqual([
102
- { inlined: null, separated: [] },
103
- ]);
104
- expect(stream.getOptionValues(kSofPositive)).toStrictEqual([
105
- { inlined: "true", separated: [] },
106
- ]);
107
- expect(stream.getOptionValues(kSofNegative)).toStrictEqual([
108
- { inlined: "false", separated: [] },
109
- ]);
101
+ expect(kSofUnset()).toStrictEqual([]);
102
+ expect(kSofNormal()).toStrictEqual([{ inlined: null, separated: [] }]);
103
+ expect(kSofPositive()).toStrictEqual([{ inlined: "true", separated: [] }]);
104
+ expect(kSofNegative()).toStrictEqual([{ inlined: "false", separated: [] }]);
110
105
 
111
- expect(stream.getOptionValues(kAa)).toStrictEqual([
112
- { inlined: null, separated: [] },
113
- ]);
114
- expect(stream.getOptionValues(kBb)).toStrictEqual([
115
- { inlined: null, separated: [] },
116
- ]);
117
- expect(stream.getOptionValues(kCc)).toStrictEqual([
118
- { inlined: null, separated: [] },
119
- ]);
106
+ expect(kAa()).toStrictEqual([{ inlined: null, separated: [] }]);
107
+ expect(kBb()).toStrictEqual([{ inlined: null, separated: [] }]);
108
+ expect(kCc()).toStrictEqual([{ inlined: null, separated: [] }]);
120
109
 
121
- expect(stream.getOptionValues(kSovUnset)).toStrictEqual([]);
122
- expect(stream.getOptionValues(kSovSplit)).toStrictEqual([
110
+ expect(kSovUnset()).toStrictEqual([]);
111
+ expect(kSovSplit()).toStrictEqual([
123
112
  { inlined: null, separated: ["1.1"] },
124
113
  { inlined: null, separated: ["1.2"] },
125
114
  ]);
126
- expect(stream.getOptionValues(kSovJoin)).toStrictEqual([
115
+ expect(kSovJoin()).toStrictEqual([
127
116
  { inlined: "2.1", separated: [] },
128
117
  { inlined: "2.2", separated: [] },
129
118
  ]);
130
119
 
131
- expect(stream.getOptionValues(kDd)).toStrictEqual([
132
- { inlined: null, separated: [] },
133
- ]);
134
- expect(stream.getOptionValues(kEe)).toStrictEqual([
135
- { inlined: null, separated: [] },
136
- ]);
137
- expect(stream.getOptionValues(kFf)).toStrictEqual([
138
- { inlined: null, separated: [] },
139
- ]);
140
- expect(stream.getOptionValues(kGg)).toStrictEqual([
141
- { inlined: null, separated: [] },
142
- ]);
120
+ expect(kDd()).toStrictEqual([{ inlined: null, separated: [] }]);
121
+ expect(kEe()).toStrictEqual([{ inlined: null, separated: [] }]);
122
+ expect(kFf()).toStrictEqual([{ inlined: null, separated: [] }]);
123
+ expect(kGg()).toStrictEqual([{ inlined: null, separated: [] }]);
143
124
  });
144
125
 
145
- const optionFlagParsing: ReaderOptionParsing = {
146
- consumeShortGroup: false,
147
- consumeNextArg: () => false,
148
- };
149
-
150
- const optionValueFixedUniqueParsing: ReaderOptionParsing = {
151
- consumeShortGroup: true,
152
- consumeNextArg: (inlined, separated) =>
153
- inlined === null && separated.length === 0,
154
- };
126
+ const optionFlagNextGuard: ReaderOptionNextGuard = () => false;
127
+ const optionValuedNextGuard: ReaderOptionNextGuard = (value) =>
128
+ value.inlined === null && value.separated.length === 0;
@@ -0,0 +1,88 @@
1
+ import { expect, it } from "@jest/globals";
2
+ import {
3
+ command,
4
+ operation,
5
+ optionFlag,
6
+ optionRepeatable,
7
+ optionSingleValue,
8
+ ReaderArgs,
9
+ typeString,
10
+ } from "../src";
11
+
12
+ it("run", async function () {
13
+ const cmd = command(
14
+ { description: "Description" },
15
+ operation(
16
+ {
17
+ options: {
18
+ option: optionRepeatable({
19
+ long: "option",
20
+ type: typeString(),
21
+ aliases: {
22
+ longs: ["option-alias1", "option-alias2"],
23
+ shorts: ["pts", "o"],
24
+ },
25
+ }),
26
+ flag1: optionFlag({
27
+ long: "flag1",
28
+ aliases: { longs: ["flag1-alias"], shorts: ["fa"] },
29
+ }),
30
+ flag2: optionFlag({
31
+ long: "flag2",
32
+ aliases: { longs: ["flag2-alias"], shorts: ["fb"] },
33
+ }),
34
+ weird: optionRepeatable({
35
+ long: "2",
36
+ aliases: { shorts: ["2o"] },
37
+ type: typeString(),
38
+ }),
39
+ v1: optionSingleValue({
40
+ long: "v1",
41
+ aliases: { shorts: ["va"] },
42
+ type: typeString(),
43
+ impliedValueIfNotInlined: () => "bypass",
44
+ fallbackValueIfAbsent: () => undefined,
45
+ }),
46
+ v2: optionSingleValue({
47
+ long: "v2",
48
+ aliases: { shorts: ["vb"] },
49
+ type: typeString(),
50
+ impliedValueIfNotInlined: () => "bypass",
51
+ fallbackValueIfAbsent: () => undefined,
52
+ }),
53
+ },
54
+ positionals: [],
55
+ },
56
+ async function (_context, inputs) {
57
+ return inputs;
58
+ },
59
+ ),
60
+ );
61
+ const readerArgs = new ReaderArgs([
62
+ "--option=1.1",
63
+ "--option-alias1=1.2",
64
+ "--option-alias2",
65
+ "1.3",
66
+ "-pts=1.4",
67
+ "-vbva=42",
68
+ "-o",
69
+ "1.5",
70
+ "--flag1-alias",
71
+ "--2=woops",
72
+ "-fb2o=1.6",
73
+ ]);
74
+ const decoder = cmd.consumeAndMakeDecoder(readerArgs);
75
+ const interpreter = decoder.decodeAndMakeInterpreter();
76
+ const output = await interpreter.executeWithContext({});
77
+ expect(output).toStrictEqual({
78
+ options: {
79
+ option: ["1.1", "1.2", "1.3", "1.4", "1.5"],
80
+ flag1: true,
81
+ flag2: true,
82
+ weird: ["woops", "1.6"],
83
+ v1: "42",
84
+ v2: "bypass",
85
+ },
86
+ positionals: [],
87
+ });
88
+ });
@@ -12,9 +12,9 @@ import {
12
12
  positionalRequired,
13
13
  positionalVariadics,
14
14
  ReaderArgs,
15
- type,
16
15
  typeList,
17
16
  typeNumber,
17
+ typeString,
18
18
  } from "../src";
19
19
 
20
20
  const rootCommand = commandChained(
@@ -46,8 +46,8 @@ const rootCommand = commandChained(
46
46
  options: {
47
47
  string: optionSingleValue({
48
48
  long: "string-option",
49
- type: type(),
50
- defaultIfNotSpecified: () => undefined,
49
+ type: typeString(),
50
+ fallbackValueIfAbsent: () => undefined,
51
51
  }),
52
52
  number: optionRepeatable({
53
53
  long: "number-option",
@@ -66,7 +66,7 @@ const rootCommand = commandChained(
66
66
  operation(
67
67
  {
68
68
  options: {},
69
- positionals: [positionalRequired({ type: type() })],
69
+ positionals: [positionalRequired({ type: typeString() })],
70
70
  },
71
71
  async function (context, inputs) {
72
72
  return { at: "sub1", context, inputs };
@@ -80,8 +80,8 @@ const rootCommand = commandChained(
80
80
  options: {},
81
81
  positionals: [
82
82
  positionalRequired({ type: typeNumber() }),
83
- positionalOptional({ type: type(), default: () => "42" }),
84
- positionalVariadics({ type: type() }),
83
+ positionalOptional({ type: typeString(), default: () => "42" }),
84
+ positionalVariadics({ type: typeString() }),
85
85
  ],
86
86
  },
87
87
  async function (context, inputs) {
@@ -1,4 +1,4 @@
1
- import { it } from "@jest/globals";
1
+ import { expect, it } from "@jest/globals";
2
2
  import {
3
3
  command,
4
4
  Command,
@@ -12,10 +12,10 @@ import {
12
12
  positionalRequired,
13
13
  positionalVariadics,
14
14
  ReaderArgs,
15
- type,
16
15
  typeChoice,
17
16
  typeList,
18
17
  typeNumber,
18
+ typeString,
19
19
  typeTuple,
20
20
  TypoSupport,
21
21
  usageToStyledLines,
@@ -37,10 +37,9 @@ const rootCommand = commandChained<any, any, any>(
37
37
  options: {
38
38
  choiceOption: optionSingleValue({
39
39
  long: "choice-option",
40
- type: typeChoice("choice", ["unset", "empty", "choice1", "choice2"]),
40
+ type: typeChoice("choice", ["unset", "choice1", "choice2"]),
41
41
  description: "choice-option description",
42
- valueIfNothingInlined: () => "empty",
43
- defaultIfNotSpecified: () => "unset",
42
+ fallbackValueIfAbsent: () => "unset",
44
43
  }),
45
44
  booleanFlag: optionFlag({
46
45
  short: "b",
@@ -80,13 +79,13 @@ const rootCommand = commandChained<any, any, any>(
80
79
  stringOption: optionSingleValue({
81
80
  short: "s",
82
81
  long: "string-option",
83
- type: type("cool-stuff"),
84
- defaultIfNotSpecified: () => undefined,
82
+ type: typeString("cool-stuff"),
83
+ fallbackValueIfAbsent: () => undefined,
85
84
  description: "string-option description",
86
85
  }),
87
86
  complexOption: optionRepeatable({
88
87
  long: "complex-option",
89
- type: typeTuple([typeNumber(), typeList(type("string"))]),
88
+ type: typeTuple([typeNumber(), typeList(typeString("string"))]),
90
89
  description: "complex-option description",
91
90
  }),
92
91
  },
@@ -128,7 +127,7 @@ const rootCommand = commandChained<any, any, any>(
128
127
  positionals: [
129
128
  positionalRequired({
130
129
  description: "Required positional string",
131
- type: type("pos-3.1"),
130
+ type: typeString("pos-3.1"),
132
131
  }),
133
132
  ],
134
133
  },
@@ -173,11 +172,17 @@ const rootCommand = commandChained<any, any, any>(
173
172
  options: {
174
173
  duduValue: optionSingleValue({
175
174
  long: "dudu",
176
- type: type("dudu-value"),
177
- defaultIfNotSpecified: () => "duduDefault",
175
+ type: typeString("dudu-value"),
176
+ fallbackValueIfAbsent: () => "duduDefault",
178
177
  hint: "Dudu option hint",
179
178
  description: "Dudu option description",
180
179
  }),
180
+ impliable: optionSingleValue({
181
+ long: "impliable",
182
+ type: typeString("text"),
183
+ impliedValueIfNotInlined: () => "implied",
184
+ fallbackValueIfAbsent: () => "absent",
185
+ }),
181
186
  },
182
187
  positionals: [
183
188
  positionalRequired({
@@ -187,12 +192,12 @@ const rootCommand = commandChained<any, any, any>(
187
192
  positionalOptional({
188
193
  description: "Optional positional string",
189
194
  hint: "Optional positional hint",
190
- type: type("pos-4"),
195
+ type: typeString("pos-4"),
191
196
  default: () => "42",
192
197
  }),
193
198
  positionalVariadics({
194
199
  description: "Variadic positionals strings",
195
- type: type("pos-5"),
200
+ type: typeString("pos-5"),
196
201
  }),
197
202
  ],
198
203
  },
@@ -308,6 +313,7 @@ it("run", async function () {
308
313
  " {{-s}@darkCyan}+, {{--string-option}@darkCyan}+ {{<cool-stuff>}@darkBlue}+ string-option description",
309
314
  " {{--complex-option}@darkCyan}+ {{<number,string[,string]...>}@darkBlue}+{{ [*]}-}* complex-option description",
310
315
  " {{--dudu}@darkCyan}+ {{<dudu-value>}@darkBlue}+ Dudu option description {{(Dudu option hint)}-}*",
316
+ " {{--impliable}@darkCyan}+{{[=text]}-}*",
311
317
  "",
312
318
  "{{Examples:}@darkGreen}+",
313
319
  " {{# Example usage of subcommand 2}-}*",
@@ -1,34 +1,43 @@
1
- import { it } from "@jest/globals";
2
- import { similaritySort } from "../src/lib/Similarity";
1
+ import { expect, it } from "@jest/globals";
2
+ import { TypoString, TypoText } from "../src";
3
+ import { suggestTextPushMessage } from "../src/lib/Suggest";
3
4
 
4
5
  it("run", async function () {
5
- expect(
6
- orderBySimilarity("--inst", ["--flag", "--blah", "--install"]),
7
- ).toStrictEqual(["--install", "--flag", "--blah"]);
6
+ expectReasonables(["--flag", "--blah", "--install"], "--inst", ["--install"]);
7
+ expectReasonables(["install", "dudu", "--blah"], "instlal", ["install"]);
8
+ expectReasonables(["hello", "kat", "cats"], "cat", ["cats", "kat"]);
9
+ expectReasonables(["cut", "kat"], "cat", ["cut", "kat"]);
10
+ expectReasonables(["abc", "ac", "ab"], "acb", ["abc", "ac", "ab"]);
8
11
 
9
- expect(
10
- orderBySimilarity("instlal", ["install", "dudu", "--blah"]),
11
- ).toStrictEqual(["install", "--blah", "dudu"]);
12
-
13
- expect(
14
- orderBySimilarity("cat", ["cats", "catz", "cut", "kat", "hello", "world"]),
15
- ).toStrictEqual(["cats", "catz", "cut", "kat", "hello", "world"]);
16
-
17
- expect(orderBySimilarity("cat", ["cut", "kat"])).toStrictEqual([
18
- "cut",
19
- "kat",
20
- ]);
21
-
22
- expect(orderBySimilarity("acb", ["abc", "ac", "ab"])).toStrictEqual([
23
- "abc",
24
- "ac",
25
- "ab",
12
+ const library = [
13
+ "install",
14
+ "install-package",
15
+ "install-package-latest",
16
+ "uninstall",
17
+ "update",
18
+ "list",
19
+ ];
20
+ expectReasonables(library, "instal", ["install", "uninstall"]);
21
+ expectReasonables(library, "insta-package", ["install-package"]);
22
+ expectReasonables(library, "insta-package-lates", ["install-package-latest"]);
23
+ expectReasonables(library, "install-package-lat", [
24
+ "install-package-latest",
25
+ "install-package",
26
26
  ]);
27
27
  });
28
28
 
29
- function orderBySimilarity(reference: string, candidates: Array<string>) {
30
- return similaritySort(
31
- reference,
32
- candidates.map((key) => ({ key, value: key })),
29
+ function expectReasonables(
30
+ references: Array<string>,
31
+ query: string,
32
+ reasonables: Array<string>,
33
+ ) {
34
+ const text = new TypoText();
35
+ suggestTextPushMessage(
36
+ text,
37
+ query,
38
+ references.map((key) => ({ reference: key, hint: new TypoString(key) })),
39
+ );
40
+ expect(text.computeRawString()).toStrictEqual(
41
+ " Did you mean: " + reasonables.join(", ") + " ?",
33
42
  );
34
43
  }
@@ -1,4 +1,4 @@
1
- import { it } from "@jest/globals";
1
+ import { expect, it } from "@jest/globals";
2
2
  import {
3
3
  command,
4
4
  operation,
@@ -33,12 +33,12 @@ const usageTty = usageToStyledLines({
33
33
  }).join("\n");
34
34
 
35
35
  const unknownOptionNone =
36
- 'Error: Unknown option: "--color": did you mean: --help, --version ?';
36
+ 'Error: Unknown option: "--color". Did you mean: --help, --version ?';
37
37
  const unknownOptionMock =
38
- '{{Error:}@darkRed}+ Unknown option: {{"--color"}@darkYellow}+: did you mean: {{--help}@darkCyan}+, {{--version}@darkCyan}+ ?';
38
+ '{{Error:}@darkRed}+ Unknown option: {{"--color"}@darkYellow}+. Did you mean: {{--help}@darkCyan}+, {{--version}@darkCyan}+ ?';
39
39
 
40
40
  it("run", async function () {
41
- await withEnv("FORCE_COLOR", "false", async () => {
41
+ await withEnv("FORCE_COLOR", "", async () => {
42
42
  if (process.stdout.isTTY) {
43
43
  await testAllHelpsSuccesses(usageTty);
44
44
  } else {
@@ -55,9 +55,6 @@ it("run", async function () {
55
55
  await withEnv("NO_COLOR", "", async () => {
56
56
  await testAllHelpsSuccesses(usageTty);
57
57
  });
58
- await withEnv("MOCK_COLOR", "", async () => {
59
- await testAllHelpsSuccesses(usageTty);
60
- });
61
58
  await withEnv("TERM", "dumb", async () => {
62
59
  await testAllHelpsSuccesses(usageTty);
63
60
  });
@@ -72,32 +69,12 @@ it("run", async function () {
72
69
  await withEnv("FORCE_COLOR", "0", async () => {
73
70
  await testAllHelpsSuccesses(usageNone);
74
71
  });
75
- await withEnv("MOCK_COLOR", "true", async () => {
76
- await testAllHelpsSuccesses(usageMock);
77
- });
78
-
79
- await withEnv("MOCK_COLOR", "1", async () => {
80
- await testCase(
81
- "flag",
82
- ["--color=42"],
83
- [],
84
- [
85
- usageMock,
86
- '{{Error:}@darkRed}+ {{--color}@darkCyan}+: {{<color-mode>}@darkBlue}+: Unknown value: {{"42"}@darkYellow}+: did you mean: {{"auto"}@darkYellow}+, {{"always"}@darkYellow}+, {{"never"}@darkYellow}+ ?',
87
- ],
88
- 1,
89
- );
90
- });
91
72
 
92
- await withEnv("MOCK_COLOR", "1", async () => {
93
- await testAllFlagsFailures("env", usageMock, unknownOptionMock);
94
- });
73
+ await testAllFlagsFailures("mock", usageMock, unknownOptionMock);
74
+ await testAllFlagsFailures("never", usageNone, unknownOptionNone);
95
75
  await withEnv("FORCE_COLOR", "0", async () => {
96
76
  await testAllFlagsFailures("env", usageNone, unknownOptionNone);
97
77
  });
98
-
99
- await testAllFlagsFailures("mock", usageMock, unknownOptionMock);
100
- await testAllFlagsFailures("never", usageNone, unknownOptionNone);
101
78
  });
102
79
  });
103
80
 
@@ -106,24 +83,22 @@ async function testAllFlagsFailures(
106
83
  usageErr: string,
107
84
  message: string,
108
85
  ) {
86
+ await testCase(colorSetup, ["--color"], [], [usageErr, message], 1);
109
87
  await testCase(colorSetup, ["--color=auto"], [], [usageErr, message], 1);
110
88
  await testCase(colorSetup, ["--color=always"], [], [usageErr, message], 1);
111
89
  await testCase(colorSetup, ["--color=never"], [], [usageErr, message], 1);
112
- await testCase(colorSetup, ["--color=mock"], [], [usageErr, message], 1);
113
- await testCase(colorSetup, ["--color"], [], [usageErr, message], 1);
114
90
  }
115
91
 
116
92
  async function testAllHelpsSuccesses(usageFromEnv: string) {
117
93
  await testCase("flag", ["--color=auto", "--help"], [usageFromEnv], [], 0);
118
94
  await testCase("flag", ["--color=always", "--help"], [usageTty], [], 0);
119
95
  await testCase("flag", ["--color=never", "--help"], [usageNone], [], 0);
120
- await testCase("flag", ["--color=mock", "--help"], [usageMock], [], 0);
121
96
  await testCase("flag", ["--color", "--help"], [usageTty], [], 0);
122
97
  await testCase("flag", ["--help"], [usageFromEnv], [], 0);
123
- await testCase("env", ["--help"], [usageFromEnv], [], 0);
124
98
  await testCase("always", ["--help"], [usageTty], [], 0);
125
99
  await testCase("never", ["--help"], [usageNone], [], 0);
126
100
  await testCase("mock", ["--help"], [usageMock], [], 0);
101
+ await testCase("env", ["--help"], [usageFromEnv], [], 0);
127
102
  }
128
103
 
129
104
  async function testCase(