choosy 0.1.0 → 0.2.0
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.
- 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
|