bosonson 0.304.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. data/CHANGELOG.rdoc +108 -0
  2. data/LICENSE.txt +22 -0
  3. data/README.rdoc +181 -0
  4. data/bin/bss +6 -0
  5. data/bosonson.gemspec +24 -0
  6. data/deps.rip +2 -0
  7. data/lib/boson.rb +96 -0
  8. data/lib/boson/command.rb +196 -0
  9. data/lib/boson/commands.rb +7 -0
  10. data/lib/boson/commands/core.rb +77 -0
  11. data/lib/boson/commands/web_core.rb +153 -0
  12. data/lib/boson/index.rb +48 -0
  13. data/lib/boson/inspector.rb +120 -0
  14. data/lib/boson/inspectors/argument_inspector.rb +97 -0
  15. data/lib/boson/inspectors/comment_inspector.rb +100 -0
  16. data/lib/boson/inspectors/method_inspector.rb +98 -0
  17. data/lib/boson/libraries/file_library.rb +144 -0
  18. data/lib/boson/libraries/gem_library.rb +30 -0
  19. data/lib/boson/libraries/local_file_library.rb +30 -0
  20. data/lib/boson/libraries/module_library.rb +37 -0
  21. data/lib/boson/libraries/require_library.rb +23 -0
  22. data/lib/boson/library.rb +179 -0
  23. data/lib/boson/loader.rb +118 -0
  24. data/lib/boson/manager.rb +169 -0
  25. data/lib/boson/namespace.rb +31 -0
  26. data/lib/boson/option_command.rb +222 -0
  27. data/lib/boson/option_parser.rb +475 -0
  28. data/lib/boson/options.rb +146 -0
  29. data/lib/boson/pipe.rb +147 -0
  30. data/lib/boson/pipes.rb +75 -0
  31. data/lib/boson/repo.rb +107 -0
  32. data/lib/boson/repo_index.rb +124 -0
  33. data/lib/boson/runner.rb +81 -0
  34. data/lib/boson/runners/bin_runner.rb +208 -0
  35. data/lib/boson/runners/console_runner.rb +58 -0
  36. data/lib/boson/scientist.rb +182 -0
  37. data/lib/boson/util.rb +129 -0
  38. data/lib/boson/version.rb +3 -0
  39. data/lib/boson/view.rb +95 -0
  40. data/test/argument_inspector_test.rb +62 -0
  41. data/test/bin_runner_test.rb +223 -0
  42. data/test/command_test.rb +22 -0
  43. data/test/commands_test.rb +22 -0
  44. data/test/comment_inspector_test.rb +126 -0
  45. data/test/deps.rip +4 -0
  46. data/test/file_library_test.rb +42 -0
  47. data/test/loader_test.rb +235 -0
  48. data/test/manager_test.rb +114 -0
  49. data/test/method_inspector_test.rb +90 -0
  50. data/test/option_parser_test.rb +367 -0
  51. data/test/options_test.rb +189 -0
  52. data/test/pipes_test.rb +65 -0
  53. data/test/repo_index_test.rb +122 -0
  54. data/test/repo_test.rb +23 -0
  55. data/test/runner_test.rb +40 -0
  56. data/test/scientist_test.rb +341 -0
  57. data/test/test_helper.rb +130 -0
  58. data/test/util_test.rb +56 -0
  59. data/vendor/bundle/gems/bacon-bits-0.1.0/deps.rip +1 -0
  60. data/vendor/bundle/gems/hirb-0.6.0/test/deps.rip +4 -0
  61. metadata +217 -0
@@ -0,0 +1,114 @@
1
+ require File.join(File.dirname(__FILE__), 'test_helper')
2
+
3
+ describe "Manager" do
4
+ describe ".after_load" do
5
+ def load_library(hash)
6
+ new_attributes = {:name=>hash[:name], :commands=>[], :created_dependencies=>[], :loaded=>true}
7
+ [:module, :commands].each {|e| new_attributes[e] = hash.delete(e) if hash[e] }
8
+ Manager.expects(:rescue_load_action).returns(Library.new(new_attributes))
9
+ Manager.load([hash[:name]])
10
+ end
11
+
12
+ before { reset_boson }
13
+
14
+ it "loads basic library" do
15
+ load_library :name=>'blah'
16
+ library_loaded? 'blah'
17
+ end
18
+
19
+ it "loads library with commands" do
20
+ load_library :name=>'blah', :commands=>['frylock','meatwad']
21
+ library_loaded? 'blah'
22
+ command_exists?('frylock')
23
+ command_exists?('meatwad')
24
+ end
25
+
26
+ it "prints error for library with SyntaxError" do
27
+ Manager.expects(:loader_create).raises(SyntaxError)
28
+ capture_stderr {
29
+ Manager.load 'blah'
30
+ }.should =~ /Unable to load library blah. Reason: SyntaxError/
31
+ end
32
+
33
+ it "prints error for library with LoadError" do
34
+ Manager.expects(:loader_create).raises(LoadError)
35
+ capture_stderr {
36
+ Manager.load 'blah'
37
+ }.should =~ /Unable to load library blah. Reason: LoadError/
38
+ end
39
+
40
+ describe "command aliases" do
41
+ before { eval %[module ::Aquateen; def frylock; end; end] }
42
+ after { Object.send(:remove_const, "Aquateen") }
43
+
44
+ it "created with command specific config" do
45
+ with_config(:command_aliases=>{'frylock'=>'fr'}) do
46
+ Manager.expects(:create_instance_aliases).with({"Aquateen"=>{"frylock"=>"fr"}})
47
+ load_library :name=>'aquateen', :commands=>['frylock'], :module=>Aquateen
48
+ library_loaded? 'aquateen'
49
+ end
50
+ end
51
+
52
+ it "created with config command_aliases" do
53
+ with_config(:command_aliases=>{"frylock"=>"fr"}) do
54
+ Manager.expects(:create_instance_aliases).with({"Aquateen"=>{"frylock"=>"fr"}})
55
+ load_library :name=>'aquateen', :commands=>['frylock'], :module=>Aquateen
56
+ library_loaded? 'aquateen'
57
+ end
58
+ end
59
+
60
+ it "not created and warns for commands with no module" do
61
+ with_config(:command_aliases=>{'frylock'=>'fr'}) do
62
+ capture_stderr {
63
+ load_library(:name=>'aquateen', :commands=>['frylock'])
64
+ }.should =~ /No aliases/
65
+ library_loaded? 'aquateen'
66
+ Aquateen.method_defined?(:fr).should == false
67
+ end
68
+ end
69
+ end
70
+
71
+ it "merges with existing created library" do
72
+ create_library('blah')
73
+ load_library :name=>'blah'
74
+ library_loaded? 'blah'
75
+ Boson.libraries.size.should == 1
76
+ end
77
+ end
78
+
79
+ describe "option commands without args" do
80
+ before_all {
81
+ reset_boson
82
+ @library = Library.new(:name=>'blah', :commands=>['foo', 'bar'])
83
+ Boson.libraries << @library
84
+ @foo = Command.new(:name=>'foo', :lib=>'blah', :options=>{:fool=>:string}, :args=>'*')
85
+ Boson.commands << @foo
86
+ Boson.commands << Command.new(:name=>'bar', :lib=>'blah', :options=>{:bah=>:string})
87
+ }
88
+
89
+ it "are deleted" do
90
+ Scientist.expects(:redefine_command).with(anything, @foo)
91
+ Manager.redefine_commands(@library, @library.commands)
92
+ end
93
+
94
+ it "are deleted and printed when verbose" do
95
+ Scientist.expects(:redefine_command).with(anything, @foo)
96
+ @library.instance_eval("@options = {:verbose=>true}")
97
+ capture_stdout { Manager.redefine_commands(@library, @library.commands) } =~ /options.*blah/
98
+ end
99
+ end
100
+
101
+ describe ".loaded?" do
102
+ before { reset_libraries }
103
+
104
+ it "returns false when library isn't loaded" do
105
+ create_library('blah')
106
+ Manager.loaded?('blah').should == false
107
+ end
108
+
109
+ it "returns true when library is loaded" do
110
+ create_library('blah', :loaded=>true)
111
+ Manager.loaded?('blah').should == true
112
+ end
113
+ end
114
+ end
@@ -0,0 +1,90 @@
1
+ require File.join(File.dirname(__FILE__), 'test_helper')
2
+
3
+ describe "MethodInspector" do
4
+ it "non commands module can't set anything" do
5
+ eval "module Blah; end"
6
+ MethodInspector.current_module = Blah
7
+ Inspector.enable
8
+ Blah.module_eval("desc 'test'; def test; end; options :a=>1; def test2; end")
9
+ Inspector.disable
10
+ MethodInspector.store[:desc].empty?.should == true
11
+ MethodInspector.store[:options].empty?.should == true
12
+ end
13
+
14
+ it "handles anonymous classes" do
15
+ MethodInspector.mod_store = {}
16
+ Inspector.enable
17
+ Class.new.module_eval "def blah; end"
18
+ Inspector.disable
19
+ MethodInspector.store.should == nil
20
+ end
21
+
22
+ describe "commands module with" do
23
+ def parse(string)
24
+ Inspector.enable
25
+ ::Boson::Commands::Zzz.module_eval(string)
26
+ Inspector.disable
27
+ MethodInspector.store
28
+ end
29
+
30
+ before_all { eval "module ::Boson::Commands::Zzz; end" }
31
+ before { MethodInspector.mod_store.delete(::Boson::Commands::Zzz) }
32
+
33
+ it "desc sets descriptions" do
34
+ parsed = parse "desc 'test'; def m1; end; desc 'one'; desc 'more'; def m2; end"
35
+ parsed[:desc].should == {"m1"=>"test", "m2"=>"more"}
36
+ end
37
+
38
+ it "options sets options" do
39
+ parse("options :z=>'b'; def zee; end")[:options].should == {"zee"=>{:z=>'b'}}
40
+ end
41
+
42
+ it "option sets options" do
43
+ parse("option :z, 'b'; option :y, :boolean; def zee; end")[:options].should ==
44
+ {"zee"=>{:z=>'b', :y=>:boolean}}
45
+ end
46
+
47
+ it "option(s) sets options" do
48
+ parse("options :z=>'b'; option :y, :string; def zee; end")[:options].should ==
49
+ {"zee"=>{:z=>'b', :y=>:string}}
50
+ end
51
+
52
+ it "option(s) option overrides options" do
53
+ parse("options :z=>'b'; option :z, :string; def zee; end")[:options].should ==
54
+ {"zee"=>{:z=>:string}}
55
+ end
56
+
57
+ it "render_options sets render_options" do
58
+ parse("render_options :z=>true; def zee; end")[:render_options].should == {"zee"=>{:z=>true}}
59
+ end
60
+
61
+ it "config sets config" do
62
+ parse("config :z=>true; def zee; end")[:config].should == {"zee"=>{:z=>true}}
63
+ end
64
+
65
+ it "not all method attributes set causes method_locations to be set" do
66
+ MethodInspector.stubs(:find_method_locations).returns(["/some/path", 10])
67
+ parsed = parse "desc 'yo'; def yo; end; options :yep=>1; def yep; end; " +
68
+ "option :b, :boolean; render_options :a=>1; config :a=>1; desc 'z'; options :a=>1; def az; end"
69
+ parsed[:method_locations].key?('yo').should == true
70
+ parsed[:method_locations].key?('yep').should == true
71
+ parsed[:method_locations].key?('az').should == false
72
+ end
73
+
74
+ it "no find_method_locations doesn't set method_locations" do
75
+ MethodInspector.stubs(:find_method_locations).returns(nil)
76
+ parse("def bluh; end")[:method_locations].key?('bluh').should == false
77
+ end
78
+
79
+ it "options calls scrape_with_eval" do
80
+ ArgumentInspector.expects(:scrape_with_eval).returns([['arg1']])
81
+ parse("desc 'desc'; options :some=>:opts; def doy(arg1); end")[:args]['doy'].should == [['arg1']]
82
+ end
83
+
84
+ it "options in file calls scrape_with_eval" do
85
+ MethodInspector.expects(:inspector_in_file?).returns(true)
86
+ ArgumentInspector.expects(:scrape_with_eval).returns([['arg1']])
87
+ parse("desc 'desc'; def doz(arg1); end")[:args]['doz'].should == [['arg1']]
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,367 @@
1
+ require File.join(File.dirname(__FILE__), 'test_helper')
2
+
3
+ describe "OptionParser" do
4
+ def create(opts)
5
+ @opt = OptionParser.new(opts)
6
+ end
7
+
8
+ def opt; @opt; end
9
+
10
+ def parse(*args)
11
+ @non_opts = []
12
+ opt.parse(args.flatten)
13
+ end
14
+
15
+ describe "IndifferentAccessHash" do
16
+ before {
17
+ @hash = IndifferentAccessHash.new 'foo' => 'bar', 'baz' => 'bee'
18
+ }
19
+ it "can access values indifferently" do
20
+ @hash['foo'].should == 'bar'
21
+ @hash[:foo].should == 'bar'
22
+ @hash.values_at(:foo, :baz).should == ['bar', 'bee']
23
+ end
24
+
25
+ it "can be initialized with either strings or symbols and be equal" do
26
+ hash2 = IndifferentAccessHash.new :foo=>'bar', :baz=>'bee'
27
+ @hash.should == hash2
28
+ end
29
+
30
+ it "returns keys as symbols by default" do
31
+ @hash.should == {:foo=>'bar', :baz=>'bee'}
32
+ end
33
+
34
+ it "can set values indifferently" do
35
+ @hash['foo'] = 'duh'
36
+ @hash[:foo].should == 'duh'
37
+ @hash[:baz] = 'wasp'
38
+ @hash['baz'].should == 'wasp'
39
+ end
40
+ end
41
+
42
+ describe "naming" do
43
+ it "automatically aliases long options with their first letter" do
44
+ create "--foo" => true
45
+ parse("-f")["foo"].should == true
46
+ end
47
+
48
+ it "automatically aliases two options with same first letters by aliasing alphabetical first with lowercase and second with uppercase" do
49
+ create :verbose=>:boolean, :vertical=>:string, :verz=>:boolean
50
+ parse('-v', '-V','2').should == {:verbose=>true, :vertical=>'2'}
51
+ end
52
+
53
+ it "doesn't auto-alias options that have multiple names given" do
54
+ create ["--foo", "--bar"] => :boolean
55
+ parse("-f")["foo"].should == nil
56
+ end
57
+
58
+ it "allows aliases to be symbols or strings" do
59
+ create [:foo, :bar, 'baz'] =>:string
60
+ parse("--foo", "12")[:foo].should == "12"
61
+ parse("--bar", "12")[:foo].should == "12"
62
+ parse("--baz", "12")[:foo].should == "12"
63
+ end
64
+
65
+ it "allows multiple aliases for a given opt" do
66
+ create ["--foo", "--bar", "--baz"] => :string
67
+ parse("--foo", "12")["foo"].should == "12"
68
+ parse("--bar", "12")["foo"].should == "12"
69
+ parse("--baz", "12")["foo"].should == "12"
70
+ end
71
+
72
+ it "allows custom short names" do
73
+ create "-f" => :string
74
+ parse("-f", "12").should == {:f => "12"}
75
+ end
76
+
77
+ it "allows capital short names" do
78
+ create :A => :boolean
79
+ parse("-A")[:A].should == true
80
+ end
81
+
82
+ it "allows capital short aliases" do
83
+ create [:awesome, :A] => :string
84
+ parse("--awesome", "bar")[:awesome].should == 'bar'
85
+ parse("-A", "bar")[:awesome].should == 'bar'
86
+ end
87
+
88
+ it "allows custom short aliases" do
89
+ create ["--bar", "-f"] => :string
90
+ parse("-f", "12").should == {:bar => "12"}
91
+ end
92
+
93
+ it "allows humanized opt name" do
94
+ create 'foo' => :string, :bar => :string
95
+ parse("-f", "1", "-b", "2").should == {:foo => "1", :bar => "2"}
96
+ end
97
+
98
+ it "allows humanized symbol opt name" do
99
+ create :foo=>:string
100
+ parse('-f','1').should == {:foo=>'1'}
101
+ end
102
+
103
+ it "doesn't allow alias to override another option" do
104
+ create :foo=>:string, [:bar, :foo]=>:boolean
105
+ parse("--foo", "boo")[:foo].should == 'boo'
106
+ end
107
+
108
+ it "doesn't recognize long opt format for a opt that is originally short" do
109
+ create 'f' => :string
110
+ parse("-f", "1").should == {:f => "1"}
111
+ parse("--f", "1").should == {}
112
+ end
113
+
114
+ it "accepts --[no-]opt variant for booleans, setting false for value" do
115
+ create "--foo" => :boolean
116
+ parse("--no-foo")["foo"].should == false
117
+ parse("--no-f")["foo"].should == false
118
+ parse("--foo")["foo"].should == true
119
+ end
120
+
121
+ it "accepts --[no-]opt variant for single letter booleans" do
122
+ create :e=>true
123
+ parse("--no-e")[:e].should == false
124
+ end
125
+
126
+ it "will prefer 'no-opt' variant over inverting 'opt' if explicitly set" do
127
+ create "--no-foo" => true
128
+ parse("--no-foo")["no-foo"].should == true
129
+ end
130
+
131
+ end
132
+
133
+ describe "option values can be set with" do
134
+ it "a opt=<value> assignment" do
135
+ create :foo => :string
136
+ parse("--foo=12")["foo"].should == "12"
137
+ parse("-f=12")["foo"].should == "12"
138
+ parse("--foo=bar=baz")["foo"].should == "bar=baz"
139
+ parse("--foo=sentence with spaces")["foo"].should == "sentence with spaces"
140
+ end
141
+
142
+ it "a -nXY assignment" do
143
+ create "--num" => :numeric
144
+ parse("-n12")["num"].should == 12
145
+ end
146
+
147
+ it "conjoined short options" do
148
+ create "--foo" => true, "--bar" => true, "--app" => true
149
+ opts = parse "-fba"
150
+ opts["foo"].should == true
151
+ opts["bar"].should == true
152
+ opts["app"].should == true
153
+ end
154
+
155
+ it "conjoined short options with argument" do
156
+ create "--foo" => true, "--bar" => true, "--app" => :numeric
157
+ opts = parse "-fba", "12"
158
+ opts["foo"].should == true
159
+ opts["bar"].should == true
160
+ opts["app"].should == 12
161
+ end
162
+ end
163
+
164
+ describe "parse" do
165
+ it "extracts non-option arguments" do
166
+ create "--foo" => :string, "--bar" => true
167
+ parse("foo", "bar", "--baz", "--foo", "12", "--bar", "-T", "bang").should == {
168
+ :foo => "12", :bar => true
169
+ }
170
+ opt.leading_non_opts.should == ["foo", "bar", "--baz"]
171
+ opt.trailing_non_opts.should == ["-T", "bang"]
172
+ opt.non_opts.should == ["foo", "bar", "--baz", "-T", "bang"]
173
+ end
174
+
175
+ it "stopped by --" do
176
+ create :foo=>:boolean, :dude=>:boolean
177
+ parse("foo", "bar", "--", "-f").should == {}
178
+ opt.leading_non_opts.should == %w{foo bar}
179
+ opt.trailing_non_opts.should == %w{-- -f}
180
+ end
181
+
182
+ describe "with parse flag" do
183
+ it ":delete_invalid_opts deletes and warns of invalid options" do
184
+ create(:foo=>:boolean)
185
+ capture_stderr {
186
+ opt.parse(%w{-f -d ok}, :delete_invalid_opts=>true)
187
+ }.should =~ /Deleted invalid option '-d'/
188
+ opt.non_opts.should == ['ok']
189
+ end
190
+
191
+ it ":delete_invalid_opts deletes until - or --" do
192
+ create(:foo=>:boolean, :bar=>:boolean)
193
+ %w{- --}.each do |stop_char|
194
+ capture_stderr {
195
+ opt.parse(%w{ok -b -d} << stop_char << '-f', :delete_invalid_opts=>true)
196
+ }.should =~ /'-d'/
197
+ opt.non_opts.should == %w{ok -d} << stop_char << '-f'
198
+ end
199
+ end
200
+
201
+ it ":opts_before_args only allows options before args" do
202
+ create(:foo=>:boolean)
203
+ opt.parse(%w{ok -f}, :opts_before_args=>true).should == {}
204
+ opt.parse(%w{-f ok}, :opts_before_args=>true).should == {:foo=>true}
205
+ end
206
+ end
207
+
208
+ describe "with no arguments" do
209
+ it "and no options returns an empty hash" do
210
+ create({})
211
+ parse.should == {}
212
+ end
213
+
214
+ it "and several options returns an empty hash" do
215
+ create "--foo" => :boolean, "--bar" => :string
216
+ parse.should == {}
217
+ end
218
+ end
219
+ end
220
+
221
+ describe "option hashes" do
222
+ it "make hash keys available as symbols as well" do
223
+ create "--foo" => :string
224
+ parse("--foo", "12")[:foo].should == "12"
225
+ end
226
+
227
+ it "don't set nonexistant options" do
228
+ create "--foo" => :boolean
229
+ parse("--foo")["bar"].should == nil
230
+ opts = parse
231
+ opts["foo"].should == nil
232
+ end
233
+ end
234
+
235
+ describe ":required option attribute" do
236
+ before_all {
237
+ create "--foo" => {:type=>:string, :required=>true}, :bar => {:type=>:hash, :required=>true}
238
+ }
239
+
240
+ it "raises an error if string option isn't given" do
241
+ assert_error(OptionParser::Error, 'no value.*required.*foo') { parse("--bar", "str:ok") }
242
+ end
243
+
244
+ it "raises an error if non-string option isn't given" do
245
+ assert_error(OptionParser::Error, 'no value.*required.*bar') { parse("--foo", "yup") }
246
+ end
247
+
248
+ it "raises no error when given arguments" do
249
+ parse("--foo", "yup", "--bar","ok:dude").should == {:foo=>'yup', :bar=>{'ok'=>'dude'}}
250
+ end
251
+ end
252
+
253
+ describe ":bool_default option attribute" do
254
+ before_all {
255
+ create :foo=>{:type=>:string, :bool_default=>'whoop'}, :bar=>{:type=>:array, :bool_default=>'1'},
256
+ :verbose=>:boolean, :yep=>{:type=>:string, :bool_default=>true}
257
+ }
258
+
259
+ it "sets default boolean" do
260
+ parse('--foo', '--bar', '1')[:foo].should == 'whoop'
261
+ parse('--foo', 'ok', 'dokay')[:foo].should == 'whoop'
262
+ end
263
+
264
+ it "sets options normally" do
265
+ parse('--foo=boo', '--bar=har').should == {:foo=>'boo', :bar=>['har']}
266
+ end
267
+
268
+ it "sets default boolean for array" do
269
+ parse("--bar", '--foo', '2')[:bar].should == ['1']
270
+ end
271
+
272
+ it "sets default boolean for non-string value" do
273
+ parse('--yep', '--foo=2')[:yep].should == true
274
+ end
275
+
276
+ it "default booleans can be joined with boolean options" do
277
+ parse('-fbv').should == {:verbose=>true, :bar=>['1'], :foo=>'whoop'}
278
+ end
279
+ end
280
+
281
+ describe "option with attributes" do
282
+ it "can get type from :type" do
283
+ create :foo=>{:type=>:numeric}
284
+ parse("-f", '3')[:foo].should == 3
285
+ end
286
+
287
+ it "can get type and default from :default" do
288
+ create :foo=>{:default=>[]}
289
+ parse("-f", "1")[:foo].should == ['1']
290
+ parse[:foo].should == []
291
+ end
292
+
293
+ it "assumes :boolean type if no type found" do
294
+ create :foo=>{:some=>'params'}
295
+ parse('-f')[:foo].should == true
296
+ end
297
+ end
298
+
299
+ def usage
300
+ opt.formatted_usage.split(" ").sort
301
+ end
302
+
303
+ describe "#formatted_usage" do
304
+ it "outputs string args with sample values" do
305
+ create "--repo" => :string, "--branch" => "bugfix", "-n" => 6
306
+ usage.should == %w([--branch=bugfix] [--repo=REPO] [-n=6])
307
+ end
308
+
309
+ it "outputs numeric args with 'N' as sample value" do
310
+ create "--iter" => :numeric
311
+ usage.should == ["[--iter=N]"]
312
+ end
313
+
314
+ it "outputs array args with sample value" do
315
+ create "--libs" => :array
316
+ usage.should == ["[--libs=A,B,C]"]
317
+ end
318
+
319
+ it "outputs hash args with sample value" do
320
+ create '--paths' => :hash
321
+ usage.should == ["[--paths=A:B,C:D]"]
322
+ end
323
+ end
324
+
325
+ describe "user defined option class" do
326
+ before_all {
327
+ ::FooBoo = Struct.new(:name)
328
+ module Options::FooBoo
329
+ def create_foo_boo(value)
330
+ ::FooBoo.new(value)
331
+ end
332
+ def validate_foo_boo(value); end
333
+ end
334
+ ::OptionParser.send :include, Options::FooBoo
335
+ create :a=>:foo_boo, :b=>::FooBoo.new('blah'), :c=>:blah_blah,
336
+ :d=>{:type=>:foo_boo, :type=>::FooBoo.new('bling')}
337
+ }
338
+
339
+ it "created from symbol" do
340
+ (obj = parse('-a', 'whoop')[:a]).class.should == ::FooBoo
341
+ obj.name.should == 'whoop'
342
+ end
343
+
344
+ it "created from default" do
345
+ (obj = parse[:b]).class.should == ::FooBoo
346
+ obj.name.should == 'blah'
347
+ end
348
+
349
+ it "created from type attribute" do
350
+ (obj = parse('-d', 'whoop')[:d]).class.should == ::FooBoo
351
+ obj.name.should == 'whoop'
352
+ end
353
+
354
+ it "has its validation called" do
355
+ opt.expects(:validate_foo_boo)
356
+ parse("-a", 'blah')
357
+ end
358
+
359
+ it "has default usage" do
360
+ usage[0].should == "[-a=:foo_boo]"
361
+ end
362
+
363
+ it "when nonexistant raises error" do
364
+ assert_error(OptionParser::Error, "invalid.*:blah_blah") { parse("-c", 'ok') }
365
+ end
366
+ end
367
+ end