From 582bdc173863262cfa65450f0b2db218e678f6b5 Mon Sep 17 00:00:00 2001 From: mpeterv Date: Wed, 1 Jan 2014 14:49:31 +0400 Subject: [PATCH] more tests, fixed wrong behaviour of joined options --- spec/options_spec.lua | 80 ++++++++++++++++++++++++++++++++++++++++++- src/largparse.lua | 2 +- src/state.lua | 11 ++---- 3 files changed, 83 insertions(+), 10 deletions(-) diff --git a/spec/options_spec.lua b/spec/options_spec.lua index c02062c..12f2843 100644 --- a/spec/options_spec.lua +++ b/spec/options_spec.lua @@ -93,6 +93,73 @@ describe("tests related to options", function() assert.same(args, {password = {"password"}}) end) end) + + it("handles multi-argument options correctly", function() + local parser = largparse.parser() + parser:option("--pair", { + args = 2 + }) + local args = parser:parse({"--pair", "Alice", "Bob"}) + assert.same(args, {pair = {"Alice", "Bob"}}) + end) + + describe("Multi-count options", function() + it("handles multi-count option correctly", function() + local parser = largparse.parser() + parser:option("-e", "--exclude", { + count = "*" + }) + local args = parser:parse({"-efoo", "--exclude=bar", "-e", "baz"}) + assert.same(args, {exclude = {"foo", "bar", "baz"}}) + end) + + it("handles not used multi-count option correctly", function() + local parser = largparse.parser() + parser:option("-e", "--exclude", { + count = "*" + }) + local args = parser:parse({}) + assert.same(args, {exclude = {}}) + end) + + it("handles multi-count multi-argument option correctly", function() + local parser = largparse.parser() + parser:option("-e", "--exclude", { + count = "*", + args = 2 + }) + local args = parser:parse({"-e", "Alice", "Bob", "-e", "Emma", "Jacob"}) + assert.same(args, {exclude = {{"Alice", "Bob"}, {"Emma", "Jacob"}}}) + end) + + it("handles multi-count option with optional argument correctly", function() + local parser = largparse.parser() + parser:option("-w", "--why", "--why-would-someone-use-this", { + count = "*", + args = "?" + }) + local args = parser:parse({"-w", "-wfoo", "--why=because", "-ww"}) + assert.same(args, {why = {{}, {"foo"}, {"because"}, {}, {}}}) + end) + + it("handles multi-count flag correctly", function() + local parser = largparse.parser() + parser:flag("-q", "--quiet", { + count = "*" + }) + local args = parser:parse({"-qq", "--quiet"}) + assert.same(args, {quiet = 3}) + end) + + it("handles not used multi-count flag correctly", function() + local parser = largparse.parser() + parser:flag("-q", "--quiet", { + count = "*" + }) + local args = parser:parse({}) + assert.same(args, {quiet = 0}) + end) + end) end) describe("passing incorrect options", function() @@ -105,7 +172,18 @@ describe("tests related to options", function() end end) - -- TODO + it("handles lack of required argument correctly", function() + local parser = largparse.parser() + parser:option("-s", "--server") + assert.has_error(curry(parser.parse, parser, {"--server"}), "too few arguments") + end) + + it("handles too many arguments correctly", function() + local parser = largparse.parser() + parser:option("-s", "--server") + assert.has_error(curry(parser.parse, parser, {"-sfoo", "bar"}), "too many arguments") + end) + end) end) \ No newline at end of file diff --git a/src/largparse.lua b/src/largparse.lua index b6cb7b9..bd34a5a 100644 --- a/src/largparse.lua +++ b/src/largparse.lua @@ -250,7 +250,7 @@ function Parser:parse(args) element = self:assert(state.context[name], "unknown option " .. name) state:handle_option(name) - if i ~= #data and not (element.minargs == 0 and data:sub(i+1, i+1):match "[a-zA-Z]") then + if i ~= #data and not (element.minargs == 0 and state.context["-" .. data:sub(i+1, i+1)]) then state:handle_argument(data:sub(i+1)) break end diff --git a/src/state.lua b/src/state.lua index 0ea76d6..bba5aba 100644 --- a/src/state.lua +++ b/src/state.lua @@ -98,7 +98,7 @@ function State:_check() if #invocations > element.maxcount then if element.no_overwrite then - self:_error("option %s can only be used %d times", element.name, element.maxcount) + self:_error("option %s must be used at most %d times", element.name, element.maxcount) else local new_invocations = {} for i = 1, element.maxcount do @@ -111,13 +111,8 @@ function State:_check() self:_assert(#invocations >= element.mincount, "option %s must be used at least %d times", element.name, element.mincount) for _, passed in ipairs(invocations) do - if element.type == "option" then - self:_assert(#passed <= element.maxargs, "%s takes at most %d arguments", element.name, element.maxargs) - self:_assert(#passed >= element.minargs, "%s takes at least %d arguments", element.name, element.minargs) - else - self:_assert(#passed <= element.maxargs, "too many arguments") - self:_assert(#passed >= element.minargs, "too few arguments") - end + self:_assert(#passed <= element.maxargs, "too many arguments") + self:_assert(#passed >= element.minargs, "too few arguments") end self._result[element.target] = invocations