clive 0.8.1 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +1 -1
- data/README.md +328 -227
- data/lib/clive.rb +130 -50
- data/lib/clive/argument.rb +170 -0
- data/lib/clive/arguments.rb +139 -0
- data/lib/clive/arguments/parser.rb +210 -0
- data/lib/clive/base.rb +189 -0
- data/lib/clive/command.rb +342 -444
- data/lib/clive/error.rb +66 -0
- data/lib/clive/formatter.rb +57 -141
- data/lib/clive/formatter/colour.rb +37 -0
- data/lib/clive/formatter/plain.rb +172 -0
- data/lib/clive/option.rb +185 -75
- data/lib/clive/option/runner.rb +163 -0
- data/lib/clive/output.rb +141 -16
- data/lib/clive/parser.rb +180 -87
- data/lib/clive/struct_hash.rb +109 -0
- data/lib/clive/type.rb +117 -0
- data/lib/clive/type/definitions.rb +170 -0
- data/lib/clive/type/lookup.rb +23 -0
- data/lib/clive/version.rb +3 -3
- data/spec/clive/a_cli_spec.rb +245 -0
- data/spec/clive/argument_spec.rb +148 -0
- data/spec/clive/arguments/parser_spec.rb +35 -0
- data/spec/clive/arguments_spec.rb +191 -0
- data/spec/clive/command_spec.rb +276 -209
- data/spec/clive/formatter/colour_spec.rb +129 -0
- data/spec/clive/formatter/plain_spec.rb +129 -0
- data/spec/clive/option/runner_spec.rb +92 -0
- data/spec/clive/option_spec.rb +149 -23
- data/spec/clive/output_spec.rb +86 -2
- data/spec/clive/parser_spec.rb +201 -81
- data/spec/clive/struct_hash_spec.rb +82 -0
- data/spec/clive/type/definitions_spec.rb +312 -0
- data/spec/clive/type_spec.rb +107 -0
- data/spec/clive_spec.rb +60 -0
- data/spec/extras/expectations.rb +86 -0
- data/spec/extras/focus.rb +22 -0
- data/spec/helper.rb +35 -0
- metadata +56 -36
- data/lib/clive/bool.rb +0 -67
- data/lib/clive/exceptions.rb +0 -54
- data/lib/clive/flag.rb +0 -199
- data/lib/clive/switch.rb +0 -31
- data/lib/clive/tokens.rb +0 -141
- data/spec/clive/bool_spec.rb +0 -54
- data/spec/clive/flag_spec.rb +0 -117
- data/spec/clive/formatter_spec.rb +0 -108
- data/spec/clive/switch_spec.rb +0 -14
- data/spec/clive/tokens_spec.rb +0 -38
- data/spec/shared_specs.rb +0 -16
- data/spec/spec_helper.rb +0 -12
@@ -0,0 +1,35 @@
|
|
1
|
+
$: << File.dirname(__FILE__) + '/../..'
|
2
|
+
require 'helper'
|
3
|
+
|
4
|
+
class Clive::Arguments::ParserSubject < Clive::Arguments::Parser
|
5
|
+
attr_reader :opts
|
6
|
+
end
|
7
|
+
|
8
|
+
describe Clive::Arguments::Parser do
|
9
|
+
|
10
|
+
subject { Clive::Arguments::ParserSubject }
|
11
|
+
|
12
|
+
describe '#initialize' do
|
13
|
+
it 'normalises key names' do
|
14
|
+
subject.new(:kind => String, :in => %w(a b c)).opts.keys.must_include :type, :within
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe '#to_a' do
|
19
|
+
it 'returns an array of hashes' do
|
20
|
+
subject.new(:type => [Integer, Time]).to_a.must_equal [{:type => Integer, :name => 'arg'},
|
21
|
+
{:type => Time, :name => 'arg'}]
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe '#to_args' do
|
26
|
+
it 'returns an array of Argument instances' do
|
27
|
+
args = subject.new(:args => '<a> <b> [<c>]', :type => [Integer, Time]).to_args
|
28
|
+
args.size.must_equal 3
|
29
|
+
args[0].must_be_argument :name => :a, :type => Clive::Type::Integer
|
30
|
+
args[1].must_be_argument :name => :b, :type => Clive::Type::Time
|
31
|
+
args[2].must_be_argument :name => :c, :optional => true
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
@@ -0,0 +1,191 @@
|
|
1
|
+
$: << File.dirname(__FILE__) + '/..'
|
2
|
+
require 'helper'
|
3
|
+
|
4
|
+
describe Clive::Arguments do
|
5
|
+
|
6
|
+
subject {
|
7
|
+
Clive::Arguments.create :args => '[<a>] <b> <c> [<d>]',
|
8
|
+
:type => [Integer] * 4,
|
9
|
+
:constraint => [:even?, :odd?] * 2
|
10
|
+
}
|
11
|
+
|
12
|
+
describe '.create' do
|
13
|
+
it 'parses the options passed using Parser' do
|
14
|
+
parser, opts = mock, stub
|
15
|
+
parser.expects(:to_args).returns([])
|
16
|
+
Clive::Arguments::Parser.expects(:new).with(opts).returns(parser)
|
17
|
+
Clive::Arguments.create opts
|
18
|
+
end
|
19
|
+
it 'returns a list of Argument instances' do
|
20
|
+
a = Clive::Arguments.create :args => '[<a>] <b>', :as => [Integer, nil], :in => [1..5, nil]
|
21
|
+
a[0].must_be_argument :name => :a, :optional => true, :within => 1..5,
|
22
|
+
:type => Clive::Type::Integer
|
23
|
+
a[1].must_be_argument :name => :b, :optional => false
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe '#zip' do
|
28
|
+
it 'zips arguments properly' do
|
29
|
+
def subject.simple_zip(other); zip(other).map(&:last); end
|
30
|
+
|
31
|
+
# These behaviours are definitely what should happen
|
32
|
+
subject.simple_zip(%w(1 4)).must_equal [nil, '1', '4', nil]
|
33
|
+
subject.simple_zip(%w(1 4 3)).must_equal [nil, '1', '4', '3']
|
34
|
+
subject.simple_zip(%w(2 1 4 3)).must_equal ['2', '1', '4', '3']
|
35
|
+
subject.simple_zip(%w(2 1 4)).must_equal ['2', '1', '4', nil]
|
36
|
+
|
37
|
+
# These behaviours may change
|
38
|
+
subject.simple_zip(%w(2)).must_equal [nil, nil, '2', nil]
|
39
|
+
subject.simple_zip(%w(1)).must_equal [nil, '1', nil, nil]
|
40
|
+
subject.simple_zip(%w(2 1)).must_equal [nil, nil, '2', nil]
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
describe '#to_s' do
|
45
|
+
subject {
|
46
|
+
Clive::Arguments.new( [
|
47
|
+
Clive::Argument.new(:a),
|
48
|
+
Clive::Argument.new(:b, :optional => true),
|
49
|
+
Clive::Argument.new(:c, :optional => true),
|
50
|
+
Clive::Argument.new(:d)
|
51
|
+
])
|
52
|
+
}
|
53
|
+
|
54
|
+
it 'removes extra square brackets' do
|
55
|
+
subject.to_s.must_equal "<a> [<b> <c>] <d>"
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
describe '#min' do
|
60
|
+
it 'returns the number of non-optional arguments' do
|
61
|
+
subject.min.must_equal 2
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
describe '#max' do
|
66
|
+
it 'returns the total number of arguments' do
|
67
|
+
subject.max.must_equal 4
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
describe '#possible?' do
|
72
|
+
it 'is true if each argument is possible and list is not too long' do
|
73
|
+
subject.must_be :possible?, [2]
|
74
|
+
subject.must_be :possible?, [2, 3]
|
75
|
+
subject.must_be :possible?, [2, 3, 4]
|
76
|
+
subject.must_be :possible?, [2, 3, 4, 5]
|
77
|
+
end
|
78
|
+
|
79
|
+
it 'is false if the list is too long' do
|
80
|
+
subject.wont_be :possible?, [2, 3, 4, 5, 6]
|
81
|
+
end
|
82
|
+
|
83
|
+
it 'is true even if an argument is not possible' do
|
84
|
+
subject.must_be :possible?, ['hello']
|
85
|
+
end
|
86
|
+
|
87
|
+
it 'single' do
|
88
|
+
subject = Clive::Arguments.create :arg => '<name>'
|
89
|
+
subject.must_be :possible?, []
|
90
|
+
subject.must_be :possible?, %w(John)
|
91
|
+
subject.wont_be :possible?, %w(John Doe)
|
92
|
+
end
|
93
|
+
|
94
|
+
it 'single optional' do
|
95
|
+
subject = Clive::Arguments.create :arg => '[<name>]'
|
96
|
+
subject.must_be :possible?, []
|
97
|
+
subject.must_be :possible?, %w(John)
|
98
|
+
subject.wont_be :possible?, %w(John Doe)
|
99
|
+
end
|
100
|
+
|
101
|
+
it 'single with constraint' do
|
102
|
+
subject = Clive::Arguments.create :arg => '<name>', :constraint => proc {|i| i.size == 4 }
|
103
|
+
subject.must_be :possible?, []
|
104
|
+
subject.must_be :possible?, %w(John)
|
105
|
+
subject.wont_be :possible?, %w(James)
|
106
|
+
subject.wont_be :possible?, %w(John Doe)
|
107
|
+
end
|
108
|
+
|
109
|
+
it 'single optional with constraint' do
|
110
|
+
subject = Clive::Arguments.create :arg => '[<name>]', :constraint => proc {|i| i.size == 4 }
|
111
|
+
subject.must_be :possible?, []
|
112
|
+
subject.must_be :possible?, %w(John)
|
113
|
+
subject.wont_be :possible?, %w(James)
|
114
|
+
subject.wont_be :possible?, %w(John Doe)
|
115
|
+
end
|
116
|
+
|
117
|
+
it 'multiple surrounding' do
|
118
|
+
subject = Clive::Arguments.create :args => '<first> [<middle>] <last>'
|
119
|
+
subject.must_be :possible?, []
|
120
|
+
subject.must_be :possible?, %w(John)
|
121
|
+
subject.must_be :possible?, %w(John Doe)
|
122
|
+
subject.must_be :possible?, %w(John David Doe)
|
123
|
+
subject.wont_be :possible?, %w(John David James Doe)
|
124
|
+
end
|
125
|
+
|
126
|
+
it 'multiple middle' do
|
127
|
+
subject = Clive::Arguments.create :args => '[<first>] <middle> [<last>]'
|
128
|
+
subject.must_be :possible?, []
|
129
|
+
subject.must_be :possible?, %w(John)
|
130
|
+
subject.must_be :possible?, %w(John Doe)
|
131
|
+
subject.must_be :possible?, %w(John David Doe)
|
132
|
+
subject.wont_be :possible?, %w(John David James Doe)
|
133
|
+
end
|
134
|
+
|
135
|
+
it 'multiple surrounding with constraints' do
|
136
|
+
subject = Clive::Arguments.create :args => '<first> [<middle>] <last>',
|
137
|
+
:constraint => [proc {|i| i.size == 3 }, proc {|i| i.size == 4 }, proc {|i| i.size == 5 }]
|
138
|
+
subject.must_be :possible?, []
|
139
|
+
|
140
|
+
subject.must_be :possible?, %w(Joe) # [Joe, ..., ...]
|
141
|
+
subject.wont_be :possible?, %w(Gary) # [!!!, Gary, ...]
|
142
|
+
subject.wont_be :possible?, %w(David) # [!!!, nil, David]
|
143
|
+
|
144
|
+
subject.must_be :possible?, %w(Joe Gary) # [Joe, Gary, ...]
|
145
|
+
subject.must_be :possible?, %w(Joe David) # [Joe, ..., David]
|
146
|
+
subject.wont_be :possible?, %w(Gary David) # [!!!, Gary, David]
|
147
|
+
|
148
|
+
subject.must_be :possible?, %w(Joe Gary David) # [Joe, Gary, David]
|
149
|
+
subject.wont_be :possible?, %w(Joe Gary David Doe) # [Joe, Gary, David] Doe
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
describe '#valid?' do
|
154
|
+
it 'is false if the list is not #possible' do
|
155
|
+
subject.stubs(:possible?).returns(false)
|
156
|
+
subject.wont_be :valid?, [1, 2]
|
157
|
+
end
|
158
|
+
|
159
|
+
it 'is false if the list is too short' do
|
160
|
+
subject.stubs(:possible?).returns(true)
|
161
|
+
subject.wont_be :valid?, [1]
|
162
|
+
end
|
163
|
+
|
164
|
+
it 'is true if the list is #possible? and not too short' do
|
165
|
+
subject.stubs(:possible?).returns(true)
|
166
|
+
subject.must_be :valid?, [1, 2]
|
167
|
+
subject.must_be :valid?, [1, 2, 3]
|
168
|
+
subject.must_be :valid?, [0, 1, 2, 3]
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
describe '#create_valid' do
|
173
|
+
it 'returns the correct arguments' do
|
174
|
+
a = Clive::Arguments.create :args => '[<a>] <b> [<c>]'
|
175
|
+
a.create_valid(%w(a b c)).must_equal ['a', 'b', 'c']
|
176
|
+
a.create_valid(%w(a b)).must_equal ['a', 'b', nil]
|
177
|
+
a.create_valid(%w(a)).must_equal [nil, 'a', nil]
|
178
|
+
end
|
179
|
+
|
180
|
+
it 'coerces the arguments' do
|
181
|
+
a = Clive::Arguments.create :args => '<a> <b>', :as => [Integer, Float]
|
182
|
+
a.create_valid(%w(50.55 50.55)).must_equal [50, 50.55]
|
183
|
+
end
|
184
|
+
|
185
|
+
it 'uses defaults where needed' do
|
186
|
+
a = Clive::Arguments.create :args => '[<a>] <b> [<c>]', :defaults => ['y', nil, 'y']
|
187
|
+
a.create_valid(%w(n)).must_equal %w(y n y)
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
191
|
+
end
|
data/spec/clive/command_spec.rb
CHANGED
@@ -1,240 +1,307 @@
|
|
1
|
-
|
1
|
+
$: << File.dirname(__FILE__) + '/..'
|
2
|
+
require 'helper'
|
2
3
|
|
3
4
|
describe Clive::Command do
|
4
5
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
6
|
+
it 'can take arguments' do
|
7
|
+
command = Clive::Command.create([:test], '', :arg => '<dir>')
|
8
|
+
|
9
|
+
state = {:test => {}}
|
10
|
+
command.run(state, ['~/somewhere'])
|
11
|
+
state[:test][:args].must_equal '~/somewhere'
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'can run a block with arguments' do
|
15
|
+
command = Clive::Command.create [], '', :arg => '<dir>' do
|
16
|
+
action { puts dir }
|
17
|
+
end
|
18
|
+
|
19
|
+
this { command.run({}, ['~/somewhere']) }.must_output "~/somewhere\n"
|
20
|
+
end
|
21
|
+
|
22
|
+
describe '#initialize' do
|
23
|
+
subject {
|
24
|
+
Clive::Command.new([:c,:b,:a],
|
25
|
+
'A command',
|
26
|
+
:head => true,
|
27
|
+
:args => '<a> [<b>]',
|
28
|
+
:as => [Integer, nil],
|
29
|
+
:group => 'Cool commands',
|
30
|
+
:help => true,
|
31
|
+
:name => 'file.rb')
|
25
32
|
}
|
26
|
-
|
27
|
-
it
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
it
|
50
|
-
subject.
|
51
|
-
|
52
|
-
|
53
|
-
|
33
|
+
|
34
|
+
it 'sets the names' do
|
35
|
+
subject.names.must_equal [:c,:b,:a]
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'sets the description' do
|
39
|
+
subject.description.must_equal 'A command'
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'sets the options' do
|
43
|
+
subject.config[:head].must_be_true
|
44
|
+
subject.config[:group].must_equal 'Cool commands'
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'sets the arguments' do
|
48
|
+
subject.args.size.must_equal 2
|
49
|
+
subject.args.map(&:name).must_equal [:a, :b]
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'sets a default header' do
|
53
|
+
subject.instance_variable_get(:@header).call.must_equal 'Usage: file.rb c,b,a [options]'
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'sets a default footer' do
|
57
|
+
subject.instance_variable_get(:@footer).must_equal ''
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'adds the help option' do
|
61
|
+
subject.must_be :has?, '--help'
|
62
|
+
subject.must_be :has?, '-h'
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'resets the current description' do
|
66
|
+
subject.instance_variable_get(:@_last_desc).must_equal ''
|
54
67
|
end
|
55
68
|
end
|
56
|
-
|
57
|
-
describe
|
58
|
-
it
|
59
|
-
|
60
|
-
|
61
|
-
i.should be_kind_of Clive::Switch
|
62
|
-
end
|
69
|
+
|
70
|
+
describe '#name' do
|
71
|
+
it 'returns the first, in order when defined, name' do
|
72
|
+
command = Clive::Command.new [:efg, :abc, :zxy]
|
73
|
+
command.name.must_equal :efg
|
63
74
|
end
|
64
75
|
end
|
65
|
-
|
66
|
-
describe
|
67
|
-
it
|
68
|
-
|
69
|
-
|
70
|
-
i.should be_kind_of Clive::Flag
|
71
|
-
end
|
76
|
+
|
77
|
+
describe '#to_s' do
|
78
|
+
it 'returns the names joined' do
|
79
|
+
command = Clive::Command.new [:a, :b, :c]
|
80
|
+
command.to_s.must_equal 'a,b,c'
|
72
81
|
end
|
73
82
|
end
|
74
|
-
|
75
|
-
describe
|
76
|
-
it
|
77
|
-
|
78
|
-
|
79
|
-
subject.flags.size.should == 1
|
80
|
-
end
|
81
|
-
|
82
|
-
it "sets the block to nil" do
|
83
|
-
subject.find
|
84
|
-
subject.block.should be_nil
|
85
|
-
end
|
86
|
-
end
|
87
|
-
|
88
|
-
describe "#run" do
|
89
|
-
it "returns an array of unused arguments" do
|
90
|
-
subject.find
|
91
|
-
subject.run(%w(--swi what)).should == ['what']
|
92
|
-
end
|
93
|
-
end
|
94
|
-
|
95
|
-
describe "#to_h" do
|
96
|
-
it "returns a hash of data for help formatting" do
|
97
|
-
hsh = {'names' => subject.names, 'desc' => subject.desc}
|
98
|
-
subject.to_h.should == hsh
|
99
|
-
end
|
100
|
-
end
|
101
|
-
|
102
|
-
describe "#command" do
|
103
|
-
it "creates a new command" do
|
104
|
-
expect {
|
105
|
-
subject.command(:comm)
|
106
|
-
}.should change {subject.commands.size}.by(1)
|
107
|
-
end
|
108
|
-
|
109
|
-
it "resets the current description" do
|
110
|
-
subject.desc 'A command'
|
111
|
-
subject.command(:comm)
|
112
|
-
subject.current_desc.should == ""
|
113
|
-
end
|
114
|
-
end
|
115
|
-
|
116
|
-
describe "#switch" do
|
117
|
-
it "creates a new switch" do
|
118
|
-
expect {
|
119
|
-
subject.switch(:s, :switch)
|
120
|
-
}.should change {subject.switches.size}.by(1)
|
121
|
-
end
|
122
|
-
|
123
|
-
it "resets the current description" do
|
124
|
-
subject.desc 'A switch'
|
125
|
-
subject.switch(:s, :switch)
|
126
|
-
subject.current_desc.should == ""
|
127
|
-
end
|
128
|
-
end
|
129
|
-
|
130
|
-
describe "#flag" do
|
131
|
-
it "creates a new flag" do
|
132
|
-
expect {
|
133
|
-
subject.flag(:f, :flag)
|
134
|
-
}.should change {subject.flags.size}.by(1)
|
135
|
-
end
|
136
|
-
|
137
|
-
it "resets the current description" do
|
138
|
-
subject.desc 'A flag'
|
139
|
-
subject.flag(:f, :flag)
|
140
|
-
subject.current_desc.should == ""
|
141
|
-
end
|
142
|
-
end
|
143
|
-
|
144
|
-
describe "#bool" do
|
145
|
-
it "creates two bool switches" do
|
146
|
-
expect {
|
147
|
-
subject.bool(:b, :bool)
|
148
|
-
}.should change {subject.bools.size}.by(2)
|
149
|
-
end
|
150
|
-
|
151
|
-
it "resets the current description" do
|
152
|
-
subject.desc 'A bool'
|
153
|
-
subject.bool(:b, :bool)
|
154
|
-
subject.current_desc.should == ""
|
155
|
-
end
|
156
|
-
end
|
157
|
-
|
158
|
-
describe "#desc" do
|
159
|
-
context "when called with no arguments" do
|
160
|
-
it "returns the description for the command" do
|
161
|
-
subject.desc.should == "A command"
|
83
|
+
|
84
|
+
describe '#run_block' do
|
85
|
+
it 'runs the block passed to command' do
|
86
|
+
command = Clive::Command.new do
|
87
|
+
print 'Hey I was ran'
|
162
88
|
end
|
89
|
+
this { command.run_block({}) }.must_output 'Hey I was ran'
|
163
90
|
end
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
91
|
+
|
92
|
+
it 'returns a possibly modified state' do
|
93
|
+
state = {}
|
94
|
+
command = Clive::Command.new { set :a, true }
|
95
|
+
state.wont_have :key?, :a
|
96
|
+
command.run_block(state)
|
97
|
+
state.must_have :key?, :a
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
describe '#header' do
|
102
|
+
it 'sets the header' do
|
103
|
+
command = Clive::Command.new
|
104
|
+
command.header 'A header'
|
105
|
+
command.instance_variable_get(:@header).must_equal 'A header'
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
describe '#footer' do
|
110
|
+
it 'sets the footer' do
|
111
|
+
command = Clive::Command.new
|
112
|
+
command.footer 'A footer'
|
113
|
+
command.instance_variable_get(:@footer).must_equal 'A footer'
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
describe '#config' do
|
118
|
+
it 'sets options' do
|
119
|
+
command = Clive::Command.new
|
120
|
+
command.config :name => 'my cool app'
|
121
|
+
command.config[:name].must_equal 'my cool app'
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
describe '#set' do
|
126
|
+
it 'sets a value to the state hash' do
|
127
|
+
command = Clive::Command.new
|
128
|
+
command.instance_variable_set :@state, {}
|
129
|
+
command.set :a, true
|
130
|
+
command.instance_variable_get(:@state).must_equal :a => true
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
describe '#option' do
|
135
|
+
it 'creates an option' do
|
136
|
+
command = Clive::Command.new
|
137
|
+
command.option :O, :opt, 'An option', :tail => true
|
138
|
+
|
139
|
+
opt = command.find('-O')
|
140
|
+
opt.name.must_equal :opt
|
141
|
+
opt.description.must_equal 'An option'
|
142
|
+
opt.config.must_contain :tail => true
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
describe '#boolean' do
|
147
|
+
it 'creates a new boolean option' do
|
148
|
+
command = Clive::Command.new
|
149
|
+
command.boolean :auto, 'Auto build', :head => true
|
150
|
+
|
151
|
+
bool = command.find('--auto')
|
152
|
+
bool.name.must_equal :auto
|
153
|
+
bool.description.must_equal 'Auto build'
|
154
|
+
bool.config.must_contain :head => true
|
155
|
+
bool.config[:boolean].must_be_true
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
describe '#action' do
|
160
|
+
it 'stores a block' do
|
161
|
+
command = Clive::Command.new
|
162
|
+
block = proc {}
|
163
|
+
command.action &block
|
164
|
+
command.instance_variable_get(:@block).to_s.must_equal block.to_s
|
170
165
|
end
|
171
166
|
end
|
172
|
-
|
173
|
-
describe
|
174
|
-
it
|
175
|
-
|
176
|
-
|
177
|
-
|
167
|
+
|
168
|
+
describe '#description' do
|
169
|
+
it 'sets the description' do
|
170
|
+
command = Clive::Command.new
|
171
|
+
command.description 'Some description'
|
172
|
+
command.instance_variable_get(:@_last_desc).must_equal 'Some description'
|
173
|
+
end
|
174
|
+
|
175
|
+
it 'gets the description' do
|
176
|
+
command = Clive::Command.new [], 'A command'
|
177
|
+
command.description.must_equal 'A command'
|
178
178
|
end
|
179
179
|
end
|
180
|
-
|
181
|
-
describe
|
182
|
-
|
183
|
-
|
184
|
-
|
180
|
+
|
181
|
+
describe '#find' do
|
182
|
+
subject {
|
183
|
+
Clive::Command.create [:command] do
|
184
|
+
bool :F, :force
|
185
|
+
opt :auto_build
|
186
|
+
end
|
187
|
+
}
|
188
|
+
|
189
|
+
it 'finds boolean options' do
|
190
|
+
subject.find('--force').name.must_equal :force
|
191
|
+
end
|
192
|
+
|
193
|
+
it 'finds short options' do
|
194
|
+
subject.find('-F').name.must_equal :force
|
195
|
+
end
|
196
|
+
|
197
|
+
it 'does not find short negative boolean options' do
|
198
|
+
subject.find('--no-F').must_be_nil
|
199
|
+
end
|
200
|
+
|
201
|
+
it 'does not find negative boolean options' do
|
202
|
+
subject.find('--no-force').must_be_nil
|
203
|
+
end
|
204
|
+
|
205
|
+
it 'finds options with multiple words in name' do
|
206
|
+
subject.find('--auto_build').name.must_equal :auto_build
|
207
|
+
end
|
208
|
+
|
209
|
+
it 'finds options with dashes in name' do
|
210
|
+
subject.find('--auto-build').name.must_equal :auto_build
|
211
|
+
end
|
212
|
+
|
213
|
+
it 'does not find non existent options' do
|
214
|
+
subject.find('--no-auto-build').must_be_nil
|
215
|
+
subject.find('--unreal').must_be_nil
|
185
216
|
end
|
186
217
|
end
|
187
|
-
|
188
|
-
describe
|
189
|
-
|
190
|
-
|
191
|
-
|
218
|
+
|
219
|
+
describe '#find_option' do
|
220
|
+
subject {
|
221
|
+
Clive::Command.create do
|
222
|
+
bool :F, :force
|
223
|
+
opt :auto_build
|
224
|
+
end
|
225
|
+
}
|
226
|
+
|
227
|
+
it 'finds boolean options' do
|
228
|
+
subject.find_option(:force).name.must_equal :force
|
229
|
+
end
|
230
|
+
|
231
|
+
it 'finds short options' do
|
232
|
+
subject.find_option(:F).name.must_equal :force
|
233
|
+
end
|
234
|
+
|
235
|
+
it 'does not find short negative boolean options' do
|
236
|
+
subject.find_option(:no_F).must_be_nil
|
237
|
+
end
|
238
|
+
|
239
|
+
it 'does not find negative boolean options' do
|
240
|
+
subject.find_option(:no_force).must_be_nil
|
241
|
+
end
|
242
|
+
|
243
|
+
it 'finds options with multiple words in name' do
|
244
|
+
subject.find_option(:auto_build).name.must_equal :auto_build
|
245
|
+
end
|
246
|
+
|
247
|
+
it 'does not find non existent options' do
|
248
|
+
subject.find_option(:no_auto_build).must_be_nil
|
249
|
+
subject.find_option(:unreal).must_be_nil
|
192
250
|
end
|
193
251
|
end
|
194
|
-
|
195
|
-
describe
|
196
|
-
it
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
subject.options.map(&:names).should include ['h', 'help']
|
252
|
+
|
253
|
+
describe '#has?' do
|
254
|
+
it 'tries to find the option' do
|
255
|
+
command = Clive::Command.new
|
256
|
+
command.expects(:find).with('--option').returns(Clive::Option.new)
|
257
|
+
command.has?('--option').must_be_true
|
201
258
|
end
|
202
259
|
end
|
203
|
-
|
204
|
-
describe "#help" do
|
205
|
-
it "returns a string of help" do
|
206
|
-
help = <<EOS
|
207
|
-
Usage: rspec co, comm [options]
|
208
260
|
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
261
|
+
describe '#group' do
|
262
|
+
it 'sets the group for options created' do
|
263
|
+
command = Clive::Command.create do
|
264
|
+
group 'Testing'
|
265
|
+
opt :test
|
266
|
+
group 'Changed'
|
267
|
+
opt :change
|
268
|
+
opt :manual, :group => 'Set'
|
269
|
+
end
|
270
|
+
|
271
|
+
command.find_option(:test).config[:group].must_equal 'Testing'
|
272
|
+
command.find_option(:change).config[:group].must_equal 'Changed'
|
273
|
+
command.find_option(:manual).config[:group].must_equal 'Set'
|
214
274
|
end
|
215
275
|
end
|
216
|
-
|
217
|
-
describe
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
276
|
+
|
277
|
+
describe '#end_group' do
|
278
|
+
it 'calls #group with nil' do
|
279
|
+
command = Clive::Command.create do
|
280
|
+
group 'Testing'
|
281
|
+
option :test
|
282
|
+
end_group
|
283
|
+
option :none
|
223
284
|
end
|
285
|
+
|
286
|
+
command.find_option(:none).config[:group].must_be_nil
|
224
287
|
end
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
end
|
234
|
-
formatter = subject.instance_variable_get("@formatter")
|
235
|
-
formatter.width.should == 40
|
288
|
+
end
|
289
|
+
|
290
|
+
describe '#help' do
|
291
|
+
it 'builds a help string using the defined formatter' do
|
292
|
+
f = mock
|
293
|
+
command = Clive::Command.create [], "", :formatter => f, :help => true do
|
294
|
+
header 'Top'
|
295
|
+
footer 'Bottom'
|
236
296
|
end
|
297
|
+
|
298
|
+
f.expects(:header=).with('Top')
|
299
|
+
f.expects(:footer=).with('Bottom')
|
300
|
+
f.expects(:options=).with([command.find_option(:help)])
|
301
|
+
f.expects(:to_s).with()
|
302
|
+
|
303
|
+
command.help
|
237
304
|
end
|
238
305
|
end
|
239
306
|
|
240
|
-
end
|
307
|
+
end
|