choosy 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.markdown +229 -221
- data/Rakefile +21 -3
- data/examples/bar.rb +44 -0
- data/examples/foo.rb +198 -0
- data/examples/superfoo.rb +125 -0
- data/lib/VERSION +1 -1
- data/lib/choosy/argument.rb +51 -0
- data/lib/choosy/base_command.rb +22 -7
- data/lib/choosy/command.rb +12 -4
- data/lib/choosy/dsl/argument_builder.rb +88 -0
- data/lib/choosy/dsl/base_command_builder.rb +71 -56
- data/lib/choosy/dsl/command_builder.rb +14 -2
- data/lib/choosy/dsl/option_builder.rb +43 -83
- data/lib/choosy/dsl/super_command_builder.rb +37 -9
- data/lib/choosy/option.rb +13 -11
- data/lib/choosy/parse_result.rb +8 -27
- data/lib/choosy/parser.rb +20 -16
- data/lib/choosy/printing/color.rb +39 -21
- data/lib/choosy/printing/erb_printer.rb +12 -3
- data/lib/choosy/printing/formatting_element.rb +17 -0
- data/lib/choosy/printing/help_printer.rb +204 -117
- data/lib/choosy/printing/terminal.rb +53 -0
- data/lib/choosy/super_command.rb +6 -6
- data/lib/choosy/super_parser.rb +26 -15
- data/lib/choosy/verifier.rb +61 -6
- data/spec/choosy/base_command_spec.rb +27 -2
- data/spec/choosy/command_spec.rb +31 -9
- data/spec/choosy/dsl/argument_builder_spec.rb +180 -0
- data/spec/choosy/dsl/base_command_builder_spec.rb +87 -44
- data/spec/choosy/dsl/commmand_builder_spec.rb +15 -4
- data/spec/choosy/dsl/option_builder_spec.rb +101 -191
- data/spec/choosy/dsl/super_command_builder_spec.rb +34 -9
- data/spec/choosy/parser_spec.rb +30 -8
- data/spec/choosy/printing/color_spec.rb +19 -5
- data/spec/choosy/printing/help_printer_spec.rb +152 -73
- data/spec/choosy/printing/terminal_spec.rb +27 -0
- data/spec/choosy/super_command_spec.rb +17 -17
- data/spec/choosy/super_parser_spec.rb +20 -10
- data/spec/choosy/verifier_spec.rb +137 -47
- data/spec/integration/command-A_spec.rb +6 -6
- data/spec/integration/command-B_spec.rb +45 -0
- data/spec/integration/supercommand-A_spec.rb +33 -27
- data/spec/integration/supercommand-B_spec.rb +32 -0
- data/spec/spec_helpers.rb +8 -5
- metadata +95 -54
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'spec_helpers'
|
2
|
+
require 'choosy/printing/terminal'
|
3
|
+
|
4
|
+
module Choosy::Printing
|
5
|
+
class TerminalTest
|
6
|
+
include Terminal
|
7
|
+
end
|
8
|
+
|
9
|
+
describe Terminal do
|
10
|
+
before :each do
|
11
|
+
@t = TerminalTest.new
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should know the width of the screen, if possible, or set a default [COULD BREAK ON YOUR MACHINE]" do
|
15
|
+
@t.columns.should satisfy {|c| c >= Terminal::DEFAULT_COLUMN_COUNT }
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should know the lenght the screen, if possible, or set a default [COULD BREAK ON YOUR MACHINE]" do
|
19
|
+
@t.lines.should satisfy {|l| l >= Terminal::DEFAULT_LINE_COUNT }
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should allow for setting the column width" do
|
23
|
+
@t.columns = 40
|
24
|
+
@t.columns.should eql(40)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -9,8 +9,8 @@ module Choosy
|
|
9
9
|
|
10
10
|
describe :parse! do
|
11
11
|
it "should be able to print out the version number" do
|
12
|
-
@c.alter do
|
13
|
-
|
12
|
+
@c.alter do
|
13
|
+
version "superblah"
|
14
14
|
end
|
15
15
|
|
16
16
|
o = capture :stdout do
|
@@ -21,27 +21,27 @@ module Choosy
|
|
21
21
|
end
|
22
22
|
|
23
23
|
it "should print out the supercommand help message" do
|
24
|
-
@c.alter do
|
25
|
-
|
24
|
+
@c.alter do
|
25
|
+
help
|
26
26
|
end
|
27
27
|
|
28
28
|
o = capture :stdout do
|
29
29
|
@c.parse!([])
|
30
30
|
end
|
31
31
|
|
32
|
-
o.should match(/
|
32
|
+
o.should match(/Usage:/)
|
33
33
|
end
|
34
34
|
|
35
35
|
it "should print out a subcommand help message" do
|
36
|
-
@c.alter do
|
37
|
-
|
38
|
-
|
39
|
-
|
36
|
+
@c.alter do
|
37
|
+
help
|
38
|
+
command :bar do
|
39
|
+
boolean :count, "The count"
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
43
43
|
o = capture :stdout do
|
44
|
-
@c.parse!
|
44
|
+
@c.parse! ['help', 'bar']
|
45
45
|
end
|
46
46
|
|
47
47
|
o.should match(/--count/)
|
@@ -50,9 +50,9 @@ module Choosy
|
|
50
50
|
|
51
51
|
describe :execute! do
|
52
52
|
it "should fail when no executor is present" do
|
53
|
-
@c.alter do
|
54
|
-
|
55
|
-
|
53
|
+
@c.alter do
|
54
|
+
command :bar do
|
55
|
+
boolean :count, "The count"
|
56
56
|
end
|
57
57
|
end
|
58
58
|
|
@@ -63,10 +63,10 @@ module Choosy
|
|
63
63
|
|
64
64
|
it "should call the executors" do
|
65
65
|
count = 0
|
66
|
-
@c.alter do
|
67
|
-
|
68
|
-
|
69
|
-
|
66
|
+
@c.alter do
|
67
|
+
command :bar do
|
68
|
+
integer :count, "The count"
|
69
|
+
executor do |opts, args|
|
70
70
|
count = opts[:count]
|
71
71
|
end
|
72
72
|
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'spec_helpers'
|
2
2
|
require 'choosy/super_parser'
|
3
3
|
require 'choosy/super_command'
|
4
|
+
require 'choosy/dsl/super_command_builder'
|
4
5
|
|
5
6
|
module Choosy
|
6
7
|
class SuperParserBuilder
|
@@ -8,12 +9,11 @@ module Choosy
|
|
8
9
|
|
9
10
|
def initialize
|
10
11
|
@super = Choosy::SuperCommand.new :super
|
11
|
-
@parsimonious = false
|
12
12
|
end
|
13
13
|
|
14
14
|
def command(name)
|
15
|
-
@super.alter do
|
16
|
-
|
15
|
+
@super.alter do
|
16
|
+
command name do |c|
|
17
17
|
yield c if block_given?
|
18
18
|
end
|
19
19
|
end
|
@@ -21,8 +21,8 @@ module Choosy
|
|
21
21
|
end
|
22
22
|
|
23
23
|
def single(name)
|
24
|
-
@super.alter do
|
25
|
-
|
24
|
+
@super.alter do
|
25
|
+
single name, name.to_s
|
26
26
|
end
|
27
27
|
self
|
28
28
|
end
|
@@ -33,11 +33,13 @@ module Choosy
|
|
33
33
|
end
|
34
34
|
|
35
35
|
def parsimonious!
|
36
|
-
@
|
37
|
-
|
36
|
+
@super.alter do
|
37
|
+
parsimonious
|
38
|
+
end
|
39
|
+
end
|
38
40
|
|
39
41
|
def build
|
40
|
-
SuperParser.new(@super
|
42
|
+
SuperParser.new(@super)
|
41
43
|
end
|
42
44
|
end
|
43
45
|
|
@@ -69,7 +71,7 @@ module Choosy
|
|
69
71
|
@p.super.builder.help
|
70
72
|
attempting {
|
71
73
|
@p.parse!()
|
72
|
-
}.should raise_error(Choosy::HelpCalled,
|
74
|
+
}.should raise_error(Choosy::HelpCalled, Choosy::DSL::SuperCommandBuilder::SUPER)
|
73
75
|
end
|
74
76
|
end
|
75
77
|
|
@@ -88,7 +90,15 @@ module Choosy
|
|
88
90
|
end
|
89
91
|
|
90
92
|
it "should collect other names of commands as arguments" do
|
91
|
-
@p.command(:bar)
|
93
|
+
@p.command(:bar) do |c|
|
94
|
+
c.arguments
|
95
|
+
end.command(:baz).parse!('bar', 'baz').subresults.should have(1).item
|
96
|
+
end
|
97
|
+
|
98
|
+
it "should fail when the first command doesn't take arguments" do
|
99
|
+
attempting {
|
100
|
+
@p.command(:bar).command(:baz).parse!('bar', 'baz')
|
101
|
+
}.should raise_error(Choosy::ValidationError, /bar: no arguments allowed: baz/)
|
92
102
|
end
|
93
103
|
end
|
94
104
|
|
@@ -26,30 +26,40 @@ module Choosy
|
|
26
26
|
|
27
27
|
before :each do
|
28
28
|
reset!
|
29
|
-
@res = ParseResult.new(@c)
|
29
|
+
@res = ParseResult.new(@c, false)
|
30
30
|
end
|
31
31
|
|
32
|
-
describe :
|
32
|
+
describe :verify! do
|
33
33
|
it "should not try to validate arguments if not set" do
|
34
34
|
b.boolean :debug, "Debug"
|
35
|
+
b.arguments do
|
36
|
+
count 0..10
|
37
|
+
end
|
38
|
+
|
35
39
|
@res.args << "a"
|
36
40
|
attempting {
|
37
|
-
v.
|
41
|
+
v.verify!(@res)
|
38
42
|
}.should_not raise_error
|
39
43
|
end
|
40
44
|
end
|
41
45
|
|
42
|
-
describe :
|
43
|
-
it "should
|
44
|
-
b.
|
45
|
-
|
46
|
+
describe :required? do
|
47
|
+
it "should fail when an option is required but not provided" do
|
48
|
+
o = b.string :str, "String" do
|
49
|
+
required
|
46
50
|
end
|
51
|
+
attempting {
|
52
|
+
v.required?(o, @res)
|
53
|
+
}.should raise_error(Choosy::ValidationError, /required/)
|
54
|
+
end
|
47
55
|
|
56
|
+
it "should succeed when nothing is required" do
|
57
|
+
o = b.string :str, "String"
|
48
58
|
attempting {
|
49
|
-
v.
|
50
|
-
}.
|
59
|
+
v.required?(o, @res)
|
60
|
+
}.should_not raise_error
|
51
61
|
end
|
52
|
-
end
|
62
|
+
end#required?
|
53
63
|
|
54
64
|
describe :populate! do
|
55
65
|
it "should fill in default boolean values to false if unset" do
|
@@ -93,13 +103,66 @@ module Choosy
|
|
93
103
|
v.populate!(o, @res)
|
94
104
|
@res.options.should be_empty
|
95
105
|
end
|
96
|
-
end#
|
106
|
+
end#populate!
|
107
|
+
|
108
|
+
describe :convert! do
|
109
|
+
it "should convert files" do
|
110
|
+
o = b.file :afile, "A File"
|
111
|
+
@res[:afile] = __FILE__
|
112
|
+
v.convert!(o, @res)
|
113
|
+
@res[:afile].path.should eql(__FILE__)
|
114
|
+
end
|
115
|
+
|
116
|
+
class CustomConverter
|
117
|
+
def convert(value)
|
118
|
+
value.to_i
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
it "should convert a custom type" do
|
123
|
+
o = b.single :an_int, "An int" do
|
124
|
+
cast CustomConverter.new
|
125
|
+
end
|
126
|
+
@res[:an_int] = "1"
|
127
|
+
|
128
|
+
v.convert!(o, @res)
|
129
|
+
@res[:an_int].should eql(1)
|
130
|
+
end
|
131
|
+
end#convert!
|
132
|
+
|
133
|
+
describe :restricted? do
|
134
|
+
it "should verify that arguments are restricted to a certain subset for a single valued option" do
|
135
|
+
o = b.option :value do
|
136
|
+
flags '-v', '--value', 'VALUE'
|
137
|
+
desc "Description"
|
138
|
+
cast :symbol
|
139
|
+
only :a, :b, :c
|
140
|
+
end
|
141
|
+
|
142
|
+
@res[:value] = :d
|
143
|
+
attempting {
|
144
|
+
v.restricted?(o, @res)
|
145
|
+
}.should raise_error(Choosy::ValidationError, "unrecognized value (only 'a', 'b', 'c' allowed): 'd'")
|
146
|
+
end
|
147
|
+
|
148
|
+
it "should verify that all arguments are restricted for a muli-valued option" do
|
149
|
+
o = b.option :value do
|
150
|
+
long '--value', 'VALUES+'
|
151
|
+
only :a, :b, :c
|
152
|
+
end
|
153
|
+
|
154
|
+
@res[:value] = [:a, :b, :c, :d]
|
155
|
+
attempting {
|
156
|
+
v.restricted?(o, @res)
|
157
|
+
}.should raise_error(Choosy::ValidationError, "unrecognized value (only 'a', 'b', 'c' allowed): 'd'")
|
158
|
+
end
|
159
|
+
end
|
97
160
|
|
98
161
|
describe :validate! do
|
99
162
|
it "should call the validate proc associated with each option" do
|
100
|
-
o = b.string :line, "Line" do
|
101
|
-
|
102
|
-
|
163
|
+
o = b.string :line, "Line" do
|
164
|
+
validate do |arg, options|
|
165
|
+
die "Validated!"
|
103
166
|
end
|
104
167
|
end
|
105
168
|
@res[:line] = "line"
|
@@ -110,9 +173,9 @@ module Choosy
|
|
110
173
|
end
|
111
174
|
|
112
175
|
it "should not call the proc on empty arguments" do
|
113
|
-
o = b.strings :line, "Line" do
|
114
|
-
|
115
|
-
|
176
|
+
o = b.strings :line, "Line" do
|
177
|
+
validate do |arg|
|
178
|
+
die "Validated!"
|
116
179
|
end
|
117
180
|
end
|
118
181
|
@res[:line] = []
|
@@ -124,7 +187,7 @@ module Choosy
|
|
124
187
|
it "should not call the proc when the arguments are null" do
|
125
188
|
o = b.string :line, "Line" do |l|
|
126
189
|
l.validate do |arg|
|
127
|
-
|
190
|
+
die "Validated!"
|
128
191
|
end
|
129
192
|
end
|
130
193
|
@res[:line] = nil
|
@@ -132,49 +195,76 @@ module Choosy
|
|
132
195
|
v.validate!(o, @res)
|
133
196
|
@res[:line].should be(nil)
|
134
197
|
end
|
135
|
-
end#validate!
|
136
198
|
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
199
|
+
it "should call the proc with the additional option param" do
|
200
|
+
o = b.string :line, "Line" do
|
201
|
+
validate do |arg, options|
|
202
|
+
options[:populated] = arg
|
203
|
+
options[:line] = "this"
|
204
|
+
end
|
141
205
|
end
|
142
|
-
|
143
|
-
|
144
|
-
|
206
|
+
@res[:line] = 'blah'
|
207
|
+
|
208
|
+
v.validate!(o, @res)
|
209
|
+
@res[:populated].should eql('blah')
|
210
|
+
@res[:line].should eql("this")
|
145
211
|
end
|
212
|
+
end#validate!
|
213
|
+
|
214
|
+
describe :verify_arguments! do
|
215
|
+
it "should validate arguments if asked" do
|
216
|
+
b.arguments do
|
217
|
+
validate do |args, option|
|
218
|
+
raise RuntimeError.new('Called!')
|
219
|
+
end
|
220
|
+
end
|
221
|
+
@res.args << 'a'
|
146
222
|
|
147
|
-
it "should succeed when nothing is required" do
|
148
|
-
o = b.string :str, "String"
|
149
223
|
attempting {
|
150
|
-
v.
|
151
|
-
}.
|
224
|
+
v.verify_arguments!(@res)
|
225
|
+
}.should raise_error(RuntimeError, 'Called!')
|
152
226
|
end
|
153
|
-
end
|
154
227
|
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
228
|
+
it "should validate that the argument count isn't too few" do
|
229
|
+
b.arguments do
|
230
|
+
count 2
|
231
|
+
end
|
232
|
+
@res.args << "a"
|
233
|
+
|
234
|
+
attempting {
|
235
|
+
v.verify_arguments!(@res)
|
236
|
+
}.should raise_error(Choosy::ValidationError, /too few arguments/)
|
161
237
|
end
|
162
238
|
|
163
|
-
|
164
|
-
|
165
|
-
|
239
|
+
it "should validate that the argument count isn't too many" do
|
240
|
+
b.arguments do
|
241
|
+
count 1
|
166
242
|
end
|
243
|
+
@res.args << "a"
|
244
|
+
@res.args << "b"
|
245
|
+
|
246
|
+
attempting {
|
247
|
+
v.verify_arguments!(@res)
|
248
|
+
}.should raise_error(Choosy::ValidationError, /too many arguments/)
|
167
249
|
end
|
168
250
|
|
169
|
-
it "should
|
170
|
-
|
171
|
-
|
251
|
+
it "should succed when the argument count is in an acceptable range" do
|
252
|
+
b.arguments do
|
253
|
+
count 1..3
|
172
254
|
end
|
173
|
-
@res
|
255
|
+
@res.args << "1"
|
174
256
|
|
175
|
-
|
176
|
-
|
257
|
+
attempting {
|
258
|
+
v.verify_arguments!(@res)
|
259
|
+
}.should_not raise_error
|
177
260
|
end
|
178
|
-
|
261
|
+
|
262
|
+
it "should fail when no arguments are allowed" do
|
263
|
+
@res.args << 'a'
|
264
|
+
attempting {
|
265
|
+
v.verify_arguments!(@res)
|
266
|
+
}.should raise_error(Choosy::ValidationError, /no arguments allowed/)
|
267
|
+
end
|
268
|
+
end
|
179
269
|
end
|
180
270
|
end
|
@@ -4,11 +4,11 @@ require 'choosy'
|
|
4
4
|
describe "Command A" do
|
5
5
|
|
6
6
|
before :each do
|
7
|
-
@cmd = Choosy::Command.new :A do
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
7
|
+
@cmd = Choosy::Command.new :A do
|
8
|
+
integer :count, "The count"
|
9
|
+
boolean :bold, "Bold the output"
|
10
|
+
version "blah"
|
11
|
+
help
|
12
12
|
end
|
13
13
|
end
|
14
14
|
|
@@ -17,7 +17,7 @@ describe "Command A" do
|
|
17
17
|
@cmd.parse! ['--help']
|
18
18
|
end
|
19
19
|
|
20
|
-
o.should match /
|
20
|
+
o.should match /Usage:/
|
21
21
|
end
|
22
22
|
|
23
23
|
it "should handle multiple arguments" do
|