zod-opts
Version:
node.js CLI option parser / validator using Zod
588 lines • 24 kB
JavaScript
"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