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.
Files changed (67) hide show
  1. data/.gemspec +22 -0
  2. data/LICENSE.txt +22 -0
  3. data/README.md +97 -0
  4. data/Rakefile +35 -0
  5. data/deps.rip +1 -0
  6. data/lib/boson/alias.rb +75 -0
  7. data/lib/boson/argument_inspector.rb +90 -0
  8. data/lib/boson/commands/core.rb +67 -0
  9. data/lib/boson/commands/view_core.rb +19 -0
  10. data/lib/boson/commands/web_core.rb +153 -0
  11. data/lib/boson/comment_inspector.rb +100 -0
  12. data/lib/boson/console.rb +40 -0
  13. data/lib/boson/console_runner.rb +60 -0
  14. data/lib/boson/index.rb +48 -0
  15. data/lib/boson/libraries/file_library.rb +144 -0
  16. data/lib/boson/libraries/gem_library.rb +30 -0
  17. data/lib/boson/libraries/local_file_library.rb +30 -0
  18. data/lib/boson/libraries/module_library.rb +37 -0
  19. data/lib/boson/libraries/require_library.rb +23 -0
  20. data/lib/boson/libraries.rb +183 -0
  21. data/lib/boson/more/version.rb +5 -0
  22. data/lib/boson/more.rb +18 -0
  23. data/lib/boson/more_commands.rb +14 -0
  24. data/lib/boson/more_inspector.rb +42 -0
  25. data/lib/boson/more_manager.rb +34 -0
  26. data/lib/boson/more_method_inspector.rb +74 -0
  27. data/lib/boson/more_option_parser.rb +28 -0
  28. data/lib/boson/more_scientist.rb +68 -0
  29. data/lib/boson/more_util.rb +30 -0
  30. data/lib/boson/namespace.rb +31 -0
  31. data/lib/boson/namespacer.rb +117 -0
  32. data/lib/boson/pipe.rb +156 -0
  33. data/lib/boson/pipe_runner.rb +44 -0
  34. data/lib/boson/pipes.rb +75 -0
  35. data/lib/boson/repo.rb +96 -0
  36. data/lib/boson/repo_index.rb +135 -0
  37. data/lib/boson/runner_options.rb +88 -0
  38. data/lib/boson/save.rb +198 -0
  39. data/lib/boson/science.rb +273 -0
  40. data/lib/boson/view.rb +98 -0
  41. data/lib/boson/viewable.rb +48 -0
  42. data/test/alias_test.rb +55 -0
  43. data/test/argument_inspector_test.rb +40 -0
  44. data/test/command_test.rb +22 -0
  45. data/test/commands_test.rb +53 -0
  46. data/test/comment_inspector_test.rb +126 -0
  47. data/test/console_runner_test.rb +58 -0
  48. data/test/deps.rip +4 -0
  49. data/test/file_library_test.rb +41 -0
  50. data/test/gem_library_test.rb +40 -0
  51. data/test/libraries_test.rb +55 -0
  52. data/test/loader_test.rb +38 -0
  53. data/test/module_library_test.rb +30 -0
  54. data/test/more_manager_test.rb +29 -0
  55. data/test/more_method_inspector_test.rb +42 -0
  56. data/test/more_scientist_test.rb +10 -0
  57. data/test/namespacer_test.rb +61 -0
  58. data/test/pipes_test.rb +65 -0
  59. data/test/repo_index_test.rb +123 -0
  60. data/test/repo_test.rb +23 -0
  61. data/test/runner_options_test.rb +29 -0
  62. data/test/save_test.rb +86 -0
  63. data/test/science_test.rb +58 -0
  64. data/test/scientist_test.rb +195 -0
  65. data/test/test_helper.rb +165 -0
  66. data/test/web_test.rb +22 -0
  67. 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,4 @@
1
+ mocha >=0
2
+ bacon >=1.1.0
3
+ mocha-on-bacon >=0
4
+ bacon-bits >=0
@@ -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
@@ -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