UNPKG

zod-opts

Version:

node.js CLI option parser / validator using Zod

588 lines 24 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const internal_parser_1 = require("../src/internal_parser"); const test_util_1 = require("./test_util"); describe("isNumericValue()", () => { test("common", () => { expect((0, internal_parser_1.isNumericValue)("0")).toEqual(true); expect((0, internal_parser_1.isNumericValue)("-0.10")).toEqual(true); expect((0, internal_parser_1.isNumericValue)("0x10")).toEqual(true); expect((0, internal_parser_1.isNumericValue)("111111")).toEqual(true); expect((0, internal_parser_1.isNumericValue)(" 1 ")).toEqual(true); expect((0, internal_parser_1.isNumericValue)("1 ")).toEqual(true); expect((0, internal_parser_1.isNumericValue)(" 1")).toEqual(true); expect((0, internal_parser_1.isNumericValue)("a10")).toEqual(false); expect((0, internal_parser_1.isNumericValue)("10a")).toEqual(false); expect((0, internal_parser_1.isNumericValue)("")).toEqual(false); expect((0, internal_parser_1.isNumericValue)("a")).toEqual(false); expect((0, internal_parser_1.isNumericValue)(" ")).toEqual(false); expect((0, internal_parser_1.isNumericValue)("1.1.1")).toEqual(false); }); }); describe("findOptionByPrefixedName()", () => { test("common", () => { expect((0, internal_parser_1.findOptionByPrefixedName)([], "--opt")).toEqual(undefined); expect((0, internal_parser_1.findOptionByPrefixedName)([(0, test_util_1.createInternalOption)({ name: "opt1" })], "--opt2")).toEqual(undefined); expect((0, internal_parser_1.findOptionByPrefixedName)([(0, test_util_1.createInternalOption)({ name: "opt1" })], "--opt1")).toEqual([(0, test_util_1.createInternalOption)({ name: "opt1" }), false]); // In parse phase, don't mind about the value expect((0, internal_parser_1.findOptionByPrefixedName)([(0, test_util_1.createInternalOption)({ name: "opt1", type: "number" })], "--opt1")).toEqual([(0, test_util_1.createInternalOption)({ name: "opt1", type: "number" }), false]); expect((0, internal_parser_1.findOptionByPrefixedName)([(0, test_util_1.createInternalOption)({ name: "opt1", type: "boolean" })], "--opt1")).toEqual([(0, test_util_1.createInternalOption)({ name: "opt1", type: "boolean" }), false]); expect((0, internal_parser_1.findOptionByPrefixedName)([(0, test_util_1.createInternalOption)({ name: "opt1", type: "boolean" })], "--no-opt1")).toEqual([(0, test_util_1.createInternalOption)({ name: "opt1", type: "boolean" }), true]); // don't check required expect((0, internal_parser_1.findOptionByPrefixedName)([(0, test_util_1.createInternalOption)({ name: "opt1", type: "string" })], "--no-opt1")).toEqual([(0, test_util_1.createInternalOption)({ name: "opt1", type: "string" }), true]); expect((0, internal_parser_1.findOptionByPrefixedName)([(0, test_util_1.createInternalOption)({ name: "opt1", type: "boolean" })], "--no-opt2")).toEqual(undefined); }); }); describe("likesOptionArg()", () => { test("common", () => { expect((0, internal_parser_1.likesOptionArg)("--arg", [])).toEqual(true); expect((0, internal_parser_1.likesOptionArg)("-a", [])).toEqual(true); expect((0, internal_parser_1.likesOptionArg)("-a=a", [])).toEqual(true); expect((0, internal_parser_1.likesOptionArg)("--a=-10", [])).toEqual(true); expect((0, internal_parser_1.likesOptionArg)("--10", [])).toEqual(true); expect((0, internal_parser_1.likesOptionArg)("-1", [(0, test_util_1.createInternalOption)({ alias: "1" })])).toEqual(true); expect((0, internal_parser_1.likesOptionArg)("--", [])).toEqual(false); expect((0, internal_parser_1.likesOptionArg)("arg", [])).toEqual(false); expect((0, internal_parser_1.likesOptionArg)("10", [])).toEqual(false); expect((0, internal_parser_1.likesOptionArg)("-1", [])).toEqual(false); expect((0, internal_parser_1.likesOptionArg)("-10.0", [])).toEqual(false); }); }); describe("pickPositionalArguments()", () => { test("common", () => { expect((0, internal_parser_1.pickPositionalArguments)(["pos1", "pos2", "pos3"], [], false)).toEqual({ positionalArgs: ["pos1", "pos2", "pos3"], shift: 3, }); expect((0, internal_parser_1.pickPositionalArguments)(["pos1"], [], false)).toEqual({ positionalArgs: ["pos1"], shift: 1, }); expect((0, internal_parser_1.pickPositionalArguments)(["pos1", "--opt1"], [], false)).toEqual({ positionalArgs: ["pos1"], shift: 1, }); expect((0, internal_parser_1.pickPositionalArguments)(["pos1", "--opt1"], [], true)).toEqual({ positionalArgs: ["pos1", "--opt1"], shift: 2, }); }); }); describe("parse()", () => { describe("normal", () => { test("when option and positional argument", () => { expect((0, internal_parser_1.parse)({ args: ["--opt1", "opt_str1"], options: [ (0, test_util_1.createInternalOption)({ name: "opt1" }), (0, test_util_1.createInternalOption)({ name: "opt2" }), ], positionalArgs: [], })).toEqual({ candidates: [ { name: "opt1", value: "opt_str1", isNegative: false, }, ], positionalCandidates: [], isHelp: false, isVersion: false, }); }); test("multiple positional arguments", () => { expect((0, internal_parser_1.parse)({ args: ["pos1", "pos2"], options: [ (0, test_util_1.createInternalOption)({ name: "opt1" }), (0, test_util_1.createInternalOption)({ name: "opt2" }), ], positionalArgs: [ (0, test_util_1.createInternalPositionalArgument)({ name: "pos1" }), (0, test_util_1.createInternalPositionalArgument)({ name: "pos2" }), ], })).toEqual({ candidates: [], positionalCandidates: [ { name: "pos1", value: "pos1", }, { name: "pos2", value: "pos2", }, ], isHelp: false, isVersion: false, }); }); test("when double dash", () => { expect((0, internal_parser_1.parse)({ args: ["--opt1", "opt1", "--", "--", "-b=opt2", "pos3"], options: [(0, test_util_1.createInternalOption)({ name: "opt1" })], positionalArgs: [ (0, test_util_1.createInternalPositionalArgument)({ name: "pos1" }), (0, test_util_1.createInternalPositionalArgument)({ name: "pos2" }), (0, test_util_1.createInternalPositionalArgument)({ name: "pos3" }), ], })).toEqual({ candidates: [ { name: "opt1", value: "opt1", isNegative: false, }, ], positionalCandidates: [ { name: "pos1", value: "--", }, { name: "pos2", value: "-b=opt2", }, { name: "pos3", value: "pos3", }, ], isHelp: false, isVersion: false, }); }); test("", () => { expect((0, internal_parser_1.parse)({ args: ["--flag1", "pos1"], options: [(0, test_util_1.createInternalOption)({ name: "flag1", type: "boolean" })], positionalArgs: [(0, test_util_1.createInternalPositionalArgument)({})], })).toEqual({ candidates: [ { name: "flag1", value: undefined, isNegative: false, }, ], positionalCandidates: [ { name: "pos1", value: "pos1", }, ], isHelp: false, isVersion: false, }); }); test("when array type positional argument", () => { expect((0, internal_parser_1.parse)({ args: ["pos1", "pos2"], options: [], positionalArgs: [ (0, test_util_1.createInternalPositionalArgument)({ name: "pos1", isArray: true }), ], })).toEqual({ candidates: [], positionalCandidates: [ { name: "pos1", value: ["pos1", "pos2"], }, ], isHelp: false, isVersion: false, }); }); test("help", () => { expect((0, internal_parser_1.parse)({ args: ["pos1", "--help"], options: [], positionalArgs: [(0, test_util_1.createInternalPositionalArgument)({ name: "pos1" })], })).toEqual({ candidates: [], positionalCandidates: [ { name: "pos1", value: "pos1", }, ], isHelp: true, isVersion: false, }); }); test("option value type", () => { expect((0, internal_parser_1.parse)({ args: [ "--opt1", "opt1", "--opt2=opt2", "-b10", "-cd", "opt5", "--opt6=", "pos1", ], options: [ (0, test_util_1.createInternalOption)({ name: "opt1" }), (0, test_util_1.createInternalOption)({ name: "opt2" }), (0, test_util_1.createInternalOption)({ name: "opt3", alias: "b" }), (0, test_util_1.createInternalOption)({ name: "opt4", type: "boolean", alias: "c" }), (0, test_util_1.createInternalOption)({ name: "opt5", alias: "d" }), (0, test_util_1.createInternalOption)({ name: "opt6" }), ], positionalArgs: [(0, test_util_1.createInternalPositionalArgument)({})], })).toEqual({ candidates: [ { name: "opt1", value: "opt1", isNegative: false, }, { name: "opt2", value: "opt2", isNegative: false, }, { name: "opt3", value: "10", isNegative: false, }, { name: "opt4", value: undefined, isNegative: false, }, { name: "opt5", value: "opt5", isNegative: false, }, { name: "opt6", value: "", isNegative: false, }, ], positionalCandidates: [ { name: "pos1", value: "pos1", }, ], isHelp: false, isVersion: false, }); }); }); describe("unified option", () => { test("single character alias", () => { expect((0, internal_parser_1.parse)({ args: ["-ab", "pos1"], options: [ (0, test_util_1.createInternalOption)({ name: "opt1", type: "boolean", alias: "a" }), (0, test_util_1.createInternalOption)({ name: "opt2", type: "boolean", alias: "b" }), ], positionalArgs: [(0, test_util_1.createInternalPositionalArgument)({ name: "pos1" })], })).toEqual({ candidates: [ { name: "opt1", value: undefined, isNegative: false, }, { name: "opt2", value: undefined, isNegative: false, }, ], positionalCandidates: [ { name: "pos1", value: "pos1", }, ], isHelp: false, isVersion: false, }); }); test("multiple character alias", () => { expect((0, internal_parser_1.parse)({ args: ["-ab", "pos1"], options: [ (0, test_util_1.createInternalOption)({ name: "opt1", type: "boolean", alias: "ab", }), ], positionalArgs: [(0, test_util_1.createInternalPositionalArgument)({ name: "pos1" })], })).toEqual({ candidates: [ { name: "opt1", value: undefined, isNegative: false, }, ], positionalCandidates: [ { name: "pos1", value: "pos1", }, ], isHelp: false, isVersion: false, }); }); test("multiple character alias and string type", () => { expect((0, internal_parser_1.parse)({ args: ["-ab", "str1"], options: [ (0, test_util_1.createInternalOption)({ name: "opt1", type: "string", alias: "ab" }), ], positionalArgs: [], })).toEqual({ candidates: [ { name: "opt1", value: "str1", isNegative: false, }, ], positionalCandidates: [], isHelp: false, isVersion: false, }); }); }); describe("exception", () => { test("Option 'opt1' needs value: opt1", () => { expect(() => { (0, internal_parser_1.parse)({ args: ["--opt1"], options: [(0, test_util_1.createInternalOption)({ name: "opt1" })], positionalArgs: [], }); }).toThrow("Option 'opt1' needs value: opt1"); }); test("missing option name", () => { expect(() => { (0, internal_parser_1.parse)({ args: ["--missing", "value"], options: [(0, test_util_1.createInternalOption)({ name: "opt1" })], positionalArgs: [], }); }).toThrow("Invalid option"); }); test("missing option arg on multiple options", () => { expect(() => { (0, internal_parser_1.parse)({ args: ["--opt1", "--opt2", "opt2"], options: [ (0, test_util_1.createInternalOption)({ name: "opt1" }), (0, test_util_1.createInternalOption)({ name: "opt2" }), ], positionalArgs: [], }); }).toThrow("Option 'opt1' needs value: opt1"); }); test("too many positional arguments when option exists", () => { expect(() => { (0, internal_parser_1.parse)({ args: ["pos1"], options: [(0, test_util_1.createInternalOption)({ name: "opt1" })], positionalArgs: [], }); }).toThrow("Too many positional arguments"); }); test("too many positional arguments when option and positional argument exist", () => { expect(() => { (0, internal_parser_1.parse)({ args: ["pos1", "pos2"], options: [(0, test_util_1.createInternalOption)({ name: "opt1" })], positionalArgs: [(0, test_util_1.createInternalPositionalArgument)({ name: "pos1" })], }); }).toThrow("Too many positional arguments"); }); test("multiple positional argument groups", () => { expect(() => { (0, internal_parser_1.parse)({ args: ["pos1", "--opt1=opt1", "pos2"], options: [(0, test_util_1.createInternalOption)({ name: "opt1" })], positionalArgs: [(0, test_util_1.createInternalPositionalArgument)({ name: "pos1" })], }); }).toThrow("Positional arguments specified twice"); }); describe("unified option", () => { test("-abc => -ab -c", () => { expect(() => { (0, internal_parser_1.parse)({ args: ["-abc"], options: [ (0, test_util_1.createInternalOption)({ name: "opt1", type: "boolean", alias: "ab", }), (0, test_util_1.createInternalOption)({ name: "opt1", type: "boolean", alias: "c", }), ], positionalArgs: [], }); }).toThrow("Invalid option: a"); }); test("-abc1 => -abc=1", () => { expect(() => { (0, internal_parser_1.parse)({ args: ["-abc1"], options: [ (0, test_util_1.createInternalOption)({ name: "opt1", type: "string", alias: "abc", }), ], positionalArgs: [], }); }).toThrow("Invalid option: a"); }); test("-= is invalid", () => { expect(() => { (0, internal_parser_1.parse)({ args: ["-="], options: [], positionalArgs: [], }); }).toThrow("Invalid option: -="); }); test("--= is invalid", () => { expect(() => { (0, internal_parser_1.parse)({ args: ["--="], options: [], positionalArgs: [], }); }).toThrow("Invalid option: "); }); }); }); }); describe("parseMultipleCommands", () => { test("parse", () => { expect((0, internal_parser_1.parseMultipleCommands)({ args: ["cmd1", "--opt1", "opt_str1"], commands: [ { name: "cmd1", options: [ (0, test_util_1.createInternalOption)({ name: "opt1" }), (0, test_util_1.createInternalOption)({ name: "opt2" }), ], positionalArgs: [], }, ], })).toEqual({ commandName: "cmd1", candidates: [ { name: "opt1", value: "opt_str1", isNegative: false, }, ], positionalCandidates: [], isHelp: false, isVersion: false, }); }); test("global help", () => { expect((0, internal_parser_1.parseMultipleCommands)({ args: ["--help"], commands: [ { name: "cmd1", options: [ (0, test_util_1.createInternalOption)({ name: "opt1" }), (0, test_util_1.createInternalOption)({ name: "opt2" }), ], positionalArgs: [], }, ], })).toEqual({ candidates: [], positionalCandidates: [], isHelp: true, isVersion: false, }); }); test("command help when '--help' before command name", () => { expect((0, internal_parser_1.parseMultipleCommands)({ args: ["--help", "cmd1"], commands: [ { name: "cmd1", options: [ (0, test_util_1.createInternalOption)({ name: "opt1" }), (0, test_util_1.createInternalOption)({ name: "opt2" }), ], positionalArgs: [], }, ], })).toEqual({ commandName: "cmd1", candidates: [], positionalCandidates: [], isHelp: true, isVersion: false, }); }); test("command help when '--help' after command name", () => { expect((0, internal_parser_1.parseMultipleCommands)({ args: ["cmd1", "--help"], commands: [ { name: "cmd1", options: [ (0, test_util_1.createInternalOption)({ name: "opt1" }), (0, test_util_1.createInternalOption)({ name: "opt2" }), ], positionalArgs: [], }, ], })).toEqual({ commandName: "cmd1", candidates: [], positionalCandidates: [], isHelp: true, isVersion: false, }); }); test("version", () => { expect((0, internal_parser_1.parseMultipleCommands)({ args: ["--version"], commands: [ { name: "cmd1", options: [ (0, test_util_1.createInternalOption)({ name: "opt1" }), (0, test_util_1.createInternalOption)({ name: "opt2" }), ], positionalArgs: [], }, ], })).toEqual({ candidates: [], positionalCandidates: [], isHelp: false, isVersion: true, }); }); }); //# sourceMappingURL=internal_parser.test.js.map