UNPKG

appcenter-cli

Version:

Command line tool for Visual Studio App Center

281 lines (243 loc) 8.1 kB
import { expect } from "chai"; import { parseOptions, OptionsDescription, PositionalOptionsDescription } from "../../../src/util/commandline/option-parser"; describe("Command line option parsing", function () { describe("single option", function () { const opts: OptionsDescription = { singleFlag: { shortName: "a", longName: "a-flag", required: false } }; it("should parse single flag correctly when flag is present", function () { const target: any = {}; const args = [ "-a" ]; parseOptions(opts, target, args); expect(target).to.have.property("singleFlag", true); }); it("should succeed parsing when optional flag not present", function () { const target: any = {}; const args: string[] = []; parseOptions(opts, target, args); expect(target).to.have.property("singleFlag", false); }); it("should parse long option flag when present", function () { const target: any = {}; const args = [ "--a-flag" ]; parseOptions(opts, target, args); expect(target).to.have.property("singleFlag", true); }); it("should throw on unknown argument", function () { expect(() => parseOptions(opts, {}, ["-x"])) .to.throw(/unknown argument/i); }); }); describe("single option with argument", function () { const opts: OptionsDescription = { optionWithArg: { shortName: "a", longName: "with-arg", hasArg: true } }; it("should read argument from next arg if separate", function () { const target: any = {}; const args = [ "-a", "argValue" ]; parseOptions(opts, target, args); expect(target).to.have.property("optionWithArg", "argValue"); }); }); describe("required option", function () { const opts: OptionsDescription = { req: { shortName: "r", longName: "required", hasArg: true, required: true } }; it("should parse correctly when present", function () { const target = {}; parseOptions(opts, target, ["-r", "stuff"]); expect(target).to.have.property("req", "stuff"); }); it("should throw if required argument is not given", function () { const target = {}; expect(() => parseOptions(opts, target, [])) .to.throw(/missing required option/i); }); }); describe("option with default value", function () { const opts: OptionsDescription = { def: { shortName: "d", defaultValue: "defined", hasArg: true, } }; it("should take command line option if given", function () { const target: any = {}; parseOptions(opts, target, "-d specificValue".split(" ")); expect(target).to.have.property("def", "specificValue"); }); it("should return default value if not in arguments", function () { const target: any = {}; parseOptions(opts, target, []); expect(target).to.have.property("def", "defined"); }); }); describe("multiple options", function () { const opts: OptionsDescription = { flag: { shortName: "f", longName: "flag" }, input: { shortName: "i", longName: "input", required: true, hasArg: true }, output: { longName: "out", hasArg: true, defaultValue: "out.dat" } }; it("should parse all options if all present", function () { const target: any = {}; parseOptions(opts, target, "-i in.txt -f --out=myFile.txt".split(" ")); expect(target).to.have.property("flag", true); expect(target).to.have.property("input", "in.txt"); expect(target).to.have.property("output", "myFile.txt"); }); it("should return default values for options not present", function () { const target: any = {}; parseOptions(opts, target, "-f --input myfile.txt".split(" ")); expect(target).to.have.property("flag", true); expect(target).to.have.property("input", "myfile.txt"); expect(target).to.have.property("output", "out.dat"); }); it("should throw if required option missing", function () { const target: any = {}; expect(() => parseOptions(opts, target, "--out foo.txt".split(" "))) .to.throw(/missing required option -i \/ --input/i); }); }); describe("positional options", function () { it("should parse single positional argument", function () { const opts: PositionalOptionsDescription = [ { name: "inputFile", propertyName: "file", position: 0, required: true } ]; const target: any = {}; parseOptions({}, opts, target, "input.txt".split(" ")); expect(target).to.have.property("file", "input.txt"); }); it ("should throw when required positional argument is missing", function () { const opts: PositionalOptionsDescription = [ { name: "inputFile", propertyName: "file", position: 0, required: true } ]; const target: any = {}; expect(() => parseOptions({}, opts, target, [])) .to.throw(/missing required positional argument inputFile/i); }); it ("should populate rest option", function () { const opts: PositionalOptionsDescription = [ { name: "inputFile", propertyName: "file", position: 0 }, { name: "moreFiles", propertyName: "moreFiles", position: null } ]; const target: any = {}; parseOptions({}, opts, target, "a.txt b.txt c.txt".split(" ")); expect(target).to.have.property("file", "a.txt"); expect(target).to.have.property("moreFiles") .and.to.be.instanceof(Array) .and.to.have.lengthOf(2); expect(target.moreFiles[0]).to.equal("b.txt"); expect(target.moreFiles[1]).to.equal("c.txt"); }); it("should not assign missing optional positionals", function () { const opts: PositionalOptionsDescription = [ { name: "file", propertyName: "file", position: 0, required: true }, { name: "moreFiles", propertyName: "moreFiles", position: 1, required: false } ]; const target: any = {}; parseOptions({}, opts, target, "a.txt".split(" ")); expect(target).to.have.property("file", "a.txt"); expect(target).to.not.have.property("moreFiles"); }); it("should throw if there are extra positional args and no rest arg", function () { const opts: PositionalOptionsDescription = [ { name: "file", propertyName: "file", position: 0, required: true } ]; const target: any = {}; expect(() => parseOptions({}, opts, target, "a.txt b.txt".split(" "))) .to.throw(Error, /Unknown arguments: b.txt/); }); }); describe("flags and positional together", function () { it("should parse as expected", function () { const flagOpts: OptionsDescription = { verbose: { shortName: "v", longName: "verbose" }, format: { shortName: "f", longName: "format", hasArg: true } }; const positionOpts: PositionalOptionsDescription = [ { name: "inputFile", propertyName: "inputFile", position: 0 }, { name: "configFile", propertyName: "configFile", position: 1 } ]; const target: any = {}; parseOptions(flagOpts, positionOpts, target, "in.txt -v conf.json --format=csv".split(" ")); expect(target).to.have.property("verbose", true); expect(target).to.have.property("format", "csv"); expect(target).to.have.property("inputFile", "in.txt"); expect(target).to.have.property("configFile", "conf.json"); }); }); });