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,223 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'test_helper')
|
2
|
+
require 'boson/runners/bin_runner'
|
3
|
+
BinRunner = Boson::BinRunner
|
4
|
+
|
5
|
+
describe "BinRunner" do
|
6
|
+
def start(*args)
|
7
|
+
Hirb.stubs(:enable)
|
8
|
+
BinRunner.start(args)
|
9
|
+
end
|
10
|
+
|
11
|
+
before {|e|
|
12
|
+
BinRunner.instance_variables.each {|e| BinRunner.instance_variable_set(e, nil)}
|
13
|
+
}
|
14
|
+
describe "at commandline" do
|
15
|
+
before_all { reset }
|
16
|
+
|
17
|
+
it "no arguments prints usage" do
|
18
|
+
capture_stdout { start }.should =~ /^boson/
|
19
|
+
end
|
20
|
+
|
21
|
+
it "invalid option value prints error" do
|
22
|
+
aborts_with(/Error: no value/) { start("-l") }
|
23
|
+
end
|
24
|
+
|
25
|
+
it "help option but no arguments prints usage" do
|
26
|
+
capture_stdout { start '-h' }.should =~ /^boson/
|
27
|
+
end
|
28
|
+
|
29
|
+
it "help option and command prints help" do
|
30
|
+
capture_stdout { start('-h', 'commands') }.should =~ /^commands/
|
31
|
+
end
|
32
|
+
|
33
|
+
it "load option loads libraries" do
|
34
|
+
Manager.expects(:load).with {|*args| args[0][0].is_a?(Module) ? true : args[0][0] == 'blah'}.times(2)
|
35
|
+
BinRunner.stubs(:execute_command)
|
36
|
+
start('-l', 'blah', 'libraries')
|
37
|
+
end
|
38
|
+
|
39
|
+
it "console option starts irb" do
|
40
|
+
ConsoleRunner.expects(:start)
|
41
|
+
Util.expects(:which).returns("/usr/bin/irb")
|
42
|
+
ConsoleRunner.expects(:load_repl).with("/usr/bin/irb")
|
43
|
+
start("--console")
|
44
|
+
end
|
45
|
+
|
46
|
+
it "console option but no irb found prints error" do
|
47
|
+
ConsoleRunner.expects(:start)
|
48
|
+
Util.expects(:which).returns(nil)
|
49
|
+
ConsoleRunner.expects(:abort).with {|arg| arg[/Console not found/] }
|
50
|
+
start '--console'
|
51
|
+
end
|
52
|
+
|
53
|
+
it "execute option executes string" do
|
54
|
+
BinRunner.expects(:define_autoloader)
|
55
|
+
capture_stdout { start("-e", "p 1 + 1") }.should == "2\n"
|
56
|
+
end
|
57
|
+
|
58
|
+
it "global option takes value with whitespace" do
|
59
|
+
View.expects(:render).with {|*args| args[1][:fields] = %w{f1 f2} }
|
60
|
+
start('commands', '-f', 'f1, f2')
|
61
|
+
end
|
62
|
+
|
63
|
+
it "debug option sets Runner.debug" do
|
64
|
+
View.expects(:render)
|
65
|
+
start('-d', 'commands')
|
66
|
+
Runner.debug.should == true
|
67
|
+
Runner.debug = nil
|
68
|
+
end
|
69
|
+
|
70
|
+
it "ruby_debug option sets $DEBUG" do
|
71
|
+
View.expects(:render)
|
72
|
+
start('-D', 'commands')
|
73
|
+
$DEBUG.should == true
|
74
|
+
$DEBUG = nil
|
75
|
+
end
|
76
|
+
|
77
|
+
it "execute option errors are caught" do
|
78
|
+
aborts_with(/^Error:/) { start("-e", "raise 'blah'") }
|
79
|
+
end
|
80
|
+
|
81
|
+
it "option command and too many arguments prints error" do
|
82
|
+
capture_stdout {
|
83
|
+
aborts_with(/'commands'.*incorrect/) { start('commands','1','2','3') }
|
84
|
+
}
|
85
|
+
end
|
86
|
+
|
87
|
+
it "normal command and too many arguments prints error" do
|
88
|
+
capture_stdout {
|
89
|
+
aborts_with(/'render'.*incorrect/) { start('render') }
|
90
|
+
}
|
91
|
+
end
|
92
|
+
|
93
|
+
it "failed subcommand prints error and not command not found" do
|
94
|
+
BinRunner.expects(:execute_command).raises("bling")
|
95
|
+
aborts_with(/Error: bling/) { start("commands.to_s") }
|
96
|
+
end
|
97
|
+
|
98
|
+
it "nonexistant subcommand prints command not found" do
|
99
|
+
aborts_with(/'to_s.bling' not found/) { start("to_s.bling") }
|
100
|
+
end
|
101
|
+
|
102
|
+
it "undiscovered command prints error" do
|
103
|
+
BinRunner.expects(:autoload_command).returns(false)
|
104
|
+
aborts_with(/Error.*not found/) { start 'blah' }
|
105
|
+
end
|
106
|
+
|
107
|
+
it "with backtrace option prints backtrace" do
|
108
|
+
BinRunner.expects(:autoload_command).returns(false)
|
109
|
+
aborts_with(/not found\nOriginal.*runner\.rb:/m) { start("--backtrace", "blah") }
|
110
|
+
end
|
111
|
+
|
112
|
+
it "basic command executes" do
|
113
|
+
BinRunner.expects(:init).returns(true)
|
114
|
+
BinRunner.stubs(:render_output)
|
115
|
+
Boson.main_object.expects(:send).with('kick','it')
|
116
|
+
start 'kick','it'
|
117
|
+
end
|
118
|
+
|
119
|
+
it "sub command executes" do
|
120
|
+
obj = Object.new
|
121
|
+
Boson.main_object.extend Module.new { def phone; Struct.new(:home).new('done'); end }
|
122
|
+
BinRunner.expects(:init).returns(true)
|
123
|
+
BinRunner.expects(:render_output).with('done')
|
124
|
+
start 'phone.home'
|
125
|
+
end
|
126
|
+
|
127
|
+
it "bin_defaults config loads by default" do
|
128
|
+
defaults = Runner.default_libraries + ['yo']
|
129
|
+
with_config(:bin_defaults=>['yo']) do
|
130
|
+
Manager.expects(:load).with {|*args| args[0] == defaults }
|
131
|
+
aborts_with(/blah/) { start 'blah' }
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
describe "autoload_command" do
|
137
|
+
def index(options={})
|
138
|
+
Manager.expects(:load).with {|*args| args[0][0].is_a?(Module) ? true : args[0] == options[:load]
|
139
|
+
}.at_least(1).returns(!options[:fails])
|
140
|
+
Index.indexes[0].expects(:write)
|
141
|
+
end
|
142
|
+
|
143
|
+
it "with index option, no existing index and core command updates index and prints index message" do
|
144
|
+
index :load=>Runner.all_libraries
|
145
|
+
Index.indexes[0].stubs(:exists?).returns(false)
|
146
|
+
capture_stdout { start("--index", "libraries") }.should =~ /Generating index/
|
147
|
+
end
|
148
|
+
|
149
|
+
it "with index option, existing index and core command updates incremental index" do
|
150
|
+
index :load=>['changed']
|
151
|
+
Index.indexes[0].stubs(:exists?).returns(true)
|
152
|
+
capture_stdout { start("--index=changed", "libraries")}.should =~ /Indexing.*changed/
|
153
|
+
end
|
154
|
+
|
155
|
+
it "with index option, failed indexing prints error" do
|
156
|
+
index :load=>['changed'], :fails=>true
|
157
|
+
Index.indexes[0].stubs(:exists?).returns(true)
|
158
|
+
Manager.stubs(:failed_libraries).returns(['changed'])
|
159
|
+
capture_stderr {
|
160
|
+
capture_stdout { start("--index=changed", "libraries")}.should =~ /Indexing.*changed/
|
161
|
+
}.should =~ /Error:.*failed.*changed/
|
162
|
+
end
|
163
|
+
|
164
|
+
it "with core command updates index and doesn't print index message" do
|
165
|
+
Index.indexes[0].expects(:write)
|
166
|
+
Boson.main_object.expects(:send).with('libraries')
|
167
|
+
capture_stdout { start 'libraries'}.should.not =~ /index/i
|
168
|
+
end
|
169
|
+
|
170
|
+
it "with non-core command not finding library, does update index" do
|
171
|
+
Index.expects(:find_library).returns(nil, 'sweet_lib')
|
172
|
+
Manager.expects(:load).with {|*args| args[0].is_a?(String) ? args[0] == 'sweet_lib' : true}.at_least(1)
|
173
|
+
Index.indexes[0].expects(:update).returns(true)
|
174
|
+
aborts_with(/sweet/) { start 'sweet' }
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
describe "render_output" do
|
179
|
+
before { Scientist.rendered = false; BinRunner.instance_eval "@options = {}" }
|
180
|
+
|
181
|
+
it "doesn't render when nil, false or true" do
|
182
|
+
View.expects(:render).never
|
183
|
+
[nil, false, true].each do |e|
|
184
|
+
BinRunner.render_output e
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
it "doesn't render when rendered with Scientist" do
|
189
|
+
Scientist.rendered = true
|
190
|
+
View.expects(:render).never
|
191
|
+
BinRunner.render_output 'blah'
|
192
|
+
end
|
193
|
+
|
194
|
+
it "render with puts when non-string" do
|
195
|
+
View.expects(:render).with('dude', {:method => 'puts'})
|
196
|
+
BinRunner.render_output 'dude'
|
197
|
+
end
|
198
|
+
|
199
|
+
it "renders with inspect when non-array and non-string" do
|
200
|
+
[{:a=>true}, :ok].each do |e|
|
201
|
+
View.expects(:puts).with(e.inspect)
|
202
|
+
BinRunner.render_output e
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
it "renders with inspect when Scientist rendering toggled off with :render" do
|
207
|
+
Scientist.global_options = {:render=>true}
|
208
|
+
View.expects(:puts).with([1,2].inspect)
|
209
|
+
BinRunner.render_output [1,2]
|
210
|
+
Scientist.global_options = nil
|
211
|
+
end
|
212
|
+
|
213
|
+
it "renders with hirb when array" do
|
214
|
+
View.expects(:render_object)
|
215
|
+
BinRunner.render_output [1,2,3]
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
it "parse_args only translates options before command" do
|
220
|
+
BinRunner.parse_args(['-v', 'com', '-v']).should == ["com", {:verbose=>true}, ['-v']]
|
221
|
+
BinRunner.parse_args(['com', '-v']).should == ["com", {}, ['-v']]
|
222
|
+
end
|
223
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'test_helper')
|
2
|
+
|
3
|
+
describe "Command" do
|
4
|
+
describe ".find" do
|
5
|
+
before_all {
|
6
|
+
reset_boson
|
7
|
+
Boson.libraries << Library.new(:name=>'bling', :namespace=>true)
|
8
|
+
@namespace_command = Command.new(:name=>'blah', :lib=>'bling', :namespace=>'bling')
|
9
|
+
@top_level_command = Command.new(:name=>'blah', :lib=>'bling')
|
10
|
+
Boson.commands << @namespace_command
|
11
|
+
Boson.commands << @top_level_command
|
12
|
+
}
|
13
|
+
|
14
|
+
it 'finds correct command when a subcommand of the same name exists' do
|
15
|
+
Command.find('blah').should == @top_level_command
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'finds correct command when a top level command of the same name exists' do
|
19
|
+
Command.find('bling.blah').should == @namespace_command
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'test_helper')
|
2
|
+
|
3
|
+
describe "WebCore" do
|
4
|
+
it "#get with no options" do
|
5
|
+
request = mock { expects(:request).with({}) }
|
6
|
+
Commands::WebCore::Get.expects(:new).with('blah.com').returns(request)
|
7
|
+
Commands::WebCore.get 'blah.com'
|
8
|
+
end
|
9
|
+
|
10
|
+
it "#post with no options" do
|
11
|
+
Net::HTTP.expects(:post_form).with(anything, {}).returns(nil)
|
12
|
+
Commands::WebCore.post 'blah.com'
|
13
|
+
end
|
14
|
+
|
15
|
+
it "#build_url with string params" do
|
16
|
+
Commands::WebCore.build_url('ababd.com', :q=>'search').should == 'ababd.com?q=search'
|
17
|
+
end
|
18
|
+
|
19
|
+
it "#build_url with array params" do
|
20
|
+
Commands::WebCore.build_url('ababd.com', :q=>%w{multi word search}).should == 'ababd.com?q=multi+word+search'
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,126 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'test_helper')
|
2
|
+
|
3
|
+
describe "CommentInspector" do
|
4
|
+
before_all { eval "module ::Optional; def self.bling; {:a=>'bling'}; end; end" }
|
5
|
+
describe "scrapes description" do
|
6
|
+
before {
|
7
|
+
@lines = ["module Foo", " # some comments yay", " def foo", " end", "end"]
|
8
|
+
}
|
9
|
+
def description(options={})
|
10
|
+
CommentInspector.scrape(@lines.join("\n"), options[:line] || 3, Optional)[:desc]
|
11
|
+
end
|
12
|
+
|
13
|
+
it "directly above method returns desc" do
|
14
|
+
description.should == "some comments yay"
|
15
|
+
end
|
16
|
+
|
17
|
+
it "with explicit @desc returns desc" do
|
18
|
+
@lines[1] = '#@desc some comments yay'
|
19
|
+
description.should == "some comments yay"
|
20
|
+
end
|
21
|
+
|
22
|
+
it "of multiple lines returns desc" do
|
23
|
+
@lines.delete_at(1)
|
24
|
+
@lines.insert(1, '#@options :b=>1', '#@desc here be', '# comments')
|
25
|
+
description(:line=>5).should == "here be comments"
|
26
|
+
end
|
27
|
+
|
28
|
+
it "that is empty returns nil" do
|
29
|
+
@lines[1] = ""
|
30
|
+
description.should == nil
|
31
|
+
end
|
32
|
+
|
33
|
+
it "that is empty with options keyword returns nil" do
|
34
|
+
@lines[1] = '#@options {:a=>1}'
|
35
|
+
description.should == nil
|
36
|
+
end
|
37
|
+
|
38
|
+
it "not directly above returns nil" do
|
39
|
+
@lines.insert(2, " ")
|
40
|
+
description(:line=>4).should == nil
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
describe "scrapes options" do
|
45
|
+
before {
|
46
|
+
@lines = ["module Foo", ' #@options {:a=>true}', " def foo", " end", "end"]
|
47
|
+
}
|
48
|
+
def options(opts={})
|
49
|
+
@lines[1] = opts[:value] if opts[:value]
|
50
|
+
args = [@lines.join("\n"), opts[:line] || 3, Optional]
|
51
|
+
CommentInspector.scrape(*args)[:options]
|
52
|
+
end
|
53
|
+
|
54
|
+
it "that are basic" do
|
55
|
+
options.should == {:a=>true}
|
56
|
+
end
|
57
|
+
|
58
|
+
it "that are hash-like" do
|
59
|
+
options(:value=>'#@options :a => 2').should == {:a=>2}
|
60
|
+
end
|
61
|
+
|
62
|
+
it "that are whitespaced" do
|
63
|
+
options(:value=>"\t"+ '# @options {:a=>1}').should == {:a=>1}
|
64
|
+
end
|
65
|
+
|
66
|
+
it "that have a local value" do
|
67
|
+
options(:value=>'#@options bling').should == {:a=>'bling'}
|
68
|
+
end
|
69
|
+
|
70
|
+
it "that are multi-line" do
|
71
|
+
@lines.delete_at(1)
|
72
|
+
@lines.insert(1, '#@options {:a =>', " # 1}", "# some comments")
|
73
|
+
options(:line=>5).should == {:a=>1}
|
74
|
+
end
|
75
|
+
|
76
|
+
it "with failed eval and returns nil" do
|
77
|
+
options(:value=>'#@options !--').should == nil
|
78
|
+
end
|
79
|
+
|
80
|
+
it "that are empty and returns nil" do
|
81
|
+
options(:value=>"# nada").should == nil
|
82
|
+
end
|
83
|
+
|
84
|
+
it "when @option overwrites @options" do
|
85
|
+
@lines.insert(1, ' #@option :a, :boolean')
|
86
|
+
options(:line=>4).should == {:a=>:boolean}
|
87
|
+
end
|
88
|
+
|
89
|
+
it "when set by @option and @options" do
|
90
|
+
@lines.insert(1, ' #@option :b, :boolean')
|
91
|
+
options(:line=>4).should == {:b=>:boolean, :a=>true}
|
92
|
+
end
|
93
|
+
|
94
|
+
it "when set by @option" do
|
95
|
+
@lines.delete_at(1)
|
96
|
+
@lines.insert(1, ' #@option :b, :string', ' #@option :a, 4')
|
97
|
+
options(:line=>4).should == {:b=>:string, :a=>4}
|
98
|
+
end
|
99
|
+
|
100
|
+
it "when set by multi-line @option" do
|
101
|
+
@lines.delete_at(1)
|
102
|
+
@lines.insert(1, ' #@option :b, :type=>:string,', ' # :values=>%w{one two}', '# some comments')
|
103
|
+
options(:line=>5).should == {:b=>{:type=>:string, :values=>%w{one two}}}
|
104
|
+
end
|
105
|
+
|
106
|
+
it "and ignores invalid @option's" do
|
107
|
+
@lines.delete_at(1)
|
108
|
+
@lines.insert(1, ' #@option :b=>:string', ' #@option :a, :string')
|
109
|
+
options(:line=>4).should == {:a=>:string}
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
it "scrapes all comment types with implicit desc" do
|
114
|
+
@lines = ["module Foo", '# @config :a=>true', '# @render_options :b=>1', ' # @options {:a=>true}',
|
115
|
+
'#blah', " def foo", " end", "end"]
|
116
|
+
expected = {:desc=>"blah", :options=>{:a=>true}, :render_options=>{:b=>1}, :config=>{:a=>true}}
|
117
|
+
CommentInspector.scrape(@lines.join("\n"), 6, Optional).should == expected
|
118
|
+
end
|
119
|
+
|
120
|
+
it "scrapes all comment types with explicit desc" do
|
121
|
+
@lines = ["module Foo", '#@desc blah', '# @render_options :b=>1,', '# :c=>2',
|
122
|
+
' # @options {:a=>true}', ' # @config :a=>true', " def foo", " end", "end"]
|
123
|
+
expected = {:desc=>"blah", :options=>{:a=>true}, :render_options=>{:b=>1, :c=>2}, :config=>{:a=>true}}
|
124
|
+
CommentInspector.scrape(@lines.join("\n"), 7, Optional).should == expected
|
125
|
+
end
|
126
|
+
end
|
data/test/deps.rip
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'test_helper')
|
2
|
+
|
3
|
+
describe "file library" do
|
4
|
+
before { reset; FileLibrary.reset_file_cache }
|
5
|
+
before { Gem.stubs(:loaded_specs).returns({}) } if RUBY_VERSION >= '1.9.2' && defined? Gem
|
6
|
+
|
7
|
+
it "loads" do
|
8
|
+
load :blah, :file_string=>"module Blah; def blah; end; end"
|
9
|
+
library_has_module('blah', 'Boson::Commands::Blah')
|
10
|
+
command_exists?('blah')
|
11
|
+
end
|
12
|
+
|
13
|
+
it "in a subdirectory loads" do
|
14
|
+
load 'site/delicious', :file_string=>"module Delicious; def blah; end; end"
|
15
|
+
library_has_module('site/delicious', "Boson::Commands::Site::Delicious")
|
16
|
+
command_exists?('blah')
|
17
|
+
end
|
18
|
+
|
19
|
+
it "in a sub subdirectory loads" do
|
20
|
+
load 'web/site/delicious', :file_string=>"module Delicious; def blah; end; end"
|
21
|
+
library_has_module('web/site/delicious', "Boson::Commands::Web::Site::Delicious")
|
22
|
+
command_exists?('blah')
|
23
|
+
end
|
24
|
+
|
25
|
+
it "loads by basename" do
|
26
|
+
Dir.stubs(:[]).returns([RUBY_VERSION < '1.9.2' ? './test/commands/site/github.rb' :
|
27
|
+
File.expand_path('./test/commands/site/github.rb')])
|
28
|
+
load 'github', :file_string=>"module Github; def blah; end; end", :exists=>false
|
29
|
+
library_has_module('site/github', "Boson::Commands::Site::Github")
|
30
|
+
command_exists?('blah')
|
31
|
+
end
|
32
|
+
|
33
|
+
it "loads a plugin library by creating its module" do
|
34
|
+
load(:blah, :file_string=>"def blah; end")
|
35
|
+
library_has_module('blah', "Boson::Commands::Blah")
|
36
|
+
command_exists?('blah', false)
|
37
|
+
end
|
38
|
+
|
39
|
+
it "prints error for file library with multiple modules" do
|
40
|
+
capture_stderr { load(:blah, :file_string=>"module Doo; end; module Daa; end") }.should =~ /Can't.*config/
|
41
|
+
end
|
42
|
+
end
|
data/test/loader_test.rb
ADDED
@@ -0,0 +1,235 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'test_helper')
|
2
|
+
|
3
|
+
describe "Loader" do
|
4
|
+
def load_namespace_library
|
5
|
+
Manager.load([Boson::Commands::Namespace])
|
6
|
+
end
|
7
|
+
|
8
|
+
before { Gem.stubs(:loaded_specs).returns({}) } if RUBY_VERSION >= '1.9.2' && defined? Gem
|
9
|
+
describe "config" do
|
10
|
+
before { reset }
|
11
|
+
it "from callback overridden by user's config" do
|
12
|
+
with_config(:libraries=>{'blih'=>{:namespace=>false}}) do
|
13
|
+
load :blih, :file_string=>"module Blah; def self.config; {:namespace=>'bling'}; end; end"
|
14
|
+
library('blih').namespace.should == false
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
# if this test fails, other exists? using methods fail
|
19
|
+
it "from callback recursively merges with user's config" do
|
20
|
+
with_config(:libraries=>{'blah'=>{:commands=>{'bling'=>{:desc=>'bling', :options=>{:num=>3}}}}}) do
|
21
|
+
File.stubs(:exists?).returns(true)
|
22
|
+
load :blah, :file_string=> "module Blah; def self.config; {:commands=>{'blang'=>{:alias=>'ba'}, " +
|
23
|
+
"'bling'=>{:options=>{:verbose=>:boolean}}}}; end; end"
|
24
|
+
library('blah').command_object('bling').options.should == {:verbose=>:boolean, :num=>3}
|
25
|
+
library('blah').command_object('bling').desc.should == 'bling'
|
26
|
+
library('blah').command_object('blang').alias.should == 'ba'
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
it "non-hash from inspector overridden by user's config" do
|
31
|
+
with_config(:libraries=>{'blah'=>{:commands=>{'bling'=>{:desc=>'already'}}}}) do
|
32
|
+
load :blah, :file_string=>"module Blah; #from file\ndef bling; end; end"
|
33
|
+
library('blah').command_object('bling').desc.should == 'already'
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
it "from inspector attribute config sets command's config" do
|
38
|
+
load :blah, :file_string=>"module Blah; config :alias=>'ok'\n; def bling; end; end"
|
39
|
+
library('blah').command_object('bling').alias.should == 'ok'
|
40
|
+
end
|
41
|
+
|
42
|
+
it "hash from inspector recursively merged with user's config" do
|
43
|
+
with_config(:libraries=>{'blah'=>{:commands=>{'blung'=>{:args=>[], :render_options=>{:sort=>'this'}}}}}) do
|
44
|
+
CommentInspector.expects(:scrape).returns({:render_options=>{:fields=>['this']}})
|
45
|
+
load :blah, :file_string=>"module Blah; def blung; end; end"
|
46
|
+
library('blah').command_object('blung').render_options.should == {:fields=>["this"], :sort=>"this"}
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
describe "load" do
|
52
|
+
before { reset }
|
53
|
+
it "calls included callback" do
|
54
|
+
capture_stdout {
|
55
|
+
load :blah, :file_string=>"module Blah; def self.included(mod); puts 'included blah'; end; def blah; end; end"
|
56
|
+
}.should =~ /included blah/
|
57
|
+
end
|
58
|
+
|
59
|
+
it "calls after_included callback" do
|
60
|
+
capture_stdout {
|
61
|
+
load :blah, :file_string=>"module Blah; def self.after_included; puts 'yo'; end; end"
|
62
|
+
}.should == "yo\n"
|
63
|
+
end
|
64
|
+
|
65
|
+
it "prints error if library module conflicts with top level constant/module" do
|
66
|
+
capture_stderr {
|
67
|
+
load :blah, :file_string=>"module Object; def self.blah; end; end"
|
68
|
+
}.should =~ /conflict.*'Object'/
|
69
|
+
library_loaded?('blah')
|
70
|
+
end
|
71
|
+
|
72
|
+
it "prints error and returns false for existing library" do
|
73
|
+
libs = create_library('blah', :loaded=>true)
|
74
|
+
Manager.stubs(:loader_create).returns(libs[0])
|
75
|
+
capture_stderr { load('blah', :no_mock=>true, :verbose=>true).should == false }.should =~ /already exists/
|
76
|
+
end
|
77
|
+
|
78
|
+
it "loads and strips aliases from a library's commands" do
|
79
|
+
with_config(:command_aliases=>{"blah"=>'b'}) do
|
80
|
+
load :blah, :file_string=>"module Blah; def blah; end; alias_method(:b, :blah); end"
|
81
|
+
library_loaded?('blah')
|
82
|
+
library('blah').commands.should == ['blah']
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
it "loads a library and creates its class commands" do
|
87
|
+
with_config(:libraries=>{"blah"=>{:class_commands=>{"bling"=>"Blah.bling", "Blah"=>['hmm']}}}) do
|
88
|
+
load :blah, :file_string=>"module Blah; def self.bling; end; def self.hmm; end; end"
|
89
|
+
command_exists? 'bling'
|
90
|
+
command_exists? 'hmm'
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
it "loads a library with dependencies" do
|
95
|
+
File.stubs(:exists?).returns(true)
|
96
|
+
File.stubs(:read).returns("module Water; def water; end; end", "module Oaks; def oaks; end; end")
|
97
|
+
with_config(:libraries=>{"water"=>{:dependencies=>"oaks"}}) do
|
98
|
+
load 'water', :no_mock=>true
|
99
|
+
library_has_module('water', "Boson::Commands::Water")
|
100
|
+
library_has_module('oaks', "Boson::Commands::Oaks")
|
101
|
+
command_exists?('water')
|
102
|
+
command_exists?('oaks')
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
it "prints error for library with invalid dependencies" do
|
107
|
+
GemLibrary.stubs(:is_a_gem?).returns(true) #mock all as gem libs
|
108
|
+
Util.stubs(:safe_require).returns(true)
|
109
|
+
with_config(:libraries=>{"water"=>{:dependencies=>"fire"}, "fire"=>{:dependencies=>"man"}}) do
|
110
|
+
capture_stderr {
|
111
|
+
load('water', :no_mock=>true)
|
112
|
+
}.should == "Unable to load library fire. Reason: Can't load dependency man\nUnable to load"+
|
113
|
+
" library water. Reason: Can't load dependency fire\n"
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
it "prints error for method conflicts with main_object method" do
|
118
|
+
with_config(:error_method_conflicts=>true) do
|
119
|
+
capture_stderr {
|
120
|
+
load('blah', :file_string=>"module Blah; def require; end; end")
|
121
|
+
}.should =~ /Unable to load library blah.*conflict.*require/
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
it "prints error for method conflicts with config error_method_conflicts" do
|
126
|
+
with_config(:error_method_conflicts=>true) do
|
127
|
+
load('blah', :file_string=>"module Blah; def chwhat; end; end")
|
128
|
+
capture_stderr {
|
129
|
+
load('chwhat', :file_string=>"module Chwhat; def chwhat; end; end")
|
130
|
+
}.should =~ /Unable to load library chwhat.*conflict.*chwhat/
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
it "namespaces a library that has a method conflict" do
|
135
|
+
load('blah', :file_string=>"module Blah; def chwhat; end; end")
|
136
|
+
capture_stderr {
|
137
|
+
load('chwhat2', :file_string=>"module Chwhat2; def chwhat; end; end")
|
138
|
+
}.should =~ /conflict.*chwhat.*chwhat2/
|
139
|
+
library_has_command('namespace', 'chwhat2')
|
140
|
+
library_has_command('chwhat2', 'chwhat')
|
141
|
+
end
|
142
|
+
|
143
|
+
describe "module library" do
|
144
|
+
def mock_library(*args); end
|
145
|
+
|
146
|
+
it "loads a module library and all its class methods by default" do
|
147
|
+
eval %[module ::Harvey; def self.bird; end; def self.eagle; end; end]
|
148
|
+
load ::Harvey, :no_mock=>true
|
149
|
+
library_has_command('harvey', 'bird')
|
150
|
+
library_has_command('harvey', 'eagle')
|
151
|
+
end
|
152
|
+
|
153
|
+
it "loads a module library with specified commands" do
|
154
|
+
eval %[module ::Peanut; def self.bird; end; def self.eagle; end; end]
|
155
|
+
load ::Peanut, :no_mock=>true, :commands=>%w{bird}
|
156
|
+
library('peanut').commands.size.should == 1
|
157
|
+
library_has_command('peanut', 'bird')
|
158
|
+
end
|
159
|
+
|
160
|
+
it "loads a module library as a class" do
|
161
|
+
eval %[class ::Mentok; def self.bird; end; def self.eagle; end; end]
|
162
|
+
load ::Mentok, :no_mock=>true, :commands=>%w{bird}
|
163
|
+
library('mentok').commands.size.should == 1
|
164
|
+
library_has_command('mentok', 'bird')
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
describe "gem library" do
|
169
|
+
def mock_library(lib, options={})
|
170
|
+
options[:file_string] ||= ''
|
171
|
+
File.stubs(:exists?).returns(false)
|
172
|
+
GemLibrary.expects(:is_a_gem?).returns(true)
|
173
|
+
Util.expects(:safe_require).with { eval options.delete(:file_string) || ''; true}.returns(true)
|
174
|
+
end
|
175
|
+
|
176
|
+
it "loads" do
|
177
|
+
with_config(:libraries=>{"dude"=>{:module=>'Dude'}}) do
|
178
|
+
load "dude", :file_string=>"module ::Dude; def blah; end; end"
|
179
|
+
library_has_module('dude', "Dude")
|
180
|
+
command_exists?("blah")
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
it "with kernel methods loads" do
|
185
|
+
load "dude", :file_string=>"module ::Kernel; def dude; end; end"
|
186
|
+
library_loaded? 'dude'
|
187
|
+
library('dude').module.should == nil
|
188
|
+
command_exists?("dude")
|
189
|
+
end
|
190
|
+
|
191
|
+
it "prints error when nonexistent" do
|
192
|
+
capture_stderr { load('blah') }.should =~ /Library blah did not/
|
193
|
+
end
|
194
|
+
|
195
|
+
it "with invalid module prints error" do
|
196
|
+
with_config(:libraries=>{"coolio"=>{:module=>"Cool"}}) do
|
197
|
+
capture_stderr {
|
198
|
+
load('coolio', :file_string=>"module ::Coolio; def coolio; end; end")
|
199
|
+
}.should =~ /Unable.*coolio.*No module/
|
200
|
+
end
|
201
|
+
end
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
describe "library with namespace" do
|
206
|
+
before_all { reset_main_object }
|
207
|
+
before { reset_boson }
|
208
|
+
|
209
|
+
it "loads and defaults to library name" do
|
210
|
+
with_config(:libraries=>{'blang'=>{:namespace=>true}}) do
|
211
|
+
load 'blang', :file_string=>"module Blang; def bling; end; end"
|
212
|
+
library_has_command('blang', 'bling')
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
it "loads with config namespace" do
|
217
|
+
with_config(:libraries=>{'blung'=>{:namespace=>'dope'}}) do
|
218
|
+
load 'blung', :file_string=>"module Blung; def bling; end; end"
|
219
|
+
library_has_command('blung', 'bling')
|
220
|
+
library('blung').commands.size.should == 1
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
224
|
+
it "prints error if namespace conflicts with existing commands" do
|
225
|
+
eval "module ::Conflict; def self.bleng; end; end"
|
226
|
+
load Conflict, :no_mock=>true
|
227
|
+
with_config(:libraries=>{'bleng'=>{:namespace=>true}}) do
|
228
|
+
capture_stderr {
|
229
|
+
load 'bleng', :file_string=>"module Bleng; def bling; end; end"
|
230
|
+
}.should =~ /conflict.*bleng/
|
231
|
+
end
|
232
|
+
end
|
233
|
+
end
|
234
|
+
after_all { FileUtils.rm_r File.dirname(__FILE__)+'/commands/', :force=>true }
|
235
|
+
end
|