From 2a49500a01043af2216bb9dd3f01af3a484a8484 Mon Sep 17 00:00:00 2001 From: mpeterv Date: Sun, 26 Jan 2014 19:02:36 +0400 Subject: [PATCH] added cli test --- spec/integrity_spec.lua | 166 ++++++++++++++++++++++++++++++++++++++++ spec/options_spec.lua | 2 +- spec/script | 35 +++++++++ src/argparse.lua | 4 +- 4 files changed, 204 insertions(+), 3 deletions(-) create mode 100644 spec/integrity_spec.lua create mode 100755 spec/script diff --git a/spec/integrity_spec.lua b/spec/integrity_spec.lua new file mode 100644 index 0000000..67ef0bd --- /dev/null +++ b/spec/integrity_spec.lua @@ -0,0 +1,166 @@ +local argparse = require "argparse" + +describe("tests related to CLI behaviour #unsafe", function() + describe("error messages", function() + it("generates correct error message without arguments", function() + local handler = io.popen("./spec/script 2>&1", "r") + assert.equal(table.concat({ + "Usage: test [-v] [-h] [] ...", + "", + "Error: too few arguments", + "" + }, "\r\n"), handler:read "*a") + handler:close() + end) + + it("generates correct error message with too many arguments", function() + local handler = io.popen("./spec/script foo bar 2>&1", "r") + assert.equal(table.concat({ + "Usage: test [-v] [-h] [] ...", + "", + "Error: unknown command 'bar'", + "" + }, "\r\n"), handler:read "*a") + handler:close() + end) + + it("generates correct error message with unexpected argument", function() + local handler = io.popen("./spec/script --verbose=true 2>&1", "r") + assert.equal(table.concat({ + "Usage: test [-v] [-h] [] ...", + "", + "Error: option '--verbose' does not take arguments", + "" + }, "\r\n"), handler:read "*a") + handler:close() + end) + + it("generates correct error message with unexpected option", function() + local handler = io.popen("./spec/script -vq 2>&1", "r") + assert.equal(table.concat({ + "Usage: test [-v] [-h] [] ...", + "", + "Error: unknown option '-q'", + "Did you mean one of these: '-h' '-v'?", + "" + }, "\r\n"), handler:read "*a") + handler:close() + end) + + it("generates correct error message and tip with unexpected command", function() + local handler = io.popen("./spec/script foo nstall 2>&1", "r") + assert.equal(table.concat({ + "Usage: test [-v] [-h] [] ...", + "", + "Error: unknown command 'nstall'", + "Did you mean 'install'?", + "" + }, "\r\n"), handler:read "*a") + handler:close() + end) + + it("generates correct error message without arguments in command", function() + local handler = io.popen("./spec/script foo install 2>&1", "r") + assert.equal(table.concat({ + "Usage: test install [-f ] [-h] []", + "", + "Error: too few arguments", + "" + }, "\r\n"), handler:read "*a") + handler:close() + end) + + it("generates correct error message and tip in command", function() + local handler = io.popen("./spec/script foo install bar --form=there 2>&1", "r") + assert.equal(table.concat({ + "Usage: test install [-f ] [-h] []", + "", + "Error: unknown option '--form'", + "Did you mean '--from'?", + "" + }, "\r\n"), handler:read "*a") + handler:close() + end) + end) + + describe("help messages", function() + it("generates correct help message", function() + local handler = io.popen("./spec/script --help 2>&1", "r") + assert.equal(table.concat({ + "Usage: test [-v] [-h] [] ...", + "", + "A testing program. ", + "", + "Arguments: ", + " input", + "", + "Options: ", + " -v, --verbose Sets verbosity level. ", + " -h, --help Show this help message and exit. ", + "", + "Commands: ", + " install Install a rock. ", + "" + }, "\r\n"), handler:read "*a") + handler:close() + end) + + it("generates correct help message for command", function() + local handler = io.popen("./spec/script foo install --help 2>&1", "r") + assert.equal(table.concat({ + "Usage: test install [-f ] [-h] []", + "", + "Install a rock. ", + "", + "Arguments: ", + " rock Name of the rock. ", + " version Version of the rock. ", + "", + "Options: ", + " -f , --from ", + " Fetch the rock from this server. ", + " -h, --help Show this help message and exit. ", + "", + }, "\r\n"), handler:read "*a") + handler:close() + end) + end) + + describe("data flow", function() + it("works with one argument", function() + local handler = io.popen("./spec/script foo 2>&1", "r") + assert.equal("foo", handler:read "*l") + assert.equal("0", handler:read "*l") + handler:close() + end) + + it("works with one argument and a flag", function() + local handler = io.popen("./spec/script -v foo --verbose 2>&1", "r") + assert.equal("foo", handler:read "*l") + assert.equal("2", handler:read "*l") + handler:close() + end) + + it("works with command", function() + local handler = io.popen("./spec/script foo -v install bar 2>&1", "r") + assert.equal("foo", handler:read "*l") + assert.equal("1", handler:read "*l") + assert.equal("true", handler:read "*l") + assert.equal("bar", handler:read "*l") + assert.equal("nil", handler:read "*l") + assert.equal("nil", handler:read "*l") + handler:close() + end) + + it("works with command and options", function() + local handler = io.popen("./spec/script foo --verbose install bar 0.1 --from=there -vv 2>&1", "r") + assert.equal("foo", handler:read "*l") + assert.equal("2", handler:read "*l") + assert.equal("true", handler:read "*l") + assert.equal("bar", handler:read "*l") + assert.equal("0.1", handler:read "*l") + assert.equal("there", handler:read "*l") + handler:close() + end) + end) +end) diff --git a/spec/options_spec.lua b/spec/options_spec.lua index 8a63dbe..5edbdc6 100644 --- a/spec/options_spec.lua +++ b/spec/options_spec.lua @@ -201,7 +201,7 @@ describe("tests related to options", function() it("doesn't accept GNU-like long options when it doesn't need arguments", function() local parser = argparse.parser() parser:flag("-q", "--quiet") - assert.has_error(function() parser:parse{"--quiet=very_quiet"} end, "option '--quiet' doesn't take arguments") + assert.has_error(function() parser:parse{"--quiet=very_quiet"} end, "option '--quiet' does not take arguments") end) it("handles too many invocations correctly", function() diff --git a/spec/script b/spec/script new file mode 100755 index 0000000..1c59746 --- /dev/null +++ b/spec/script @@ -0,0 +1,35 @@ +#!/usr/bin/env lua +local argparse = require "argparse" + +local parser = argparse.parser "test" + :description "A testing program. " + +parser:argument "input" + +parser:flag "-v" "--verbose" + :description "Sets verbosity level. " + :target "verbosity" + :count "0-2" + +local install = parser:command "install" + :description "Install a rock. " + +install:argument "rock" + :description "Name of the rock. " + +install:argument "version" + :description "Version of the rock. " + :args "?" + +install:option "-f" "--from" + :description "Fetch the rock from this server. " + :target "server" + +local args = parser:parse() + +print(args.input) +print(args.verbosity) +print(args.install) +print(args.rock) +print(args.version) +print(args.server) diff --git a/src/argparse.lua b/src/argparse.lua index 60dd3e0..36e2484 100644 --- a/src/argparse.lua +++ b/src/argparse.lua @@ -299,7 +299,7 @@ function Parser:prepare() self:flag "-h" "--help" :description "Show this help message and exit. " :action(function() - print(self:get_help()) + io.stdout:write(self:get_help() .. "\r\n") os.exit(0) end) end @@ -700,7 +700,7 @@ function Parser:parse(args) if equal then name = data:sub(1, equal-1) option = get_option(name) - parser:assert(option._maxargs > 0, "option '%s' doesn't take arguments", name) + parser:assert(option._maxargs > 0, "option '%s' does not take arguments", name) handle_option(data:sub(1, equal-1)) handle_argument(data:sub(equal+1))