command_mapper-gen 0.1.0.pre1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.github/workflows/ruby.yml +27 -0
- data/.gitignore +10 -0
- data/.rspec +1 -0
- data/.yardopts +1 -0
- data/ChangeLog.md +20 -0
- data/Gemfile +17 -0
- data/LICENSE.txt +20 -0
- data/README.md +145 -0
- data/Rakefile +15 -0
- data/bin/command_mapper-gen +7 -0
- data/commnad_mapper-gen.gemspec +61 -0
- data/examples/grep.rb +63 -0
- data/gemspec.yml +26 -0
- data/lib/command_mapper/gen/arg.rb +43 -0
- data/lib/command_mapper/gen/argument.rb +53 -0
- data/lib/command_mapper/gen/cli.rb +233 -0
- data/lib/command_mapper/gen/command.rb +202 -0
- data/lib/command_mapper/gen/exceptions.rb +9 -0
- data/lib/command_mapper/gen/option.rb +66 -0
- data/lib/command_mapper/gen/option_value.rb +23 -0
- data/lib/command_mapper/gen/parsers/common.rb +49 -0
- data/lib/command_mapper/gen/parsers/help.rb +351 -0
- data/lib/command_mapper/gen/parsers/man.rb +80 -0
- data/lib/command_mapper/gen/parsers/options.rb +127 -0
- data/lib/command_mapper/gen/parsers/usage.rb +141 -0
- data/lib/command_mapper/gen/parsers.rb +2 -0
- data/lib/command_mapper/gen/task.rb +90 -0
- data/lib/command_mapper/gen/types/enum.rb +30 -0
- data/lib/command_mapper/gen/types/key_value.rb +34 -0
- data/lib/command_mapper/gen/types/list.rb +34 -0
- data/lib/command_mapper/gen/types/map.rb +36 -0
- data/lib/command_mapper/gen/types/num.rb +18 -0
- data/lib/command_mapper/gen/types/str.rb +48 -0
- data/lib/command_mapper/gen/types.rb +6 -0
- data/lib/command_mapper/gen/version.rb +6 -0
- data/lib/command_mapper/gen.rb +2 -0
- data/spec/argument_spec.rb +92 -0
- data/spec/cli_spec.rb +269 -0
- data/spec/command_spec.rb +316 -0
- data/spec/option_spec.rb +85 -0
- data/spec/option_value_spec.rb +20 -0
- data/spec/parsers/common_spec.rb +616 -0
- data/spec/parsers/help_spec.rb +612 -0
- data/spec/parsers/man_spec.rb +158 -0
- data/spec/parsers/options_spec.rb +802 -0
- data/spec/parsers/usage_spec.rb +1175 -0
- data/spec/spec_helper.rb +6 -0
- data/spec/task_spec.rb +69 -0
- data/spec/types/enum_spec.rb +45 -0
- data/spec/types/key_value_spec.rb +36 -0
- data/spec/types/list_spec.rb +36 -0
- data/spec/types/map_spec.rb +48 -0
- data/spec/types/str_spec.rb +70 -0
- metadata +133 -0
@@ -0,0 +1,90 @@
|
|
1
|
+
require 'rake/tasklib'
|
2
|
+
|
3
|
+
module CommandMapper
|
4
|
+
module Gen
|
5
|
+
#
|
6
|
+
# Defines a `command_mapper:gen` task which automatically generates a
|
7
|
+
# command class file.
|
8
|
+
#
|
9
|
+
# require 'command_mapper/gen/task'
|
10
|
+
# CommandMapper::Gen::Task.new('grep','lib/path/to/grep.rb')
|
11
|
+
#
|
12
|
+
# $ rake command_mapper:gen
|
13
|
+
#
|
14
|
+
class Task < Rake::TaskLib
|
15
|
+
|
16
|
+
# The command name or path to the command.
|
17
|
+
#
|
18
|
+
# @return [String]
|
19
|
+
attr_accessor :command_name
|
20
|
+
|
21
|
+
# The output file path.
|
22
|
+
#
|
23
|
+
# @return [String]
|
24
|
+
attr_accessor :output
|
25
|
+
|
26
|
+
# The parser to invoke.
|
27
|
+
#
|
28
|
+
# @return [:help, :man, nil]
|
29
|
+
attr_accessor :parser
|
30
|
+
|
31
|
+
#
|
32
|
+
# Initializes the task.
|
33
|
+
#
|
34
|
+
# @param [String] command_name
|
35
|
+
# The command name or path to the command.
|
36
|
+
#
|
37
|
+
# @param [String] output
|
38
|
+
# The output file path.
|
39
|
+
#
|
40
|
+
# @param [:help, :man, nil] parser
|
41
|
+
# The optional parser to target.
|
42
|
+
#
|
43
|
+
# @yield [task]
|
44
|
+
# If a block is given, it will be yielded to before the rake task has
|
45
|
+
# been defined.
|
46
|
+
#
|
47
|
+
# @yieldparam [Task] task
|
48
|
+
# The newly created task.
|
49
|
+
#
|
50
|
+
def initialize(command_name,output, parser: nil)
|
51
|
+
@command_name = command_name
|
52
|
+
@output = output
|
53
|
+
|
54
|
+
@parser = parser
|
55
|
+
|
56
|
+
yield self if block_given?
|
57
|
+
define
|
58
|
+
end
|
59
|
+
|
60
|
+
#
|
61
|
+
# Defines the `command_mapper:gen` task and output file's task.
|
62
|
+
#
|
63
|
+
def define
|
64
|
+
output_dir = File.dirname(@output)
|
65
|
+
|
66
|
+
directory(output_dir)
|
67
|
+
file(@output => output_dir) do
|
68
|
+
generate
|
69
|
+
end
|
70
|
+
|
71
|
+
desc "Generates the #{@output} file"
|
72
|
+
task 'command_mapper:gen' => @output
|
73
|
+
end
|
74
|
+
|
75
|
+
#
|
76
|
+
# Generates the {#output} file.
|
77
|
+
#
|
78
|
+
def generate
|
79
|
+
args = ["--output", @output]
|
80
|
+
|
81
|
+
if @parser
|
82
|
+
args << '--parser' << @parser.to_s
|
83
|
+
end
|
84
|
+
|
85
|
+
sh "command_mapper-gen", *args, @command_name
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module CommandMapper
|
2
|
+
module Gen
|
3
|
+
module Types
|
4
|
+
class Enum
|
5
|
+
|
6
|
+
# @return [Array<Symbol>]
|
7
|
+
attr_reader :values
|
8
|
+
|
9
|
+
#
|
10
|
+
# Initializes the enum type.
|
11
|
+
#
|
12
|
+
# @param [Array<Symbol>] values
|
13
|
+
#
|
14
|
+
def initialize(values)
|
15
|
+
@values = values
|
16
|
+
end
|
17
|
+
|
18
|
+
#
|
19
|
+
# Converts the map type to Ruby source code.
|
20
|
+
#
|
21
|
+
# @return [String]
|
22
|
+
#
|
23
|
+
def to_ruby
|
24
|
+
"Enum[#{@values.map(&:inspect).join(', ')}]"
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module CommandMapper
|
2
|
+
module Gen
|
3
|
+
module Types
|
4
|
+
class KeyValue
|
5
|
+
|
6
|
+
# @return [String]
|
7
|
+
attr_reader :separator
|
8
|
+
|
9
|
+
#
|
10
|
+
# Initializes the key-value type.
|
11
|
+
#
|
12
|
+
# @param [String] separator
|
13
|
+
# The separator character.
|
14
|
+
#
|
15
|
+
def initialize(separator: '=')
|
16
|
+
@separator = separator
|
17
|
+
end
|
18
|
+
|
19
|
+
#
|
20
|
+
# Converts the key-value type to Ruby source code.
|
21
|
+
#
|
22
|
+
# @return [String]
|
23
|
+
#
|
24
|
+
def to_ruby
|
25
|
+
ruby = "KeyValue.new("
|
26
|
+
ruby << "separator: #{@separator.inspect}" unless @separator == '='
|
27
|
+
ruby << ")"
|
28
|
+
ruby
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module CommandMapper
|
2
|
+
module Gen
|
3
|
+
module Types
|
4
|
+
class List
|
5
|
+
|
6
|
+
# @return [String]
|
7
|
+
attr_reader :separator
|
8
|
+
|
9
|
+
#
|
10
|
+
# Initializes the list type.
|
11
|
+
#
|
12
|
+
# @param [String] separator
|
13
|
+
# The separator character.
|
14
|
+
#
|
15
|
+
def initialize(separator: ',')
|
16
|
+
@separator = separator
|
17
|
+
end
|
18
|
+
|
19
|
+
#
|
20
|
+
# Converts the list type to Ruby source code.
|
21
|
+
#
|
22
|
+
# @return [String]
|
23
|
+
#
|
24
|
+
def to_ruby
|
25
|
+
ruby = "List.new("
|
26
|
+
ruby << "separator: #{@separator.inspect}" unless @separator == ','
|
27
|
+
ruby << ")"
|
28
|
+
ruby
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module CommandMapper
|
2
|
+
module Gen
|
3
|
+
module Types
|
4
|
+
class Map
|
5
|
+
|
6
|
+
# @return [Hash{Object => String}]
|
7
|
+
attr_reader :map
|
8
|
+
|
9
|
+
#
|
10
|
+
# Initializes the map type.
|
11
|
+
#
|
12
|
+
# @param [Hash{Object => String}] map
|
13
|
+
#
|
14
|
+
def initialize(map)
|
15
|
+
@map = map
|
16
|
+
end
|
17
|
+
|
18
|
+
#
|
19
|
+
# Converts the map type to Ruby source code.
|
20
|
+
#
|
21
|
+
# @return [String]
|
22
|
+
#
|
23
|
+
def to_ruby
|
24
|
+
pairs = []
|
25
|
+
|
26
|
+
@map.each do |value,string|
|
27
|
+
pairs << "#{value.inspect} => #{string.inspect}"
|
28
|
+
end
|
29
|
+
|
30
|
+
return "Map.new(#{pairs.join(', ')})"
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module CommandMapper
|
2
|
+
module Gen
|
3
|
+
module Types
|
4
|
+
class Str
|
5
|
+
|
6
|
+
# The `allow_empty` keyword.
|
7
|
+
#
|
8
|
+
# @return [Boolean, nil]
|
9
|
+
attr_reader :allow_empty
|
10
|
+
|
11
|
+
# The `allow_blank` keyword.
|
12
|
+
#
|
13
|
+
# @return [Boolean, nil]
|
14
|
+
attr_reader :allow_blank
|
15
|
+
|
16
|
+
#
|
17
|
+
# Initializes the value type.
|
18
|
+
#
|
19
|
+
# @param [Boolean, nil] allow_empty
|
20
|
+
# The `allow_empty` keyword value.
|
21
|
+
#
|
22
|
+
# @param [Boolean, nil] allow_blank
|
23
|
+
# The `allow_blank` keyword value.
|
24
|
+
#
|
25
|
+
def initialize(allow_empty: nil, allow_blank: nil)
|
26
|
+
@allow_empty = allow_empty
|
27
|
+
@allow_blank = allow_blank
|
28
|
+
end
|
29
|
+
|
30
|
+
#
|
31
|
+
# Converts the value type to Ruby source code.
|
32
|
+
#
|
33
|
+
# @return [String, nil]
|
34
|
+
#
|
35
|
+
def to_ruby
|
36
|
+
unless (@allow_empty.nil? && @allow_blank.nil?)
|
37
|
+
keywords = []
|
38
|
+
|
39
|
+
keywords << "allow_empty: #{@allow_empty.inspect}" unless @allow_empty.nil?
|
40
|
+
keywords << "allow_blank: #{@allow_blank.inspect}" unless @allow_blank.nil?
|
41
|
+
keywords.join(', ')
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'command_mapper/gen/argument'
|
3
|
+
require 'command_mapper/gen/types/str'
|
4
|
+
require 'command_mapper/gen/types/num'
|
5
|
+
|
6
|
+
describe CommandMapper::Gen::Argument do
|
7
|
+
let(:name) { :arg1 }
|
8
|
+
|
9
|
+
subject { described_class.new(name) }
|
10
|
+
|
11
|
+
describe "#initialize" do
|
12
|
+
it "must set #name" do
|
13
|
+
expect(subject.name).to eq(name)
|
14
|
+
end
|
15
|
+
|
16
|
+
it "must default #type to nil" do
|
17
|
+
expect(subject.type).to be(nil)
|
18
|
+
end
|
19
|
+
|
20
|
+
it "must default #repeats to nil" do
|
21
|
+
expect(subject.repeats).to be(nil)
|
22
|
+
end
|
23
|
+
|
24
|
+
context "when given the value: keyword argument" do
|
25
|
+
context "and it's a Types object" do
|
26
|
+
let(:type) { Types::Num.new }
|
27
|
+
|
28
|
+
subject { described_class.new(name, type: type) }
|
29
|
+
|
30
|
+
it "must set #type" do
|
31
|
+
expect(subject.type).to be(type)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
context "when given the repeats: keyword argument" do
|
37
|
+
let(:repeats) { true }
|
38
|
+
|
39
|
+
subject { described_class.new(name, repeats: repeats) }
|
40
|
+
|
41
|
+
it "must set #repeats" do
|
42
|
+
expect(subject.repeats).to eq(repeats)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe "#to_ruby" do
|
48
|
+
it "must output 'argument \#{name}'" do
|
49
|
+
expect(subject.to_ruby).to eq("argument #{name.inspect}")
|
50
|
+
end
|
51
|
+
|
52
|
+
context "when #required is true" do
|
53
|
+
let(:required) { true}
|
54
|
+
|
55
|
+
subject { described_class.new(name, required: required) }
|
56
|
+
|
57
|
+
it "must not append 'required: true'" do
|
58
|
+
expect(subject.to_ruby).to eq("argument #{name.inspect}")
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
context "when #required is false" do
|
63
|
+
let(:required) { false }
|
64
|
+
|
65
|
+
subject { described_class.new(name, required: required) }
|
66
|
+
|
67
|
+
it "must append 'required: false'" do
|
68
|
+
expect(subject.to_ruby).to eq("argument #{name.inspect}, required: #{required.inspect}")
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
context "when #type is not nil" do
|
73
|
+
let(:type) { Types::Num.new }
|
74
|
+
|
75
|
+
subject { described_class.new(name, type: type) }
|
76
|
+
|
77
|
+
it "must append 'type: ...' and call the #type's #to_ruby method" do
|
78
|
+
expect(subject.to_ruby).to eq("argument #{name.inspect}, type: #{type.to_ruby}")
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
context "when #repeats is true" do
|
83
|
+
let(:repeats) { true }
|
84
|
+
|
85
|
+
subject { described_class.new(name, repeats: repeats) }
|
86
|
+
|
87
|
+
it "must append 'repeats: true'" do
|
88
|
+
expect(subject.to_ruby).to eq("argument #{name.inspect}, repeats: #{repeats.inspect}")
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
data/spec/cli_spec.rb
ADDED
@@ -0,0 +1,269 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'command_mapper/gen/cli'
|
3
|
+
|
4
|
+
describe CommandMapper::Gen::CLI do
|
5
|
+
describe "#initialize" do
|
6
|
+
it "must default #output to nil" do
|
7
|
+
expect(subject.output).to be(nil)
|
8
|
+
end
|
9
|
+
|
10
|
+
it "must default #parsers to [Parsers::Help, Parsers::Man]" do
|
11
|
+
expect(subject.parsers).to eq([Parsers::Help, Parsers::Man])
|
12
|
+
end
|
13
|
+
|
14
|
+
it "must default #command to nil" do
|
15
|
+
expect(subject.command).to be(nil)
|
16
|
+
end
|
17
|
+
|
18
|
+
it "must initialize #option_parser" do
|
19
|
+
expect(subject.option_parser).to be_kind_of(OptionParser)
|
20
|
+
end
|
21
|
+
|
22
|
+
it "must set #debug to false" do
|
23
|
+
expect(subject.debug).to be(false)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe ".run" do
|
28
|
+
subject { described_class }
|
29
|
+
|
30
|
+
context "when Interrupt is raised" do
|
31
|
+
before do
|
32
|
+
expect_any_instance_of(described_class).to receive(:run).and_raise(Interrupt)
|
33
|
+
end
|
34
|
+
|
35
|
+
it "must exit with 130" do
|
36
|
+
expect(subject.run([])).to eq(130)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
context "when Errno::EPIPE is raised" do
|
41
|
+
before do
|
42
|
+
expect_any_instance_of(described_class).to receive(:run).and_raise(Errno::EPIPE)
|
43
|
+
end
|
44
|
+
|
45
|
+
it "must exit with 0" do
|
46
|
+
expect(subject.run([])).to eq(0)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
describe "#run" do
|
52
|
+
let(:command_name) { 'yes' }
|
53
|
+
|
54
|
+
let(:expected_output) do
|
55
|
+
[
|
56
|
+
"require 'command_mapper/command'",
|
57
|
+
"",
|
58
|
+
"#",
|
59
|
+
"# Represents the `#{command_name}` command",
|
60
|
+
"#",
|
61
|
+
"class #{command_name.capitalize} < CommandMapper::Command",
|
62
|
+
"",
|
63
|
+
" command \"#{command_name}\" do",
|
64
|
+
" option \"--help\"",
|
65
|
+
" option \"--version\"",
|
66
|
+
"",
|
67
|
+
" argument :string, required: false, repeats: true",
|
68
|
+
" end",
|
69
|
+
"",
|
70
|
+
"end",
|
71
|
+
].join($/) + $/
|
72
|
+
end
|
73
|
+
|
74
|
+
context "when given a COMMAND_NAME" do
|
75
|
+
let(:argv) { [command_name] }
|
76
|
+
|
77
|
+
it "must parse the command's --help and/or man page and print ruby code" do
|
78
|
+
expect {
|
79
|
+
subject.run(argv)
|
80
|
+
}.to output(expected_output).to_stdout
|
81
|
+
end
|
82
|
+
|
83
|
+
context "but the command isn't installed" do
|
84
|
+
before do
|
85
|
+
allow(CommandMapper::Gen::Parsers::Help).to receive(:`).with("#{command_name} --help 2>&1").and_raise(Errno::ENOENT.new(command_name))
|
86
|
+
end
|
87
|
+
|
88
|
+
it "must print an error and exit with -1" do
|
89
|
+
expect {
|
90
|
+
expect(subject.run(argv)).to eq(-1)
|
91
|
+
}.to output("#{described_class::PROGRAM_NAME}: command #{command_name.inspect} is not installed#{$/}").to_stderr
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
context "when an invalid option is given" do
|
97
|
+
let(:option) { "--foo" }
|
98
|
+
let(:argv) { [option] }
|
99
|
+
|
100
|
+
it "must print an error message and return -1" do
|
101
|
+
expect {
|
102
|
+
expect(subject.run(argv)).to eq(-1)
|
103
|
+
}.to output("#{described_class::PROGRAM_NAME}: invalid option: #{option}#{$/}").to_stderr
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
context "when the command's --help and -h output are empty" do
|
108
|
+
let(:argv) { %w[true] }
|
109
|
+
|
110
|
+
it "must print an error message and return -2" do
|
111
|
+
expect {
|
112
|
+
expect(subject.run(argv)).to eq(-2)
|
113
|
+
}.to output("#{described_class::PROGRAM_NAME}: no options or arguments detected#{$/}").to_stderr
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
context "when no arguments are given" do
|
118
|
+
let(:argv) { [] }
|
119
|
+
|
120
|
+
it "must print an error message and return -1" do
|
121
|
+
expect {
|
122
|
+
expect(subject.run(argv)).to eq(-1)
|
123
|
+
}.to output("#{described_class::PROGRAM_NAME}: expects a COMMAND_NAME#{$/}").to_stderr
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
describe "#option_parser" do
|
129
|
+
context "when given -o FILE" do
|
130
|
+
let(:file) { "/path/to/file.rb" }
|
131
|
+
let(:argv) { ['-o', file] }
|
132
|
+
|
133
|
+
before { subject.option_parser.parse(argv) }
|
134
|
+
|
135
|
+
it "must set #output to the FILE" do
|
136
|
+
expect(subject.output).to eq(file)
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
context "when given --output FILE" do
|
141
|
+
let(:file) { "/path/to/file.rb" }
|
142
|
+
let(:argv) { ['--output', file] }
|
143
|
+
|
144
|
+
before { subject.option_parser.parse(argv) }
|
145
|
+
|
146
|
+
it "must set #output to the FILE" do
|
147
|
+
expect(subject.output).to eq(file)
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
context "when givne -p help" do
|
152
|
+
let(:argv) { ['-p', "help"] }
|
153
|
+
|
154
|
+
before { subject.option_parser.parse(argv) }
|
155
|
+
|
156
|
+
it "must set #parsers to [Parser::Help]" do
|
157
|
+
expect(subject.parsers).to eq([Parsers::Help])
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
context "when givne -p man" do
|
162
|
+
let(:argv) { ['-p', "man"] }
|
163
|
+
|
164
|
+
before { subject.option_parser.parse(argv) }
|
165
|
+
|
166
|
+
it "must set #parsers to [Parser::Man]" do
|
167
|
+
expect(subject.parsers).to eq([Parsers::Man])
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
context "when givne --parser help" do
|
172
|
+
let(:argv) { ['--parser', "help"] }
|
173
|
+
|
174
|
+
before { subject.option_parser.parse(argv) }
|
175
|
+
|
176
|
+
it "must set #parsers to [Parser::Help]" do
|
177
|
+
expect(subject.parsers).to eq([Parsers::Help])
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
context "when givne --parser man" do
|
182
|
+
let(:argv) { ['--parser', "man"] }
|
183
|
+
|
184
|
+
before { subject.option_parser.parse(argv) }
|
185
|
+
|
186
|
+
it "must set #parsers to [Parser::Man]" do
|
187
|
+
expect(subject.parsers).to eq([Parsers::Man])
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
191
|
+
context "when given -d" do
|
192
|
+
let(:argv) { ['-d'] }
|
193
|
+
|
194
|
+
before { subject.option_parser.parse(argv) }
|
195
|
+
|
196
|
+
it "must set #debug to true" do
|
197
|
+
expect(subject.debug).to be(true)
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
context "when given --debug" do
|
202
|
+
let(:argv) { ['--debug'] }
|
203
|
+
|
204
|
+
before { subject.option_parser.parse(argv) }
|
205
|
+
|
206
|
+
it "must set #debug to true" do
|
207
|
+
expect(subject.debug).to be(true)
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
context "when given -V" do
|
212
|
+
let(:argv) { ["-v"] }
|
213
|
+
|
214
|
+
it "must print the command name and version, then exit" do
|
215
|
+
expect(subject).to receive(:exit)
|
216
|
+
|
217
|
+
expect {
|
218
|
+
subject.option_parser.parse(argv)
|
219
|
+
}.to output("#{described_class::PROGRAM_NAME} #{VERSION}#{$/}").to_stdout
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
223
|
+
context "when given --version" do
|
224
|
+
let(:argv) { ["--version"] }
|
225
|
+
|
226
|
+
it "must print the command name and version, then exit" do
|
227
|
+
expect(subject).to receive(:exit)
|
228
|
+
|
229
|
+
expect {
|
230
|
+
subject.option_parser.parse(argv)
|
231
|
+
}.to output("#{described_class::PROGRAM_NAME} #{VERSION}#{$/}").to_stdout
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
235
|
+
context "when given -h" do
|
236
|
+
let(:argv) { ["-h"] }
|
237
|
+
|
238
|
+
it "must print help text and then exit" do
|
239
|
+
expect(subject).to receive(:exit)
|
240
|
+
|
241
|
+
expect {
|
242
|
+
subject.option_parser.parse(argv)
|
243
|
+
}.to output("#{subject.option_parser}").to_stdout
|
244
|
+
end
|
245
|
+
end
|
246
|
+
|
247
|
+
context "when given --help" do
|
248
|
+
let(:argv) { ["-h"] }
|
249
|
+
|
250
|
+
it "must print help text and then exit" do
|
251
|
+
expect(subject).to receive(:exit)
|
252
|
+
|
253
|
+
expect {
|
254
|
+
subject.option_parser.parse(argv)
|
255
|
+
}.to output("#{subject.option_parser}").to_stdout
|
256
|
+
end
|
257
|
+
end
|
258
|
+
end
|
259
|
+
|
260
|
+
describe "#print_error" do
|
261
|
+
let(:message) { "error!" }
|
262
|
+
|
263
|
+
it "must print the command name and the message to stderr" do
|
264
|
+
expect {
|
265
|
+
subject.print_error(message)
|
266
|
+
}.to output("#{described_class::PROGRAM_NAME}: #{message}#{$/}").to_stderr
|
267
|
+
end
|
268
|
+
end
|
269
|
+
end
|