bosonson 0.304.1
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/CHANGELOG.rdoc +108 -0
- data/LICENSE.txt +22 -0
- data/README.rdoc +181 -0
- data/bin/bss +6 -0
- data/bosonson.gemspec +24 -0
- data/deps.rip +2 -0
- data/lib/boson.rb +96 -0
- data/lib/boson/command.rb +196 -0
- data/lib/boson/commands.rb +7 -0
- data/lib/boson/commands/core.rb +77 -0
- data/lib/boson/commands/web_core.rb +153 -0
- data/lib/boson/index.rb +48 -0
- data/lib/boson/inspector.rb +120 -0
- data/lib/boson/inspectors/argument_inspector.rb +97 -0
- data/lib/boson/inspectors/comment_inspector.rb +100 -0
- data/lib/boson/inspectors/method_inspector.rb +98 -0
- data/lib/boson/libraries/file_library.rb +144 -0
- data/lib/boson/libraries/gem_library.rb +30 -0
- data/lib/boson/libraries/local_file_library.rb +30 -0
- data/lib/boson/libraries/module_library.rb +37 -0
- data/lib/boson/libraries/require_library.rb +23 -0
- data/lib/boson/library.rb +179 -0
- data/lib/boson/loader.rb +118 -0
- data/lib/boson/manager.rb +169 -0
- data/lib/boson/namespace.rb +31 -0
- data/lib/boson/option_command.rb +222 -0
- data/lib/boson/option_parser.rb +475 -0
- data/lib/boson/options.rb +146 -0
- data/lib/boson/pipe.rb +147 -0
- data/lib/boson/pipes.rb +75 -0
- data/lib/boson/repo.rb +107 -0
- data/lib/boson/repo_index.rb +124 -0
- data/lib/boson/runner.rb +81 -0
- data/lib/boson/runners/bin_runner.rb +208 -0
- data/lib/boson/runners/console_runner.rb +58 -0
- data/lib/boson/scientist.rb +182 -0
- data/lib/boson/util.rb +129 -0
- data/lib/boson/version.rb +3 -0
- data/lib/boson/view.rb +95 -0
- data/test/argument_inspector_test.rb +62 -0
- data/test/bin_runner_test.rb +223 -0
- data/test/command_test.rb +22 -0
- data/test/commands_test.rb +22 -0
- data/test/comment_inspector_test.rb +126 -0
- data/test/deps.rip +4 -0
- data/test/file_library_test.rb +42 -0
- data/test/loader_test.rb +235 -0
- data/test/manager_test.rb +114 -0
- data/test/method_inspector_test.rb +90 -0
- data/test/option_parser_test.rb +367 -0
- data/test/options_test.rb +189 -0
- data/test/pipes_test.rb +65 -0
- data/test/repo_index_test.rb +122 -0
- data/test/repo_test.rb +23 -0
- data/test/runner_test.rb +40 -0
- data/test/scientist_test.rb +341 -0
- data/test/test_helper.rb +130 -0
- data/test/util_test.rb +56 -0
- data/vendor/bundle/gems/bacon-bits-0.1.0/deps.rip +1 -0
- data/vendor/bundle/gems/hirb-0.6.0/test/deps.rip +4 -0
- 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
|