import { Command } from "commander" ;
import { describe, expect, it } from "vitest" ;
import { inheritOptionFromParent } from "./command-options.js" ;
function attachRunCommandAndCaptureInheritedToken(command: Command) {
let inherited: string | undefined;
command
.command("run" )
.option("--token <token>" , "Run token" )
.action((_opts, childCommand) => {
inherited = inheritOptionFromParent<string>(childCommand, "token" );
});
return () => inherited;
}
describe("inheritOptionFromParent" , () => {
it.each([
{
label: "inherits from grandparent when parent does not define the option" ,
parentHasTokenOption: false ,
argv: ["--token" , "root-token" , "gateway" , "run" ],
expected: "root-token" ,
},
{
label: "prefers nearest ancestor value when multiple ancestors set the same option" ,
parentHasTokenOption: true ,
argv: ["--token" , "root-token" , "gateway" , "--token" , "gateway-token" , "run" ],
expected: "gateway-token" ,
},
])("$label" , async ({ parentHasTokenOption, argv, expected }) => {
const program = new Command().option("--token <token>" , "Root token" );
const gateway = parentHasTokenOption
? program.command("gateway" ).option("--token <token>" , "Gateway token" )
: program.command("gateway" );
const getInherited = attachRunCommandAndCaptureInheritedToken(gateway);
await program.parseAsync(argv, { from: "user" });
expect(getInherited()).toBe(expected);
});
it("does not inherit when the child option was set explicitly" , async () => {
const program = new Command().option("--token <token>" , "Root token" );
const gateway = program.command("gateway" ).option("--token <token>" , "Gateway token" );
const run = gateway.command("run" ).option("--token <token>" , "Run token" );
program.setOptionValueWithSource("token" , "root-token" , "cli" );
gateway.setOptionValueWithSource("token" , "gateway-token" , "cli" );
run.setOptionValueWithSource("token" , "run-token" , "cli" );
expect(inheritOptionFromParent<string>(run, "token" )).toBeUndefined();
});
it("does not inherit from ancestors beyond the bounded traversal depth" , async () => {
const program = new Command().option("--token <token>" , "Root token" );
const level1 = program.command("level1" );
const level2 = level1.command("level2" );
const getInherited = attachRunCommandAndCaptureInheritedToken(level2);
await program.parseAsync(["--token" , "root-token" , "level1" , "level2" , "run" ], {
from: "user" ,
});
expect(getInherited()).toBeUndefined();
});
it("inherits values from non-default ancestor sources (for example env)" , () => {
const program = new Command().option("--token <token>" , "Root token" );
const gateway = program.command("gateway" ).option("--token <token>" , "Gateway token" );
const run = gateway.command("run" ).option("--token <token>" , "Run token" );
gateway.setOptionValueWithSource("token" , "gateway-env-token" , "env" );
expect(inheritOptionFromParent<string>(run, "token" )).toBe("gateway-env-token" );
});
it("skips default-valued ancestor options and keeps traversing" , async () => {
const program = new Command().option("--token <token>" , "Root token" );
const gateway = program
.command("gateway" )
.option("--token <token>" , "Gateway token" , "default" );
const getInherited = attachRunCommandAndCaptureInheritedToken(gateway);
await program.parseAsync(["--token" , "root-token" , "gateway" , "run" ], {
from: "user" ,
});
expect(getInherited()).toBe("root-token" );
});
it("returns undefined when command is missing" , () => {
expect(inheritOptionFromParent<string>(undefined, "token" )).toBeUndefined();
});
});
Messung V0.5 in Prozent C=100 H=100 G=100
¤ Dauer der Verarbeitung: 0.11 Sekunden
(vorverarbeitet am 2026-06-09)
¤
*© Formatika GbR, Deutschland