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,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
@@ -0,0 +1,4 @@
1
+ mocha >=0
2
+ bacon >=1.1.0
3
+ mocha-on-bacon >=0
4
+ bacon-bits >=0
@@ -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
@@ -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