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.
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