boson 0.2.3 → 0.2.4
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.rdoc +76 -0
- data/README.rdoc +6 -6
- data/Rakefile +24 -41
- data/gemspec +19 -0
- data/lib/boson.rb +4 -4
- data/lib/boson/command.rb +2 -2
- data/lib/boson/commands/core.rb +1 -1
- data/lib/boson/commands/web_core.rb +16 -12
- data/lib/boson/manager.rb +1 -1
- data/lib/boson/pipes.rb +6 -2
- data/lib/boson/repo_index.rb +1 -1
- data/lib/boson/runner.rb +2 -2
- data/lib/boson/runners/bin_runner.rb +72 -29
- data/lib/boson/scientist.rb +22 -4
- data/lib/boson/util.rb +9 -1
- data/lib/boson/version.rb +3 -0
- data/test/argument_inspector_test.rb +47 -51
- data/test/bacon_extensions.rb +26 -0
- data/test/bin_runner_test.rb +160 -160
- data/test/comment_inspector_test.rb +87 -89
- data/test/file_library_test.rb +32 -34
- data/test/loader_test.rb +181 -182
- data/test/manager_test.rb +76 -78
- data/test/method_inspector_test.rb +51 -53
- data/test/option_parser_test.rb +49 -42
- data/test/options_test.rb +168 -168
- data/test/pipes_test.rb +48 -46
- data/test/repo_index_test.rb +117 -113
- data/test/repo_test.rb +17 -17
- data/test/runner_test.rb +31 -34
- data/test/scientist_test.rb +258 -254
- data/test/test_helper.rb +21 -38
- data/test/util_test.rb +40 -42
- metadata +55 -46
- data/VERSION.yml +0 -5
data/test/manager_test.rb
CHANGED
@@ -1,102 +1,100 @@
|
|
1
1
|
require File.join(File.dirname(__FILE__), 'test_helper')
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
end
|
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
|
12
11
|
|
13
|
-
|
12
|
+
before { reset_boson }
|
14
13
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
14
|
+
it "loads basic library" do
|
15
|
+
load_library :name=>'blah'
|
16
|
+
library_loaded? 'blah'
|
17
|
+
end
|
19
18
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
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
|
26
25
|
|
27
|
-
|
28
|
-
|
29
|
-
|
26
|
+
describe "command aliases" do
|
27
|
+
before { eval %[module ::Aquateen; def frylock; end; end] }
|
28
|
+
after { Object.send(:remove_const, "Aquateen") }
|
30
29
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
end
|
30
|
+
it "created with command specific config" do
|
31
|
+
with_config(:command_aliases=>{'frylock'=>'fr'}) do
|
32
|
+
Manager.expects(:create_instance_aliases).with({"Aquateen"=>{"frylock"=>"fr"}})
|
33
|
+
load_library :name=>'aquateen', :commands=>['frylock'], :module=>Aquateen
|
34
|
+
library_loaded? 'aquateen'
|
37
35
|
end
|
36
|
+
end
|
38
37
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
end
|
38
|
+
it "created with config command_aliases" do
|
39
|
+
with_config(:command_aliases=>{"frylock"=>"fr"}) do
|
40
|
+
Manager.expects(:create_instance_aliases).with({"Aquateen"=>{"frylock"=>"fr"}})
|
41
|
+
load_library :name=>'aquateen', :commands=>['frylock'], :module=>Aquateen
|
42
|
+
library_loaded? 'aquateen'
|
45
43
|
end
|
44
|
+
end
|
46
45
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
end
|
46
|
+
it "not created and warns for commands with no module" do
|
47
|
+
with_config(:command_aliases=>{'frylock'=>'fr'}) do
|
48
|
+
capture_stderr {
|
49
|
+
load_library(:name=>'aquateen', :commands=>['frylock'])
|
50
|
+
}.should =~ /No aliases/
|
51
|
+
library_loaded? 'aquateen'
|
52
|
+
Aquateen.method_defined?(:fr).should == false
|
55
53
|
end
|
56
54
|
end
|
55
|
+
end
|
57
56
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
end
|
57
|
+
it "merges with existing created library" do
|
58
|
+
create_library('blah')
|
59
|
+
load_library :name=>'blah'
|
60
|
+
library_loaded? 'blah'
|
61
|
+
Boson.libraries.size.should == 1
|
64
62
|
end
|
63
|
+
end
|
65
64
|
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
65
|
+
describe "option commands without args" do
|
66
|
+
before_all {
|
67
|
+
reset_boson
|
68
|
+
@library = Library.new(:name=>'blah', :commands=>['foo', 'bar'])
|
69
|
+
Boson.libraries << @library
|
70
|
+
@foo = Command.new(:name=>'foo', :lib=>'blah', :options=>{:fool=>:string}, :args=>'*')
|
71
|
+
Boson.commands << @foo
|
72
|
+
Boson.commands << Command.new(:name=>'bar', :lib=>'blah', :options=>{:bah=>:string})
|
73
|
+
}
|
75
74
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
75
|
+
it "are deleted" do
|
76
|
+
Scientist.expects(:redefine_command).with(anything, @foo)
|
77
|
+
Manager.redefine_commands(@library, @library.commands)
|
78
|
+
end
|
80
79
|
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
end
|
80
|
+
it "are deleted and printed when verbose" do
|
81
|
+
Scientist.expects(:redefine_command).with(anything, @foo)
|
82
|
+
@library.instance_eval("@options = {:verbose=>true}")
|
83
|
+
capture_stdout { Manager.redefine_commands(@library, @library.commands) } =~ /options.*blah/
|
86
84
|
end
|
85
|
+
end
|
87
86
|
|
88
|
-
|
89
|
-
|
87
|
+
describe "loaded" do
|
88
|
+
before { reset_libraries }
|
90
89
|
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
90
|
+
it "returns false when library isn't loaded" do
|
91
|
+
create_library('blah')
|
92
|
+
Manager.loaded?('blah').should == false
|
93
|
+
end
|
95
94
|
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
end
|
95
|
+
it "returns true when library is loaded" do
|
96
|
+
create_library('blah', :loaded=>true)
|
97
|
+
Manager.loaded?('blah').should == true
|
100
98
|
end
|
101
99
|
end
|
102
|
-
end
|
100
|
+
end
|
@@ -1,69 +1,67 @@
|
|
1
1
|
require File.join(File.dirname(__FILE__), 'test_helper')
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
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
|
+
describe "commands module with" do
|
15
|
+
def parse(string)
|
8
16
|
Inspector.enable
|
9
|
-
|
17
|
+
::Boson::Commands::Zzz.module_eval(string)
|
10
18
|
Inspector.disable
|
11
|
-
MethodInspector.store
|
12
|
-
MethodInspector.store[:options].empty?.should == true
|
19
|
+
MethodInspector.store
|
13
20
|
end
|
14
21
|
|
15
|
-
|
16
|
-
|
17
|
-
Inspector.enable
|
18
|
-
::Boson::Commands::Zzz.module_eval(string)
|
19
|
-
Inspector.disable
|
20
|
-
MethodInspector.store
|
21
|
-
end
|
22
|
-
|
23
|
-
before(:all) { eval "module ::Boson::Commands::Zzz; end" }
|
24
|
-
before(:each) { MethodInspector.mod_store.delete(::Boson::Commands::Zzz) }
|
22
|
+
before_all { eval "module ::Boson::Commands::Zzz; end" }
|
23
|
+
before { MethodInspector.mod_store.delete(::Boson::Commands::Zzz) }
|
25
24
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
25
|
+
it "desc sets descriptions" do
|
26
|
+
parsed = parse "desc 'test'; def m1; end; desc 'one'; desc 'more'; def m2; end"
|
27
|
+
parsed[:desc].should == {"m1"=>"test", "m2"=>"more"}
|
28
|
+
end
|
30
29
|
|
31
|
-
|
32
|
-
|
33
|
-
|
30
|
+
it "options sets options" do
|
31
|
+
parse("options :z=>'b'; def zee; end")[:options].should == {"zee"=>{:z=>'b'}}
|
32
|
+
end
|
34
33
|
|
35
|
-
|
36
|
-
|
37
|
-
|
34
|
+
it "render_options sets render_options" do
|
35
|
+
parse("render_options :z=>true; def zee; end")[:render_options].should == {"zee"=>{:z=>true}}
|
36
|
+
end
|
38
37
|
|
39
|
-
|
40
|
-
|
41
|
-
|
38
|
+
it "config sets config" do
|
39
|
+
parse("config :z=>true; def zee; end")[:config].should == {"zee"=>{:z=>true}}
|
40
|
+
end
|
42
41
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
42
|
+
it "not all method attributes set causes method_locations to be set" do
|
43
|
+
MethodInspector.stubs(:find_method_locations).returns(["/some/path", 10])
|
44
|
+
parsed = parse "desc 'yo'; def yo; end; options :yep=>1; def yep; end; " +
|
45
|
+
"render_options :a=>1; config :a=>1; desc 'z'; options :a=>1; def az; end"
|
46
|
+
parsed[:method_locations].key?('yo').should == true
|
47
|
+
parsed[:method_locations].key?('yep').should == true
|
48
|
+
parsed[:method_locations].key?('az').should == false
|
49
|
+
end
|
51
50
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
51
|
+
it "no find_method_locations doesn't set method_locations" do
|
52
|
+
MethodInspector.stubs(:find_method_locations).returns(nil)
|
53
|
+
parse("def bluh; end")[:method_locations].key?('bluh').should == false
|
54
|
+
end
|
56
55
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
56
|
+
it "options calls scrape_with_eval" do
|
57
|
+
ArgumentInspector.expects(:scrape_with_eval).returns([['arg1']])
|
58
|
+
parse("desc 'desc'; options :some=>:opts; def doy(arg1); end")[:args]['doy'].should == [['arg1']]
|
59
|
+
end
|
61
60
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
end
|
61
|
+
it "options in file calls scrape_with_eval" do
|
62
|
+
MethodInspector.expects(:inspector_in_file?).returns(true)
|
63
|
+
ArgumentInspector.expects(:scrape_with_eval).returns([['arg1']])
|
64
|
+
parse("desc 'desc'; def doz(arg1); end")[:args]['doz'].should == [['arg1']]
|
67
65
|
end
|
68
66
|
end
|
69
|
-
end
|
67
|
+
end
|
data/test/option_parser_test.rb
CHANGED
@@ -1,11 +1,19 @@
|
|
1
1
|
require File.join(File.dirname(__FILE__), 'test_helper')
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
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
|
6
14
|
|
7
|
-
|
8
|
-
before
|
15
|
+
describe "IndifferentAccessHash" do
|
16
|
+
before {
|
9
17
|
@hash = IndifferentAccessHash.new 'foo' => 'bar', 'baz' => 'bee'
|
10
18
|
}
|
11
19
|
it "can access values indifferently" do
|
@@ -31,7 +39,7 @@ module Boson
|
|
31
39
|
end
|
32
40
|
end
|
33
41
|
|
34
|
-
|
42
|
+
describe "naming" do
|
35
43
|
it "automatically aliases long options with their first letter" do
|
36
44
|
create "--foo" => true
|
37
45
|
parse("-f")["foo"].should == true
|
@@ -122,7 +130,7 @@ module Boson
|
|
122
130
|
|
123
131
|
end
|
124
132
|
|
125
|
-
|
133
|
+
describe "option values can be set with" do
|
126
134
|
it "a opt=<value> assignment" do
|
127
135
|
create :foo => :string
|
128
136
|
parse("--foo=12")["foo"].should == "12"
|
@@ -153,51 +161,51 @@ module Boson
|
|
153
161
|
end
|
154
162
|
end
|
155
163
|
|
156
|
-
|
164
|
+
describe "parse" do
|
157
165
|
it "extracts non-option arguments" do
|
158
166
|
create "--foo" => :string, "--bar" => true
|
159
167
|
parse("foo", "bar", "--baz", "--foo", "12", "--bar", "-T", "bang").should == {
|
160
168
|
:foo => "12", :bar => true
|
161
169
|
}
|
162
|
-
|
163
|
-
|
164
|
-
|
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"]
|
165
173
|
end
|
166
174
|
|
167
175
|
it "stopped by --" do
|
168
176
|
create :foo=>:boolean, :dude=>:boolean
|
169
177
|
parse("foo", "bar", "--", "-f").should == {}
|
170
|
-
|
171
|
-
|
178
|
+
opt.leading_non_opts.should == %w{foo bar}
|
179
|
+
opt.trailing_non_opts.should == %w{-- -f}
|
172
180
|
end
|
173
181
|
|
174
|
-
|
182
|
+
describe "with parse flag" do
|
175
183
|
it ":delete_invalid_opts deletes and warns of invalid options" do
|
176
184
|
create(:foo=>:boolean)
|
177
185
|
capture_stderr {
|
178
|
-
|
186
|
+
opt.parse(%w{-f -d ok}, :delete_invalid_opts=>true)
|
179
187
|
}.should =~ /Deleted invalid option '-d'/
|
180
|
-
|
188
|
+
opt.non_opts.should == ['ok']
|
181
189
|
end
|
182
190
|
|
183
191
|
it ":delete_invalid_opts deletes until - or --" do
|
184
192
|
create(:foo=>:boolean, :bar=>:boolean)
|
185
193
|
%w{- --}.each do |stop_char|
|
186
194
|
capture_stderr {
|
187
|
-
|
195
|
+
opt.parse(%w{ok -b -d} << stop_char << '-f', :delete_invalid_opts=>true)
|
188
196
|
}.should =~ /'-d'/
|
189
|
-
|
197
|
+
opt.non_opts.should == %w{ok -d} << stop_char << '-f'
|
190
198
|
end
|
191
199
|
end
|
192
200
|
|
193
201
|
it ":opts_before_args only allows options before args" do
|
194
202
|
create(:foo=>:boolean)
|
195
|
-
|
196
|
-
|
203
|
+
opt.parse(%w{ok -f}, :opts_before_args=>true).should == {}
|
204
|
+
opt.parse(%w{-f ok}, :opts_before_args=>true).should == {:foo=>true}
|
197
205
|
end
|
198
206
|
end
|
199
207
|
|
200
|
-
|
208
|
+
describe "with no arguments" do
|
201
209
|
it "and no options returns an empty hash" do
|
202
210
|
create({})
|
203
211
|
parse.should == {}
|
@@ -210,7 +218,7 @@ module Boson
|
|
210
218
|
end
|
211
219
|
end
|
212
220
|
|
213
|
-
|
221
|
+
describe "option hashes" do
|
214
222
|
it "make hash keys available as symbols as well" do
|
215
223
|
create "--foo" => :string
|
216
224
|
parse("--foo", "12")[:foo].should == "12"
|
@@ -224,8 +232,8 @@ module Boson
|
|
224
232
|
end
|
225
233
|
end
|
226
234
|
|
227
|
-
|
228
|
-
|
235
|
+
describe ":required option attribute" do
|
236
|
+
before_all {
|
229
237
|
create "--foo" => {:type=>:string, :required=>true}, :bar => {:type=>:hash, :required=>true}
|
230
238
|
}
|
231
239
|
|
@@ -242,8 +250,8 @@ module Boson
|
|
242
250
|
end
|
243
251
|
end
|
244
252
|
|
245
|
-
|
246
|
-
|
253
|
+
describe ":bool_default option attribute" do
|
254
|
+
before_all {
|
247
255
|
create :foo=>{:type=>:string, :bool_default=>'whoop'}, :bar=>{:type=>:array, :bool_default=>'1'},
|
248
256
|
:verbose=>:boolean, :yep=>{:type=>:string, :bool_default=>true}
|
249
257
|
}
|
@@ -270,10 +278,10 @@ module Boson
|
|
270
278
|
end
|
271
279
|
end
|
272
280
|
|
273
|
-
|
281
|
+
describe "option with attributes" do
|
274
282
|
it "can get type from :type" do
|
275
283
|
create :foo=>{:type=>:numeric}
|
276
|
-
parse("-f", '3')[:foo] == 3
|
284
|
+
parse("-f", '3')[:foo].should == 3
|
277
285
|
end
|
278
286
|
|
279
287
|
it "can get type and default from :default" do
|
@@ -289,10 +297,10 @@ module Boson
|
|
289
297
|
end
|
290
298
|
|
291
299
|
def usage
|
292
|
-
|
300
|
+
opt.formatted_usage.split(" ").sort
|
293
301
|
end
|
294
302
|
|
295
|
-
|
303
|
+
describe "#formatted_usage" do
|
296
304
|
it "outputs string args with sample values" do
|
297
305
|
create "--repo" => :string, "--branch" => "bugfix", "-n" => 6
|
298
306
|
usage.should == %w([--branch=bugfix] [--repo=REPO] [-n=6])
|
@@ -314,47 +322,46 @@ module Boson
|
|
314
322
|
end
|
315
323
|
end
|
316
324
|
|
317
|
-
|
318
|
-
|
325
|
+
describe "user defined option class" do
|
326
|
+
before_all {
|
319
327
|
::FooBoo = Struct.new(:name)
|
320
|
-
module
|
328
|
+
module Options::FooBoo
|
321
329
|
def create_foo_boo(value)
|
322
330
|
::FooBoo.new(value)
|
323
331
|
end
|
324
332
|
def validate_foo_boo(value); end
|
325
333
|
end
|
326
|
-
::
|
334
|
+
::OptionParser.send :include, Options::FooBoo
|
327
335
|
create :a=>:foo_boo, :b=>::FooBoo.new('blah'), :c=>:blah_blah,
|
328
336
|
:d=>{:type=>:foo_boo, :type=>::FooBoo.new('bling')}
|
329
337
|
}
|
330
338
|
|
331
|
-
|
339
|
+
it "created from symbol" do
|
332
340
|
(obj = parse('-a', 'whoop')[:a]).class.should == ::FooBoo
|
333
341
|
obj.name.should == 'whoop'
|
334
342
|
end
|
335
343
|
|
336
|
-
|
344
|
+
it "created from default" do
|
337
345
|
(obj = parse[:b]).class.should == ::FooBoo
|
338
346
|
obj.name.should == 'blah'
|
339
347
|
end
|
340
348
|
|
341
|
-
|
349
|
+
it "created from type attribute" do
|
342
350
|
(obj = parse('-d', 'whoop')[:d]).class.should == ::FooBoo
|
343
351
|
obj.name.should == 'whoop'
|
344
352
|
end
|
345
353
|
|
346
|
-
|
347
|
-
|
354
|
+
it "has its validation called" do
|
355
|
+
opt.expects(:validate_foo_boo)
|
348
356
|
parse("-a", 'blah')
|
349
357
|
end
|
350
358
|
|
351
|
-
|
359
|
+
it "has default usage" do
|
352
360
|
usage[0].should == "[-a=:foo_boo]"
|
353
361
|
end
|
354
362
|
|
355
|
-
|
363
|
+
it "when nonexistant raises error" do
|
356
364
|
assert_error(OptionParser::Error, "invalid.*:blah_blah") { parse("-c", 'ok') }
|
357
365
|
end
|
358
366
|
end
|
359
|
-
end
|
360
367
|
end
|