From ecc9099968be328d359bfd5abda3a3a8801367d3 Mon Sep 17 00:00:00 2001 From: Michael Molisani Date: Sat, 19 Oct 2024 16:12:45 -0400 Subject: [PATCH] fix: allow flags to parse arrays without variadic modifier Signed-off-by: Michael Molisani --- packages/core/src/parameter/flag/types.ts | 14 +- .../reference/parameter/flag/formatting.txt | 8 + .../reference/parameter/formatting.txt | 4 + .../tests/parameter/flag/formatting.spec.ts | 55 ++ .../core/tests/parameter/formatting.spec.ts | 51 ++ packages/core/tests/parameter/scanner.spec.ts | 824 ++++++++++++++++++ 6 files changed, 952 insertions(+), 4 deletions(-) diff --git a/packages/core/src/parameter/flag/types.ts b/packages/core/src/parameter/flag/types.ts index de3bc98..a9eaba4 100644 --- a/packages/core/src/parameter/flag/types.ts +++ b/packages/core/src/parameter/flag/types.ts @@ -298,8 +298,11 @@ interface RequiredVariadicParsedFlagParameter type TypedFlagParameter_Optional = [T] extends [readonly (infer A)[]] ? [A] extends [string] - ? OptionalVariadicParsedFlagParameter | OptionalVariadicEnumFlagParameter - : OptionalVariadicParsedFlagParameter + ? + | OptionalVariadicParsedFlagParameter + | OptionalParsedFlagParameter + | OptionalVariadicEnumFlagParameter + : OptionalVariadicParsedFlagParameter | OptionalParsedFlagParameter : [T] extends [boolean] ? OptionalBooleanFlagParameter | OptionalParsedFlagParameter : [T] extends [number] @@ -312,8 +315,11 @@ type TypedFlagParameter_Optional = [T] extend type TypedFlagParameter_Required = [T] extends [readonly (infer A)[]] ? [A] extends [string] - ? RequiredVariadicParsedFlagParameter | RequiredVariadicEnumFlagParameter - : RequiredVariadicParsedFlagParameter + ? + | RequiredVariadicParsedFlagParameter + | RequiredParsedFlagParameter + | RequiredVariadicEnumFlagParameter + : RequiredVariadicParsedFlagParameter | RequiredParsedFlagParameter : [T] extends [boolean] ? RequiredBooleanFlagParameter | RequiredParsedFlagParameter : [T] extends [number] diff --git a/packages/core/tests/baselines/reference/parameter/flag/formatting.txt b/packages/core/tests/baselines/reference/parameter/flag/formatting.txt index 38787ce..8fdbad7 100644 --- a/packages/core/tests/baselines/reference/parameter/flag/formatting.txt +++ b/packages/core/tests/baselines/reference/parameter/flag/formatting.txt @@ -50,6 +50,10 @@  --required-parsed-with-kebab-case-name required parsed flag with kebab-case name -h --help Print help information and exit  -- All subsequent inputs should be interpreted as arguments +:::: formatDocumentationForFlagParameters / parsed / optional array parsed flag + [--optionalArrayParsed] optional array parsed flag +-h  --help Print help information and exit +  -- All subsequent inputs should be interpreted as arguments :::: formatDocumentationForFlagParameters / parsed / optional parsed flag  [--optionalParsed] optional parsed flag -h  --help Print help information and exit @@ -62,6 +66,10 @@  [--optionalVariadicParsed]... optional variadic parsed flag -h  --help Print help information and exit   -- All subsequent inputs should be interpreted as arguments +:::: formatDocumentationForFlagParameters / parsed / required array parsed flag + --requiredArrayParsed required array parsed flag +-h --help Print help information and exit + -- All subsequent inputs should be interpreted as arguments :::: formatDocumentationForFlagParameters / parsed / required parsed flag  --requiredParsed required parsed flag -h --help Print help information and exit diff --git a/packages/core/tests/baselines/reference/parameter/formatting.txt b/packages/core/tests/baselines/reference/parameter/formatting.txt index 37661cc..1fe0a3e 100644 --- a/packages/core/tests/baselines/reference/parameter/formatting.txt +++ b/packages/core/tests/baselines/reference/parameter/formatting.txt @@ -12,6 +12,8 @@ cli [--optionalEnum a|b|c] cli (--requiredEnum a|b|c) :::: formatUsageLineForParameters / flags / enum / required enum flag with default cli [--requiredEnum a|b|c] +:::: formatUsageLineForParameters / flags / parsed / optional array parsed flag +cli [--optionalArrayParsed value] :::: formatUsageLineForParameters / flags / parsed / optional parsed flag cli [--optionalParsed value] :::: formatUsageLineForParameters / flags / parsed / optional parsed flag [hidden] @@ -20,6 +22,8 @@ cli cli [--optionalParsed parsed] :::: formatUsageLineForParameters / flags / parsed / optional variadic parsed flag cli [--optionalVariadicParsed value]... +:::: formatUsageLineForParameters / flags / parsed / required array parsed flag +cli (--requiredArrayParsed value) :::: formatUsageLineForParameters / flags / parsed / required parsed flag cli (--requiredParsed value) :::: formatUsageLineForParameters / flags / parsed / required parsed flag with alias diff --git a/packages/core/tests/parameter/flag/formatting.spec.ts b/packages/core/tests/parameter/flag/formatting.spec.ts index 47668f9..3865c3a 100644 --- a/packages/core/tests/parameter/flag/formatting.spec.ts +++ b/packages/core/tests/parameter/flag/formatting.spec.ts @@ -637,6 +637,61 @@ describe("formatDocumentationForFlagParameters", function () { compareToBaseline(this, StringArrayBaselineFormat, lines); }); + it("required array parsed flag", function () { + // GIVEN + type Positional = []; + type Flags = { + readonly requiredArrayParsed: string[]; + }; + + const parameters: TypedCommandParameters = { + flags: { + requiredArrayParsed: { + kind: "parsed", + parse: (values) => values.split(","), + brief: "required array parsed flag", + }, + }, + positional: { kind: "tuple", parameters: [] }, + }; + + // WHEN + const lines = formatDocumentationForFlagParameters(parameters.flags, parameters.aliases ?? {}, defaultArgs); + + // THEN + compareToBaseline(this, StringArrayBaselineFormat, lines); + }); + + it("optional array parsed flag", function () { + // GIVEN + type Positional = []; + type Flags = { + readonly optionalArrayParsed?: string[]; + }; + + const parameters: TypedCommandParameters = { + flags: { + optionalArrayParsed: { + kind: "parsed", + parse: (values) => values.split(","), + optional: true, + brief: "optional array parsed flag", + }, + }, + positional: { kind: "tuple", parameters: [] }, + }; + + // WHEN + const lines = formatDocumentationForFlagParameters( + parameters.flags ?? {}, + parameters.aliases ?? {}, + defaultArgs, + ); + + // THEN + compareToBaseline(this, StringArrayBaselineFormat, lines); + }); + it("multiple parsed flags", function () { // GIVEN type Positional = []; diff --git a/packages/core/tests/parameter/formatting.spec.ts b/packages/core/tests/parameter/formatting.spec.ts index f6e7757..0a73dcf 100644 --- a/packages/core/tests/parameter/formatting.spec.ts +++ b/packages/core/tests/parameter/formatting.spec.ts @@ -676,6 +676,57 @@ describe("formatUsageLineForParameters", function () { // THEN compareToBaseline(this, StringArrayBaselineFormat, [line]); }); + + it("required array parsed flag", function () { + // GIVEN + type Positional = []; + type Flags = { + readonly requiredArrayParsed: string[]; + }; + + const parameters: TypedCommandParameters = { + flags: { + requiredArrayParsed: { + kind: "parsed", + parse: (values) => values.split(","), + brief: "required array parsed flag", + }, + }, + positional: { kind: "tuple", parameters: [] }, + }; + + // WHEN + const line = formatUsageLineForParameters(parameters, defaultArgs); + + // THEN + compareToBaseline(this, StringArrayBaselineFormat, [line]); + }); + + it("optional array parsed flag", function () { + // GIVEN + type Positional = []; + type Flags = { + readonly optionalArrayParsed?: string[]; + }; + + const parameters: TypedCommandParameters = { + flags: { + optionalArrayParsed: { + kind: "parsed", + parse: (values) => values.split(","), + optional: true, + brief: "optional array parsed flag", + }, + }, + positional: { kind: "tuple", parameters: [] }, + }; + + // WHEN + const line = formatUsageLineForParameters(parameters, defaultArgs); + + // THEN + compareToBaseline(this, StringArrayBaselineFormat, [line]); + }); }); }); }); diff --git a/packages/core/tests/parameter/scanner.spec.ts b/packages/core/tests/parameter/scanner.spec.ts index 293584c..ca53ca5 100644 --- a/packages/core/tests/parameter/scanner.spec.ts +++ b/packages/core/tests/parameter/scanner.spec.ts @@ -8399,6 +8399,830 @@ describe("ArgumentScanner", () => { }); }); + describe("optional variadic parsed flags", () => { + type Positional = []; + type Flags = { + readonly foo?: number[]; + }; + + const numberArrayParser = (values: string) => values.split(",").map((value) => numberParser(value)); + + const parameters: TypedCommandParameters = { + flags: { + foo: { + kind: "parsed", + parse: numberArrayParser, + optional: true, + brief: "foo", + }, + }, + positional: { kind: "tuple", parameters: [] }, + }; + + it("parseArguments", async () => { + await testArgumentScannerParse({ + parameters, + config: defaultScannerConfig, + inputs: [], + expected: { + success: true, + arguments: [{ foo: void 0 }], + }, + }); + await testArgumentScannerParse({ + parameters, + config: defaultScannerConfig, + inputs: ["--foo=100"], + expected: { + success: true, + arguments: [{ foo: [100] }], + }, + }); + await testArgumentScannerParse({ + parameters, + config: defaultScannerConfig, + inputs: ["--foo", "100"], + expected: { + success: true, + arguments: [ + { + foo: [100], + }, + ], + }, + }); + await testArgumentScannerParse({ + parameters, + config: defaultScannerConfig, + inputs: ["--foo=100,200"], + expected: { + success: true, + arguments: [ + { + foo: [100, 200], + }, + ], + }, + }); + await testArgumentScannerParse({ + parameters, + config: defaultScannerConfig, + inputs: ["--foo", "100,200"], + expected: { + success: true, + arguments: [ + { + foo: [100, 200], + }, + ], + }, + }); + + await testArgumentScannerParse({ + parameters, + config: defaultScannerConfig, + inputs: ["--foo"], + expected: { + success: false, + errors: [ + { + type: "UnsatisfiedFlagError", + properties: { + externalFlagName: "foo", + }, + }, + ], + }, + }); + await testArgumentScannerParse({ + parameters, + config: defaultScannerConfig, + inputs: ["--foo=100", "--foo"], + expected: { + success: false, + errors: [ + { + type: "UnsatisfiedFlagError", + properties: { + externalFlagName: "foo", + }, + }, + ], + }, + }); + }); + + it("proposeCompletions", async () => { + await testCompletions({ + parameters, + inputs: [], + partial: "", + scannerConfig: defaultScannerConfig, + completionConfig: defaultCompletionConfig, + expected: [{ kind: "argument:flag", completion: "--foo", brief: "foo" }], + }); + await testCompletions({ + parameters, + inputs: [], + partial: "-", + scannerConfig: defaultScannerConfig, + completionConfig: defaultCompletionConfig, + expected: [{ kind: "argument:flag", completion: "--foo", brief: "foo" }], + }); + await testCompletions({ + parameters, + inputs: [], + partial: "--", + scannerConfig: defaultScannerConfig, + completionConfig: defaultCompletionConfig, + expected: [{ kind: "argument:flag", completion: "--foo", brief: "foo" }], + }); + await testCompletions({ + parameters, + inputs: [], + partial: "--f", + scannerConfig: defaultScannerConfig, + completionConfig: defaultCompletionConfig, + expected: [{ kind: "argument:flag", completion: "--foo", brief: "foo" }], + }); + + await testCompletions({ + parameters, + inputs: ["--foo"], + partial: "", + scannerConfig: defaultScannerConfig, + completionConfig: defaultCompletionConfig, + expected: [], + }); + await testCompletions({ + parameters, + inputs: ["--foo"], + partial: "-", + scannerConfig: defaultScannerConfig, + completionConfig: defaultCompletionConfig, + expected: [], + }); + await testCompletions({ + parameters, + inputs: ["--foo"], + partial: "--", + scannerConfig: defaultScannerConfig, + completionConfig: defaultCompletionConfig, + expected: [], + }); + await testCompletions({ + parameters, + inputs: ["--foo"], + partial: "--b", + scannerConfig: defaultScannerConfig, + completionConfig: defaultCompletionConfig, + expected: [], + }); + + await testCompletions({ + parameters, + inputs: ["--foo", "100"], + partial: "", + scannerConfig: defaultScannerConfig, + completionConfig: defaultCompletionConfig, + expected: [], + }); + await testCompletions({ + parameters, + inputs: ["--foo", "100"], + partial: "-", + scannerConfig: defaultScannerConfig, + completionConfig: defaultCompletionConfig, + expected: [], + }); + await testCompletions({ + parameters, + inputs: ["--foo", "100"], + partial: "--", + scannerConfig: defaultScannerConfig, + completionConfig: defaultCompletionConfig, + expected: [], + }); + }); + + describe("with alias", () => { + const parametersWithAlias: TypedCommandParameters = { + ...parameters, + aliases: { f: "foo" }, + }; + + it("parseArguments", async () => { + await testArgumentScannerParse({ + parameters: parametersWithAlias, + config: defaultScannerConfig, + inputs: [], + expected: { + success: true, + arguments: [{ foo: void 0 }], + }, + }); + await testArgumentScannerParse({ + parameters: parametersWithAlias, + config: defaultScannerConfig, + inputs: ["-f", "100"], + expected: { + success: true, + arguments: [ + { + foo: [100], + }, + ], + }, + }); + await testArgumentScannerParse({ + parameters: parametersWithAlias, + config: defaultScannerConfig, + inputs: ["-f", "100,200"], + expected: { + success: true, + arguments: [ + { + foo: [100, 200], + }, + ], + }, + }); + + await testArgumentScannerParse({ + parameters: parametersWithAlias, + config: defaultScannerConfig, + inputs: ["-f", "100", "-f"], + expected: { + success: false, + errors: [ + { + type: "UnsatisfiedFlagError", + properties: { + externalFlagName: "foo", + }, + }, + ], + }, + }); + }); + + it("proposeCompletions", async () => { + await testCompletions({ + parameters: parametersWithAlias, + inputs: [], + partial: "", + scannerConfig: defaultScannerConfig, + completionConfig: defaultCompletionConfig, + expected: [{ kind: "argument:flag", completion: "--foo", brief: "foo" }], + }); + await testCompletions({ + parameters: parametersWithAlias, + inputs: [], + partial: "-", + scannerConfig: defaultScannerConfig, + completionConfig: defaultCompletionConfig, + expected: [{ kind: "argument:flag", completion: "--foo", brief: "foo" }], + }); + await testCompletions({ + parameters: parametersWithAlias, + inputs: [], + partial: "--", + scannerConfig: defaultScannerConfig, + completionConfig: defaultCompletionConfig, + expected: [{ kind: "argument:flag", completion: "--foo", brief: "foo" }], + }); + + await testCompletions({ + parameters: parametersWithAlias, + inputs: [], + partial: "", + scannerConfig: defaultScannerConfig, + completionConfig: { ...defaultCompletionConfig, includeAliases: true }, + expected: [ + { kind: "argument:flag", completion: "--foo", brief: "foo" }, + { kind: "argument:flag", completion: "-f", brief: "foo" }, + ], + }); + await testCompletions({ + parameters: parametersWithAlias, + inputs: [], + partial: "-", + scannerConfig: defaultScannerConfig, + completionConfig: { ...defaultCompletionConfig, includeAliases: true }, + expected: [ + { kind: "argument:flag", completion: "--foo", brief: "foo" }, + { kind: "argument:flag", completion: "-f", brief: "foo" }, + ], + }); + await testCompletions({ + parameters: parametersWithAlias, + inputs: [], + partial: "--", + scannerConfig: defaultScannerConfig, + completionConfig: { ...defaultCompletionConfig, includeAliases: true }, + expected: [{ kind: "argument:flag", completion: "--foo", brief: "foo" }], + }); + + await testCompletions({ + parameters: parametersWithAlias, + inputs: ["-f"], + partial: "", + scannerConfig: defaultScannerConfig, + completionConfig: defaultCompletionConfig, + expected: [], + }); + await testCompletions({ + parameters: parametersWithAlias, + inputs: ["-f"], + partial: "-", + scannerConfig: defaultScannerConfig, + completionConfig: defaultCompletionConfig, + expected: [], + }); + await testCompletions({ + parameters: parametersWithAlias, + inputs: ["-f"], + partial: "--", + scannerConfig: defaultScannerConfig, + completionConfig: defaultCompletionConfig, + expected: [], + }); + await testCompletions({ + parameters: parametersWithAlias, + inputs: ["-f"], + partial: "--b", + scannerConfig: defaultScannerConfig, + completionConfig: defaultCompletionConfig, + expected: [], + }); + + await testCompletions({ + parameters: parametersWithAlias, + inputs: ["-f", "100"], + partial: "", + scannerConfig: defaultScannerConfig, + completionConfig: defaultCompletionConfig, + expected: [], + }); + await testCompletions({ + parameters: parametersWithAlias, + inputs: ["-f", "100"], + partial: "-", + scannerConfig: defaultScannerConfig, + completionConfig: defaultCompletionConfig, + expected: [], + }); + await testCompletions({ + parameters: parametersWithAlias, + inputs: ["-f", "100"], + partial: "--", + scannerConfig: defaultScannerConfig, + completionConfig: defaultCompletionConfig, + expected: [], + }); + await testCompletions({ + parameters: parametersWithAlias, + inputs: ["-f", "100"], + partial: "--b", + scannerConfig: defaultScannerConfig, + completionConfig: defaultCompletionConfig, + expected: [], + }); + + await testCompletions({ + parameters: parametersWithAlias, + inputs: ["-f", "100"], + partial: "", + scannerConfig: defaultScannerConfig, + completionConfig: { ...defaultCompletionConfig, includeAliases: true }, + expected: [], + }); + await testCompletions({ + parameters: parametersWithAlias, + inputs: ["-f", "100"], + partial: "-", + scannerConfig: defaultScannerConfig, + completionConfig: { ...defaultCompletionConfig, includeAliases: true }, + expected: [], + }); + await testCompletions({ + parameters: parametersWithAlias, + inputs: ["-f", "100"], + partial: "--", + scannerConfig: defaultScannerConfig, + completionConfig: { ...defaultCompletionConfig, includeAliases: true }, + expected: [], + }); + }); + }); + }); + + describe("required array parsed flags", () => { + type Positional = []; + type Flags = { + readonly foo: number[]; + }; + + const numberArrayParser = (values: string) => values.split(",").map((value) => numberParser(value)); + + const parameters: TypedCommandParameters = { + flags: { + foo: { + kind: "parsed", + parse: numberArrayParser, + brief: "foo", + }, + }, + positional: { kind: "tuple", parameters: [] }, + }; + + it("parseArguments", async () => { + await testArgumentScannerParse({ + parameters, + config: defaultScannerConfig, + inputs: ["--foo=100"], + expected: { + success: true, + arguments: [{ foo: [100] }], + }, + }); + await testArgumentScannerParse({ + parameters, + config: defaultScannerConfig, + inputs: ["--foo=100,200"], + expected: { + success: true, + arguments: [ + { + foo: [100, 200], + }, + ], + }, + }); + + await testArgumentScannerParse({ + parameters, + config: defaultScannerConfig, + inputs: [], + expected: { + success: false, + errors: [ + { + type: "UnsatisfiedFlagError", + properties: { + externalFlagName: "foo", + }, + }, + ], + }, + }); + await testArgumentScannerParse({ + parameters, + config: defaultScannerConfig, + inputs: ["--foo"], + expected: { + success: false, + errors: [ + { + type: "UnsatisfiedFlagError", + properties: { + externalFlagName: "foo", + }, + }, + ], + }, + }); + await testArgumentScannerParse({ + parameters, + config: defaultScannerConfig, + inputs: ["--foo=100", "--foo"], + expected: { + success: false, + errors: [ + { + type: "UnsatisfiedFlagError", + properties: { + externalFlagName: "foo", + }, + }, + ], + }, + }); + await testArgumentScannerParse({ + parameters, + config: defaultScannerConfig, + inputs: ["--foo=100", "--foo=200"], + expected: { + success: false, + errors: [ + { + type: "UnexpectedFlagError", + properties: { + externalFlagName: "foo", + input: "200", + previousInput: "100", + }, + }, + ], + }, + }); + }); + + it("proposeCompletions", async () => { + await testCompletions({ + parameters, + inputs: [], + partial: "", + scannerConfig: defaultScannerConfig, + completionConfig: defaultCompletionConfig, + expected: [{ kind: "argument:flag", completion: "--foo", brief: "foo" }], + }); + await testCompletions({ + parameters, + inputs: [], + partial: "-", + scannerConfig: defaultScannerConfig, + completionConfig: defaultCompletionConfig, + expected: [{ kind: "argument:flag", completion: "--foo", brief: "foo" }], + }); + await testCompletions({ + parameters, + inputs: [], + partial: "--", + scannerConfig: defaultScannerConfig, + completionConfig: defaultCompletionConfig, + expected: [{ kind: "argument:flag", completion: "--foo", brief: "foo" }], + }); + await testCompletions({ + parameters, + inputs: [], + partial: "--f", + scannerConfig: defaultScannerConfig, + completionConfig: defaultCompletionConfig, + expected: [{ kind: "argument:flag", completion: "--foo", brief: "foo" }], + }); + + await testCompletions({ + parameters, + inputs: ["--foo"], + partial: "", + scannerConfig: defaultScannerConfig, + completionConfig: defaultCompletionConfig, + expected: [], + }); + await testCompletions({ + parameters, + inputs: ["--foo"], + partial: "-", + scannerConfig: defaultScannerConfig, + completionConfig: defaultCompletionConfig, + expected: [], + }); + await testCompletions({ + parameters, + inputs: ["--foo"], + partial: "--", + scannerConfig: defaultScannerConfig, + completionConfig: defaultCompletionConfig, + expected: [], + }); + await testCompletions({ + parameters, + inputs: ["--foo"], + partial: "--b", + scannerConfig: defaultScannerConfig, + completionConfig: defaultCompletionConfig, + expected: [], + }); + + await testCompletions({ + parameters, + inputs: ["--foo", "100"], + partial: "", + scannerConfig: defaultScannerConfig, + completionConfig: defaultCompletionConfig, + expected: [], + }); + await testCompletions({ + parameters, + inputs: ["--foo", "100"], + partial: "-", + scannerConfig: defaultScannerConfig, + completionConfig: defaultCompletionConfig, + expected: [], + }); + await testCompletions({ + parameters, + inputs: ["--foo", "100"], + partial: "--", + scannerConfig: defaultScannerConfig, + completionConfig: defaultCompletionConfig, + expected: [], + }); + }); + + describe("with alias", () => { + const parametersWithAlias: TypedCommandParameters = { + ...parameters, + aliases: { f: "foo" }, + }; + + it("parseArguments", async () => { + await testArgumentScannerParse({ + parameters: parametersWithAlias, + config: defaultScannerConfig, + inputs: ["-f", "100"], + expected: { + success: true, + arguments: [ + { + foo: [100], + }, + ], + }, + }); + await testArgumentScannerParse({ + parameters: parametersWithAlias, + config: defaultScannerConfig, + inputs: ["-f", "100,200"], + expected: { + success: true, + arguments: [ + { + foo: [100, 200], + }, + ], + }, + }); + + await testArgumentScannerParse({ + parameters: parametersWithAlias, + config: defaultScannerConfig, + inputs: [], + expected: { + success: false, + errors: [ + { + type: "UnsatisfiedFlagError", + properties: { + externalFlagName: "foo", + }, + }, + ], + }, + }); + await testArgumentScannerParse({ + parameters: parametersWithAlias, + config: defaultScannerConfig, + inputs: ["-f"], + expected: { + success: false, + errors: [ + { + type: "UnsatisfiedFlagError", + properties: { + externalFlagName: "foo", + }, + }, + ], + }, + }); + await testArgumentScannerParse({ + parameters: parametersWithAlias, + config: defaultScannerConfig, + inputs: ["-f", "100", "-f"], + expected: { + success: false, + errors: [ + { + type: "UnsatisfiedFlagError", + properties: { + externalFlagName: "foo", + }, + }, + ], + }, + }); + }); + + it("proposeCompletions", async () => { + await testCompletions({ + parameters: parametersWithAlias, + inputs: [], + partial: "", + scannerConfig: defaultScannerConfig, + completionConfig: defaultCompletionConfig, + expected: [{ kind: "argument:flag", completion: "--foo", brief: "foo" }], + }); + await testCompletions({ + parameters: parametersWithAlias, + inputs: [], + partial: "-", + scannerConfig: defaultScannerConfig, + completionConfig: defaultCompletionConfig, + expected: [{ kind: "argument:flag", completion: "--foo", brief: "foo" }], + }); + await testCompletions({ + parameters: parametersWithAlias, + inputs: [], + partial: "--", + scannerConfig: defaultScannerConfig, + completionConfig: defaultCompletionConfig, + expected: [{ kind: "argument:flag", completion: "--foo", brief: "foo" }], + }); + + await testCompletions({ + parameters: parametersWithAlias, + inputs: [], + partial: "", + scannerConfig: defaultScannerConfig, + completionConfig: { ...defaultCompletionConfig, includeAliases: true }, + expected: [ + { kind: "argument:flag", completion: "--foo", brief: "foo" }, + { kind: "argument:flag", completion: "-f", brief: "foo" }, + ], + }); + await testCompletions({ + parameters: parametersWithAlias, + inputs: [], + partial: "-", + scannerConfig: defaultScannerConfig, + completionConfig: { ...defaultCompletionConfig, includeAliases: true }, + expected: [ + { kind: "argument:flag", completion: "--foo", brief: "foo" }, + { kind: "argument:flag", completion: "-f", brief: "foo" }, + ], + }); + await testCompletions({ + parameters: parametersWithAlias, + inputs: [], + partial: "--", + scannerConfig: defaultScannerConfig, + completionConfig: { ...defaultCompletionConfig, includeAliases: true }, + expected: [{ kind: "argument:flag", completion: "--foo", brief: "foo" }], + }); + + await testCompletions({ + parameters: parametersWithAlias, + inputs: ["-f"], + partial: "", + scannerConfig: defaultScannerConfig, + completionConfig: defaultCompletionConfig, + expected: [], + }); + await testCompletions({ + parameters: parametersWithAlias, + inputs: ["-f"], + partial: "-", + scannerConfig: defaultScannerConfig, + completionConfig: defaultCompletionConfig, + expected: [], + }); + await testCompletions({ + parameters: parametersWithAlias, + inputs: ["-f"], + partial: "--", + scannerConfig: defaultScannerConfig, + completionConfig: defaultCompletionConfig, + expected: [], + }); + await testCompletions({ + parameters: parametersWithAlias, + inputs: ["-f"], + partial: "--b", + scannerConfig: defaultScannerConfig, + completionConfig: defaultCompletionConfig, + expected: [], + }); + + await testCompletions({ + parameters: parametersWithAlias, + inputs: ["-f", "100"], + partial: "", + scannerConfig: defaultScannerConfig, + completionConfig: defaultCompletionConfig, + expected: [], + }); + await testCompletions({ + parameters: parametersWithAlias, + inputs: ["-f", "100"], + partial: "-", + scannerConfig: defaultScannerConfig, + completionConfig: defaultCompletionConfig, + expected: [], + }); + await testCompletions({ + parameters: parametersWithAlias, + inputs: ["-f", "100"], + partial: "--", + scannerConfig: defaultScannerConfig, + completionConfig: defaultCompletionConfig, + expected: [], + }); + }); + }); + }); + describe("parsed flags with custom completions", () => { type Positional = []; type Flags = {