choosy 0.1.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/Gemfile +7 -0
- data/Gemfile.lock +25 -0
- data/LICENSE +23 -0
- data/README.markdown +393 -0
- data/Rakefile +57 -0
- data/lib/VERSION +1 -0
- data/lib/choosy/base_command.rb +59 -0
- data/lib/choosy/command.rb +32 -0
- data/lib/choosy/converter.rb +115 -0
- data/lib/choosy/dsl/base_command_builder.rb +172 -0
- data/lib/choosy/dsl/command_builder.rb +43 -0
- data/lib/choosy/dsl/option_builder.rb +155 -0
- data/lib/choosy/dsl/super_command_builder.rb +41 -0
- data/lib/choosy/errors.rb +11 -0
- data/lib/choosy/option.rb +22 -0
- data/lib/choosy/parse_result.rb +64 -0
- data/lib/choosy/parser.rb +184 -0
- data/lib/choosy/printing/color.rb +101 -0
- data/lib/choosy/printing/erb_printer.rb +23 -0
- data/lib/choosy/printing/help_printer.rb +174 -0
- data/lib/choosy/super_command.rb +77 -0
- data/lib/choosy/super_parser.rb +81 -0
- data/lib/choosy/verifier.rb +62 -0
- data/lib/choosy/version.rb +12 -0
- data/lib/choosy.rb +16 -0
- data/spec/choosy/base_command_spec.rb +11 -0
- data/spec/choosy/command_spec.rb +51 -0
- data/spec/choosy/converter_spec.rb +145 -0
- data/spec/choosy/dsl/base_command_builder_spec.rb +328 -0
- data/spec/choosy/dsl/commmand_builder_spec.rb +80 -0
- data/spec/choosy/dsl/option_builder_spec.rb +386 -0
- data/spec/choosy/dsl/super_command_builder_spec.rb +83 -0
- data/spec/choosy/parser_spec.rb +275 -0
- data/spec/choosy/printing/color_spec.rb +74 -0
- data/spec/choosy/printing/help_printer_spec.rb +117 -0
- data/spec/choosy/super_command_spec.rb +80 -0
- data/spec/choosy/super_parser_spec.rb +106 -0
- data/spec/choosy/verifier_spec.rb +180 -0
- data/spec/integration/command-A_spec.rb +37 -0
- data/spec/integration/supercommand-A_spec.rb +61 -0
- data/spec/spec_helpers.rb +30 -0
- metadata +150 -0
data/lib/choosy.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
# $:.unshift File.dirname(__FILE__)
|
2
|
+
|
3
|
+
require 'choosy/command'
|
4
|
+
require 'choosy/super_command'
|
5
|
+
require 'choosy/converter'
|
6
|
+
require 'choosy/errors'
|
7
|
+
require 'choosy/option'
|
8
|
+
require 'choosy/version'
|
9
|
+
require 'choosy/parser'
|
10
|
+
require 'choosy/verifier'
|
11
|
+
require 'choosy/dsl/command_builder'
|
12
|
+
require 'choosy/dsl/super_command_builder'
|
13
|
+
require 'choosy/dsl/option_builder'
|
14
|
+
require 'choosy/printing/color'
|
15
|
+
require 'choosy/printing/erb_printer'
|
16
|
+
require 'choosy/printing/help_printer'
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'spec_helpers'
|
2
|
+
require 'choosy/command'
|
3
|
+
require 'choosy/printing/help_printer'
|
4
|
+
|
5
|
+
module Choosy
|
6
|
+
describe Command do
|
7
|
+
before :each do
|
8
|
+
@c = Command.new :foo
|
9
|
+
end
|
10
|
+
|
11
|
+
describe :parse! do
|
12
|
+
it "should print out the version number" do
|
13
|
+
@c.alter do |c|
|
14
|
+
c.version "blah"
|
15
|
+
end
|
16
|
+
|
17
|
+
o = capture :stdout do
|
18
|
+
attempting {
|
19
|
+
@c.parse!(['--version'])
|
20
|
+
}.should raise_error(SystemExit)
|
21
|
+
end
|
22
|
+
|
23
|
+
o.should eql("blah\n")
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should print out the help info" do
|
27
|
+
@c.alter do |c|
|
28
|
+
c.summary "Summary"
|
29
|
+
c.desc "this is a description"
|
30
|
+
c.help
|
31
|
+
end
|
32
|
+
|
33
|
+
o = capture :stdout do
|
34
|
+
attempting {
|
35
|
+
@c.parse!(['--help'])
|
36
|
+
}.should raise_error(SystemExit)
|
37
|
+
end
|
38
|
+
|
39
|
+
o.should match(/-h, --help/)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
describe :execute! do
|
44
|
+
it "should fail when no executor is given" do
|
45
|
+
attempting {
|
46
|
+
@c.execute!(['a', 'b'])
|
47
|
+
}.should raise_error(Choosy::ConfigurationError, /No executor/)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,145 @@
|
|
1
|
+
require 'spec_helpers'
|
2
|
+
require 'choosy/version'
|
3
|
+
require 'choosy/converter'
|
4
|
+
|
5
|
+
module Choosy
|
6
|
+
describe Converter do
|
7
|
+
|
8
|
+
describe :for do
|
9
|
+
describe "symbols" do
|
10
|
+
it "knows about strings" do
|
11
|
+
Converter.for(:string).should eql(:string)
|
12
|
+
end
|
13
|
+
|
14
|
+
it "knows about files" do
|
15
|
+
Converter.for(:file).should eql(:file)
|
16
|
+
end
|
17
|
+
|
18
|
+
it "knows about ints" do
|
19
|
+
Converter.for(:int).should eql(:integer)
|
20
|
+
end
|
21
|
+
|
22
|
+
it "knows about integers" do
|
23
|
+
Converter.for(:integer).should eql(:integer)
|
24
|
+
end
|
25
|
+
|
26
|
+
it "knows about floats" do
|
27
|
+
Converter.for(:float).should eql(:float)
|
28
|
+
end
|
29
|
+
|
30
|
+
it "knows about Dates" do
|
31
|
+
Converter.for(:date).should eql(:date)
|
32
|
+
end
|
33
|
+
|
34
|
+
it "knows about Time" do
|
35
|
+
Converter.for(:time).should eql(:time)
|
36
|
+
end
|
37
|
+
|
38
|
+
it "knows about DateTime" do
|
39
|
+
Converter.for(:datetime).should eql(:datetime)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
describe "unknown types" do
|
44
|
+
it "returns nil" do
|
45
|
+
Converter.for(Hash).should be(nil)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
describe "unknown symbols" do
|
50
|
+
it "returns nil" do
|
51
|
+
Converter.for(:tada).should be(nil)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
describe "booleans" do
|
56
|
+
it "returns :boolean on :boolean" do
|
57
|
+
Converter.for(:boolean).should eql(:boolean)
|
58
|
+
end
|
59
|
+
|
60
|
+
it "returns :boolean on :bool" do
|
61
|
+
Converter.for(:bool).should eql(:boolean)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end#for
|
65
|
+
|
66
|
+
describe "converting" do
|
67
|
+
describe :integer do
|
68
|
+
it "should return an integer value" do
|
69
|
+
Converter.convert(:integer, "42").should eql(42)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
describe :float do
|
74
|
+
it "should return an float value" do
|
75
|
+
Converter.convert(:float, "3.2").should eql(3.2)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
describe :symbol do
|
80
|
+
it "should return a symbol" do
|
81
|
+
Converter.convert(:symbol, "this").should eql(:this)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
describe :file do
|
86
|
+
it "should return a file" do
|
87
|
+
Converter.convert(:file, __FILE__).path.should eql(__FILE__)
|
88
|
+
end
|
89
|
+
|
90
|
+
it "should succeed if the file is present" do
|
91
|
+
Converter.convert(:file, __FILE__).path.should eql(__FILE__)
|
92
|
+
end
|
93
|
+
|
94
|
+
it "should fail if the file is not present" do
|
95
|
+
attempting {
|
96
|
+
Converter.convert(:file, __FILE__ + "nothere")
|
97
|
+
}.should raise_error(Choosy::ValidationError, /Unable to locate file:/)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
describe :yaml do
|
102
|
+
it "should raise an error if the file doesn't exist" do
|
103
|
+
attempting {
|
104
|
+
Converter.convert(:yaml, __FILE__ + "non")
|
105
|
+
}.should raise_error(Choosy::ValidationError, /Unable to locate/)
|
106
|
+
end
|
107
|
+
|
108
|
+
it "should be able to parse a good yaml file" do
|
109
|
+
y = Converter.convert(:yaml, File.join(File.dirname(__FILE__), '..', '..', 'lib', 'VERSION'))
|
110
|
+
y.should eql(Choosy::Version.to_s.chomp)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
describe :date do
|
115
|
+
it "should return a Date" do
|
116
|
+
date = Converter.convert(:date, "July 17, 2010")
|
117
|
+
date.month.should eql(7)
|
118
|
+
date.day.should eql(17)
|
119
|
+
date.year.should eql(2010)
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
describe :time do
|
124
|
+
it "should return a Time" do
|
125
|
+
time = Converter.convert(:time, "12:30:15")
|
126
|
+
time.hour.should eql(12)
|
127
|
+
time.min.should eql(30)
|
128
|
+
time.sec.should eql(15)
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
describe :datetime do
|
133
|
+
it "should return a DateTime" do
|
134
|
+
datetime = Converter.convert(:datetime, "July 17, 2010 12:30:15")
|
135
|
+
datetime.month.should eql(7)
|
136
|
+
datetime.day.should eql(17)
|
137
|
+
datetime.year.should eql(2010)
|
138
|
+
datetime.hour.should eql(12)
|
139
|
+
datetime.min.should eql(30)
|
140
|
+
datetime.sec.should eql(15)
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end#converting
|
144
|
+
end
|
145
|
+
end
|
@@ -0,0 +1,328 @@
|
|
1
|
+
require 'spec_helpers'
|
2
|
+
require 'choosy/dsl/base_command_builder'
|
3
|
+
require 'choosy/command'
|
4
|
+
|
5
|
+
module Choosy::DSL
|
6
|
+
describe BaseCommandBuilder do
|
7
|
+
before :each do
|
8
|
+
@command = Choosy::Command.new(:cmd)
|
9
|
+
@builder = @command.builder
|
10
|
+
end
|
11
|
+
|
12
|
+
describe :printer do
|
13
|
+
it "should raise an error on a non-standard printer" do
|
14
|
+
attempting {
|
15
|
+
@builder.printer :non_standard
|
16
|
+
}.should raise_error(Choosy::ConfigurationError, /Unknown printing/)
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should know how to set the default printer" do
|
20
|
+
@builder.printer :standard
|
21
|
+
@command.printer.should be_a(Choosy::Printing::HelpPrinter)
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should know how to turn off color" do
|
25
|
+
@builder.printer :standard, :color => false
|
26
|
+
@command.printer.color.disabled?.should be(true)
|
27
|
+
end
|
28
|
+
|
29
|
+
class TestPrinter
|
30
|
+
def print!(cmd)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should understand how to set custom printers" do
|
35
|
+
attempting {
|
36
|
+
@builder.printer TestPrinter.new
|
37
|
+
}.should_not raise_error
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should fail when the printer doesn't implement 'print!'" do
|
41
|
+
attempting {
|
42
|
+
@builder.printer "this"
|
43
|
+
}.should raise_error(Choosy::ConfigurationError, /Unknown printing/)
|
44
|
+
end
|
45
|
+
|
46
|
+
describe "for :erb printing" do
|
47
|
+
it "should be able to handle a given template" do
|
48
|
+
@builder.printer :erb, :template => __FILE__
|
49
|
+
@command.printer.should be_a(Choosy::Printing::ERBPrinter)
|
50
|
+
end
|
51
|
+
|
52
|
+
it "should fail when the tempate file doesn't exist" do
|
53
|
+
attempting {
|
54
|
+
@builder.printer :erb, :template => "non"
|
55
|
+
}.should raise_error(Choosy::ConfigurationError, /template file doesn't exist/)
|
56
|
+
end
|
57
|
+
|
58
|
+
it "should fail when no template option is specified" do
|
59
|
+
attempting {
|
60
|
+
@builder.printer :erb
|
61
|
+
}.should raise_error(Choosy::ConfigurationError, /no template/)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end#printer
|
65
|
+
|
66
|
+
describe :summary do
|
67
|
+
it "should set the summary for this command" do
|
68
|
+
@builder.summary "This is a summary"
|
69
|
+
@command.summary.should eql("This is a summary")
|
70
|
+
end
|
71
|
+
end#summary
|
72
|
+
|
73
|
+
describe :desc do
|
74
|
+
it "should set the summary for this command" do
|
75
|
+
@builder.desc "This is a description"
|
76
|
+
@command.description.should match(/This is/)
|
77
|
+
end
|
78
|
+
end#desc
|
79
|
+
|
80
|
+
describe :separator do
|
81
|
+
it "should add a separator to the list of options for printing" do
|
82
|
+
@builder.separator 'Required arguments'
|
83
|
+
@command.listing[0].should eql('Required arguments')
|
84
|
+
end
|
85
|
+
|
86
|
+
it "should add an empty string to the listing when called with no arguments" do
|
87
|
+
@builder.separator
|
88
|
+
@command.listing[0].should eql('')
|
89
|
+
end
|
90
|
+
end#separator
|
91
|
+
|
92
|
+
describe :option do
|
93
|
+
describe "when using just a name" do
|
94
|
+
it "should set the name of the option" do
|
95
|
+
o = @builder.option :opto do |o|
|
96
|
+
o.short '-o'
|
97
|
+
end
|
98
|
+
o.name.should eql(:opto)
|
99
|
+
end
|
100
|
+
|
101
|
+
it "should handle a CommandBuilder block" do
|
102
|
+
@builder.option :opto do |o|
|
103
|
+
o.short '-s'
|
104
|
+
o.should be_a(OptionBuilder)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
it "should fail when no block is given" do
|
109
|
+
attempting {
|
110
|
+
@builder.option "blah"
|
111
|
+
}.should raise_error(Choosy::ConfigurationError, /No configuration block/)
|
112
|
+
end
|
113
|
+
|
114
|
+
it "should fail when the symbol is nil" do
|
115
|
+
attempting {
|
116
|
+
@builder.option nil do |o|
|
117
|
+
o.short = '-o'
|
118
|
+
end
|
119
|
+
}.should raise_error(Choosy::ConfigurationError, /The option name was nil/)
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
describe "when using a hash" do
|
124
|
+
describe "for dependencies" do
|
125
|
+
it "should set the dependencies of that option" do
|
126
|
+
o = @builder.option :o => [:s] do |o|
|
127
|
+
o.short '-o'
|
128
|
+
end
|
129
|
+
o.dependent_options.should have(1).items
|
130
|
+
o.dependent_options[0].should eql(:s)
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
describe "for options" do
|
135
|
+
it "should set the name of the option" do
|
136
|
+
o = @builder.option :o => {:short => '-o'}
|
137
|
+
o.name.should eql(:o)
|
138
|
+
end
|
139
|
+
|
140
|
+
it "should set the properties via the hash" do
|
141
|
+
o = @builder.option :o => {:short => '-o'}
|
142
|
+
o.short_flag.should eql('-o')
|
143
|
+
end
|
144
|
+
|
145
|
+
it "should still accept the block" do
|
146
|
+
o = @builder.option :o => {:short => '-o'} do |s|
|
147
|
+
s.desc "short"
|
148
|
+
end
|
149
|
+
o.description.should eql('short')
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
describe "whose arguments are invalid" do
|
154
|
+
it "should fail when more than one key is present" do
|
155
|
+
attempting {
|
156
|
+
@builder.option({:o => nil, :p => nil})
|
157
|
+
}.should raise_error(Choosy::ConfigurationError, /Malformed option hash/)
|
158
|
+
end
|
159
|
+
|
160
|
+
it "should fail when more than the hash is empty" do
|
161
|
+
attempting {
|
162
|
+
@builder.option({})
|
163
|
+
}.should raise_error(Choosy::ConfigurationError, /Malformed option hash/)
|
164
|
+
end
|
165
|
+
|
166
|
+
it "should fail when the option value is not an Array or a Hash" do
|
167
|
+
attempting {
|
168
|
+
@builder.option({:o => :noop})
|
169
|
+
}.should raise_error(Choosy::ConfigurationError, "Unable to process option hash")
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
describe "after the option block has been processed" do
|
174
|
+
it "should call the 'finalize!' method on the builder" do
|
175
|
+
o = @builder.option :o do |o|
|
176
|
+
o.short '-o'
|
177
|
+
end
|
178
|
+
o.cast_to.should eql(:boolean)
|
179
|
+
end
|
180
|
+
|
181
|
+
it "should add the builder with the given name to the command option_builders hash" do
|
182
|
+
@builder.option :o => {:short => '-l'}
|
183
|
+
@builder.command.option_builders.should have(1).item
|
184
|
+
end
|
185
|
+
|
186
|
+
it "adds the option to the listing" do
|
187
|
+
@builder.option :o => {:short => '-l'}
|
188
|
+
@builder.command.listing.should have(1).item
|
189
|
+
@builder.command.listing[0].name.should eql(:o)
|
190
|
+
end
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end#option
|
194
|
+
|
195
|
+
describe :boolean do
|
196
|
+
it "should be able to set short flag" do
|
197
|
+
o = @builder.boolean :Debug, "Show the debug output"
|
198
|
+
o.short_flag.should eql('-D')
|
199
|
+
end
|
200
|
+
|
201
|
+
it "should be able to set the long flag" do
|
202
|
+
o = @builder.boolean :Debug, "show debug"
|
203
|
+
o.long_flag.should eql('--debug')
|
204
|
+
end
|
205
|
+
|
206
|
+
it "should be able to fix the naming convention for long names" do
|
207
|
+
o = @builder.boolean :no_COLOR, "No color output"
|
208
|
+
o.long_flag.should eql('--no-color')
|
209
|
+
end
|
210
|
+
|
211
|
+
it "should set the description" do
|
212
|
+
o = @builder.boolean :no_color, "No color output"
|
213
|
+
o.description.should eql("No color output")
|
214
|
+
end
|
215
|
+
|
216
|
+
it "should handle optional configuration" do
|
217
|
+
o = @builder.boolean :debug, "Debug", {:short => '-D'}
|
218
|
+
o.short_flag.should eql('-D')
|
219
|
+
end
|
220
|
+
|
221
|
+
it "should be able to capture block level data" do
|
222
|
+
o = @builder.boolean :debug, "Show debug output" do |d|
|
223
|
+
d.short '-D'
|
224
|
+
end
|
225
|
+
o.short_flag.should eql("-D")
|
226
|
+
end
|
227
|
+
|
228
|
+
it "should suppress the short flag for boolean_" do
|
229
|
+
o = @builder.boolean_ :debug, "Show debug output"
|
230
|
+
o.short_flag.should be(nil)
|
231
|
+
end
|
232
|
+
end#boolean
|
233
|
+
|
234
|
+
describe :single do
|
235
|
+
it "should be able to set the short flag" do
|
236
|
+
o = @builder.single :count, "Show the count"
|
237
|
+
o.short_flag.should eql('-c')
|
238
|
+
end
|
239
|
+
|
240
|
+
it "should be able to set the parameter name" do
|
241
|
+
o = @builder.single :count, "Show the count"
|
242
|
+
o.flag_parameter.should eql('COUNT')
|
243
|
+
end
|
244
|
+
end#single
|
245
|
+
|
246
|
+
describe :multiple do
|
247
|
+
it "should be able to set the short flag" do
|
248
|
+
o = @builder.multiple :file_names, "The file names"
|
249
|
+
o.short_flag.should eql('-f')
|
250
|
+
end
|
251
|
+
|
252
|
+
it "should be able to set the parameter name" do
|
253
|
+
o = @builder.multiple :file_names, "The file names"
|
254
|
+
o.flag_parameter.should eql('FILE_NAMES+')
|
255
|
+
end
|
256
|
+
|
257
|
+
it "should be able to yield a block" do
|
258
|
+
o = @builder.multiple :file_names, "The file names" do |f|
|
259
|
+
f.long '--files'
|
260
|
+
end
|
261
|
+
o.long_flag.should eql('--files')
|
262
|
+
end
|
263
|
+
end#multiple
|
264
|
+
|
265
|
+
describe "dynamically generated method for" do
|
266
|
+
Choosy::Converter::CONVERSIONS.keys.each do |method|
|
267
|
+
it "#{method}" do
|
268
|
+
o = @builder.send(method, method, "Desc of #{method}")
|
269
|
+
o.cast_to.should eql(Choosy::Converter.for(method))
|
270
|
+
if o.cast_to == :boolean
|
271
|
+
o.flag_parameter.should be(nil)
|
272
|
+
else
|
273
|
+
o.flag_parameter.should eql(method.to_s.upcase)
|
274
|
+
end
|
275
|
+
end
|
276
|
+
|
277
|
+
it "#{method}_" do
|
278
|
+
underscore = "#{method}_".to_sym
|
279
|
+
o = @builder.send(underscore, method, "Desc of #{method}_")
|
280
|
+
o.short_flag.should be(nil)
|
281
|
+
end
|
282
|
+
|
283
|
+
next if method == :boolean || method == :bool
|
284
|
+
|
285
|
+
it "#{method}s" do
|
286
|
+
plural = "#{method}s".to_sym
|
287
|
+
o = @builder.send(plural, plural, "Desc of #{plural}")
|
288
|
+
o.cast_to.should eql(Choosy::Converter.for(method))
|
289
|
+
o.flag_parameter.should eql("#{plural.to_s.upcase}+")
|
290
|
+
end
|
291
|
+
|
292
|
+
it "#{method}s_" do
|
293
|
+
underscore = "#{method}s_".to_sym
|
294
|
+
o = @builder.send(underscore, method, "Desc of #{method}s_")
|
295
|
+
o.short_flag.should be(nil)
|
296
|
+
end
|
297
|
+
end
|
298
|
+
end
|
299
|
+
|
300
|
+
describe :version do
|
301
|
+
it "should allow you to set the message" do
|
302
|
+
v = @builder.version 'blah'
|
303
|
+
attempting {
|
304
|
+
v.validation_step.call
|
305
|
+
}.should raise_error(Choosy::VersionCalled, 'blah')
|
306
|
+
end
|
307
|
+
|
308
|
+
it "should allow you to use a block to alter the help message" do
|
309
|
+
v = @builder.version 'blah' do |v|
|
310
|
+
v.desc "Version"
|
311
|
+
end
|
312
|
+
v.description.should eql("Version")
|
313
|
+
end
|
314
|
+
|
315
|
+
it "should set the message automatically" do
|
316
|
+
v = @builder.version "blah"
|
317
|
+
v.description.should eql("The version number")
|
318
|
+
end
|
319
|
+
end#version
|
320
|
+
|
321
|
+
describe :finalize! do
|
322
|
+
it "should set the printer if not already set" do
|
323
|
+
@builder.finalize!
|
324
|
+
@command.printer.should be_a(Choosy::Printing::HelpPrinter)
|
325
|
+
end
|
326
|
+
end#finalize!
|
327
|
+
end
|
328
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
require 'spec_helpers'
|
2
|
+
require 'choosy/dsl/command_builder'
|
3
|
+
require 'choosy/command'
|
4
|
+
require 'choosy/converter'
|
5
|
+
require 'choosy/errors'
|
6
|
+
|
7
|
+
module Choosy::DSL
|
8
|
+
class FakeExecutor
|
9
|
+
attr_reader :options, :args
|
10
|
+
def execute!(options, args)
|
11
|
+
@options = options
|
12
|
+
@args = args
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
describe CommandBuilder do
|
17
|
+
before :each do
|
18
|
+
@command = Choosy::Command.new(:cmd)
|
19
|
+
@builder = @command.builder
|
20
|
+
end
|
21
|
+
|
22
|
+
describe :executor do
|
23
|
+
it "should set the executor in the command" do
|
24
|
+
@builder.executor FakeExecutor.new
|
25
|
+
@command.executor.should be_a(FakeExecutor)
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should handle proc arguments" do
|
29
|
+
@builder.executor {|opts, args| puts "hi"}
|
30
|
+
@command.executor.should_not be(nil)
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should raise an error if the executor is nil" do
|
34
|
+
attempting {
|
35
|
+
@builder.executor nil
|
36
|
+
}.should raise_error(Choosy::ConfigurationError, /executor was nil/)
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should raise an error if the executor class doesn't have an 'execute!' method" do
|
40
|
+
attempting {
|
41
|
+
@builder.executor Array.new
|
42
|
+
}.should raise_error(Choosy::ConfigurationError, /'execute!'/)
|
43
|
+
end
|
44
|
+
end#executor
|
45
|
+
|
46
|
+
describe :help do
|
47
|
+
it "should allow for a no arg" do
|
48
|
+
h = @builder.help
|
49
|
+
h.description.should eql("Show this help message")
|
50
|
+
end
|
51
|
+
|
52
|
+
it "should allow you to set the message" do
|
53
|
+
h = @builder.help 'Help message'
|
54
|
+
h.description.should eql('Help message')
|
55
|
+
end
|
56
|
+
|
57
|
+
it "should throw a HelpCalled upon validation" do
|
58
|
+
h = @builder.help
|
59
|
+
attempting {
|
60
|
+
h.validation_step.call
|
61
|
+
}.should raise_error(Choosy::HelpCalled)
|
62
|
+
end
|
63
|
+
end#help
|
64
|
+
|
65
|
+
describe :arguments do
|
66
|
+
it "should fail if there is no block given" do
|
67
|
+
attempting {
|
68
|
+
@builder.arguments
|
69
|
+
}.should raise_error(Choosy::ConfigurationError, /arguments/)
|
70
|
+
end
|
71
|
+
|
72
|
+
it "should pass in the arguments to validate" do
|
73
|
+
@builder.arguments do |args|
|
74
|
+
args.should have(3).items
|
75
|
+
end
|
76
|
+
@command.argument_validation.call([1, 2, 3])
|
77
|
+
end
|
78
|
+
end#arguments
|
79
|
+
end
|
80
|
+
end
|