nur-sery/nur_tests/cli/ArgsParserTest.php

675 lines
21 KiB
PHP

<?php
namespace nur\cli;
use nur\cli\impl\AbcdDest;
use nur\cli\impl\SimpleDest;
use nur\t\TestCase;
use stdClass;
class ArgsParserTest extends TestCase {
const SIMPLE_DEFS = [
"autohelp" => false,
"autoremains" => false,
["-a", "key" => "enabled"],
["-b", "key" => "enabled", "value" => 52],
["-z", "key" => "enabled", "inverse" => true],
["--keep", "key" => "keep"],
["-s", "--long", "key" => "option"],
["-v", "--value", "arg" => "value", "key" => "value"],
["-f", "--file", "arg" => "path", "key" => "file"],
["-h", "--host", "arg" => "host", "key" => "host"],
];
const DEBUG_ARGS = ["--keep", "-asvvalue"];
const SIMPLE_ARGS0 = [
"--keep",
"--long",
"--value", "value",
"--value=value",
"--file", "file",
"--file=file",
"--host", "host",
"--host=host",
];
const SIMPLE_ARGS1 = [
"-a", "-aa",
"-s", "-ss",
"-aass",
"-v", "value",
"-vvalue",
"-f", "file",
"-ffile",
"-h", "host",
"-hhost",
"-asv", "value",
"-asvvalue",
];
function testNormArgs() {
$parser = new ArgsParser(self::SIMPLE_DEFS);
$args = $parser->normArgs(self::DEBUG_ARGS);
#var_dump($args);
self::assertCount(6, $args);
$args = $parser->normArgs(self::SIMPLE_ARGS0);
#var_dump($args);
self::assertCount(15, $args);
$args = $parser->normArgs(self::SIMPLE_ARGS1);
#var_dump($args);
self::assertCount(31, $args);
self::assertSame(["--"], $parser->normArgs([]));
self::assertSame(["--"], $parser->normArgs(["--"]));
self::assertSame(["--", "a"], $parser->normArgs(["--", "a"]));
self::assertSame(["--", "--"], $parser->normArgs(["--", "--"]));
self::assertSame(["--", "--", "a"], $parser->normArgs(["--", "--", "a"]));
self::assertSame(["--", "--", "--"], $parser->normArgs(["--", "--", "--"]));
self::assertSame(["--", "--", "--", "a"], $parser->normArgs(["--", "--", "--", "a"]));
self::assertSame(["--", "a"], $parser->normArgs(["a"]));
self::assertSame(["--", "a"], $parser->normArgs(["a", "--"]));
self::assertSame(["--", "a", "b"], $parser->normArgs(["a", "--", "b"]));
self::assertSame(["--", "a", "--", "b"], $parser->normArgs(["a", "--", "--", "b"]));
self::assertSame(["--", "a", "--", "--", "b"], $parser->normArgs(["a", "--", "--", "--", "b"]));
}
function testNormArgs2() {
$parser = new ArgsParser(self::SIMPLE_DEFS);
self::assertSame(["-a", "--", "a"],
$parser->normArgs(["a", "-a"]));
self::assertSame(["-a", "--", "a"],
$parser->normArgs(["a", "-a", "//"]));
self::assertSame(["-a", "--", "a", "//", "--", "b"],
$parser->normArgs(["a", "-a", "//", "b"]));
self::assertSame(["-a", "--", "a", "//", "-b", "--", "b"],
$parser->normArgs(["a", "-a", "//", "b", "-b"]));
self::assertSame(["-a", "--", "a", "\\//"],
$parser->normArgs(["a", "-a", "\\//"]));
self::assertSame(["-a", "--", "a", "\\//", "b"],
$parser->normArgs(["a", "-a", "\\//", "b"]));
self::assertSame(["-a", "-b", "--", "a", "\\//", "b"],
$parser->normArgs(["a", "-a", "\\//", "b", "-b"]));
}
function testParseArgs() {
$parser = new ArgsParser(self::SIMPLE_DEFS);
$dest = [];
$parser->parseArgs($parser->normArgs(["-asvvalue", "--keep"]));
#var_dump($dest);
self::assertSame(1, $dest["enabled"]);
self::assertSame(1, $dest["keep"]);
self::assertSame(1, $dest["option"]);
self::assertSame("value", $dest["value"]);
$dest = [];
$parser->parseArgs($parser->normArgs(["-aa"]));
self::assertSame(2, $dest["enabled"]);
$dest = [];
$parser->parseArgs($parser->normArgs(["-aazz"]));
self::assertSame(0, $dest["enabled"]);
$dest = [];
$parser->parseArgs($parser->normArgs(["-b"]));
self::assertSame(52, $dest["enabled"]);
$dest = [];
$parser->parseArgs($parser->normArgs(["-bb"]));
self::assertSame(52, $dest["enabled"]);
self::assertException(ArgsException::class, function()
use ($parser, $dest) {
$parser->parseArgs($parser->normArgs(["-a", "arg"]));
});
}
function testParseArgs2() {
$defs = self::SIMPLE_DEFS;
$defs["autoremains"] = true;
$parser = new ArgsParser($defs);
$dest = []; $parser->parseArgs($parser->normArgs([]));
self::assertSame([], $dest["args"]);
$dest = []; $parser->parseArgs($parser->normArgs(["--"]));
self::assertSame([], $dest["args"]);
$dest = []; $parser->parseArgs($parser->normArgs(["--", "a"]));
self::assertSame(["a"], $dest["args"]);
$dest = []; $parser->parseArgs($parser->normArgs(["--", "--"]));
self::assertSame(["--"], $dest["args"]);
$dest = []; $parser->parseArgs($parser->normArgs(["--", "--", "a"]));
self::assertSame(["--", "a"], $dest["args"]);
$dest = []; $parser->parseArgs($parser->normArgs(["--", "--", "--"]));
self::assertSame(["--", "--"], $dest["args"]);
$dest = []; $parser->parseArgs($parser->normArgs(["--", "--", "--", "a"]));
self::assertSame(["--", "--", "a"], $dest["args"]);
$dest = []; $parser->parseArgs($parser->normArgs(["a"]));
self::assertSame(["a"], $dest["args"]);
$dest = []; $parser->parseArgs($parser->normArgs(["a", "--"]));
self::assertSame(["a"], $dest["args"]);
$dest = []; $parser->parseArgs($parser->normArgs(["a", "--", "b"]));
self::assertSame(["a", "b"], $dest["args"]);
$dest = []; $parser->parseArgs($parser->normArgs(["a", "--", "--", "b"]));
self::assertSame(["a", "--", "b"], $dest["args"]);
$dest = []; $parser->parseArgs($parser->normArgs(["a", "--", "--", "--", "b"]));
self::assertSame(["a", "--", "--", "b"], $dest["args"]);
}
function testParseArgs3() {
$defs = self::SIMPLE_DEFS;
$defs["autoremains"] = true;
$parser = new ArgsParser($defs);
$dest = []; $parser->parseArgs($parser->normArgs(["a", "-a"]));
self::assertSame(["a"], $dest["args"]);
self::assertSame(1, $dest["enabled"]);
$dest = []; $parser->parseArgs($parser->normArgs(["a", "-a", "//"]));
self::assertSame(["a"], $dest["args"]);
self::assertSame(1, $dest["enabled"]);
$dest = []; $parser->parseArgs($parser->normArgs(["a", "-a", "//", "b"]));
self::assertSame(["a", "b"], $dest["args"]);
self::assertSame(1, $dest["enabled"]);
$dest = []; $parser->parseArgs($parser->normArgs(["a", "-a", "//", "b", "-b"]));
self::assertSame(["a", "b"], $dest["args"]);
self::assertSame(52, $dest["enabled"]);
$dest = []; $parser->parseArgs($parser->normArgs(["a", "-a", "\\//"]));
self::assertSame(["a", "//"], $dest["args"]);
self::assertSame(1, $dest["enabled"]);
$dest = []; $parser->parseArgs($parser->normArgs(["a", "-a", "\\//", "b"]));
self::assertSame(["a", "//", "b"], $dest["args"]);
self::assertSame(1, $dest["enabled"]);
$dest = []; $parser->parseArgs($parser->normArgs(["a", "-a", "\\//", "b", "-b"]));
self::assertSame(["a", "//", "b"], $dest["args"]);
self::assertSame(52, $dest["enabled"]);
$dest = []; $parser->parseArgs($parser->normArgs(["a", "-a", "\\//", "\\\\//", "b", "-b"]));
self::assertSame(["a", "//", "\\//", "b"], $dest["args"]);
self::assertSame(52, $dest["enabled"]);
}
private static function parse(&$dest, array $defs, ?array $args=null): void {
$parser = new ArgsParser($defs);
$parser->parse($dest, $args);
}
function testAutoprop() {
unset($dest);
self::parse($dest, [
["-a", "--enable"],
["-b", "--b", "--before", "--before-date", "args" => "value"],
], [
"-aa",
"-b", "15/02/2002",
]);
self::assertSame(2, $dest->enable);
self::assertSame("15/02/2002", $dest->beforeDate);
$dest = new AbcdDest();
self::parse($dest, [
["-a", "--a"],
["-b", "--b"],
["-c", "--c"],
], [
"-abbccc"
]);
self::assertSame(1, $dest->getA());
self::assertSame(2, $dest->getB());
self::assertSame(3, $dest->getC());
}
function testArgs() {
$defs = [
["-a", "--enable"],
];
unset($dest);
self::parse($dest, $defs, []);
self::assertObjectNotHasProperty("enable", $dest);
self::assertObjectHasProperty("args", $dest);
self::assertSame([], $dest->args);
unset($dest);
self::parse($dest, $defs, ["x"]);
self::assertObjectNotHasProperty("enable", $dest);
self::assertObjectHasProperty("args", $dest);
self::assertSame(["x"], $dest->args);
unset($dest);
self::parse($dest, $defs, ["x", "-a"]);
self::assertObjectHasProperty("enable", $dest);
self::assertObjectHasProperty("args", $dest);
self::assertSame(1, $dest->enable);
self::assertSame(["x"], $dest->args);
$dest = [];
self::parse($dest, $defs, []);
self::assertArrayNotHasKey("enable", $dest);
self::assertArrayHasKey("args", $dest);
self::assertSame([], $dest["args"]);
$dest = [];
self::parse($dest, $defs, ["x"]);
self::assertArrayNotHasKey("enable", $dest);
self::assertArrayHasKey("args", $dest);
self::assertSame(["x"], $dest["args"]);
$dest = [];
self::parse($dest, $defs, ["x", "-a"]);
self::assertArrayHasKey("enable", $dest);
self::assertArrayHasKey("args", $dest);
self::assertSame(1, $dest["enable"]);
self::assertSame(["x"], $dest["args"]);
}
function testOpts() {
$defs = [
["-o", "--o", "args" => [["value"]]],
["--mm", "args" => ["value", "value"]],
["--mo", "args" => ["value", ["value"]]],
["--oo", "args" => [["value", "value"]]],
["--ma", "args" => ["value", null]],
["--a", "args" => [null]],
];
unset($dest); self::parse($dest, $defs, ["-o"]);
self::assertSame(null, $dest->o);
self::assertSame([], $dest->args);
unset($dest); self::parse($dest, $defs, ["-o", "1"]);
self::assertSame(null, $dest->o);
self::assertSame(["1"], $dest->args);
unset($dest); self::parse($dest, $defs, ["-o1"]);
self::assertSame("1", $dest->o);
self::assertSame([], $dest->args);
unset($dest); self::parse($dest, $defs, ["-o1", "2"]);
self::assertSame("1", $dest->o);
self::assertSame(["2"], $dest->args);
unset($dest); self::parse($dest, $defs, ["--o"]);
self::assertSame(null, $dest->o);
self::assertSame([], $dest->args);
unset($dest); self::parse($dest, $defs, ["--o", "1"]);
self::assertSame(null, $dest->o);
self::assertSame(["1"], $dest->args);
unset($dest); self::parse($dest, $defs, ["--o=1"]);
self::assertSame("1", $dest->o);
self::assertSame([], $dest->args);
unset($dest); self::parse($dest, $defs, ["--o=1", "2"]);
self::assertSame("1", $dest->o);
self::assertSame(["2"], $dest->args);
unset($dest); self::parse($dest, $defs, ["--mm", "1", "2"]);
self::assertSame(["1", "2"], $dest->mm);
self::assertSame([], $dest->args);
unset($dest); self::parse($dest, $defs, ["--mo", "1"]);
self::assertSame(["1"], $dest->mo);
self::assertSame([], $dest->args);
unset($dest); self::parse($dest, $defs, ["--mo", "1", "2"]);
self::assertSame(["1", "2"], $dest->mo);
self::assertSame([], $dest->args);
unset($dest); self::parse($dest, $defs, ["--mo", "1", "2", "3"]);
self::assertSame(["1", "2"], $dest->mo);
self::assertSame(["3"], $dest->args);
unset($dest); self::parse($dest, $defs, ["--oo"]);
self::assertSame([], $dest->oo);
self::assertSame([], $dest->args);
unset($dest); self::parse($dest, $defs, ["--oo", "1"]);
self::assertSame(["1"], $dest->oo);
self::assertSame([], $dest->args);
unset($dest); self::parse($dest, $defs, ["--oo", "1", "2"]);
self::assertSame(["1", "2"], $dest->oo);
self::assertSame([], $dest->args);
unset($dest); self::parse($dest, $defs, ["--oo", "1", "2", "3"]);
self::assertSame(["1", "2"], $dest->oo);
self::assertSame(["3"], $dest->args);
}
function testDefaultOptArgs() {
$defs = [
["-o", "--o", "args" => [["value"]],
"value" => "1",
],
];
unset($dest); self::parse($dest, $defs, ["-o"]);
self::assertSame("1", $dest->o);
self::assertSame([], $dest->args);
unset($dest); self::parse($dest, $defs, ["-o2"]);
self::assertSame("2", $dest->o);
self::assertSame([], $dest->args);
}
function testParseDefs() {
$defs = [
["-a", "--a"],
["x",
"cmd_args" => [
["-b", "--b"],
],
],
];
$parser = new ArgsParser($defs);
$parser->select(null);
$args = $parser->normArgs(["-a", "x", "-b"]);
self::assertSame(["-a", "x", "-b", "--"], $args);
$dest = new stdClass();
$parser->select(null);
$parser->parseArgs($args);
self::assertSame(["x"], $dest->command);
self::assertSame(1, $dest->a);
self::assertSame(1, $dest->b);
$defs = [
["-a", "--a"],
["x",
"cmd_args" => [
["-b", "--b"],
["y",
"cmd_args" => [
["-c", "--c"],
],
],
],
],
];
$parser = new ArgsParser($defs);
$parser->select(null);
$args = $parser->normArgs(["-a", "x", "-b", "y", "-c"]);
self::assertSame(["-a", "x", "-b", "y", "-c", "--"], $args);
$dest = new stdClass();
$parser->select(null);
$parser->parseArgs($args);
self::assertSame(["x", "y"], $dest->command);
self::assertSame(1, $dest->a);
self::assertSame(1, $dest->b);
self::assertSame(1, $dest->c);
}
function testTypes() {
$parser = new ArgsParser([
["-a:", "type" => "int"],
["-b:", "type" => "bool"],
["-c:", "type" => "string"],
["-d:", "type" => "array"],
]);
$dest = new AbcdDest();
$parser->parse($dest, ["-a0", "-b0", "-c0", "-d", ""]);
self::assertSame(0, $dest->getA());
self::assertSame(false, $dest->getB());
self::assertSame("0", $dest->getC());
self::assertSame([""], $dest->getD());
$dest = new AbcdDest();
$parser->parse($dest, ["-a1", "-b1", "-c1", "-d1"]);
self::assertSame(1, $dest->getA());
self::assertSame(true, $dest->getB());
self::assertSame("1", $dest->getC());
self::assertSame(["1"], $dest->getD());
$dest = new AbcdDest();
$parser->parse($dest, [
"-a1", "-a2",
"-b1", "-b2",
"-c1", "-c2",
"-d1", "-d2",
]);
self::assertSame(2, $dest->getA());
self::assertSame(true, $dest->getB());
self::assertSame("2", $dest->getC());
self::assertSame(["2"], $dest->getD());
$parser = new ArgsParser([
["-a:", "type" => "array", "action" => "--add"],
["-b:", "type" => "array", "action" => "--merge"],
["-c:", "type" => "int", "action" => "--add"],
["-d:", "type" => "int", "action" => "--merge"],
]);
$dest = new AbcdDest();
$parser->parse($dest, [
"-a1", "-a2",
"-b1", "-b2",
"-c1", "-c2",
"-d1", "-d2",
]);
self::assertSame([["1"], ["2"]], $dest->getA());
self::assertSame(["1", "2"], $dest->getB());
self::assertSame([1, 2], $dest->getC());
self::assertSame([1, 2], $dest->getD());
$parser = new ArgsParser([
["-a:", "type" => "array", "action" => "--merge"],
["-b:", "args" => ["value", [null]], "type" => "array", "action" => "--merges"],
]);
$dest = new AbcdDest();
$parser->parse($dest, [
"-a1", "-a2,3", "-a4,5,6",
"-b1", "2,3", "4,5,6", "--",
]);
self::assertSame(["1", "2", "3", "4", "5", "6"], $dest->getA());
self::assertSame(["1", "2", "3", "4", "5", "6"], $dest->getB());
}
function testRemainArgs() {
$dest = new SimpleDest();
## nombre quelconque d'arguments
$parser = new ArgsParser([
["args" => [null], "name" => "args"],
]);
# 0
$dest->reset();
$parser->parse($dest, []);
self::assertSame([], $dest->args);
# 1
$dest->reset();
$parser->parse($dest, ["a"]);
self::assertSame(["a"], $dest->args);
# 2
$dest->reset();
$parser->parse($dest, ["a", "b"]);
self::assertSame(["a", "b"], $dest->args);
# un argument
$parser = new ArgsParser([
["args" => ["value"], "name" => "args"],
]);
# 0
$dest->reset();
self::assertException(ArgsException::class, function () use ($parser, &$dest) {
$parser->parse($dest, []);
});
# 1
$dest->reset();
$parser->parse($dest, ["a"]);
self::assertSame(["a"], $dest->args);
# 2
$dest->reset();
self::assertException(ArgsException::class, function () use ($parser, &$dest) {
$parser->parse($dest, ["a", "b"]);
});
# deux arguments
$parser = new ArgsParser([
["args" => ["value", "value"], "name" => "args"],
]);
# 0
$dest->reset();
self::assertException(ArgsException::class, function () use ($parser, &$dest) {
$parser->parse($dest, []);
});
# 1
$dest->reset();
self::assertException(ArgsException::class, function () use ($parser, &$dest) {
$parser->parse($dest, ["a"]);
});
# 2
$dest->reset();
$parser->parse($dest, ["a", "b"]);
self::assertSame(["a", "b"], $dest->args);
# 3
$dest->reset();
self::assertException(ArgsException::class, function () use ($parser, &$dest) {
$parser->parse($dest, ["a", "b", "c"]);
});
# un arguments obligatoire, un argument facultatif
$parser = new ArgsParser([
["args" => ["value", ["value"]], "name" => "args"],
]);
# 0
$dest->reset();
self::assertException(ArgsException::class, function () use ($parser, &$dest) {
$parser->parse($dest, []);
});
# 1
$dest->reset();
$parser->parse($dest, ["a"]);
self::assertSame(["a"], $dest->args);
# 2
$dest->reset();
$parser->parse($dest, ["a", "b"]);
self::assertSame(["a", "b"], $dest->args);
# 3
$dest->reset();
self::assertException(ArgsException::class, function () use ($parser, &$dest) {
$parser->parse($dest, ["a", "b", "c"]);
});
# un arguments obligatoire, nombre infini d'arguments facultatifs
$parser = new ArgsParser([
["args" => ["value", null], "name" => "args"],
]);
# 0
$dest->reset();
self::assertException(ArgsException::class, function () use ($parser, &$dest) {
$parser->parse($dest, []);
});
# 1
$dest->reset();
$parser->parse($dest, ["a"]);
self::assertSame(["a"], $dest->args);
# 2
$dest->reset();
$parser->parse($dest, ["a", "b"]);
self::assertSame(["a", "b"], $dest->args);
# 3
$dest->reset();
$parser->parse($dest, ["a", "b", "c"]);
self::assertSame(["a", "b", "c"], $dest->args);
}
function testOverride() {
$parser = new ArgsParser([
["-a", "--o1"],
["-a", "--o2"],
["-b", "--v1", "args" => 1],
["-b", "--v2", "args" => 1],
["-c", "--x1"],
["-c", "--x2", "args" => 1],
]);
$object = new stdClass();
$object->o1 = 0;
$object->o2 = 0;
$object->v1 = null;
$object->v2 = null;
$object->x1 = 0;
$object->x2 = null;
$parser->parse($object, ["-a", "-b", "valb", "-c", "valc"]);
self::assertSame(0, $object->o1);
self::assertSame(1, $object->o2);
self::assertNull($object->v1);
self::assertSame("valb", $object->v2);
self::assertSame(0, $object->x1);
self::assertSame("valc", $object->x2);
$parser = new ArgsParser([
"sections" => [
[
["-a", "--o1"],
["-b", "--v1", "args" => 1],
["-c", "--x1"],
],
[
["-a", "--o2"],
["-b", "--v2", "args" => 1],
["-c", "--x2", "args" => 1],
],
],
]);
$object = new stdClass();
$object->o1 = 0;
$object->o2 = 0;
$object->v1 = null;
$object->v2 = null;
$object->x1 = 0;
$object->x2 = null;
$parser->parse($object, ["-a", "-b", "valb", "-c", "valc"]);
self::assertSame(0, $object->o1);
self::assertSame(1, $object->o2);
self::assertNull($object->v1);
self::assertSame("valb", $object->v2);
self::assertSame(0, $object->x1);
self::assertSame("valc", $object->x2);
$parser = new ArgsParser([
"merge" => [
"sections" => [
[
"title" => "une section",
["group",
["-A", "--g1"],
["-a", "--g2"],
],
],
],
],
["-a", "--o1"],
["-b", "--v1", "args" => 1],
["-c", "--x1"],
["-a", "--o2"],
["-b", "--v2", "args" => 1],
["-c", "--x2", "args" => 1],
]);
$object = new stdClass();
$object->g1 = 0;
$object->g2 = 0;
$object->o1 = 0;
$object->o2 = 0;
$object->v1 = null;
$object->v2 = null;
$object->x1 = 0;
$object->x2 = null;
$parser->parse($object, ["-a", "-b", "valb", "-c", "valc"]);
self::assertSame(0, $object->g1);
self::assertSame(0, $object->g2);
self::assertSame(0, $object->o1);
self::assertSame(1, $object->o2);
self::assertNull($object->v1);
self::assertSame("valb", $object->v2);
self::assertSame(0, $object->x1);
self::assertSame("valc", $object->x2);
}
}