boson-more 0.1.0
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/.gemspec +22 -0
- data/LICENSE.txt +22 -0
- data/README.md +97 -0
- data/Rakefile +35 -0
- data/deps.rip +1 -0
- data/lib/boson/alias.rb +75 -0
- data/lib/boson/argument_inspector.rb +90 -0
- data/lib/boson/commands/core.rb +67 -0
- data/lib/boson/commands/view_core.rb +19 -0
- data/lib/boson/commands/web_core.rb +153 -0
- data/lib/boson/comment_inspector.rb +100 -0
- data/lib/boson/console.rb +40 -0
- data/lib/boson/console_runner.rb +60 -0
- data/lib/boson/index.rb +48 -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/libraries.rb +183 -0
- data/lib/boson/more/version.rb +5 -0
- data/lib/boson/more.rb +18 -0
- data/lib/boson/more_commands.rb +14 -0
- data/lib/boson/more_inspector.rb +42 -0
- data/lib/boson/more_manager.rb +34 -0
- data/lib/boson/more_method_inspector.rb +74 -0
- data/lib/boson/more_option_parser.rb +28 -0
- data/lib/boson/more_scientist.rb +68 -0
- data/lib/boson/more_util.rb +30 -0
- data/lib/boson/namespace.rb +31 -0
- data/lib/boson/namespacer.rb +117 -0
- data/lib/boson/pipe.rb +156 -0
- data/lib/boson/pipe_runner.rb +44 -0
- data/lib/boson/pipes.rb +75 -0
- data/lib/boson/repo.rb +96 -0
- data/lib/boson/repo_index.rb +135 -0
- data/lib/boson/runner_options.rb +88 -0
- data/lib/boson/save.rb +198 -0
- data/lib/boson/science.rb +273 -0
- data/lib/boson/view.rb +98 -0
- data/lib/boson/viewable.rb +48 -0
- data/test/alias_test.rb +55 -0
- data/test/argument_inspector_test.rb +40 -0
- data/test/command_test.rb +22 -0
- data/test/commands_test.rb +53 -0
- data/test/comment_inspector_test.rb +126 -0
- data/test/console_runner_test.rb +58 -0
- data/test/deps.rip +4 -0
- data/test/file_library_test.rb +41 -0
- data/test/gem_library_test.rb +40 -0
- data/test/libraries_test.rb +55 -0
- data/test/loader_test.rb +38 -0
- data/test/module_library_test.rb +30 -0
- data/test/more_manager_test.rb +29 -0
- data/test/more_method_inspector_test.rb +42 -0
- data/test/more_scientist_test.rb +10 -0
- data/test/namespacer_test.rb +61 -0
- data/test/pipes_test.rb +65 -0
- data/test/repo_index_test.rb +123 -0
- data/test/repo_test.rb +23 -0
- data/test/runner_options_test.rb +29 -0
- data/test/save_test.rb +86 -0
- data/test/science_test.rb +58 -0
- data/test/scientist_test.rb +195 -0
- data/test/test_helper.rb +165 -0
- data/test/web_test.rb +22 -0
- metadata +169 -0
@@ -0,0 +1,40 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'test_helper')
|
2
|
+
|
3
|
+
describe "scrape_with_eval" do
|
4
|
+
def args_from(string)
|
5
|
+
# methods need options to have their args parsed with ArgumentInspector
|
6
|
+
string.gsub!(/(def blah)/, 'options :a=>1; \1')
|
7
|
+
Inspector.enable
|
8
|
+
::Boson::Commands::Aaa.module_eval(string)
|
9
|
+
Inspector.disable
|
10
|
+
MethodInspector.store[:args]['blah']
|
11
|
+
end
|
12
|
+
|
13
|
+
before_all { eval "module ::Boson::Commands::Aaa; end"; }
|
14
|
+
before { MethodInspector.mod_store[::Boson::Commands::Aaa] = {} }
|
15
|
+
|
16
|
+
it "determines arguments with literal defaults" do
|
17
|
+
args_from("def blah(arg1,arg2='val2'); end").should == [['arg1'], ['arg2','val2']]
|
18
|
+
end
|
19
|
+
|
20
|
+
it "determines splat arguments" do
|
21
|
+
args_from("def blah(arg1, *args); end").should == [['arg1'], ["*args"]]
|
22
|
+
end
|
23
|
+
|
24
|
+
it "determines arguments with local values before a method" do
|
25
|
+
body = "AWESOME='awesome'; def sweet; 'ok'; end; def blah(arg1=AWESOME, arg2=sweet); end"
|
26
|
+
args_from(body).should == [['arg1', 'awesome'], ['arg2', 'ok']]
|
27
|
+
end
|
28
|
+
|
29
|
+
it "doesn't get arguments with local values after a method" do
|
30
|
+
args_from("def blah(arg1=nope) end; def nope; 'nope'; end").should == nil
|
31
|
+
end
|
32
|
+
|
33
|
+
it "doesn't determine arguments of a private method" do
|
34
|
+
args_from("private; def blah(arg1,arg2); end").should == nil
|
35
|
+
end
|
36
|
+
|
37
|
+
it "doesn't determine arguments if an error occurs" do
|
38
|
+
args_from("def blah(arg1,arg2=raise); end").should == nil
|
39
|
+
end
|
40
|
+
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,53 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'test_helper')
|
2
|
+
|
3
|
+
module Boson
|
4
|
+
class CommandsTest < Test::Unit::TestCase
|
5
|
+
before(:all) {
|
6
|
+
@higgs = Boson.main_object
|
7
|
+
if Boson.libraries.size.zero?
|
8
|
+
reset_boson
|
9
|
+
ancestors = class <<Boson.main_object; self end.ancestors
|
10
|
+
# allows running just this test file
|
11
|
+
Manager.load Runner.default_libraries unless ancestors.include?(Boson::Commands::Core)
|
12
|
+
end
|
13
|
+
}
|
14
|
+
|
15
|
+
def render_expects(&block)
|
16
|
+
View.expects(:render).with(&block)
|
17
|
+
end
|
18
|
+
|
19
|
+
context "libraries" do
|
20
|
+
before(:all) {
|
21
|
+
Boson.libraries << Boson::Library.new(:name=>'blah')
|
22
|
+
Boson.libraries << Boson::Library.new(:name=>'another', :module=>"Cool")
|
23
|
+
}
|
24
|
+
|
25
|
+
test "lists all when given no argument" do
|
26
|
+
render_expects {|*args| args[0].size == Boson.libraries.size }
|
27
|
+
@higgs.libraries
|
28
|
+
end
|
29
|
+
|
30
|
+
test "searches with a given search field" do
|
31
|
+
render_expects {|*args| args[0] == [Boson.library('another')]}
|
32
|
+
@higgs.libraries('Cool', :query_fields=>[:module])
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
context "commands" do
|
37
|
+
before(:all) {
|
38
|
+
Boson.commands << Command.create('some', Library.new(:name=>'thing'))
|
39
|
+
Boson.commands << Command.create('and', Library.new(:name=>'this'))
|
40
|
+
}
|
41
|
+
|
42
|
+
test "lists all when given no argument" do
|
43
|
+
render_expects {|*args| args[0].size == Boson.commands.size }
|
44
|
+
@higgs.commands
|
45
|
+
end
|
46
|
+
|
47
|
+
test "searches with a given search field" do
|
48
|
+
render_expects {|*args| args[0] == [Command.find('and')]}
|
49
|
+
@higgs.commands('this', :query_fields=>[:lib])
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
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', ' # @options {:a=>true}',
|
115
|
+
'#blah', " def foo", " end", "end"]
|
116
|
+
expected = {:desc=>"blah", :options=>{:a=>true}, :config=>{:a=>true}}
|
117
|
+
CommentInspector.scrape(@lines.join("\n"), 5, Optional).should == expected
|
118
|
+
end
|
119
|
+
|
120
|
+
it "scrapes all comment types with explicit desc" do
|
121
|
+
@lines = ["module Foo", '#@desc blah', ' # @options {:a=>true}',
|
122
|
+
' # @config :a=>true', " def foo", " end", "end"]
|
123
|
+
expected = {:desc=>"blah", :options=>{:a=>true}, :config=>{:a=>true}}
|
124
|
+
CommentInspector.scrape(@lines.join("\n"), 5, Optional).should == expected
|
125
|
+
end
|
126
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'test_helper')
|
2
|
+
|
3
|
+
describe "repl_runner" do
|
4
|
+
def start(hash={})
|
5
|
+
Hirb.stubs(:enable)
|
6
|
+
Boson.start(hash.merge(:verbose=>false))
|
7
|
+
end
|
8
|
+
|
9
|
+
before_all { reset }
|
10
|
+
before { ConsoleRunner.instance_eval("@initialized = false") }
|
11
|
+
|
12
|
+
it "loads default libraries and libraries in :console_defaults config" do
|
13
|
+
defaults = BareRunner.default_libraries + ['yo']
|
14
|
+
with_config(:console_defaults=>['yo']) do
|
15
|
+
Manager.expects(:load).with {|*args| args[0] == defaults }
|
16
|
+
start
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
it "doesn't call init twice" do
|
21
|
+
capture_stderr { start }
|
22
|
+
ConsoleRunner.expects(:init).never
|
23
|
+
start
|
24
|
+
end
|
25
|
+
|
26
|
+
it "loads multiple libraries with :libraries option" do
|
27
|
+
ConsoleRunner.expects(:init)
|
28
|
+
Manager.expects(:load).with([:lib1,:lib2], anything)
|
29
|
+
start(:libraries=>[:lib1, :lib2])
|
30
|
+
end
|
31
|
+
|
32
|
+
it "autoloader autoloads libraries" do
|
33
|
+
start(:autoload_libraries=>true)
|
34
|
+
Index.expects(:read)
|
35
|
+
Index.expects(:find_library).with('blah').returns('blah')
|
36
|
+
Manager.expects(:load).with('blah', anything)
|
37
|
+
Boson.main_object.blah
|
38
|
+
end
|
39
|
+
after_all { FileUtils.rm_r File.dirname(__FILE__)+'/config', :force=>true }
|
40
|
+
end
|
41
|
+
|
42
|
+
describe "console options" do
|
43
|
+
before_all { reset }
|
44
|
+
|
45
|
+
it "console option starts irb" do
|
46
|
+
ConsoleRunner.expects(:start)
|
47
|
+
Util.expects(:which).returns("/usr/bin/irb")
|
48
|
+
ConsoleRunner.expects(:load_repl).with("/usr/bin/irb")
|
49
|
+
start("--console")
|
50
|
+
end
|
51
|
+
|
52
|
+
it "console option but no irb found prints error" do
|
53
|
+
ConsoleRunner.expects(:start)
|
54
|
+
Util.expects(:which).returns(nil)
|
55
|
+
ConsoleRunner.expects(:abort).with {|arg| arg[/Console not found/] }
|
56
|
+
start '--console'
|
57
|
+
end
|
58
|
+
end
|
data/test/deps.rip
ADDED
@@ -0,0 +1,41 @@
|
|
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({}) }
|
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([File.expand_path('./test/commands/site/github.rb')])
|
27
|
+
load 'github', :file_string=>"module Github; def blah; end; end", :exists=>false
|
28
|
+
library_has_module('site/github', "Boson::Commands::Site::Github")
|
29
|
+
command_exists?('blah')
|
30
|
+
end
|
31
|
+
|
32
|
+
it "loads a plugin library by creating its module" do
|
33
|
+
load(:blah, :file_string=>"def blah; end")
|
34
|
+
library_has_module('blah', "Boson::Commands::Blah")
|
35
|
+
command_exists?('blah', false)
|
36
|
+
end
|
37
|
+
|
38
|
+
it "prints error for file library with multiple modules" do
|
39
|
+
capture_stderr { load(:blah, :file_string=>"module Doo; end; module Daa; end") }.should =~ /Can't.*config/
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
describe "Loader" do
|
2
|
+
describe "load" do
|
3
|
+
before { reset }
|
4
|
+
describe "gem library" do
|
5
|
+
def mock_library(lib, options={})
|
6
|
+
options[:file_string] ||= ''
|
7
|
+
File.stubs(:exists?).returns(false)
|
8
|
+
GemLibrary.expects(:is_a_gem?).returns(true)
|
9
|
+
Util.expects(:safe_require).with { eval options.delete(:file_string) || ''; true}.returns(true)
|
10
|
+
end
|
11
|
+
|
12
|
+
it "loads" do
|
13
|
+
with_config(:libraries=>{"dude"=>{:module=>'Dude'}}) do
|
14
|
+
load "dude", :file_string=>"module ::Dude; def blah; end; end"
|
15
|
+
library_has_module('dude', "Dude")
|
16
|
+
command_exists?("blah")
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
it "with kernel methods loads" do
|
21
|
+
load "dude", :file_string=>"module ::Kernel; def dude; end; end"
|
22
|
+
library_loaded? 'dude'
|
23
|
+
library('dude').module.should == nil
|
24
|
+
command_exists?("dude")
|
25
|
+
end
|
26
|
+
|
27
|
+
it "prints error when nonexistent" do
|
28
|
+
capture_stderr { load('blah') }.should =~ /Library blah did not/
|
29
|
+
end
|
30
|
+
|
31
|
+
it "with invalid module prints error" do
|
32
|
+
with_config(:libraries=>{"coolio"=>{:module=>"Cool"}}) do
|
33
|
+
capture_stderr {
|
34
|
+
load('coolio', :file_string=>"module ::Coolio; def coolio; end; end")
|
35
|
+
}.should =~ /Unable.*coolio.*No module/
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
|
2
|
+
describe "Loader" do
|
3
|
+
before { Gem.stubs(:loaded_specs).returns({}) }
|
4
|
+
describe "config" do
|
5
|
+
before { reset }
|
6
|
+
|
7
|
+
# if this test fails, other exists? using methods fail
|
8
|
+
it "from callback recursively merges with user's config" do
|
9
|
+
with_config(:libraries=>{'blah'=>{:commands=>{'bling'=>{:desc=>'bling', :options=>{:num=>3}}}}}) do
|
10
|
+
File.stubs(:exists?).returns(true)
|
11
|
+
load :blah, :file_string=> "module Blah; def self.config; {:commands=>{'blang'=>{:alias=>'ba'}, " +
|
12
|
+
"'bling'=>{:options=>{:verbose=>:boolean}}}}; end; end"
|
13
|
+
library('blah').command_object('bling').options.should == {:verbose=>:boolean, :num=>3}
|
14
|
+
library('blah').command_object('bling').desc.should == 'bling'
|
15
|
+
library('blah').command_object('blang').alias.should == 'ba'
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
it "non-hash from inspector overridden by user's config" do
|
20
|
+
with_config(:libraries=>{'blah'=>{:commands=>{'bling'=>{:desc=>'already'}}}}) do
|
21
|
+
load :blah, :file_string=>"module Blah; #from file\ndef bling; end; end"
|
22
|
+
library('blah').command_object('bling').desc.should == 'already'
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
it "from inspector attribute config sets command's config" do
|
27
|
+
load :blah, :file_string=>"module Blah; config :alias=>'ok'\n; def bling; end; end"
|
28
|
+
library('blah').command_object('bling').alias.should == 'ok'
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe "load" do
|
33
|
+
before { reset }
|
34
|
+
it "calls included callback" do
|
35
|
+
capture_stdout {
|
36
|
+
load :blah, :file_string=>"module Blah; def self.included(mod); puts 'included blah'; end; def blah; end; end"
|
37
|
+
}.should =~ /included blah/
|
38
|
+
end
|
39
|
+
|
40
|
+
it "calls after_included callback" do
|
41
|
+
capture_stdout {
|
42
|
+
load :blah, :file_string=>"module Blah; def self.after_included; puts 'yo'; end; end"
|
43
|
+
}.should == "yo\n"
|
44
|
+
end
|
45
|
+
|
46
|
+
it "prints error if library module conflicts with top level constant/module" do
|
47
|
+
capture_stderr {
|
48
|
+
load :blah, :file_string=>"module Object; def self.blah; end; end"
|
49
|
+
}.should =~ /conflict.*'Object'/
|
50
|
+
library_loaded?('blah')
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
after_all { FileUtils.rm_r File.dirname(__FILE__)+'/commands/', :force=>true }
|
55
|
+
end
|
data/test/loader_test.rb
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
describe "Loader" do
|
2
|
+
it "loads a library and creates its class commands" do
|
3
|
+
with_config(:libraries=>{"blah"=>{:class_commands=>{"bling"=>"Blah.bling", "Blah"=>['hmm']}}}) do
|
4
|
+
load :blah, :file_string=>"module Blah; def self.bling; end; def self.hmm; end; end"
|
5
|
+
command_exists? 'bling'
|
6
|
+
command_exists? 'hmm'
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
it "loads a module library and all its class methods by default" do
|
11
|
+
eval %[module ::Harvey; def self.bird; end; def self.eagle; end; end]
|
12
|
+
load ::Harvey, :no_mock=>true
|
13
|
+
library_has_command('harvey', 'bird')
|
14
|
+
library_has_command('harvey', 'eagle')
|
15
|
+
end
|
16
|
+
|
17
|
+
it "prints error when nonexistent" do
|
18
|
+
capture_stderr { load('blah') }.should =~ /Library blah did not/
|
19
|
+
end
|
20
|
+
|
21
|
+
it "prints error if namespace conflicts with existing commands" do
|
22
|
+
eval "module ::Conflict; def self.bleng; end; end"
|
23
|
+
load Conflict, :no_mock=>true
|
24
|
+
with_config(:libraries=>{'bleng'=>{:namespace=>true}}) do
|
25
|
+
capture_stderr {
|
26
|
+
load 'bleng', :file_string=>"module Bleng; def bling; end; end"
|
27
|
+
}.should =~ /conflict.*bleng/
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
it "hash from inspector recursively merged with user's config" do
|
32
|
+
with_config(:libraries=>{'blah'=>{:commands=>{'blung'=>{:args=>[], :options=>{:sort=>'this'}}}}}) do
|
33
|
+
CommentInspector.expects(:scrape).returns({:options=>{:fields=>['this']}})
|
34
|
+
load :blah, :file_string=>"module Blah; def blung; end; end"
|
35
|
+
library('blah').command_object('blung').options.should == {:fields=>["this"], :sort=>"this"}
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
describe "Loader" do
|
2
|
+
describe "load" do
|
3
|
+
before { reset }
|
4
|
+
|
5
|
+
describe "module library" do
|
6
|
+
def mock_library(*args); end
|
7
|
+
|
8
|
+
it "loads a module library and all its class methods by default" do
|
9
|
+
eval %[module ::Harvey; def self.bird; end; def self.eagle; end; end]
|
10
|
+
load ::Harvey, :no_mock=>true
|
11
|
+
library_has_command('harvey', 'bird')
|
12
|
+
library_has_command('harvey', 'eagle')
|
13
|
+
end
|
14
|
+
|
15
|
+
it "loads a module library with specified commands" do
|
16
|
+
eval %[module ::Peanut; def self.bird; end; def self.eagle; end; end]
|
17
|
+
load ::Peanut, :no_mock=>true, :commands=>%w{bird}
|
18
|
+
library('peanut').commands.size.should == 1
|
19
|
+
library_has_command('peanut', 'bird')
|
20
|
+
end
|
21
|
+
|
22
|
+
it "loads a module library as a class" do
|
23
|
+
eval %[class ::Mentok; def self.bird; end; def self.eagle; end; end]
|
24
|
+
load ::Mentok, :no_mock=>true, :commands=>%w{bird}
|
25
|
+
library('mentok').commands.size.should == 1
|
26
|
+
library_has_command('mentok', 'bird')
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
describe "Loader" do
|
2
|
+
before { Gem.stubs(:loaded_specs).returns({}) }
|
3
|
+
describe 'load' do
|
4
|
+
before { reset }
|
5
|
+
|
6
|
+
it "loads a library with dependencies" do
|
7
|
+
File.stubs(:exists?).returns(true)
|
8
|
+
File.stubs(:read).returns("module Water; def water; end; end", "module Oaks; def oaks; end; end")
|
9
|
+
with_config(:libraries=>{"water"=>{:dependencies=>"oaks"}}) do
|
10
|
+
load 'water', :no_mock=>true
|
11
|
+
library_has_module('water', "Boson::Commands::Water")
|
12
|
+
library_has_module('oaks', "Boson::Commands::Oaks")
|
13
|
+
command_exists?('water')
|
14
|
+
command_exists?('oaks')
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
it "prints error for library with invalid dependencies" do
|
19
|
+
GemLibrary.stubs(:is_a_gem?).returns(true) #mock all as gem libs
|
20
|
+
Util.stubs(:safe_require).returns(true)
|
21
|
+
with_config(:libraries=>{"water"=>{:dependencies=>"fire"}, "fire"=>{:dependencies=>"man"}}) do
|
22
|
+
capture_stderr {
|
23
|
+
load('water', :no_mock=>true)
|
24
|
+
}.should == "Unable to load library fire. Reason: Can't load dependency man\nUnable to load"+
|
25
|
+
" library water. Reason: Can't load dependency fire\n"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'test_helper')
|
2
|
+
|
3
|
+
describe "MethodInspector" do
|
4
|
+
before_all { MethodInspector.mod_store = {} }
|
5
|
+
describe "commands module with" do
|
6
|
+
it "not all method attributes set causes method_locations to be set" do
|
7
|
+
MethodInspector.stubs(:find_method_locations).returns(["/some/path", 10])
|
8
|
+
parsed = parse "desc 'yo'; def yo; end; options :yep=>1; def yep; end; " +
|
9
|
+
"option :b, :boolean; config :a=>1; desc 'z'; options :a=>1; def az; end"
|
10
|
+
parsed[:method_locations].key?('yo').should == true
|
11
|
+
parsed[:method_locations].key?('yep').should == true
|
12
|
+
parsed[:method_locations].key?('az').should == false
|
13
|
+
end
|
14
|
+
|
15
|
+
it "no find_method_locations doesn't set method_locations" do
|
16
|
+
MethodInspector.stubs(:find_method_locations).returns(nil)
|
17
|
+
parse("def bluh; end")[:method_locations].key?('bluh').should == false
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe "scrape_arguments" do
|
22
|
+
def args_from(file_string)
|
23
|
+
MethodInspector.scrape_arguments(file_string, "blah")
|
24
|
+
end
|
25
|
+
|
26
|
+
it "parses arguments of class method" do
|
27
|
+
args_from(" def YAML.blah( filepath )\n").should == [['filepath']]
|
28
|
+
end
|
29
|
+
|
30
|
+
it "parses arguments with no spacing" do
|
31
|
+
args_from("def bong; end\ndef blah(arg1,arg2='val2')\nend").should == [["arg1"], ['arg2', "'val2'"]]
|
32
|
+
end
|
33
|
+
|
34
|
+
it "parses arguments with spacing" do
|
35
|
+
args_from("\t def blah( arg1=val1, arg2 = val2)").should == [["arg1","val1"], ["arg2", "val2"]]
|
36
|
+
end
|
37
|
+
|
38
|
+
it "parses arguments without parenthesis" do
|
39
|
+
args_from(" def blah arg1, arg2, arg3={}").should == [['arg1'], ['arg2'], ['arg3','{}']]
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
describe "Scientist" do
|
2
|
+
it "with debug option prints debug" do
|
3
|
+
capture_stdout { command_with_args("-v ok") }.should =~ /Arguments.*ok/
|
4
|
+
end
|
5
|
+
|
6
|
+
it "with pretend option prints arguments and returns early" do
|
7
|
+
Scientist.expects(:process_result).never
|
8
|
+
capture_stdout { command_with_args("-p ok") }.should =~ /Arguments.*ok/
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,61 @@
|
|
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({}) }
|
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
|
+
end
|
18
|
+
|
19
|
+
describe "load" do
|
20
|
+
before { reset }
|
21
|
+
|
22
|
+
it "namespaces a library that has a method conflict" do
|
23
|
+
load('blah', :file_string=>"module Blah; def chwhat; end; end")
|
24
|
+
capture_stderr {
|
25
|
+
load('chwhat2', :file_string=>"module Chwhat2; def chwhat; end; end")
|
26
|
+
}.should =~ /conflict.*chwhat.*chwhat2/
|
27
|
+
library_has_command('namespace', 'chwhat2')
|
28
|
+
library_has_command('chwhat2', 'chwhat')
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe "library with namespace" do
|
33
|
+
before_all { reset_main_object }
|
34
|
+
before { reset_boson }
|
35
|
+
|
36
|
+
it "loads and defaults to library name" do
|
37
|
+
with_config(:libraries=>{'blang'=>{:namespace=>true}}) do
|
38
|
+
load 'blang', :file_string=>"module Blang; def bling; end; end"
|
39
|
+
library_has_command('blang', 'bling')
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
it "loads with config namespace" do
|
44
|
+
with_config(:libraries=>{'blung'=>{:namespace=>'dope'}}) do
|
45
|
+
load 'blung', :file_string=>"module Blung; def bling; end; end"
|
46
|
+
library_has_command('blung', 'bling')
|
47
|
+
library('blung').commands.size.should == 1
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
it "prints error if namespace conflicts with existing commands" do
|
52
|
+
eval "module ::Conflict; def self.bleng; end; end"
|
53
|
+
load Conflict, :no_mock=>true
|
54
|
+
with_config(:libraries=>{'bleng'=>{:namespace=>true}}) do
|
55
|
+
capture_stderr {
|
56
|
+
load 'bleng', :file_string=>"module Bleng; def bling; end; end"
|
57
|
+
}.should =~ /conflict.*bleng/
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|