mirror of
https://github.com/denoland/deno.git
synced 2025-01-15 10:35:19 -05:00
parent
2351df72db
commit
700b4ce0d9
19 changed files with 1046 additions and 0 deletions
|
@ -10,6 +10,7 @@ for Deno.
|
|||
| [colors](./colors/README.md) | Modules that generate ANSI color codes for the console. |
|
||||
| [net](./net/README.md) | A framework for creating HTTP/HTTPS servers inspired by GoLang. |
|
||||
| [path](./path/README.md) | A path manipulation library. |
|
||||
| [flags](./flags/README.md) | Command line arguments parser based on minimist. |
|
||||
|
||||
---
|
||||
|
||||
|
|
59
flags/README.md
Normal file
59
flags/README.md
Normal file
|
@ -0,0 +1,59 @@
|
|||
# flags
|
||||
|
||||
Command line arguments parser for Deno based on minimist
|
||||
|
||||
# Example
|
||||
|
||||
``` ts
|
||||
import { args } from "deno";
|
||||
import parseArgs from "https://deno.land/x/parseargs/index.ts";
|
||||
|
||||
console.dir(parseArgs(args));
|
||||
```
|
||||
|
||||
```
|
||||
$ deno example.ts -a beep -b boop
|
||||
{ _: [], a: 'beep', b: 'boop' }
|
||||
```
|
||||
|
||||
```
|
||||
$ deno example.ts -x 3 -y 4 -n5 -abc --beep=boop foo bar baz
|
||||
{ _: [ 'foo', 'bar', 'baz' ],
|
||||
x: 3,
|
||||
y: 4,
|
||||
n: 5,
|
||||
a: true,
|
||||
b: true,
|
||||
c: true,
|
||||
beep: 'boop' }
|
||||
```
|
||||
|
||||
# API
|
||||
|
||||
## const parsedArgs = parseArgs(args, options = {});
|
||||
|
||||
`parsedArgs._` contains all the arguments that didn't have an option associated with
|
||||
them.
|
||||
|
||||
Numeric-looking arguments will be returned as numbers unless `options.string` or
|
||||
`options.boolean` is set for that argument name.
|
||||
|
||||
Any arguments after `'--'` will not be parsed and will end up in `parsedArgs._`.
|
||||
|
||||
options can be:
|
||||
|
||||
* `options.string` - a string or array of strings argument names to always treat as
|
||||
strings
|
||||
* `options.boolean` - a boolean, string or array of strings to always treat as
|
||||
booleans. if `true` will treat all double hyphenated arguments without equal signs
|
||||
as boolean (e.g. affects `--foo`, not `-f` or `--foo=bar`)
|
||||
* `options.alias` - an object mapping string names to strings or arrays of string
|
||||
argument names to use as aliases
|
||||
* `options.default` - an object mapping string argument names to default values
|
||||
* `options.stopEarly` - when true, populate `parsedArgs._` with everything after the
|
||||
first non-option
|
||||
* `options['--']` - when true, populate `parsedArgs._` with everything before the `--`
|
||||
and `parsedArgs['--']` with everything after the `--`. Here's an example:
|
||||
* `options.unknown` - a function which is invoked with a command line parameter not
|
||||
defined in the `options` configuration object. If the function returns `false`, the
|
||||
unknown option is not added to `parsedArgs`.
|
4
flags/example.ts
Normal file
4
flags/example.ts
Normal file
|
@ -0,0 +1,4 @@
|
|||
import { args } from "deno";
|
||||
import parseArgs from "./index.ts";
|
||||
|
||||
console.dir(parseArgs(args));
|
271
flags/index.ts
Normal file
271
flags/index.ts
Normal file
|
@ -0,0 +1,271 @@
|
|||
export interface ArgParsingOptions {
|
||||
unknown?: Function;
|
||||
boolean?: Boolean | string | string[];
|
||||
alias?: { [key: string]: string | string[] };
|
||||
string?: string | string[];
|
||||
default?: { [key: string]: any };
|
||||
"--"?: Boolean;
|
||||
stopEarly?: Boolean;
|
||||
}
|
||||
|
||||
const DEFAULT_OPTIONS = {
|
||||
unknown: i => i,
|
||||
boolean: false,
|
||||
alias: {},
|
||||
string: [],
|
||||
default: {},
|
||||
"--": false,
|
||||
stopEarly: false
|
||||
};
|
||||
|
||||
export default function parseArgs(
|
||||
args,
|
||||
initialOptions?: ArgParsingOptions
|
||||
): { [key: string]: any } {
|
||||
const options: ArgParsingOptions = {
|
||||
...DEFAULT_OPTIONS,
|
||||
...(initialOptions || {})
|
||||
};
|
||||
|
||||
const flags = {
|
||||
bools: {},
|
||||
strings: {},
|
||||
unknownFn: options.unknown!,
|
||||
allBools: false
|
||||
};
|
||||
|
||||
// TODO: get rid of this, providing two different options
|
||||
if (typeof options["boolean"] === "boolean" && options["boolean"]) {
|
||||
flags.allBools = true;
|
||||
} else {
|
||||
[]
|
||||
.concat(options["boolean"])
|
||||
.filter(Boolean)
|
||||
.forEach(function(key) {
|
||||
flags.bools[key] = true;
|
||||
});
|
||||
}
|
||||
|
||||
const aliases = {};
|
||||
Object.keys(options.alias).forEach(function(key) {
|
||||
aliases[key] = [].concat(options.alias[key]);
|
||||
aliases[key].forEach(function(x) {
|
||||
aliases[x] = [key].concat(
|
||||
aliases[key].filter(function(y) {
|
||||
return x !== y;
|
||||
})
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
[]
|
||||
.concat(options.string)
|
||||
.filter(Boolean)
|
||||
.forEach(function(key) {
|
||||
flags.strings[key] = true;
|
||||
if (aliases[key]) {
|
||||
flags.strings[aliases[key]] = true;
|
||||
}
|
||||
});
|
||||
|
||||
const defaults = options.default!;
|
||||
|
||||
const argv = { _: [] };
|
||||
Object.keys(flags.bools).forEach(function(key) {
|
||||
setArg(key, defaults[key] === undefined ? false : defaults[key]);
|
||||
});
|
||||
|
||||
let notFlags = [];
|
||||
|
||||
if (args.indexOf("--") !== -1) {
|
||||
notFlags = args.slice(args.indexOf("--") + 1);
|
||||
args = args.slice(0, args.indexOf("--"));
|
||||
}
|
||||
|
||||
function argDefined(key, arg) {
|
||||
return (
|
||||
(flags.allBools && /^--[^=]+$/.test(arg)) ||
|
||||
flags.strings[key] ||
|
||||
flags.bools[key] ||
|
||||
aliases[key]
|
||||
);
|
||||
}
|
||||
|
||||
function setArg(key, val, arg = null): void {
|
||||
if (arg && flags.unknownFn && !argDefined(key, arg)) {
|
||||
if (flags.unknownFn(arg) === false) return;
|
||||
}
|
||||
|
||||
const value = !flags.strings[key] && isNumber(val) ? Number(val) : val;
|
||||
setKey(argv, key.split("."), value);
|
||||
|
||||
(aliases[key] || []).forEach(function(x) {
|
||||
setKey(argv, x.split("."), value);
|
||||
});
|
||||
}
|
||||
|
||||
function setKey(obj, keys, value): void {
|
||||
let o = obj;
|
||||
keys.slice(0, -1).forEach(function(key) {
|
||||
if (o[key] === undefined) o[key] = {};
|
||||
o = o[key];
|
||||
});
|
||||
|
||||
const key = keys[keys.length - 1];
|
||||
if (
|
||||
o[key] === undefined ||
|
||||
flags.bools[key] ||
|
||||
typeof o[key] === "boolean"
|
||||
) {
|
||||
o[key] = value;
|
||||
} else if (Array.isArray(o[key])) {
|
||||
o[key].push(value);
|
||||
} else {
|
||||
o[key] = [o[key], value];
|
||||
}
|
||||
}
|
||||
|
||||
function aliasIsBoolean(key): boolean {
|
||||
return aliases[key].some(function(x) {
|
||||
return flags.bools[x];
|
||||
});
|
||||
}
|
||||
|
||||
for (let i = 0; i < args.length; i++) {
|
||||
const arg = args[i];
|
||||
|
||||
if (/^--.+=/.test(arg)) {
|
||||
// Using [\s\S] instead of . because js doesn't support the
|
||||
// 'dotall' regex modifier. See:
|
||||
// http://stackoverflow.com/a/1068308/13216
|
||||
const m = arg.match(/^--([^=]+)=([\s\S]*)$/);
|
||||
const key = m[1];
|
||||
let value = m[2];
|
||||
if (flags.bools[key]) {
|
||||
value = value !== "false";
|
||||
}
|
||||
setArg(key, value, arg);
|
||||
} else if (/^--no-.+/.test(arg)) {
|
||||
const key = arg.match(/^--no-(.+)/)[1];
|
||||
setArg(key, false, arg);
|
||||
} else if (/^--.+/.test(arg)) {
|
||||
const key = arg.match(/^--(.+)/)[1];
|
||||
const next = args[i + 1];
|
||||
if (
|
||||
next !== undefined &&
|
||||
!/^-/.test(next) &&
|
||||
!flags.bools[key] &&
|
||||
!flags.allBools &&
|
||||
(aliases[key] ? !aliasIsBoolean(key) : true)
|
||||
) {
|
||||
setArg(key, next, arg);
|
||||
i++;
|
||||
} else if (/^(true|false)$/.test(next)) {
|
||||
setArg(key, next === "true", arg);
|
||||
i++;
|
||||
} else {
|
||||
setArg(key, flags.strings[key] ? "" : true, arg);
|
||||
}
|
||||
} else if (/^-[^-]+/.test(arg)) {
|
||||
const letters = arg.slice(1, -1).split("");
|
||||
|
||||
let broken = false;
|
||||
for (let j = 0; j < letters.length; j++) {
|
||||
const next = arg.slice(j + 2);
|
||||
|
||||
if (next === "-") {
|
||||
setArg(letters[j], next, arg);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (/[A-Za-z]/.test(letters[j]) && /=/.test(next)) {
|
||||
setArg(letters[j], next.split("=")[1], arg);
|
||||
broken = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (
|
||||
/[A-Za-z]/.test(letters[j]) &&
|
||||
/-?\d+(\.\d*)?(e-?\d+)?$/.test(next)
|
||||
) {
|
||||
setArg(letters[j], next, arg);
|
||||
broken = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (letters[j + 1] && letters[j + 1].match(/\W/)) {
|
||||
setArg(letters[j], arg.slice(j + 2), arg);
|
||||
broken = true;
|
||||
break;
|
||||
} else {
|
||||
setArg(letters[j], flags.strings[letters[j]] ? "" : true, arg);
|
||||
}
|
||||
}
|
||||
|
||||
const key = arg.slice(-1)[0];
|
||||
if (!broken && key !== "-") {
|
||||
if (
|
||||
args[i + 1] &&
|
||||
!/^(-|--)[^-]/.test(args[i + 1]) &&
|
||||
!flags.bools[key] &&
|
||||
(aliases[key] ? !aliasIsBoolean(key) : true)
|
||||
) {
|
||||
setArg(key, args[i + 1], arg);
|
||||
i++;
|
||||
} else if (args[i + 1] && /true|false/.test(args[i + 1])) {
|
||||
setArg(key, args[i + 1] === "true", arg);
|
||||
i++;
|
||||
} else {
|
||||
setArg(key, flags.strings[key] ? "" : true, arg);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!flags.unknownFn || flags.unknownFn(arg) !== false) {
|
||||
argv._.push(flags.strings["_"] || !isNumber(arg) ? arg : Number(arg));
|
||||
}
|
||||
if (options.stopEarly) {
|
||||
argv._.push.apply(argv._, args.slice(i + 1));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Object.keys(defaults).forEach(function(key) {
|
||||
if (!hasKey(argv, key.split("."))) {
|
||||
setKey(argv, key.split("."), defaults[key]);
|
||||
|
||||
(aliases[key] || []).forEach(function(x) {
|
||||
setKey(argv, x.split("."), defaults[key]);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
if (options["--"]) {
|
||||
argv["--"] = new Array();
|
||||
notFlags.forEach(function(key) {
|
||||
argv["--"].push(key);
|
||||
});
|
||||
} else {
|
||||
notFlags.forEach(function(key) {
|
||||
argv._.push(key);
|
||||
});
|
||||
}
|
||||
|
||||
return argv;
|
||||
}
|
||||
|
||||
function hasKey(obj, keys) {
|
||||
let o = obj;
|
||||
keys.slice(0, -1).forEach(function(key) {
|
||||
o = o[key] || {};
|
||||
});
|
||||
|
||||
const key = keys[keys.length - 1];
|
||||
return key in o;
|
||||
}
|
||||
|
||||
function isNumber(x: any): boolean {
|
||||
if (typeof x === "number") return true;
|
||||
if (/^0x[0-9a-f]+$/i.test(x)) return true;
|
||||
return /^[-+]?(?:\d+(?:\.\d*)?|\.\d+)(e[-+]?\d+)?$/.test(x);
|
||||
}
|
13
flags/test.ts
Normal file
13
flags/test.ts
Normal file
|
@ -0,0 +1,13 @@
|
|||
import "./tests/all_bool.ts";
|
||||
import "./tests/bool.ts";
|
||||
import "./tests/dash.ts";
|
||||
import "./tests/default_bool.ts";
|
||||
import "./tests/dotted.ts";
|
||||
import "./tests/kv_short.ts";
|
||||
import "./tests/long.ts";
|
||||
import "./tests/num.ts";
|
||||
import "./tests/parse.ts";
|
||||
import "./tests/short.ts";
|
||||
import "./tests/stop_early.ts";
|
||||
import "./tests/unknown.ts";
|
||||
import "./tests/whitespace.ts";
|
32
flags/tests/all_bool.ts
Executable file
32
flags/tests/all_bool.ts
Executable file
|
@ -0,0 +1,32 @@
|
|||
import { test, assertEqual } from "https://deno.land/x/testing/testing.ts";
|
||||
import parseArgs from "../index.ts";
|
||||
|
||||
// flag boolean true (default all --args to boolean)
|
||||
test(function flagBooleanTrue() {
|
||||
const argv = parseArgs(['moo', '--honk', 'cow'], {
|
||||
boolean: true
|
||||
});
|
||||
|
||||
assertEqual(argv, {
|
||||
honk: true,
|
||||
_: ['moo', 'cow']
|
||||
});
|
||||
|
||||
assertEqual(typeof argv.honk, 'boolean');
|
||||
});
|
||||
|
||||
// flag boolean true only affects double hyphen arguments without equals signs
|
||||
test(function flagBooleanTrueOnlyAffectsDoubleDash() {
|
||||
var argv = parseArgs(['moo', '--honk', 'cow', '-p', '55', '--tacos=good'], {
|
||||
boolean: true
|
||||
});
|
||||
|
||||
assertEqual(argv, {
|
||||
honk: true,
|
||||
tacos: 'good',
|
||||
p: 55,
|
||||
_: ['moo', 'cow']
|
||||
});
|
||||
|
||||
assertEqual(typeof argv.honk, 'boolean');
|
||||
});
|
158
flags/tests/bool.ts
Executable file
158
flags/tests/bool.ts
Executable file
|
@ -0,0 +1,158 @@
|
|||
import { test, assertEqual } from "https://deno.land/x/testing/testing.ts";
|
||||
import parseArgs from "../index.ts";
|
||||
|
||||
test(function flagBooleanDefaultFalse() {
|
||||
const argv = parseArgs(['moo'], {
|
||||
boolean: ['t', 'verbose'],
|
||||
default: { verbose: false, t: false }
|
||||
});
|
||||
|
||||
assertEqual(argv, {
|
||||
verbose: false,
|
||||
t: false,
|
||||
_: ['moo']
|
||||
});
|
||||
|
||||
assertEqual(typeof argv.verbose, 'boolean');
|
||||
assertEqual(typeof argv.t, 'boolean');
|
||||
});
|
||||
|
||||
test(function booleanGroups() {
|
||||
const argv = parseArgs([ '-x', '-z', 'one', 'two', 'three' ], {
|
||||
boolean: ['x','y','z']
|
||||
});
|
||||
|
||||
assertEqual(argv, {
|
||||
x : true,
|
||||
y : false,
|
||||
z : true,
|
||||
_ : [ 'one', 'two', 'three' ]
|
||||
});
|
||||
|
||||
assertEqual(typeof argv.x, 'boolean');
|
||||
assertEqual(typeof argv.y, 'boolean');
|
||||
assertEqual(typeof argv.z, 'boolean');
|
||||
});
|
||||
|
||||
test(function booleanAndAliasWithChainableApi() {
|
||||
const aliased = [ '-h', 'derp' ];
|
||||
const regular = [ '--herp', 'derp' ];
|
||||
const opts = {
|
||||
herp: { alias: 'h', boolean: true }
|
||||
};
|
||||
const aliasedArgv = parseArgs(aliased, {
|
||||
boolean: 'herp',
|
||||
alias: { h: 'herp' }
|
||||
});
|
||||
const propertyArgv = parseArgs(regular, {
|
||||
boolean: 'herp',
|
||||
alias: { h: 'herp' }
|
||||
});
|
||||
const expected = {
|
||||
herp: true,
|
||||
h: true,
|
||||
'_': [ 'derp' ]
|
||||
};
|
||||
|
||||
assertEqual(aliasedArgv, expected);
|
||||
assertEqual(propertyArgv, expected);
|
||||
});
|
||||
|
||||
test(function booleanAndAliasWithOptionsHash() {
|
||||
const aliased = [ '-h', 'derp' ];
|
||||
const regular = [ '--herp', 'derp' ];
|
||||
const opts = {
|
||||
alias: { 'h': 'herp' },
|
||||
boolean: 'herp'
|
||||
};
|
||||
const aliasedArgv = parseArgs(aliased, opts);
|
||||
const propertyArgv = parseArgs(regular, opts);
|
||||
const expected = {
|
||||
herp: true,
|
||||
h: true,
|
||||
'_': [ 'derp' ]
|
||||
};
|
||||
assertEqual(aliasedArgv, expected);
|
||||
assertEqual(propertyArgv, expected);
|
||||
});
|
||||
|
||||
test(function booleanAndAliasArrayWithOptionsHash() {
|
||||
const aliased = [ '-h', 'derp' ];
|
||||
const regular = [ '--herp', 'derp' ];
|
||||
const alt = [ '--harp', 'derp' ];
|
||||
const opts = {
|
||||
alias: { 'h': ['herp', 'harp'] },
|
||||
boolean: 'h'
|
||||
};
|
||||
const aliasedArgv = parseArgs(aliased, opts);
|
||||
const propertyArgv = parseArgs(regular, opts);
|
||||
const altPropertyArgv = parseArgs(alt, opts);
|
||||
const expected = {
|
||||
harp: true,
|
||||
herp: true,
|
||||
h: true,
|
||||
'_': [ 'derp' ]
|
||||
};
|
||||
assertEqual(aliasedArgv, expected);
|
||||
assertEqual(propertyArgv, expected);
|
||||
assertEqual(altPropertyArgv, expected);
|
||||
});
|
||||
|
||||
test(function booleanAndAliasUsingExplicitTrue() {
|
||||
const aliased = [ '-h', 'true' ];
|
||||
const regular = [ '--herp', 'true' ];
|
||||
const opts = {
|
||||
alias: { h: 'herp' },
|
||||
boolean: 'h'
|
||||
};
|
||||
const aliasedArgv = parseArgs(aliased, opts);
|
||||
const propertyArgv = parseArgs(regular, opts);
|
||||
const expected = {
|
||||
herp: true,
|
||||
h: true,
|
||||
'_': [ ]
|
||||
};
|
||||
|
||||
assertEqual(aliasedArgv, expected);
|
||||
assertEqual(propertyArgv, expected);
|
||||
});
|
||||
|
||||
// regression, see https://github.com/substack/node-optimist/issues/71
|
||||
// boolean and --x=true
|
||||
test(function booleanAndNonBoolean() {
|
||||
const parsed = parseArgs(['--boool', '--other=true'], {
|
||||
boolean: 'boool'
|
||||
});
|
||||
|
||||
assertEqual(parsed.boool, true);
|
||||
assertEqual(parsed.other, 'true');
|
||||
|
||||
const parsed2 = parseArgs(['--boool', '--other=false'], {
|
||||
boolean: 'boool'
|
||||
});
|
||||
|
||||
assertEqual(parsed2.boool, true);
|
||||
assertEqual(parsed2.other, 'false');
|
||||
});
|
||||
|
||||
test(function booleanParsingTrue() {
|
||||
const parsed = parseArgs(['--boool=true'], {
|
||||
default: {
|
||||
boool: false
|
||||
},
|
||||
boolean: ['boool']
|
||||
});
|
||||
|
||||
assertEqual(parsed.boool, true);
|
||||
});
|
||||
|
||||
test(function booleanParsingFalse() {
|
||||
const parsed = parseArgs(['--boool=false'], {
|
||||
default: {
|
||||
boool: true
|
||||
},
|
||||
boolean: ['boool']
|
||||
});
|
||||
|
||||
assertEqual(parsed.boool, false);
|
||||
});
|
28
flags/tests/dash.ts
Executable file
28
flags/tests/dash.ts
Executable file
|
@ -0,0 +1,28 @@
|
|||
import { test, assertEqual } from "https://deno.land/x/testing/testing.ts";
|
||||
import parseArgs from "../index.ts";
|
||||
|
||||
test(function hyphen() {
|
||||
assertEqual(parseArgs([ '-n', '-' ]), { n: '-', _: [] });
|
||||
assertEqual(parseArgs([ '-' ]), { _: [ '-' ] });
|
||||
assertEqual(parseArgs([ '-f-' ]), { f: '-', _: [] });
|
||||
assertEqual(
|
||||
parseArgs([ '-b', '-' ], { boolean: 'b' }),
|
||||
{ b: true, _: [ '-' ] }
|
||||
);
|
||||
assertEqual(
|
||||
parseArgs([ '-s', '-' ], { string: 's' }),
|
||||
{ s: '-', _: [] }
|
||||
);
|
||||
});
|
||||
|
||||
test(function doubleDash() {
|
||||
assertEqual(parseArgs([ '-a', '--', 'b' ]), { a: true, _: [ 'b' ] });
|
||||
assertEqual(parseArgs([ '--a', '--', 'b' ]), { a: true, _: [ 'b' ] });
|
||||
assertEqual(parseArgs([ '--a', '--', 'b' ]), { a: true, _: [ 'b' ] });
|
||||
});
|
||||
|
||||
test(function moveArgsAfterDoubleDashIntoOwnArray() {
|
||||
assertEqual(
|
||||
parseArgs([ '--name', 'John', 'before', '--', 'after' ], { '--': true }),
|
||||
{ name: 'John', _: [ 'before' ], '--': [ 'after' ] });
|
||||
});
|
32
flags/tests/default_bool.ts
Executable file
32
flags/tests/default_bool.ts
Executable file
|
@ -0,0 +1,32 @@
|
|||
import { test, assertEqual } from "https://deno.land/x/testing/testing.ts";
|
||||
import parseArgs from "../index.ts";
|
||||
|
||||
test(function booleanDefaultTrue() {
|
||||
const argv = parseArgs([], {
|
||||
boolean: 'sometrue',
|
||||
default: { sometrue: true }
|
||||
});
|
||||
assertEqual(argv.sometrue, true);
|
||||
});
|
||||
|
||||
test(function booleanDefaultFalse() {
|
||||
const argv = parseArgs([], {
|
||||
boolean: 'somefalse',
|
||||
default: { somefalse: false }
|
||||
});
|
||||
assertEqual(argv.somefalse, false);
|
||||
});
|
||||
|
||||
test(function booleanDefaultNull() {
|
||||
const argv = parseArgs([], {
|
||||
boolean: 'maybe',
|
||||
default: { maybe: null }
|
||||
});
|
||||
assertEqual(argv.maybe, null);
|
||||
const argv2 = parseArgs(['--maybe'], {
|
||||
boolean: 'maybe',
|
||||
default: { maybe: null }
|
||||
});
|
||||
assertEqual(argv2.maybe, true);
|
||||
|
||||
})
|
19
flags/tests/dotted.ts
Executable file
19
flags/tests/dotted.ts
Executable file
|
@ -0,0 +1,19 @@
|
|||
import { test, assertEqual } from "https://deno.land/x/testing/testing.ts";
|
||||
import parseArgs from "../index.ts";
|
||||
|
||||
test(function dottedAlias() {
|
||||
const argv = parseArgs(['--a.b', '22'], {default: {'a.b': 11}, alias: {'a.b': 'aa.bb'}});
|
||||
assertEqual(argv.a.b, 22);
|
||||
assertEqual(argv.aa.bb, 22);
|
||||
});
|
||||
|
||||
test(function dottedDefault() {
|
||||
const argv = parseArgs('', {default: {'a.b': 11}, alias: {'a.b': 'aa.bb'}});
|
||||
assertEqual(argv.a.b, 11);
|
||||
assertEqual(argv.aa.bb, 11);
|
||||
});
|
||||
|
||||
test(function dottedDefaultWithNoAlias() {
|
||||
const argv = parseArgs('', {default: {'a.b': 11}});
|
||||
assertEqual(argv.a.b, 11);
|
||||
});
|
12
flags/tests/kv_short.ts
Executable file
12
flags/tests/kv_short.ts
Executable file
|
@ -0,0 +1,12 @@
|
|||
import { test, assertEqual } from "https://deno.land/x/testing/testing.ts";
|
||||
import parseArgs from "../index.ts";
|
||||
|
||||
test(function short() {
|
||||
const argv = parseArgs([ '-b=123' ]);
|
||||
assertEqual(argv, { b: 123, _: [] });
|
||||
});
|
||||
|
||||
test(function multiShort() {
|
||||
const argv = parseArgs([ '-a=whatever', '-b=robots' ]);
|
||||
assertEqual(argv, { a: 'whatever', b: 'robots', _: [] });
|
||||
});
|
25
flags/tests/long.ts
Executable file
25
flags/tests/long.ts
Executable file
|
@ -0,0 +1,25 @@
|
|||
import { test, assertEqual } from "https://deno.land/x/testing/testing.ts";
|
||||
import parseArgs from "../index.ts";
|
||||
|
||||
test(function longOpts() {
|
||||
assertEqual(
|
||||
parseArgs([ '--bool' ]),
|
||||
{ bool : true, _ : [] },
|
||||
);
|
||||
assertEqual(
|
||||
parseArgs([ '--pow', 'xixxle' ]),
|
||||
{ pow : 'xixxle', _ : [] },
|
||||
);
|
||||
assertEqual(
|
||||
parseArgs([ '--pow=xixxle' ]),
|
||||
{ pow : 'xixxle', _ : [] },
|
||||
);
|
||||
assertEqual(
|
||||
parseArgs([ '--host', 'localhost', '--port', '555' ]),
|
||||
{ host : 'localhost', port : 555, _ : [] },
|
||||
);
|
||||
assertEqual(
|
||||
parseArgs([ '--host=localhost', '--port=555' ]),
|
||||
{ host : 'localhost', port : 555, _ : [] },
|
||||
);
|
||||
});
|
34
flags/tests/num.ts
Executable file
34
flags/tests/num.ts
Executable file
|
@ -0,0 +1,34 @@
|
|||
import { test, assertEqual } from "https://deno.land/x/testing/testing.ts";
|
||||
import parseArgs from "../index.ts";
|
||||
|
||||
test(function nums() {
|
||||
const argv = parseArgs([
|
||||
'-x', '1234',
|
||||
'-y', '5.67',
|
||||
'-z', '1e7',
|
||||
'-w', '10f',
|
||||
'--hex', '0xdeadbeef',
|
||||
'789'
|
||||
]);
|
||||
assertEqual(argv, {
|
||||
x : 1234,
|
||||
y : 5.67,
|
||||
z : 1e7,
|
||||
w : '10f',
|
||||
hex : 0xdeadbeef,
|
||||
_ : [ 789 ]
|
||||
});
|
||||
assertEqual(typeof argv.x, 'number');
|
||||
assertEqual(typeof argv.y, 'number');
|
||||
assertEqual(typeof argv.z, 'number');
|
||||
assertEqual(typeof argv.w, 'string');
|
||||
assertEqual(typeof argv.hex, 'number');
|
||||
assertEqual(typeof argv._[0], 'number');
|
||||
});
|
||||
|
||||
test(function alreadyNumber() {
|
||||
const argv = parseArgs([ '-x', 1234, 789 ]);
|
||||
assertEqual(argv, { x : 1234, _ : [ 789 ] });
|
||||
assertEqual(typeof argv.x, 'number');
|
||||
assertEqual(typeof argv._[0], 'number');
|
||||
});
|
182
flags/tests/parse.ts
Normal file
182
flags/tests/parse.ts
Normal file
|
@ -0,0 +1,182 @@
|
|||
import { test, assertEqual } from "https://deno.land/x/testing/testing.ts";
|
||||
import parseArgs from "../index.ts";
|
||||
|
||||
|
||||
test(function _arseArgs() {
|
||||
assertEqual(
|
||||
parseArgs([ '--no-moo' ]),
|
||||
{ moo : false, _ : [] },
|
||||
);
|
||||
assertEqual(
|
||||
parseArgs([ '-v', 'a', '-v', 'b', '-v', 'c' ]),
|
||||
{ v : ['a','b','c'], _ : [] },
|
||||
);
|
||||
});
|
||||
|
||||
test(function comprehensive() {
|
||||
assertEqual(
|
||||
parseArgs([
|
||||
'--name=meowmers', 'bare', '-cats', 'woo',
|
||||
'-h', 'awesome', '--multi=quux',
|
||||
'--key', 'value',
|
||||
'-b', '--bool', '--no-meep', '--multi=baz',
|
||||
'--', '--not-a-flag', 'eek'
|
||||
]),
|
||||
{
|
||||
c : true,
|
||||
a : true,
|
||||
t : true,
|
||||
s : 'woo',
|
||||
h : 'awesome',
|
||||
b : true,
|
||||
bool : true,
|
||||
key : 'value',
|
||||
multi : [ 'quux', 'baz' ],
|
||||
meep : false,
|
||||
name : 'meowmers',
|
||||
_ : [ 'bare', '--not-a-flag', 'eek' ]
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
test(function flagBoolean() {
|
||||
const argv = parseArgs([ '-t', 'moo' ], { boolean: 't' });
|
||||
assertEqual(argv, { t : true, _ : [ 'moo' ] });
|
||||
assertEqual(typeof argv.t, 'boolean');
|
||||
});
|
||||
|
||||
test(function flagBooleanValue() {
|
||||
const argv = parseArgs(['--verbose', 'false', 'moo', '-t', 'true'], {
|
||||
boolean: [ 't', 'verbose' ],
|
||||
default: { verbose: true }
|
||||
});
|
||||
|
||||
assertEqual(argv, {
|
||||
verbose: false,
|
||||
t: true,
|
||||
_: ['moo']
|
||||
});
|
||||
|
||||
assertEqual(typeof argv.verbose, 'boolean');
|
||||
assertEqual(typeof argv.t, 'boolean');
|
||||
});
|
||||
|
||||
test(function newlinesInParams() {
|
||||
const args = parseArgs([ '-s', "X\nX" ])
|
||||
assertEqual(args, { _ : [], s : "X\nX" });
|
||||
|
||||
// reproduce in bash:
|
||||
// VALUE="new
|
||||
// line"
|
||||
// deno program.js --s="$VALUE"
|
||||
const args2 = parseArgs([ "--s=X\nX" ])
|
||||
assertEqual(args2, { _ : [], s : "X\nX" });
|
||||
});
|
||||
|
||||
test(function strings() {
|
||||
const s = parseArgs([ '-s', '0001234' ], { string: 's' }).s;
|
||||
assertEqual(s, '0001234');
|
||||
assertEqual(typeof s, 'string');
|
||||
|
||||
const x = parseArgs([ '-x', '56' ], { string: 'x' }).x;
|
||||
assertEqual(x, '56');
|
||||
assertEqual(typeof x, 'string');
|
||||
});
|
||||
|
||||
test(function stringArgs() {
|
||||
const s = parseArgs([ ' ', ' ' ], { string: '_' })._;
|
||||
assertEqual(s.length, 2);
|
||||
assertEqual(typeof s[0], 'string');
|
||||
assertEqual(s[0], ' ');
|
||||
assertEqual(typeof s[1], 'string');
|
||||
assertEqual(s[1], ' ');
|
||||
});
|
||||
|
||||
test(function emptyStrings() {
|
||||
const s = parseArgs([ '-s' ], { string: 's' }).s;
|
||||
assertEqual(s, '');
|
||||
assertEqual(typeof s, 'string');
|
||||
|
||||
const str = parseArgs([ '--str' ], { string: 'str' }).str;
|
||||
assertEqual(str, '');
|
||||
assertEqual(typeof str, 'string');
|
||||
|
||||
const letters = parseArgs([ '-art' ], {
|
||||
string: [ 'a', 't' ]
|
||||
});
|
||||
|
||||
assertEqual(letters.a, '');
|
||||
assertEqual(letters.r, true);
|
||||
assertEqual(letters.t, '');
|
||||
});
|
||||
|
||||
|
||||
test(function stringAndAlias() {
|
||||
const x = parseArgs([ '--str', '000123' ], {
|
||||
string: 's',
|
||||
alias: { s: 'str' }
|
||||
});
|
||||
|
||||
assertEqual(x.str, '000123');
|
||||
assertEqual(typeof x.str, 'string');
|
||||
assertEqual(x.s, '000123');
|
||||
assertEqual(typeof x.s, 'string');
|
||||
|
||||
const y = parseArgs([ '-s', '000123' ], {
|
||||
string: 'str',
|
||||
alias: { str: 's' }
|
||||
});
|
||||
|
||||
assertEqual(y.str, '000123');
|
||||
assertEqual(typeof y.str, 'string');
|
||||
assertEqual(y.s, '000123');
|
||||
assertEqual(typeof y.s, 'string');
|
||||
});
|
||||
|
||||
test(function slashBreak() {
|
||||
assertEqual(
|
||||
parseArgs([ '-I/foo/bar/baz' ]),
|
||||
{ I : '/foo/bar/baz', _ : [] }
|
||||
);
|
||||
assertEqual(
|
||||
parseArgs([ '-xyz/foo/bar/baz' ]),
|
||||
{ x : true, y : true, z : '/foo/bar/baz', _ : [] }
|
||||
);
|
||||
});
|
||||
|
||||
test(function alias() {
|
||||
const argv = parseArgs([ '-f', '11', '--zoom', '55' ], {
|
||||
alias: { z: 'zoom' }
|
||||
});
|
||||
assertEqual(argv.zoom, 55);
|
||||
assertEqual(argv.z, argv.zoom);
|
||||
assertEqual(argv.f, 11);
|
||||
});
|
||||
|
||||
test(function multiAlias() {
|
||||
const argv = parseArgs([ '-f', '11', '--zoom', '55' ], {
|
||||
alias: { z: [ 'zm', 'zoom' ] }
|
||||
});
|
||||
assertEqual(argv.zoom, 55);
|
||||
assertEqual(argv.z, argv.zoom);
|
||||
assertEqual(argv.z, argv.zm);
|
||||
assertEqual(argv.f, 11);
|
||||
});
|
||||
|
||||
test(function nestedDottedObjects() {
|
||||
const argv = parseArgs([
|
||||
'--foo.bar', '3', '--foo.baz', '4',
|
||||
'--foo.quux.quibble', '5', '--foo.quux.o_O',
|
||||
'--beep.boop'
|
||||
]);
|
||||
|
||||
assertEqual(argv.foo, {
|
||||
bar : 3,
|
||||
baz : 4,
|
||||
quux : {
|
||||
quibble : 5,
|
||||
o_O : true
|
||||
}
|
||||
});
|
||||
assertEqual(argv.beep, { boop : true });
|
||||
});
|
57
flags/tests/short.ts
Executable file
57
flags/tests/short.ts
Executable file
|
@ -0,0 +1,57 @@
|
|||
import { test, assertEqual } from "https://deno.land/x/testing/testing.ts";
|
||||
import parseArgs from "../index.ts";
|
||||
|
||||
test(function numbericShortArgs() {
|
||||
assertEqual(parseArgs([ '-n123' ]), { n: 123, _: [] });
|
||||
assertEqual(
|
||||
parseArgs([ '-123', '456' ]),
|
||||
{ 1: true, 2: true, 3: 456, _: [] }
|
||||
);
|
||||
});
|
||||
|
||||
test(function short() {
|
||||
assertEqual(
|
||||
parseArgs([ '-b' ]),
|
||||
{ b : true, _ : [] },
|
||||
);
|
||||
assertEqual(
|
||||
parseArgs([ 'foo', 'bar', 'baz' ]),
|
||||
{ _ : [ 'foo', 'bar', 'baz' ] },
|
||||
);
|
||||
assertEqual(
|
||||
parseArgs([ '-cats' ]),
|
||||
{ c : true, a : true, t : true, s : true, _ : [] },
|
||||
);
|
||||
assertEqual(
|
||||
parseArgs([ '-cats', 'meow' ]),
|
||||
{ c : true, a : true, t : true, s : 'meow', _ : [] },
|
||||
);
|
||||
assertEqual(
|
||||
parseArgs([ '-h', 'localhost' ]),
|
||||
{ h : 'localhost', _ : [] },
|
||||
);
|
||||
assertEqual(
|
||||
parseArgs([ '-h', 'localhost', '-p', '555' ]),
|
||||
{ h : 'localhost', p : 555, _ : [] },
|
||||
);
|
||||
});
|
||||
|
||||
test(function mixedShortBoolAndCapture() {
|
||||
assertEqual(
|
||||
parseArgs([ '-h', 'localhost', '-fp', '555', 'script.js' ]),
|
||||
{
|
||||
f : true, p : 555, h : 'localhost',
|
||||
_ : [ 'script.js' ]
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
test(function shortAndLong() {
|
||||
assertEqual(
|
||||
parseArgs([ '-h', 'localhost', '-fp', '555', 'script.js' ]),
|
||||
{
|
||||
f : true, p : 555, h : 'localhost',
|
||||
_ : [ 'script.js' ]
|
||||
}
|
||||
);
|
||||
});
|
14
flags/tests/stop_early.ts
Executable file
14
flags/tests/stop_early.ts
Executable file
|
@ -0,0 +1,14 @@
|
|||
import { test, assertEqual } from "https://deno.land/x/testing/testing.ts";
|
||||
import parseArgs from "../index.ts";
|
||||
|
||||
// stops parsing on the first non-option when stopEarly is set
|
||||
test(function stopParsing() {
|
||||
const argv = parseArgs(['--aaa', 'bbb', 'ccc', '--ddd'], {
|
||||
stopEarly: true
|
||||
});
|
||||
|
||||
assertEqual(argv, {
|
||||
aaa: 'bbb',
|
||||
_: ['ccc', '--ddd']
|
||||
});
|
||||
});
|
96
flags/tests/unknown.ts
Executable file
96
flags/tests/unknown.ts
Executable file
|
@ -0,0 +1,96 @@
|
|||
import { test, assertEqual } from "https://deno.land/x/testing/testing.ts";
|
||||
import parseArgs from "../index.ts";
|
||||
|
||||
test(function booleanAndAliasIsNotUnknown() {
|
||||
const unknown = [];
|
||||
function unknownFn(arg) {
|
||||
unknown.push(arg);
|
||||
return false;
|
||||
}
|
||||
const aliased = [ '-h', 'true', '--derp', 'true' ];
|
||||
const regular = [ '--herp', 'true', '-d', 'true' ];
|
||||
const opts = {
|
||||
alias: { h: 'herp' },
|
||||
boolean: 'h',
|
||||
unknown: unknownFn
|
||||
};
|
||||
const aliasedArgv = parseArgs(aliased, opts);
|
||||
const propertyArgv = parseArgs(regular, opts);
|
||||
|
||||
assertEqual(unknown, ['--derp', '-d']);
|
||||
});
|
||||
|
||||
test(function flagBooleanTrueAnyDoubleHyphenArgumentIsNotUnknown() {
|
||||
const unknown = [];
|
||||
function unknownFn(arg) {
|
||||
unknown.push(arg);
|
||||
return false;
|
||||
}
|
||||
const argv = parseArgs(['--honk', '--tacos=good', 'cow', '-p', '55'], {
|
||||
boolean: true,
|
||||
unknown: unknownFn
|
||||
});
|
||||
assertEqual(unknown, ['--tacos=good', 'cow', '-p']);
|
||||
assertEqual(argv, {
|
||||
honk: true,
|
||||
_: []
|
||||
});
|
||||
});
|
||||
|
||||
test(function stringAndAliasIsNotUnkown() {
|
||||
const unknown = [];
|
||||
function unknownFn(arg) {
|
||||
unknown.push(arg);
|
||||
return false;
|
||||
}
|
||||
const aliased = [ '-h', 'hello', '--derp', 'goodbye' ];
|
||||
const regular = [ '--herp', 'hello', '-d', 'moon' ];
|
||||
const opts = {
|
||||
alias: { h: 'herp' },
|
||||
string: 'h',
|
||||
unknown: unknownFn
|
||||
};
|
||||
const aliasedArgv = parseArgs(aliased, opts);
|
||||
const propertyArgv = parseArgs(regular, opts);
|
||||
|
||||
assertEqual(unknown, ['--derp', '-d']);
|
||||
});
|
||||
|
||||
test(function defaultAndAliasIsNotUnknown() {
|
||||
const unknown = [];
|
||||
function unknownFn(arg) {
|
||||
unknown.push(arg);
|
||||
return false;
|
||||
}
|
||||
const aliased = [ '-h', 'hello' ];
|
||||
const regular = [ '--herp', 'hello' ];
|
||||
const opts = {
|
||||
default: { 'h': 'bar' },
|
||||
alias: { 'h': 'herp' },
|
||||
unknown: unknownFn
|
||||
};
|
||||
const aliasedArgv = parseArgs(aliased, opts);
|
||||
const propertyArgv = parseArgs(regular, opts);
|
||||
|
||||
assertEqual(unknown, []);
|
||||
});
|
||||
|
||||
test(function valueFollowingDoubleHyphenIsNotUnknown() {
|
||||
const unknown = [];
|
||||
function unknownFn(arg) {
|
||||
unknown.push(arg);
|
||||
return false;
|
||||
}
|
||||
const aliased = [ '--bad', '--', 'good', 'arg' ];
|
||||
const opts = {
|
||||
'--': true,
|
||||
unknown: unknownFn
|
||||
};
|
||||
const argv = parseArgs(aliased, opts);
|
||||
|
||||
assertEqual(unknown, ['--bad']);
|
||||
assertEqual(argv, {
|
||||
'--': ['good', 'arg'],
|
||||
'_': []
|
||||
})
|
||||
});
|
6
flags/tests/whitespace.ts
Executable file
6
flags/tests/whitespace.ts
Executable file
|
@ -0,0 +1,6 @@
|
|||
import { test, assertEqual } from "https://deno.land/x/testing/testing.ts";
|
||||
import parseArgs from "../index.ts";
|
||||
|
||||
test(function whitespaceShouldBeWhitespace() {
|
||||
assertEqual(parseArgs([ '-x', '\t' ]).x, '\t');
|
||||
});
|
3
test.ts
3
test.ts
|
@ -4,6 +4,9 @@ import { run } from "deno";
|
|||
// colors tests
|
||||
import "colors/main_test.ts";
|
||||
|
||||
// flags tests
|
||||
import "flags/test.ts";
|
||||
|
||||
// net tests
|
||||
import "net/bufio_test.ts";
|
||||
import "net/http_test.ts";
|
||||
|
|
Loading…
Reference in a new issue