boson 0.2.2 → 0.2.3

Sign up to get free protection for your applications and to get access to all the features.
data/lib/boson/util.rb CHANGED
@@ -15,7 +15,7 @@ module Boson
15
15
  # From Rails ActiveSupport, does the reverse of underscore:
16
16
  # 'boson/method_inspector' -> 'Boson::MethodInspector'
17
17
  def camelize(string)
18
- string.to_s.gsub(/\/(.?)/) { "::#{$1.upcase}" }.gsub(/(?:^|_)(.)/) { $1.upcase }
18
+ Hirb::Util.camelize(string)
19
19
  end
20
20
 
21
21
  # Converts a module/class string to the actual constant.
@@ -27,16 +27,7 @@ module Boson
27
27
  # Returns a constant like const_get() no matter what namespace it's nested in.
28
28
  # Returns nil if the constant is not found.
29
29
  def any_const_get(name)
30
- return name if name.is_a?(Module)
31
- begin
32
- klass = Object
33
- name.split('::').each {|e|
34
- klass = klass.const_get(e)
35
- }
36
- klass
37
- rescue
38
- nil
39
- end
30
+ Hirb::Util.any_const_get(name)
40
31
  end
41
32
 
42
33
  # Detects new object/kernel methods, gems and modules created within a block.
@@ -62,6 +53,7 @@ module Boson
62
53
  def safe_require(lib)
63
54
  begin
64
55
  require lib
56
+ true
65
57
  rescue LoadError
66
58
  false
67
59
  end
@@ -102,11 +94,7 @@ module Boson
102
94
 
103
95
  # From Rubygems, determine a user's home.
104
96
  def find_home
105
- ['HOME', 'USERPROFILE'].each {|e| return ENV[e] if ENV[e] }
106
- return "#{ENV['HOMEDRIVE']}#{ENV['HOMEPATH']}" if ENV['HOMEDRIVE'] && ENV['HOMEPATH']
107
- File.expand_path("~")
108
- rescue
109
- File::ALT_SEPARATOR ? "C:/" : "/"
97
+ Hirb::Util.find_home
110
98
  end
111
99
 
112
100
  # Returns name of top level class that conflicts if it exists. For example, for base module Boson::Commands,
@@ -114,5 +102,20 @@ module Boson
114
102
  def top_level_class_conflict(base_module, conflicting_module)
115
103
  (conflicting_module =~ /^#{base_module}.*::([^:]+)/) && Object.const_defined?($1) && $1
116
104
  end
105
+
106
+ # Regular expression search of a list with underscore anchoring of words.
107
+ # For example 'some_dang_long_word' can be specified as 's_d_l_w'.
108
+ def underscore_search(input, list, first_match=false)
109
+ meth = first_match ? :find : :select
110
+ return (first_match ? input : [input]) if list.include?(input)
111
+ input = input.to_s
112
+ if input.include?("_")
113
+ underscore_regex = input.split('_').map {|e| Regexp.escape(e) }.join("([^_]+)?_")
114
+ list.send(meth) {|e| e.to_s =~ /^#{underscore_regex}/ }
115
+ else
116
+ escaped_input = Regexp.escape(input)
117
+ list.send(meth) {|e| e.to_s =~ /^#{escaped_input}/ }
118
+ end
119
+ end
117
120
  end
118
121
  end
data/lib/boson/view.rb CHANGED
@@ -51,7 +51,10 @@ module Boson
51
51
 
52
52
  # Enables hirb and reads a config file from the main repo's config/hirb.yml.
53
53
  def enable
54
- Hirb::View.enable(:config_file=>File.join(Boson.repo.config_dir, 'hirb.yml')) unless @enabled
54
+ unless @enabled
55
+ Hirb::View.enable(:config_file=>File.join(Boson.repo.config_dir, 'hirb.yml'))
56
+ Hirb::Helpers::Table.filter_any = true
57
+ end
55
58
  @enabled = true
56
59
  end
57
60
 
@@ -31,7 +31,7 @@ module Boson
31
31
  Inspector.enable
32
32
  ::Boson::Commands::Aaa.module_eval(string)
33
33
  Inspector.disable
34
- MethodInspector.store[:method_args]['blah']
34
+ MethodInspector.store[:args]['blah']
35
35
  end
36
36
 
37
37
  before(:all) { eval "module ::Boson::Commands::Aaa; end"; }
@@ -56,13 +56,13 @@ module Boson
56
56
 
57
57
  test "options calls scrape_with_eval" do
58
58
  ArgumentInspector.expects(:scrape_with_eval).returns([['arg1']])
59
- parse("desc 'desc'; options :some=>:opts; def doy(arg1); end")[:method_args]['doy'].should == [['arg1']]
59
+ parse("desc 'desc'; options :some=>:opts; def doy(arg1); end")[:args]['doy'].should == [['arg1']]
60
60
  end
61
61
 
62
62
  test "options in file calls scrape_with_eval" do
63
63
  MethodInspector.expects(:inspector_in_file?).returns(true)
64
64
  ArgumentInspector.expects(:scrape_with_eval).returns([['arg1']])
65
- parse("desc 'desc'; def doz(arg1); end")[:method_args]['doz'].should == [['arg1']]
65
+ parse("desc 'desc'; def doz(arg1); end")[:args]['doz'].should == [['arg1']]
66
66
  end
67
67
  end
68
68
  end
@@ -2,15 +2,8 @@ require File.join(File.dirname(__FILE__), 'test_helper')
2
2
 
3
3
  module Boson
4
4
  class OptionParserTest < Test::Unit::TestCase
5
- def create(opts)
6
- @opt = OptionParser.new(opts)
7
- end
8
-
9
- def parse(*args)
10
- @non_opts = []
11
- @opt.parse(args.flatten)
12
- end
13
-
5
+ include OptionTestHelper
6
+
14
7
  context "IndifferentAccessHash" do
15
8
  before(:each) {
16
9
  @hash = IndifferentAccessHash.new 'foo' => 'bar', 'baz' => 'bee'
@@ -277,187 +270,6 @@ module Boson
277
270
  end
278
271
  end
279
272
 
280
- context ":string type" do
281
- before :each do
282
- create "--foo" => :string, "--bar" => :string, :blah=>{:type=>:string, :default=>:huh}
283
- end
284
-
285
- it "doesn't set nonexistant options" do
286
- parse("--bling")[:bar].should == nil
287
- end
288
-
289
- it "sets values correctly" do
290
- parse("--foo", "12")[:foo].should == "12"
291
- parse("--bar", "12")[:bar].should == "12"
292
- end
293
-
294
- it "raises error if passed another valid option" do
295
- assert_error(OptionParser::Error, "cannot pass.*'foo'") { parse("--foo", "--bar") }
296
- end
297
-
298
- it "raises error if not passed a value" do
299
- assert_error(OptionParser::Error, "no value.*'foo'") { parse("--foo") }
300
- end
301
-
302
- it "overwrites earlier values with later values" do
303
- parse("--foo", "12", "--foo", "13")[:foo].should == "13"
304
- end
305
-
306
- it "can have symbolic default value" do
307
- parse('--blah','ok')[:blah].should == 'ok'
308
- end
309
- end
310
-
311
- context ":string type with :values attribute" do
312
- before(:all ) { create :foo=>{:type=>:string, :values=>%w{angola abu abib}} }
313
- it "auto aliases if a match exists" do
314
- parse("-f", "an")[:foo].should == 'angola'
315
- end
316
-
317
- it "auto aliases first sorted match" do
318
- parse("-f", "a")[:foo].should == 'abib'
319
- end
320
-
321
- it "raises error if option doesn't auto alias or match given values" do
322
- assert_error(OptionParser::Error, "invalid.*'z'") { parse("-f", "z") }
323
- end
324
-
325
- it "doesn't raise error for a nonmatch if enum is false" do
326
- create :foo=>{:type=>:string, :values=>%w{angola abu abib}, :enum=>false}
327
- parse("-f", "z")[:foo].should == 'z'
328
- end
329
- end
330
-
331
- context ":string type with default value" do
332
- before(:each) do
333
- create "--branch" => "master"
334
- end
335
-
336
- it "should get the specified value" do
337
- parse("--branch", "bugfix").should == { :branch => "bugfix" }
338
- end
339
-
340
- it "should get the default value when not specified" do
341
- parse.should == { :branch => "master" }
342
- end
343
- end
344
-
345
- context ":numeric type" do
346
- before(:each) do
347
- create "n" => :numeric, "m" => 5
348
- end
349
-
350
- it "supports numeric defaults" do
351
- parse["m"].should == 5
352
- end
353
-
354
- it "converts values to numeric types" do
355
- parse("-n", "3", "-m", ".5").should == {:n => 3, :m => 0.5}
356
- end
357
-
358
- it "raises error when value isn't numeric" do
359
- assert_error(OptionParser::Error, "expected numeric value for.*'n'") { parse("-n", "foo") }
360
- end
361
-
362
- it "raises error when opt is present without value" do
363
- assert_error(OptionParser::Error, "no value.*'n'") { parse("-n") }
364
- end
365
- end
366
-
367
- context ":array type" do
368
- before(:all) {
369
- create :a=>:array, :b=>[1,2,3], :c=>{:type=>:array, :values=>%w{foo fa bar zebra}, :enum=>false},
370
- :d=>{:type=>:array, :split=>" ", :values=>[:ab, :bc, :cd], :enum=>false},
371
- :e=>{:type=>:array, :values=>%w{some so silly}, :regexp=>true}
372
- }
373
-
374
- it "supports array defaults" do
375
- parse[:b].should == [1,2,3]
376
- end
377
-
378
- it "converts comma delimited values to an array" do
379
- parse("-a","1,2,5")[:a].should == %w{1 2 5}
380
- end
381
-
382
- it "raises error when option has no value" do
383
- assert_error(OptionParser::Error, "no value.*'a'") { parse("-a") }
384
- end
385
-
386
- it "auto aliases :values attribute" do
387
- parse("-c","f,b")[:c].should == %w{fa bar}
388
- end
389
-
390
- it "auto aliases symbolic :values" do
391
- parse("-d","a c")[:d].should == [:ab,:cd]
392
- end
393
-
394
- it "supports a configurable splitter" do
395
- parse("-d", "yogi berra")[:d].should == %w{yogi berra}
396
- end
397
-
398
- it "aliases * to all values" do
399
- parse("-c", '*')[:c].sort.should == %w{bar fa foo zebra}
400
- parse("-c", '*,ok')[:c].sort.should == %w{bar fa foo ok zebra}
401
- end
402
-
403
- it "aliases correctly with :regexp on" do
404
- parse("-e", 'so')[:e].sort.should == %w{so some}
405
- end
406
- end
407
-
408
- context ":hash type" do
409
- before(:all) {
410
- create :a=>:hash, :b=>{:default=>{:a=>'b'}}, :c=>{:type=>:hash, :keys=>%w{one two three}},
411
- :e=>{:type=>:hash, :keys=>[:one, :two, :three], :default_keys=>:three},
412
- :d=>{:type=>:hash, :split=>" "}
413
- }
414
-
415
- it "converts comma delimited pairs to hash" do
416
- parse("-a", "f:3,g:4")[:a].should == {'f'=>'3', 'g'=>'4'}
417
- end
418
-
419
- it "supports hash defaults" do
420
- parse[:b].should == {:a=>'b'}
421
- end
422
-
423
- it "raises error when option has no value" do
424
- assert_error(OptionParser::Error, "no value.*'a'") { parse("-a") }
425
- end
426
-
427
- it "raises error if invalid key-value pair given for unknown keys" do
428
- assert_error(OptionParser::Error, "invalid.*pair.*'a'") { parse("-a", 'b') }
429
- end
430
-
431
- it "auto aliases :keys attribute" do
432
- parse("-c","t:3,o:1")[:c].should == {'three'=>'3', 'one'=>'1'}
433
- end
434
-
435
- it "adds in explicit default keys with value only argument" do
436
- parse('-e', 'whoop')[:e].should == {:three=>'whoop'}
437
- end
438
-
439
- it "adds in default keys from known :keys with value only argument" do
440
- parse("-c","okay")[:c].should == {'one'=>'okay'}
441
- end
442
-
443
- it "auto aliases symbolic :keys" do
444
- parse("-e","t:3,o:1")[:e].should == {:three=>'3', :one=>'1'}
445
- end
446
-
447
- it "supports a configurable splitter" do
448
- parse("-d","a:ab b:bc")[:d].should == {'a'=>'ab', 'b'=>'bc'}
449
- end
450
-
451
- it "supports grouping keys" do
452
- parse("-c", "t,tw:foo,o:bar")[:c].should == {'three'=>'foo','two'=>'foo', 'one'=>'bar'}
453
- end
454
-
455
- it "aliases * to all keys" do
456
- parse("-c", "*:foo")[:c].should == {'three'=>'foo', 'two'=>'foo', 'one'=>'foo'}
457
- parse('-a', '*:foo')[:a].should == {'*'=>'foo'}
458
- end
459
- end
460
-
461
273
  context "option with attributes" do
462
274
  it "can get type from :type" do
463
275
  create :foo=>{:type=>:numeric}
@@ -0,0 +1,189 @@
1
+ require File.join(File.dirname(__FILE__), 'test_helper')
2
+
3
+ module Boson
4
+ class OptionsTest < Test::Unit::TestCase
5
+ include OptionTestHelper
6
+
7
+ context ":string type" do
8
+ before :each do
9
+ create "--foo" => :string, "--bar" => :string, :blah=>{:type=>:string, :default=>:huh}
10
+ end
11
+
12
+ it "doesn't set nonexistant options" do
13
+ parse("--bling")[:bar].should == nil
14
+ end
15
+
16
+ it "sets values correctly" do
17
+ parse("--foo", "12")[:foo].should == "12"
18
+ parse("--bar", "12")[:bar].should == "12"
19
+ end
20
+
21
+ it "raises error if passed another valid option" do
22
+ assert_error(OptionParser::Error, "cannot pass.*'foo'") { parse("--foo", "--bar") }
23
+ end
24
+
25
+ it "raises error if not passed a value" do
26
+ assert_error(OptionParser::Error, "no value.*'foo'") { parse("--foo") }
27
+ end
28
+
29
+ it "overwrites earlier values with later values" do
30
+ parse("--foo", "12", "--foo", "13")[:foo].should == "13"
31
+ end
32
+
33
+ it "can have symbolic default value" do
34
+ parse('--blah','ok')[:blah].should == 'ok'
35
+ end
36
+ end
37
+
38
+ context ":string type with :values attribute" do
39
+ before(:all ) { create :foo=>{:type=>:string, :values=>%w{angola abu abib}} }
40
+ it "auto aliases if a match exists" do
41
+ parse("-f", "an")[:foo].should == 'angola'
42
+ end
43
+
44
+ it "auto aliases first sorted match" do
45
+ parse("-f", "a")[:foo].should == 'abib'
46
+ end
47
+
48
+ it "raises error if option doesn't auto alias or match given values" do
49
+ assert_error(OptionParser::Error, "invalid.*'z'") { parse("-f", "z") }
50
+ end
51
+
52
+ it "doesn't raise error for a nonmatch if enum is false" do
53
+ create :foo=>{:type=>:string, :values=>%w{angola abu abib}, :enum=>false}
54
+ parse("-f", "z")[:foo].should == 'z'
55
+ end
56
+ end
57
+
58
+ context ":string type with default value" do
59
+ before(:each) do
60
+ create "--branch" => "master"
61
+ end
62
+
63
+ it "should get the specified value" do
64
+ parse("--branch", "bugfix").should == { :branch => "bugfix" }
65
+ end
66
+
67
+ it "should get the default value when not specified" do
68
+ parse.should == { :branch => "master" }
69
+ end
70
+ end
71
+
72
+ context ":numeric type" do
73
+ before(:each) do
74
+ create "n" => :numeric, "m" => 5
75
+ end
76
+
77
+ it "supports numeric defaults" do
78
+ parse["m"].should == 5
79
+ end
80
+
81
+ it "converts values to numeric types" do
82
+ parse("-n", "3", "-m", ".5").should == {:n => 3, :m => 0.5}
83
+ end
84
+
85
+ it "raises error when value isn't numeric" do
86
+ assert_error(OptionParser::Error, "expected numeric value for.*'n'") { parse("-n", "foo") }
87
+ end
88
+
89
+ it "raises error when opt is present without value" do
90
+ assert_error(OptionParser::Error, "no value.*'n'") { parse("-n") }
91
+ end
92
+ end
93
+
94
+ context ":array type" do
95
+ before(:all) {
96
+ create :a=>:array, :b=>[1,2,3], :c=>{:type=>:array, :values=>%w{foo fa bar zebra}, :enum=>false},
97
+ :d=>{:type=>:array, :split=>" ", :values=>[:ab, :bc, :cd], :enum=>false},
98
+ :e=>{:type=>:array, :values=>%w{some so silly}, :regexp=>true}
99
+ }
100
+
101
+ it "supports array defaults" do
102
+ parse[:b].should == [1,2,3]
103
+ end
104
+
105
+ it "converts comma delimited values to an array" do
106
+ parse("-a","1,2,5")[:a].should == %w{1 2 5}
107
+ end
108
+
109
+ it "raises error when option has no value" do
110
+ assert_error(OptionParser::Error, "no value.*'a'") { parse("-a") }
111
+ end
112
+
113
+ it "auto aliases :values attribute" do
114
+ parse("-c","f,b")[:c].should == %w{fa bar}
115
+ end
116
+
117
+ it "auto aliases symbolic :values" do
118
+ parse("-d","a c")[:d].should == [:ab,:cd]
119
+ end
120
+
121
+ it "supports a configurable splitter" do
122
+ parse("-d", "yogi berra")[:d].should == %w{yogi berra}
123
+ end
124
+
125
+ it "aliases * to all values" do
126
+ parse("-c", '*')[:c].sort.should == %w{bar fa foo zebra}
127
+ parse("-c", '*,ok')[:c].sort.should == %w{bar fa foo ok zebra}
128
+ end
129
+
130
+ it "aliases correctly with :regexp on" do
131
+ parse("-e", 'so')[:e].sort.should == %w{so some}
132
+ end
133
+ end
134
+
135
+ context ":hash type" do
136
+ before(:all) {
137
+ create :a=>:hash, :b=>{:default=>{:a=>'b'}}, :c=>{:type=>:hash, :keys=>%w{one two three}},
138
+ :e=>{:type=>:hash, :keys=>[:one, :two, :three], :default_keys=>:three},
139
+ :d=>{:type=>:hash, :split=>" "}
140
+ }
141
+
142
+ it "converts comma delimited pairs to hash" do
143
+ parse("-a", "f:3,g:4")[:a].should == {'f'=>'3', 'g'=>'4'}
144
+ end
145
+
146
+ it "supports hash defaults" do
147
+ parse[:b].should == {:a=>'b'}
148
+ end
149
+
150
+ it "raises error when option has no value" do
151
+ assert_error(OptionParser::Error, "no value.*'a'") { parse("-a") }
152
+ end
153
+
154
+ it "raises error if invalid key-value pair given for unknown keys" do
155
+ assert_error(OptionParser::Error, "invalid.*pair.*'a'") { parse("-a", 'b') }
156
+ end
157
+
158
+ it "auto aliases :keys attribute" do
159
+ parse("-c","t:3,o:1")[:c].should == {'three'=>'3', 'one'=>'1'}
160
+ end
161
+
162
+ it "adds in explicit default keys with value only argument" do
163
+ parse('-e', 'whoop')[:e].should == {:three=>'whoop'}
164
+ end
165
+
166
+ it "adds in default keys from known :keys with value only argument" do
167
+ parse("-c","okay")[:c].should == {'one'=>'okay'}
168
+ end
169
+
170
+ it "auto aliases symbolic :keys" do
171
+ parse("-e","t:3,o:1")[:e].should == {:three=>'3', :one=>'1'}
172
+ end
173
+
174
+ it "supports a configurable splitter" do
175
+ parse("-d","a:ab b:bc")[:d].should == {'a'=>'ab', 'b'=>'bc'}
176
+ end
177
+
178
+ it "supports grouping keys" do
179
+ parse("-c", "t,tw:foo,o:bar")[:c].should == {'three'=>'foo','two'=>'foo', 'one'=>'bar'}
180
+ end
181
+
182
+ it "aliases * to all keys" do
183
+ parse("-c", "*:foo")[:c].should == {'three'=>'foo', 'two'=>'foo', 'one'=>'foo'}
184
+ parse('-a', '*:foo')[:a].should == {'*'=>'foo'}
185
+ end
186
+ end
187
+
188
+ end
189
+ end