boson 0.0.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/LICENSE.txt +22 -0
- data/README.rdoc +133 -0
- data/Rakefile +52 -0
- data/VERSION.yml +4 -0
- data/bin/boson +6 -0
- data/lib/boson.rb +72 -0
- data/lib/boson/command.rb +117 -0
- data/lib/boson/commands.rb +7 -0
- data/lib/boson/commands/core.rb +66 -0
- data/lib/boson/commands/web_core.rb +36 -0
- data/lib/boson/index.rb +95 -0
- data/lib/boson/inspector.rb +80 -0
- data/lib/boson/inspectors/argument_inspector.rb +92 -0
- data/lib/boson/inspectors/comment_inspector.rb +79 -0
- data/lib/boson/inspectors/method_inspector.rb +94 -0
- data/lib/boson/libraries/file_library.rb +76 -0
- data/lib/boson/libraries/gem_library.rb +21 -0
- data/lib/boson/libraries/module_library.rb +17 -0
- data/lib/boson/libraries/require_library.rb +11 -0
- data/lib/boson/library.rb +108 -0
- data/lib/boson/loader.rb +103 -0
- data/lib/boson/manager.rb +184 -0
- data/lib/boson/namespace.rb +45 -0
- data/lib/boson/option_parser.rb +318 -0
- data/lib/boson/repo.rb +38 -0
- data/lib/boson/runner.rb +51 -0
- data/lib/boson/runners/bin_runner.rb +100 -0
- data/lib/boson/runners/repl_runner.rb +40 -0
- data/lib/boson/scientist.rb +168 -0
- data/lib/boson/util.rb +93 -0
- data/lib/boson/view.rb +31 -0
- data/test/argument_inspector_test.rb +62 -0
- data/test/bin_runner_test.rb +136 -0
- data/test/commands_test.rb +51 -0
- data/test/comment_inspector_test.rb +99 -0
- data/test/config/index.marshal +0 -0
- data/test/file_library_test.rb +50 -0
- data/test/index_test.rb +117 -0
- data/test/loader_test.rb +181 -0
- data/test/manager_test.rb +110 -0
- data/test/method_inspector_test.rb +64 -0
- data/test/option_parser_test.rb +365 -0
- data/test/repo_test.rb +22 -0
- data/test/runner_test.rb +43 -0
- data/test/scientist_test.rb +291 -0
- data/test/test_helper.rb +119 -0
- metadata +133 -0
data/test/repo_test.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'test_helper')
|
2
|
+
|
3
|
+
class Boson::RepoTest < Test::Unit::TestCase
|
4
|
+
context "config" do
|
5
|
+
before(:all) { reset }
|
6
|
+
before(:each) { @repo = Boson::Repo.new(File.dirname(__FILE__)) }
|
7
|
+
|
8
|
+
test "reloads config when passed true" do
|
9
|
+
@repo.config.object_id.should_not == @repo.config(true).object_id
|
10
|
+
end
|
11
|
+
|
12
|
+
test "reads existing config correctly" do
|
13
|
+
expected_hash = {:commands=>{'c1'=>{}}, :libraries=>{}}
|
14
|
+
YAML.expects(:load_file).returns(expected_hash)
|
15
|
+
@repo.config[:commands]['c1'].should == {}
|
16
|
+
end
|
17
|
+
|
18
|
+
test "ignores nonexistent file and sets config defaults" do
|
19
|
+
assert @repo.config[:commands].is_a?(Hash) && @repo.config[:libraries].is_a?(Hash)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
data/test/runner_test.rb
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'test_helper')
|
2
|
+
|
3
|
+
module Boson
|
4
|
+
class RunnerTest < Test::Unit::TestCase
|
5
|
+
context "repl_runner" do
|
6
|
+
def start(*args)
|
7
|
+
Hirb.stubs(:enable)
|
8
|
+
Boson.start(*args)
|
9
|
+
end
|
10
|
+
|
11
|
+
before(:all) { reset }
|
12
|
+
before(:each) { Boson::ReplRunner.instance_eval("@initialized = false") }
|
13
|
+
|
14
|
+
test "loads default libraries and libraries in :defaults config" do
|
15
|
+
defaults = Boson::Runner.default_libraries + ['yo']
|
16
|
+
with_config(:defaults=>['yo']) do
|
17
|
+
Manager.expects(:load).with {|*args| args[0] == defaults }
|
18
|
+
start
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
test "doesn't call init twice" do
|
23
|
+
start
|
24
|
+
ReplRunner.expects(:init).never
|
25
|
+
start
|
26
|
+
end
|
27
|
+
|
28
|
+
test "loads multiple libraries with :libraries option" do
|
29
|
+
ReplRunner.expects(:init)
|
30
|
+
Manager.expects(:load).with([:lib1,:lib2], anything)
|
31
|
+
start(:libraries=>[:lib1, :lib2])
|
32
|
+
end
|
33
|
+
|
34
|
+
test "autoloader autoloads libraries" do
|
35
|
+
start(:autoload_libraries=>true)
|
36
|
+
Index.expects(:read)
|
37
|
+
Index.expects(:find_library).with('blah').returns('blah')
|
38
|
+
Manager.expects(:load).with('blah', :verbose=>true)
|
39
|
+
Boson.main_object.blah
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,291 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'test_helper')
|
2
|
+
|
3
|
+
module Boson
|
4
|
+
class ScientistTest < Test::Unit::TestCase
|
5
|
+
before(:all) {
|
6
|
+
eval <<-EOF
|
7
|
+
module Blah
|
8
|
+
def blah(arg1, options={})
|
9
|
+
[arg1, options]
|
10
|
+
end
|
11
|
+
def splat_blah(*args)
|
12
|
+
args
|
13
|
+
end
|
14
|
+
def default_blah(arg1, arg2=default, options={})
|
15
|
+
[arg1, arg2, options]
|
16
|
+
end
|
17
|
+
def default; 'some default'; end
|
18
|
+
end
|
19
|
+
EOF
|
20
|
+
@opt_cmd = Object.new.extend Blah
|
21
|
+
}
|
22
|
+
|
23
|
+
def command(hash, args)
|
24
|
+
hash = {:name=>'blah', :lib=>'bling', :options=>{:force=>:boolean, :level=>2}}.merge(hash)
|
25
|
+
@cmd = Command.new hash
|
26
|
+
@cmd.instance_variable_set("@file_parsed_args", true) if hash[:file_parsed_args]
|
27
|
+
Scientist.create_option_command(@opt_cmd, @cmd)
|
28
|
+
@opt_cmd.send(hash[:name], *args)
|
29
|
+
end
|
30
|
+
|
31
|
+
def command_with_arg_size(*args)
|
32
|
+
command({:args=>2}, args)
|
33
|
+
end
|
34
|
+
|
35
|
+
def command_with_args(*args)
|
36
|
+
command({:args=>[['arg1'],['options', {}]]}, args)
|
37
|
+
end
|
38
|
+
|
39
|
+
def basic_command(hash, args)
|
40
|
+
command({:name=>'splat_blah', :args=>'*'}.merge(hash), args)
|
41
|
+
end
|
42
|
+
|
43
|
+
def command_with_splat_args(*args)
|
44
|
+
command({:name=>'splat_blah', :args=>'*'}, args)
|
45
|
+
end
|
46
|
+
|
47
|
+
def command_with_arg_defaults(*args)
|
48
|
+
arg_defaults = [%w{arg1}, %w{arg2 default}, %w{options {}}]
|
49
|
+
command({:name=>'default_blah', :file_parsed_args=>true, :args=>arg_defaults}, args)
|
50
|
+
end
|
51
|
+
|
52
|
+
def args_are_equal(args, array)
|
53
|
+
command_with_args(*args).should == array
|
54
|
+
command_with_arg_size(*args).should == array
|
55
|
+
command_with_splat_args(*args).should == array
|
56
|
+
end
|
57
|
+
|
58
|
+
ALL_COMMANDS = [:command_with_args, :command_with_arg_size, :command_with_splat_args]
|
59
|
+
|
60
|
+
context "all commands" do
|
61
|
+
test "translate arg and options as one string" do
|
62
|
+
args_are_equal ['a1 -f'], ['a1', {:force=>true, :level=>2}]
|
63
|
+
end
|
64
|
+
|
65
|
+
test "translate arg and stringified options" do
|
66
|
+
args_are_equal [:cool, '-l3'], [:cool, {:level=>3}]
|
67
|
+
end
|
68
|
+
|
69
|
+
test "translate arg and normal hash options" do
|
70
|
+
args_are_equal [:cool, {:ok=>true}], [:cool, {:ok=>true}]
|
71
|
+
end
|
72
|
+
|
73
|
+
test "translate stringified arg without options sets default options" do
|
74
|
+
args_are_equal ['cool'], ['cool', {:level=>2}]
|
75
|
+
end
|
76
|
+
|
77
|
+
test "translate arg without options sets default options" do
|
78
|
+
args_are_equal [:cool], [:cool, {:level=>2}]
|
79
|
+
end
|
80
|
+
|
81
|
+
test "with invalid options print errors and delete them" do
|
82
|
+
ALL_COMMANDS.each do |cmd|
|
83
|
+
capture_stderr {
|
84
|
+
send(cmd, 'cool -f -z').should == ['cool', {:force=>true, :level=>2}]
|
85
|
+
}.should =~/invalid.*z/
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
test "print help with help option" do
|
90
|
+
ALL_COMMANDS.each do |cmd|
|
91
|
+
Boson.expects(:invoke).with(:usage, anything, anything)
|
92
|
+
send(cmd, '-h')
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
context "command" do
|
98
|
+
context "with arg defaults" do
|
99
|
+
test "sets defaults with stringified args" do
|
100
|
+
command_with_arg_defaults('1').should == ["1", "some default", {:level=>2}]
|
101
|
+
end
|
102
|
+
|
103
|
+
test "sets defaults with normal args" do
|
104
|
+
command_with_arg_defaults(1).should == [1, "some default", {:level=>2}]
|
105
|
+
end
|
106
|
+
|
107
|
+
test "sets default if optional arg is a valid option" do
|
108
|
+
command_with_arg_defaults("cool -f").should == ["cool", "some default", {:level=>2, :force=>true}]
|
109
|
+
end
|
110
|
+
|
111
|
+
test "doesn't set defaults if not needed" do
|
112
|
+
command_with_arg_defaults(1, 'nada').should == [1, "nada", {:level=>2}]
|
113
|
+
end
|
114
|
+
|
115
|
+
test "prints error for invalid defaults" do
|
116
|
+
arg_defaults = [%w{arg1}, %w{arg2 invalidzzz}, %w{options {}}]
|
117
|
+
capture_stderr {
|
118
|
+
command({:name=>'default_blah', :file_parsed_args=>true, :args=>arg_defaults}, [1])
|
119
|
+
}.should =~ /Error.*position 2/
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
context "prints error" do
|
124
|
+
test "with option error" do
|
125
|
+
capture_stderr { command_with_args('a1 -l') }.should =~ /Error.*level/
|
126
|
+
end
|
127
|
+
|
128
|
+
test "with unexpected error in translation" do
|
129
|
+
Scientist.expects(:command_options).raises("unexpected")
|
130
|
+
capture_stderr { command_with_args('a1') }.should =~ /Error.*unexpected/
|
131
|
+
end
|
132
|
+
|
133
|
+
test "with unexpected error in render" do
|
134
|
+
Scientist.expects(:render?).raises("unexpected")
|
135
|
+
capture_stderr { command_with_args('a1') }.should =~ /Error.*unexpected/
|
136
|
+
end
|
137
|
+
|
138
|
+
test "with no argument defined for options" do
|
139
|
+
capture_stderr { command({:args=>1}, 'ok') }.should =~ /misaligned/
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
test "translates stringfied args + options starting at second arg" do
|
144
|
+
command_with_arg_defaults(1, 'nada -l3').should == [1, "nada", {:level=>3}]
|
145
|
+
end
|
146
|
+
|
147
|
+
test "with leading option-like args are translated as arguments" do
|
148
|
+
command_with_args('-z -f').should == ["-z", {:force=>true, :level=>2}]
|
149
|
+
command_with_args('--blah -f').should == ['--blah', {:force=>true, :level=>2}]
|
150
|
+
end
|
151
|
+
|
152
|
+
test "with splat args does not raise error for too few or many args" do
|
153
|
+
[[], [''], [1,2,3], ['1 2 3']].each do |args|
|
154
|
+
assert_nothing_raised { command_with_splat_args *args }
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
test "with debug option prints debug" do
|
159
|
+
capture_stdout { command_with_args("-v ok") } =~ /Arguments.*ok/
|
160
|
+
end
|
161
|
+
|
162
|
+
test "with pretend option prints arguments and returns early" do
|
163
|
+
Scientist.expects(:render_or_raw).never
|
164
|
+
capture_stdout { command_with_args("-p ok") } =~ /Arguments.*ok/
|
165
|
+
end
|
166
|
+
|
167
|
+
test "with not enough args raises ArgumentError" do
|
168
|
+
args = [ArgumentError, '0 for 1']
|
169
|
+
assert_error(*args) { command_with_args }
|
170
|
+
assert_error(*args) { command_with_args '' }
|
171
|
+
assert_error(*args) { command_with_arg_size }
|
172
|
+
assert_error(*args) { command_with_arg_size '' }
|
173
|
+
end
|
174
|
+
|
175
|
+
test "with too many args raises ArgumentError" do
|
176
|
+
args = [ArgumentError, '3 for 2']
|
177
|
+
assert_error(*args) { command_with_args 1,2,3 }
|
178
|
+
assert_error(*args) { command_with_args '1 2 3' }
|
179
|
+
assert_error(*args) { command_with_arg_size 1,2,3 }
|
180
|
+
assert_error(*args) { command_with_arg_size '1 2 3' }
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
def command_with_render(*args)
|
185
|
+
basic_command({:render_options=>{:fields=>{:values=>['f1', 'f2']}} }, args)
|
186
|
+
end
|
187
|
+
|
188
|
+
def render_expected(options=nil)
|
189
|
+
View.expects(:render).with(anything, options || anything)
|
190
|
+
end
|
191
|
+
|
192
|
+
context "render" do
|
193
|
+
test "called for command with render_options" do
|
194
|
+
render_expected
|
195
|
+
command_with_render('1')
|
196
|
+
end
|
197
|
+
|
198
|
+
test "called for command without render_options and --render" do
|
199
|
+
render_expected
|
200
|
+
command_with_args('--render 1')
|
201
|
+
end
|
202
|
+
|
203
|
+
test "not called for command with render_options and --render" do
|
204
|
+
Boson.expects(:invoke).never
|
205
|
+
command_with_render('--render 1')
|
206
|
+
end
|
207
|
+
|
208
|
+
test "not called for command without render_options" do
|
209
|
+
Boson.expects(:invoke).never
|
210
|
+
command_with_args('1')
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
context "command renders" do
|
215
|
+
test "with basic render options" do
|
216
|
+
render_expected :fields => ['f1', 'f2']
|
217
|
+
command_with_render("--fields f1,f2 ab")
|
218
|
+
end
|
219
|
+
|
220
|
+
test "without non-render options" do
|
221
|
+
render_expected :fields=>['f1']
|
222
|
+
Scientist.expects(:render?).returns(true)
|
223
|
+
args = ["--render --fields f1 ab"]
|
224
|
+
basic_command({:render_options=>{:fields=>{:values=>['f1', 'f2']}} }, args)
|
225
|
+
end
|
226
|
+
|
227
|
+
test "with user-defined render options" do
|
228
|
+
render_expected :fields=>['f1'], :foo=>true
|
229
|
+
args = ["--foo --fields f1 ab"]
|
230
|
+
basic_command({:render_options=>{:foo=>:boolean, :fields=>{:values=>['f1', 'f2']}} }, args)
|
231
|
+
end
|
232
|
+
|
233
|
+
test "with non-hash user-defined render options" do
|
234
|
+
render_expected :fields=>['f1'], :foo=>true
|
235
|
+
args = ["--foo --fields f1 ab"]
|
236
|
+
basic_command({:render_options=>{:foo=>:boolean, :fields=>%w{f1 f2 f3}} }, args)
|
237
|
+
end
|
238
|
+
end
|
239
|
+
|
240
|
+
test "optionless command renders" do
|
241
|
+
render_expected :fields=>['f1']
|
242
|
+
command({:args=>2, :options=>nil, :render_options=>{:fields=>:array}}, ["--fields f1 ab ok"])
|
243
|
+
end
|
244
|
+
|
245
|
+
context "global options:" do
|
246
|
+
def local_and_global(*args)
|
247
|
+
Scientist.stubs(:render?).returns(false) # turn off rendering caused by :render_options
|
248
|
+
@non_opts = basic_command(@command_options, args)
|
249
|
+
@non_opts.slice!(-1,1) << Scientist.global_options
|
250
|
+
end
|
251
|
+
|
252
|
+
before(:all) {
|
253
|
+
@command_options = {:options=>{:do=>:boolean, :foo=>:boolean},
|
254
|
+
:render_options=>{:dude=>:boolean}}
|
255
|
+
@expected_non_opts = [[], ['doh'], ['doh'], [:doh]]
|
256
|
+
}
|
257
|
+
|
258
|
+
test "local option overrides global one" do
|
259
|
+
['-d', 'doh -d','-d doh', [:doh, '-d']].each_with_index do |args, i|
|
260
|
+
local_and_global(*args).should == [{:do=>true}, {}]
|
261
|
+
@non_opts.should == @expected_non_opts[i]
|
262
|
+
end
|
263
|
+
end
|
264
|
+
|
265
|
+
test "global option before local one is valid" do
|
266
|
+
args_arr = ['--dude -f', '--dude doh -f', '--dude -f doh', [:doh, '--dude -f']]
|
267
|
+
args_arr.each_with_index do |args, i|
|
268
|
+
local_and_global(*args).should == [{:foo=>true}, {:dude=>true}]
|
269
|
+
@non_opts.should == @expected_non_opts[i]
|
270
|
+
end
|
271
|
+
end
|
272
|
+
|
273
|
+
test "global option after local one is invalid" do
|
274
|
+
args_arr = ['-f --dude', '-f doh --dude', '-f --dude doh', [:doh, '-f --dude'] ]
|
275
|
+
args_arr.each_with_index do |args, i|
|
276
|
+
capture_stderr {
|
277
|
+
local_and_global(*args).should == [{:foo=>true}, {}]
|
278
|
+
@non_opts.should == @expected_non_opts[i]
|
279
|
+
}.should =~ /invalid.*dude/
|
280
|
+
end
|
281
|
+
end
|
282
|
+
|
283
|
+
test "--global option adds additional global options" do
|
284
|
+
local_and_global('-g=d -d').should == [{:do=>true}, {:dude=>true, :global=>'d'}]
|
285
|
+
local_and_global('-g "r dude" -d').should == [{:do=>true},
|
286
|
+
{:global=>"r dude", :dude=>true, :render=>true}]
|
287
|
+
end
|
288
|
+
end
|
289
|
+
|
290
|
+
end
|
291
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,119 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'test/unit'
|
3
|
+
require 'context' #gem install jeremymcanally-context --source http://gems.github.com
|
4
|
+
require 'matchy' #gem install jeremymcanally-matchy --source http://gems.github.com
|
5
|
+
require 'mocha'
|
6
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
7
|
+
require 'boson'
|
8
|
+
require 'test_benchmark' if ENV['BENCHMARK']
|
9
|
+
|
10
|
+
class Test::Unit::TestCase
|
11
|
+
# make local so it doesn't pick up my real boson dir
|
12
|
+
Boson.repo.dir = File.dirname(__FILE__)
|
13
|
+
Boson.instance_variable_set "@repos", [Boson.repo]
|
14
|
+
|
15
|
+
def assert_error(error, message=nil)
|
16
|
+
yield
|
17
|
+
rescue error=>e
|
18
|
+
e.class.should == error
|
19
|
+
e.message.should =~ Regexp.new(message) if message
|
20
|
+
else
|
21
|
+
nil.should == error
|
22
|
+
end
|
23
|
+
|
24
|
+
def reset
|
25
|
+
reset_main_object
|
26
|
+
reset_boson
|
27
|
+
end
|
28
|
+
|
29
|
+
def reset_main_object
|
30
|
+
Boson.send :remove_const, "Universe"
|
31
|
+
eval "module ::Boson::Universe; include ::Boson::Commands::Namespace; end"
|
32
|
+
Boson::Commands.send :remove_const, "Blah" if Boson::Commands.const_defined?("Blah")
|
33
|
+
Boson.main_object = Object.new
|
34
|
+
end
|
35
|
+
|
36
|
+
def reset_boson
|
37
|
+
reset_libraries
|
38
|
+
Boson.instance_eval("@commands = nil")
|
39
|
+
end
|
40
|
+
|
41
|
+
def reset_libraries
|
42
|
+
Boson.instance_eval("@libraries = nil")
|
43
|
+
end
|
44
|
+
|
45
|
+
def command_exists?(name, bool=true)
|
46
|
+
!!Boson::Command.find(name).should == bool
|
47
|
+
end
|
48
|
+
|
49
|
+
def library_loaded?(name, bool=true)
|
50
|
+
Boson::Manager.loaded?(name).should == bool
|
51
|
+
end
|
52
|
+
|
53
|
+
def library(name)
|
54
|
+
Boson.library(name)
|
55
|
+
end
|
56
|
+
|
57
|
+
def library_has_module(lib, lib_module)
|
58
|
+
Boson::Manager.loaded?(lib).should == true
|
59
|
+
test_lib = library(lib)
|
60
|
+
(test_lib.module.is_a?(Module) && (test_lib.module.to_s == lib_module)).should == true
|
61
|
+
end
|
62
|
+
|
63
|
+
def library_has_command(lib, command, bool=true)
|
64
|
+
(lib = library(lib)) && lib.commands.include?(command).should == bool
|
65
|
+
end
|
66
|
+
|
67
|
+
# mocks as a file library
|
68
|
+
def mock_library(lib, options={})
|
69
|
+
options[:file_string] ||= ''
|
70
|
+
File.expects(:exists?).with(Boson::FileLibrary.library_file(lib.to_s, Boson.repo.dir)).returns(true)
|
71
|
+
File.expects(:read).returns(options.delete(:file_string))
|
72
|
+
end
|
73
|
+
|
74
|
+
def load(lib, options={})
|
75
|
+
# prevent conflicts with existing File.read stubs
|
76
|
+
Boson::MethodInspector.stubs(:inspector_in_file?).returns(false)
|
77
|
+
mock_library(lib, options) unless options.delete(:no_mock)
|
78
|
+
result = Boson::Manager.load([lib], options)
|
79
|
+
Boson::FileLibrary.reset_file_cache
|
80
|
+
result
|
81
|
+
end
|
82
|
+
|
83
|
+
def capture_stdout(&block)
|
84
|
+
original_stdout = $stdout
|
85
|
+
$stdout = fake = StringIO.new
|
86
|
+
begin
|
87
|
+
yield
|
88
|
+
ensure
|
89
|
+
$stdout = original_stdout
|
90
|
+
end
|
91
|
+
fake.string
|
92
|
+
end
|
93
|
+
|
94
|
+
def with_config(options)
|
95
|
+
old_config = Boson.repo.config
|
96
|
+
Boson.repo.config = Boson.repo.config.merge(options)
|
97
|
+
yield
|
98
|
+
Boson.repo.config = old_config
|
99
|
+
end
|
100
|
+
|
101
|
+
def capture_stderr(&block)
|
102
|
+
original_stderr = $stderr
|
103
|
+
$stderr = fake = StringIO.new
|
104
|
+
begin
|
105
|
+
yield
|
106
|
+
ensure
|
107
|
+
$stderr = original_stderr
|
108
|
+
end
|
109
|
+
fake.string
|
110
|
+
end
|
111
|
+
|
112
|
+
def create_library(libraries, attributes={})
|
113
|
+
libraries = [libraries] unless libraries.is_a?(Array)
|
114
|
+
libraries.map {|e|
|
115
|
+
lib = Boson::Library.new({:name=>e}.update(attributes))
|
116
|
+
Boson::Manager.add_library(lib); lib
|
117
|
+
}
|
118
|
+
end
|
119
|
+
end
|