mirror of
https://github.com/TangentFoxy/argparse.git
synced 2025-10-02 15:12:30 +00:00
Reworked default values
* Better out-of-the-box behavior: commonly used feature should work without configuration. Only use default value if argument/option was not used at all. * Add `defmode` field so that old behaviour can be used, too.
This commit is contained in:
@@ -4,21 +4,33 @@ describe("tests related to default values", function()
|
|||||||
describe("default values for arguments", function()
|
describe("default values for arguments", function()
|
||||||
it("handles default argument correctly", function()
|
it("handles default argument correctly", function()
|
||||||
local parser = Parser()
|
local parser = Parser()
|
||||||
parser:argument("foo", {
|
parser:argument "foo"
|
||||||
default = "bar"
|
:default "bar"
|
||||||
})
|
local args = parser:parse{}
|
||||||
local args = parser:parse({})
|
|
||||||
assert.same({foo = "bar"}, args)
|
assert.same({foo = "bar"}, args)
|
||||||
|
local args = parser:parse{"baz"}
|
||||||
|
assert.same({foo = "baz"}, args)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
it("handles default multi-argument correctly", function()
|
it("handles default argument for multi-argument correctly", function()
|
||||||
|
local parser = Parser()
|
||||||
|
parser:argument("foo", {
|
||||||
|
args = 3,
|
||||||
|
default = "bar",
|
||||||
|
defmode = "arg"
|
||||||
|
})
|
||||||
|
local args = parser:parse{"baz"}
|
||||||
|
assert.same({foo = {"baz", "bar", "bar"}}, args)
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("handles default value for multi-argument correctly", function()
|
||||||
local parser = Parser()
|
local parser = Parser()
|
||||||
parser:argument("foo", {
|
parser:argument("foo", {
|
||||||
args = 3,
|
args = 3,
|
||||||
default = "bar"
|
default = "bar"
|
||||||
})
|
})
|
||||||
local args = parser:parse({"baz"})
|
local args = parser:parse{}
|
||||||
assert.same({foo = {"baz", "bar", "bar"}}, args)
|
assert.same({foo = {"bar", "bar", "bar"}}, args)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
it("does not use default values if not needed", function()
|
it("does not use default values if not needed", function()
|
||||||
@@ -34,29 +46,57 @@ describe("tests related to default values", function()
|
|||||||
|
|
||||||
describe("default values for options", function()
|
describe("default values for options", function()
|
||||||
it("handles option with default value correctly", function()
|
it("handles option with default value correctly", function()
|
||||||
local parser = Parser()
|
|
||||||
parser:option("-f", "--foo", {
|
|
||||||
default = "bar"
|
|
||||||
})
|
|
||||||
local args = parser:parse({"-f"})
|
|
||||||
assert.same({foo = "bar"}, args)
|
|
||||||
end)
|
|
||||||
|
|
||||||
it("handles underused option with default value correctly", function()
|
|
||||||
local parser = Parser()
|
local parser = Parser()
|
||||||
parser:option "-o" "--output"
|
parser:option "-o" "--output"
|
||||||
:count(1)
|
|
||||||
:default "a.out"
|
:default "a.out"
|
||||||
local args = parser:parse{}
|
local args = parser:parse{}
|
||||||
assert.same({output = "a.out"}, args)
|
assert.same({output = "a.out"}, args)
|
||||||
|
args = parser:parse{"--output", "foo.txt"}
|
||||||
|
assert.same({output = "foo.txt"}, args)
|
||||||
|
assert.has_error(function() parser:parse{"-o"} end, "too few arguments")
|
||||||
end)
|
end)
|
||||||
|
|
||||||
it("doesn't use default if option is not invoked", function()
|
it("handles option with default value for multi-argument option correctly", function()
|
||||||
|
local parser = Parser()
|
||||||
|
parser:option("-s", "--several", {
|
||||||
|
default = "foo",
|
||||||
|
args = "2-3"
|
||||||
|
})
|
||||||
|
local args = parser:parse{}
|
||||||
|
assert.same({several = {"foo", "foo"}}, args)
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("handles option with default value and argument", function()
|
||||||
|
local parser = Parser()
|
||||||
|
parser:option("-o", "--output", {
|
||||||
|
default = "a.out",
|
||||||
|
defmode = "arg+count"
|
||||||
|
})
|
||||||
|
local args = parser:parse{}
|
||||||
|
assert.same({output = "a.out"}, args)
|
||||||
|
args = parser:parse{"-o"}
|
||||||
|
assert.same({output = "a.out"}, args)
|
||||||
|
args = parser:parse{"-o", "value"}
|
||||||
|
assert.same({output = "value"}, args)
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("handles option with default argument correctly", function()
|
||||||
|
local parser = Parser()
|
||||||
|
parser:option "-p" "--protected"
|
||||||
|
:target "password"
|
||||||
|
:default "password"
|
||||||
|
:defmode "arg"
|
||||||
|
local args = parser:parse{"-p"}
|
||||||
|
assert.same({password = "password"}, args)
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("doesn't use default argument if option is not invoked", function()
|
||||||
local parser = Parser()
|
local parser = Parser()
|
||||||
parser:option("-f", "--foo", {
|
parser:option("-f", "--foo", {
|
||||||
default = "bar"
|
default = "bar",
|
||||||
|
defmode = "arg"
|
||||||
})
|
})
|
||||||
local args = parser:parse({})
|
local args = parser:parse{}
|
||||||
assert.same({}, args)
|
assert.same({}, args)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
@@ -64,7 +104,8 @@ describe("tests related to default values", function()
|
|||||||
local parser = Parser()
|
local parser = Parser()
|
||||||
parser:option("-f", "--foo", {
|
parser:option("-f", "--foo", {
|
||||||
args = 3,
|
args = 3,
|
||||||
default = "bar"
|
default = "bar",
|
||||||
|
defmode = "arg"
|
||||||
})
|
})
|
||||||
local args = parser:parse({"--foo=baz"})
|
local args = parser:parse({"--foo=baz"})
|
||||||
assert.same({foo = {"baz", "bar", "bar"}}, args)
|
assert.same({foo = {"baz", "bar", "bar"}}, args)
|
||||||
@@ -74,7 +115,8 @@ describe("tests related to default values", function()
|
|||||||
local parser = Parser()
|
local parser = Parser()
|
||||||
parser:option("-f", "--foo", {
|
parser:option("-f", "--foo", {
|
||||||
args = "1-2",
|
args = "1-2",
|
||||||
default = "bar"
|
default = "bar",
|
||||||
|
defmode = "arg"
|
||||||
})
|
})
|
||||||
local args = parser:parse({"-f", "baz"})
|
local args = parser:parse({"-f", "baz"})
|
||||||
assert.same({foo = {"baz"}}, args)
|
assert.same({foo = {"baz"}}, args)
|
||||||
@@ -84,7 +126,8 @@ describe("tests related to default values", function()
|
|||||||
local parser = Parser()
|
local parser = Parser()
|
||||||
parser:option("-f", "--foo", {
|
parser:option("-f", "--foo", {
|
||||||
count = "*",
|
count = "*",
|
||||||
default = "bar"
|
default = "bar",
|
||||||
|
defmode = "arg + count"
|
||||||
})
|
})
|
||||||
local args = parser:parse({"-f", "--foo=baz", "--foo"})
|
local args = parser:parse({"-f", "--foo=baz", "--foo"})
|
||||||
assert.same({foo = {"bar", "baz", "bar"}}, args)
|
assert.same({foo = {"bar", "baz", "bar"}}, args)
|
||||||
|
@@ -70,10 +70,11 @@ local Argument = class {
|
|||||||
__name = "Argument",
|
__name = "Argument",
|
||||||
_args = 1,
|
_args = 1,
|
||||||
_count = 1,
|
_count = 1,
|
||||||
|
_defmode = "count",
|
||||||
_fields = {
|
_fields = {
|
||||||
"name", "description", "target", "args",
|
"name", "description", "target", "args",
|
||||||
"minargs", "maxargs", "default", "convert",
|
"minargs", "maxargs", "default", "defmode",
|
||||||
"usage", "argname"
|
"convert", "usage", "argname"
|
||||||
}
|
}
|
||||||
}:include(Declarative)
|
}:include(Declarative)
|
||||||
|
|
||||||
@@ -85,8 +86,9 @@ local Option = Argument:extends {
|
|||||||
_fields = {
|
_fields = {
|
||||||
"name", "aliases", "description", "target",
|
"name", "aliases", "description", "target",
|
||||||
"args", "minargs", "maxargs", "count",
|
"args", "minargs", "maxargs", "count",
|
||||||
"mincount", "maxcount", "default", "convert",
|
"mincount", "maxcount", "default", "defmode",
|
||||||
"overwrite", "action", "usage", "argname"
|
"convert", "overwrite", "action", "usage",
|
||||||
|
"argname"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -603,12 +605,16 @@ function Parser:_parse(args, errhandler)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function complete_invocation(element)
|
||||||
|
while passed[element] < element._minargs do
|
||||||
|
pass(element, element._default)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
function close(element)
|
function close(element)
|
||||||
if passed[element] < element._minargs then
|
if passed[element] < element._minargs then
|
||||||
if element._default then
|
if element._default and element._defmode:find "a" then
|
||||||
while passed[element] < element._minargs do
|
complete_invocation(element)
|
||||||
pass(element, element._default)
|
|
||||||
end
|
|
||||||
else
|
else
|
||||||
error_("too few arguments")
|
error_("too few arguments")
|
||||||
end
|
end
|
||||||
@@ -760,7 +766,11 @@ function Parser:_parse(args, errhandler)
|
|||||||
end
|
end
|
||||||
|
|
||||||
while cur_arg do
|
while cur_arg do
|
||||||
close(cur_arg)
|
if passed[cur_arg] == 0 and cur_arg._default and cur_arg._defmode:find "c" then
|
||||||
|
complete_invocation(cur_arg)
|
||||||
|
else
|
||||||
|
close(cur_arg)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if parser._require_command and #commands > 0 then
|
if parser._require_command and #commands > 0 then
|
||||||
@@ -768,8 +778,16 @@ function Parser:_parse(args, errhandler)
|
|||||||
end
|
end
|
||||||
|
|
||||||
for _, option in ipairs(options) do
|
for _, option in ipairs(options) do
|
||||||
|
if invocations[option] == 0 then
|
||||||
|
if option._default and option._defmode:find "c" then
|
||||||
|
invoke(option)
|
||||||
|
complete_invocation(option)
|
||||||
|
close(option)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
if invocations[option] < option._mincount then
|
if invocations[option] < option._mincount then
|
||||||
if option._default then
|
if option._default and option._defmode:find "a" then
|
||||||
while invocations[option] < option._mincount do
|
while invocations[option] < option._mincount do
|
||||||
invoke(option)
|
invoke(option)
|
||||||
close(option)
|
close(option)
|
||||||
|
Reference in New Issue
Block a user