boson-more 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
data/test/pipes_test.rb
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'test_helper')
|
2
|
+
|
3
|
+
describe "Pipes" do
|
4
|
+
before_all { ::Ab = Struct.new(:a, :b) }
|
5
|
+
describe "query_pipe" do
|
6
|
+
before_all {
|
7
|
+
@hashes = [{:a=>'some', :b=>'thing'}, {:a=>:more, :b=>:yep}]
|
8
|
+
@objects = [Ab.new('some', 'thing'), Ab.new(:more, :yep)]
|
9
|
+
}
|
10
|
+
|
11
|
+
it "searches one query" do
|
12
|
+
[@hashes, @objects].each {|e|
|
13
|
+
Pipes.query_pipe(e, :a=>'some').should == e[0,1]
|
14
|
+
}
|
15
|
+
end
|
16
|
+
|
17
|
+
it "searches non-string values" do
|
18
|
+
[@hashes, @objects].each {|e|
|
19
|
+
Pipes.query_pipe(e, :a=>'more').should == e[1,1]
|
20
|
+
}
|
21
|
+
end
|
22
|
+
|
23
|
+
it "searches multiple search terms" do
|
24
|
+
[@hashes, @objects].each {|e|
|
25
|
+
Pipes.query_pipe(e, :a=>'some', :b=>'yep').size.should == 2
|
26
|
+
}
|
27
|
+
end
|
28
|
+
|
29
|
+
it "prints error for invalid search field" do
|
30
|
+
capture_stderr { Pipes.query_pipe(@objects, :blah=>'blah') }.should =~ /failed.*'blah'/
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe "sort_pipe" do
|
35
|
+
before_all {
|
36
|
+
@hashes = [{:a=>'some', :b=>'thing'}, {:a=>:more, :b=>:yep}]
|
37
|
+
@objects = [Ab.new('some', 'thing'), Ab.new(:more, :yep)]
|
38
|
+
}
|
39
|
+
it "sorts objects with values of different types" do
|
40
|
+
Pipes.sort_pipe(@objects, :a).should == @objects.reverse
|
41
|
+
end
|
42
|
+
|
43
|
+
it "sorts hashes with values of different types" do
|
44
|
+
Pipes.sort_pipe(@hashes, :a).should == @hashes.reverse
|
45
|
+
end
|
46
|
+
|
47
|
+
it "sorts numeric values" do
|
48
|
+
hashes = [{:a=>10, :b=>4}, {:a=>5, :b=>3}]
|
49
|
+
Pipes.sort_pipe(hashes, :a).should == hashes.reverse
|
50
|
+
end
|
51
|
+
|
52
|
+
it "sorts numeric hash keys by string" do
|
53
|
+
hashes = [{2=>'thing'}, {2=>'some'}]
|
54
|
+
Pipes.sort_pipe(hashes, '2').should == hashes.reverse
|
55
|
+
end
|
56
|
+
|
57
|
+
it "sorts numeric hash keys by string" do
|
58
|
+
Pipes.sort_pipe(@hashes, 'a').should == @hashes.reverse
|
59
|
+
end
|
60
|
+
|
61
|
+
it "prints error for invalid sort field" do
|
62
|
+
capture_stderr { Pipes.sort_pipe(@objects, :blah)}.should =~ /failed.*'blah'/
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,123 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'test_helper')
|
2
|
+
|
3
|
+
describe "RepoIndex" do
|
4
|
+
# since we're defining our own @commands, @libraries, @lib_hashes
|
5
|
+
def index
|
6
|
+
@index ||= begin
|
7
|
+
ind = RepoIndex.new(Boson.repo)
|
8
|
+
ind.instance_variable_set "@read", true
|
9
|
+
ind
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
describe "read_and_transfer" do
|
14
|
+
before { reset_boson; index.instance_eval "@libraries = @commands = nil" }
|
15
|
+
|
16
|
+
def transfers(options={})
|
17
|
+
index.instance_variable_set "@libraries", [Library.new(:name=>'blah', :commands=>['blurb']),
|
18
|
+
Library.new(:name=>'bling')]
|
19
|
+
index.instance_variable_set "@commands", [Command.new(:name=>'blurb', :lib=>'blah')]
|
20
|
+
index.read_and_transfer options[:ignored] || []
|
21
|
+
Boson.libraries.map {|e| e.name}.should == options[:libraries]
|
22
|
+
Boson.commands.map {|e| e.name}.should == options[:commands]
|
23
|
+
end
|
24
|
+
|
25
|
+
it "transfers libraries with no libraries to ignore" do
|
26
|
+
transfers :libraries=>%w{blah bling}, :commands=>%w{blurb}, :ignored=>[]
|
27
|
+
end
|
28
|
+
|
29
|
+
it "transfers libraries and commands except for ignored libraries and its commands" do
|
30
|
+
transfers :libraries=>%w{bling}, :commands=>[], :ignored=>%w{blah}
|
31
|
+
end
|
32
|
+
|
33
|
+
it "doesn't replace existing libraries" do
|
34
|
+
lib = Library.new(:name=>'blah')
|
35
|
+
cmd = Command.new(:name=>'blurb', :lib=>'blah')
|
36
|
+
Boson.libraries << lib
|
37
|
+
Boson.commands << cmd
|
38
|
+
transfers :libraries=>%w{blah bling}, :commands=>%w{blurb}
|
39
|
+
Boson.libraries.include?(lib).should == true
|
40
|
+
Boson.commands.include?(cmd).should == true
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
describe "find_library" do
|
45
|
+
before_all {
|
46
|
+
reset_boson
|
47
|
+
commands = [Command.new(:name=>'blurb', :lib=>'blah', :alias=>'bb'),
|
48
|
+
Command.new(:name=>'sub', :lib=>'bling', :alias=>'s')
|
49
|
+
]
|
50
|
+
index.instance_variable_set "@commands", commands
|
51
|
+
index.instance_variable_set "@libraries", [Library.new(:name=>'blah'), Library.new(:name=>'bling', :namespace=>'bling')]
|
52
|
+
}
|
53
|
+
|
54
|
+
it "finds command aliased or not" do
|
55
|
+
index.find_library('blurb').should == 'blah'
|
56
|
+
index.find_library('bb').should == 'blah'
|
57
|
+
end
|
58
|
+
|
59
|
+
it "doesn't find command" do
|
60
|
+
index.find_library('blah').should == nil
|
61
|
+
end
|
62
|
+
|
63
|
+
it "finds a subcommand aliased or not" do
|
64
|
+
index.find_library('bling.sub').should == 'bling'
|
65
|
+
# @index.find_library('bl.s').should == 'bling'
|
66
|
+
end
|
67
|
+
|
68
|
+
it "finds namespace command aliased or not without a subcommand" do
|
69
|
+
index.find_library('bling').should == 'bling'
|
70
|
+
# @index.find_library('bl').should == 'bling'
|
71
|
+
end
|
72
|
+
|
73
|
+
it "doesn't find a subcommand" do
|
74
|
+
index.find_library('d.d').should == nil
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
# enable once this is moved
|
79
|
+
xdescribe "changed_libraries" do
|
80
|
+
before_all { index.instance_eval "@lib_hashes = nil" }
|
81
|
+
|
82
|
+
def changed(string, all_libs=['file1'])
|
83
|
+
index.repo.expects(:all_libraries).returns(all_libs)
|
84
|
+
index.instance_variable_set "@lib_hashes", {"file1"=>Digest::MD5.hexdigest("state1")}
|
85
|
+
File.stubs(:exists?).returns(true)
|
86
|
+
File.expects(:read).returns(string)
|
87
|
+
index.changed_libraries
|
88
|
+
end
|
89
|
+
|
90
|
+
it "detects changed libraries" do
|
91
|
+
changed("state2").should == %w{file1}
|
92
|
+
end
|
93
|
+
|
94
|
+
it "detects new libraries" do
|
95
|
+
changed("state1", ['file2']).should == %w{file2}
|
96
|
+
end
|
97
|
+
|
98
|
+
it "detects no changed libraries" do
|
99
|
+
changed("state1").should == []
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
describe "write" do
|
104
|
+
before_all {
|
105
|
+
reset_boson
|
106
|
+
Boson.commands << Command.new(:name=>'blah', :lib=>'blah', :args=>[['arg1', {}], ['arg2', self.class]])
|
107
|
+
Boson.libraries << Library.new(:name=>'blah', :module=>self.class)
|
108
|
+
index.expects(:latest_hashes)
|
109
|
+
libraries = commands = []
|
110
|
+
index.expects(:save_marshal_index).with {|str| libraries, commands, hashes = Marshal.load(str) ; true}
|
111
|
+
index.write
|
112
|
+
@index_hash = {:libraries=>libraries, :commands=>commands}
|
113
|
+
}
|
114
|
+
|
115
|
+
it "saves library module constants as strings" do
|
116
|
+
@index_hash[:libraries][0].module.class.should == String
|
117
|
+
end
|
118
|
+
|
119
|
+
it "save commands with arg values as strings" do
|
120
|
+
@index_hash[:commands][0].args.each {|e| e[1].class.should == String}
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
data/test/repo_test.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'test_helper')
|
2
|
+
|
3
|
+
describe "config" do
|
4
|
+
before_all { reset }
|
5
|
+
before { @repo = Repo.new(File.dirname(__FILE__)) }
|
6
|
+
|
7
|
+
it "reloads config when passed true" do
|
8
|
+
@repo.config.object_id.should.not == @repo.config(true).object_id
|
9
|
+
end
|
10
|
+
|
11
|
+
it "reads existing config correctly" do
|
12
|
+
expected_hash = {:commands=>{'c1'=>{}}, :libraries=>{}}
|
13
|
+
File.expects(:exists?).returns(true)
|
14
|
+
YAML.expects(:load_file).returns(expected_hash)
|
15
|
+
@repo.config[:commands]['c1'].should == {}
|
16
|
+
end
|
17
|
+
|
18
|
+
it "ignores nonexistent file and sets config defaults" do
|
19
|
+
@repo.config[:command_aliases].class.should == Hash
|
20
|
+
@repo.config[:libraries].class.should == Hash
|
21
|
+
end
|
22
|
+
after_all { FileUtils.rm_r File.dirname(__FILE__)+'/config', :force=>true }
|
23
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
describe "BinRunner" do
|
2
|
+
describe "at commandline" do
|
3
|
+
def start(*args)
|
4
|
+
Hirb.stubs(:enable)
|
5
|
+
BinRunner.start(args)
|
6
|
+
end
|
7
|
+
|
8
|
+
before {|e|
|
9
|
+
BinRunner.instance_variables.each {|e| BinRunner.instance_variable_set(e, nil)}
|
10
|
+
}
|
11
|
+
|
12
|
+
before_all { reset }
|
13
|
+
|
14
|
+
it "invalid option value prints error" do
|
15
|
+
aborts_with(/Error: no value/) { start("-l") }
|
16
|
+
end
|
17
|
+
|
18
|
+
it "load option loads libraries" do
|
19
|
+
Manager.expects(:load).with {|*args| args[0][0].is_a?(Module) ? true : args[0][0] == 'blah'}.times(2)
|
20
|
+
BinRunner.stubs(:execute_command)
|
21
|
+
start('-l', 'blah', 'libraries')
|
22
|
+
end
|
23
|
+
|
24
|
+
it "with backtrace option prints backtrace" do
|
25
|
+
BinRunner.expects(:autoload_command).returns(false)
|
26
|
+
aborts_with(/not found\nOriginal.*runner\.rb:/m) { start("--backtrace", "blah") }
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/test/save_test.rb
ADDED
@@ -0,0 +1,86 @@
|
|
1
|
+
describe "BinRunner" do
|
2
|
+
# TODO: moar acceptance tests
|
3
|
+
xit "basic command executes" do
|
4
|
+
BinRunner.expects(:init).returns(true)
|
5
|
+
BinRunner.stubs(:render_output)
|
6
|
+
Boson.main_object.expects(:send).with('kick','it')
|
7
|
+
start 'kick','it'
|
8
|
+
end
|
9
|
+
xit "bin_defaults config loads by default"
|
10
|
+
|
11
|
+
def start(*args)
|
12
|
+
BinRunner.start(args)
|
13
|
+
end
|
14
|
+
|
15
|
+
before {|e|
|
16
|
+
BinRunner.instance_variables.each {|e| BinRunner.instance_variable_set(e, nil)}
|
17
|
+
}
|
18
|
+
|
19
|
+
# TODO: fix missing libraries command
|
20
|
+
xdescribe "autoload_command" do
|
21
|
+
def index(options={})
|
22
|
+
Manager.expects(:load).with {|*args| args[0][0].is_a?(Module) ? true : args[0] == options[:load]
|
23
|
+
}.at_least(1).returns(!options[:fails])
|
24
|
+
Index.indexes[0].expects(:write)
|
25
|
+
end
|
26
|
+
|
27
|
+
it "with index option, no existing index and core command updates index and prints index message" do
|
28
|
+
index :load=>BareRunner.all_libraries
|
29
|
+
Index.indexes[0].stubs(:exists?).returns(false)
|
30
|
+
capture_stdout { start("--index", "libraries") }.should =~ /Generating index/
|
31
|
+
end
|
32
|
+
|
33
|
+
it "with index option, existing index and core command updates incremental index" do
|
34
|
+
index :load=>['changed']
|
35
|
+
Index.indexes[0].stubs(:exists?).returns(true)
|
36
|
+
capture_stdout { start("--index=changed", "libraries")}.should =~ /Indexing.*changed/
|
37
|
+
end
|
38
|
+
|
39
|
+
it "with index option, failed indexing prints error" do
|
40
|
+
index :load=>['changed'], :fails=>true
|
41
|
+
Index.indexes[0].stubs(:exists?).returns(true)
|
42
|
+
Manager.stubs(:failed_libraries).returns(['changed'])
|
43
|
+
capture_stderr {
|
44
|
+
capture_stdout { start("--index=changed", "libraries")}.should =~ /Indexing.*changed/
|
45
|
+
}.should =~ /Error:.*failed.*changed/
|
46
|
+
end
|
47
|
+
|
48
|
+
it "with core command updates index and doesn't print index message" do
|
49
|
+
Index.indexes[0].expects(:write)
|
50
|
+
Boson.main_object.expects(:send).with('libraries')
|
51
|
+
capture_stdout { start 'libraries'}.should.not =~ /index/i
|
52
|
+
end
|
53
|
+
|
54
|
+
it "with non-core command not finding library, does update index" do
|
55
|
+
Index.expects(:find_library).returns(nil, 'sweet_lib')
|
56
|
+
Manager.expects(:load).with {|*args| args[0].is_a?(String) ? args[0] == 'sweet_lib' : true}.at_least(1)
|
57
|
+
Index.indexes[0].expects(:update).returns(true)
|
58
|
+
aborts_with(/sweet/) { start 'sweet' }
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
|
64
|
+
__END__
|
65
|
+
describe "BinRunner" do
|
66
|
+
describe "at commandline" do
|
67
|
+
before_all { reset }
|
68
|
+
|
69
|
+
it "failed subcommand prints error and not command not found" do
|
70
|
+
BinRunner.expects(:execute_command).raises("bling")
|
71
|
+
aborts_with(/Error: bling/) { start("commands.to_s") }
|
72
|
+
end
|
73
|
+
|
74
|
+
it "nonexistant subcommand prints command not found" do
|
75
|
+
aborts_with(/'to_s.bling' not found/) { start("to_s.bling") }
|
76
|
+
end
|
77
|
+
|
78
|
+
it "sub command executes" do
|
79
|
+
obj = Object.new
|
80
|
+
Boson.main_object.extend Module.new { def phone; Struct.new(:home).new('done'); end }
|
81
|
+
BinRunner.expects(:init).returns(true)
|
82
|
+
start 'phone.home'
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
describe "BinRunner" do
|
2
|
+
it "help option and command prints help" do
|
3
|
+
capture_stdout { start('-h', 'commands') }.should =~ /^commands/
|
4
|
+
end
|
5
|
+
|
6
|
+
it "global option takes value with whitespace" do
|
7
|
+
View.expects(:render).with {|*args| args[1][:fields] = %w{f1 f2} }
|
8
|
+
start('commands', '-f', 'f1, f2')
|
9
|
+
end
|
10
|
+
|
11
|
+
describe "render_output" do
|
12
|
+
before { Scientist.rendered = false; BinRunner.instance_eval "@options = {}" }
|
13
|
+
|
14
|
+
it "doesn't render when nil, false or true" do
|
15
|
+
View.expects(:render).never
|
16
|
+
[nil, false, true].each do |e|
|
17
|
+
BinRunner.render_output e
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
it "doesn't render when rendered with Scientist" do
|
22
|
+
Scientist.rendered = true
|
23
|
+
View.expects(:render).never
|
24
|
+
BinRunner.render_output 'blah'
|
25
|
+
end
|
26
|
+
|
27
|
+
it "render with puts when non-string" do
|
28
|
+
View.expects(:render).with('dude', {:method => 'puts'})
|
29
|
+
BinRunner.render_output 'dude'
|
30
|
+
end
|
31
|
+
|
32
|
+
it "renders with inspect when non-array and non-string" do
|
33
|
+
[{:a=>true}, :ok].each do |e|
|
34
|
+
View.expects(:puts).with(e.inspect)
|
35
|
+
BinRunner.render_output e
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
it "renders with inspect when Scientist rendering toggled off with :render" do
|
40
|
+
Scientist.global_options = {:render=>true}
|
41
|
+
View.expects(:puts).with([1,2].inspect)
|
42
|
+
BinRunner.render_output [1,2]
|
43
|
+
Scientist.global_options = nil
|
44
|
+
end
|
45
|
+
|
46
|
+
it "renders with hirb when array" do
|
47
|
+
View.expects(:render_object)
|
48
|
+
BinRunner.render_output [1,2,3]
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
describe "MethodInspector" do
|
55
|
+
it "render_options sets render_options" do
|
56
|
+
parse("render_options :z=>true; def zee; end")[:render_options].should == {"zee"=>{:z=>true}}
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,195 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'test_helper')
|
2
|
+
|
3
|
+
# Now in science.rb
|
4
|
+
describe "Scientist" do
|
5
|
+
before_all {
|
6
|
+
Boson.in_shell = nil
|
7
|
+
eval <<-EOF
|
8
|
+
module Blah
|
9
|
+
def blah(arg1, options={})
|
10
|
+
[arg1, options]
|
11
|
+
end
|
12
|
+
def splat_blah(*args)
|
13
|
+
args
|
14
|
+
end
|
15
|
+
def default_blah(arg1, arg2=default, options={})
|
16
|
+
[arg1, arg2, options]
|
17
|
+
end
|
18
|
+
def default; 'some default'; end
|
19
|
+
def default_option(options={})
|
20
|
+
options
|
21
|
+
end
|
22
|
+
end
|
23
|
+
EOF
|
24
|
+
@opt_cmd = Object.new.extend Blah
|
25
|
+
}
|
26
|
+
|
27
|
+
def command(hash, args)
|
28
|
+
hash = {:name=>'blah', :lib=>'bling', :options=>{:force=>:boolean, :level=>2}}.merge(hash)
|
29
|
+
@cmd = Command.new hash
|
30
|
+
@cmd.instance_variable_set("@file_parsed_args", true) if hash[:file_parsed_args]
|
31
|
+
Scientist.redefine_command(@opt_cmd, @cmd)
|
32
|
+
@opt_cmd.send(hash[:name], *args)
|
33
|
+
end
|
34
|
+
|
35
|
+
def command_with_arg_size(*args)
|
36
|
+
command({:args=>2}, args)
|
37
|
+
end
|
38
|
+
|
39
|
+
def command_with_args(*args)
|
40
|
+
command({:args=>[['arg1'],['options', {}]]}, args)
|
41
|
+
end
|
42
|
+
|
43
|
+
def basic_command(hash, args)
|
44
|
+
command({:name=>'splat_blah', :args=>'*'}.merge(hash), args)
|
45
|
+
end
|
46
|
+
|
47
|
+
def command_with_splat_args(*args)
|
48
|
+
command({:name=>'splat_blah', :args=>'*'}, args)
|
49
|
+
end
|
50
|
+
|
51
|
+
def command_with_arg_defaults(*args)
|
52
|
+
arg_defaults = [%w{arg1}, %w{arg2 default}, %w{options {}}]
|
53
|
+
command({:name=>'default_blah', :file_parsed_args=>true, :args=>arg_defaults}, args)
|
54
|
+
end
|
55
|
+
|
56
|
+
def args_are_equal(args, array)
|
57
|
+
command_with_args(*args).should == array
|
58
|
+
command_with_arg_size(*args).should == array
|
59
|
+
command_with_splat_args(*args).should == array
|
60
|
+
end
|
61
|
+
|
62
|
+
def all_commands
|
63
|
+
[:command_with_args, :command_with_arg_size, :command_with_splat_args]
|
64
|
+
end
|
65
|
+
|
66
|
+
describe "command" do
|
67
|
+
describe "prints error" do
|
68
|
+
it "with unexpected error in render" do
|
69
|
+
Scientist.expects(:can_render?).raises("unexpected")
|
70
|
+
capture_stderr { command_with_args('a1') }.should =~ /Error.*unexpected/
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def command_with_render(*args)
|
76
|
+
basic_command({:render_options=>{:fields=>{:values=>['f1', 'f2']}} }, args)
|
77
|
+
end
|
78
|
+
|
79
|
+
def render_expected(options=nil)
|
80
|
+
View.expects(:render).with(anything, options || anything, false)
|
81
|
+
end
|
82
|
+
|
83
|
+
describe "render" do
|
84
|
+
it "called for command with render_options" do
|
85
|
+
render_expected
|
86
|
+
command_with_render('1')
|
87
|
+
end
|
88
|
+
|
89
|
+
it "called for command without render_options and --render" do
|
90
|
+
render_expected
|
91
|
+
command_with_args('--render 1')
|
92
|
+
end
|
93
|
+
|
94
|
+
it "not called for command with render_options and --render" do
|
95
|
+
Boson.expects(:invoke).never
|
96
|
+
command_with_render('--render 1')
|
97
|
+
end
|
98
|
+
|
99
|
+
it "not called for command without render_options" do
|
100
|
+
Boson.expects(:invoke).never
|
101
|
+
command_with_args('1')
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
describe "command renders" do
|
106
|
+
it "with basic render options" do
|
107
|
+
render_expected :fields => ['f1', 'f2']
|
108
|
+
command_with_render("--fields f1,f2 ab")
|
109
|
+
end
|
110
|
+
|
111
|
+
it "without non-render options" do
|
112
|
+
render_expected :fields=>['f1']
|
113
|
+
Scientist.expects(:can_render?).returns(true)
|
114
|
+
args = ["--render --fields f1 ab"]
|
115
|
+
basic_command({:render_options=>{:fields=>{:values=>['f1', 'f2']}} }, args)
|
116
|
+
end
|
117
|
+
|
118
|
+
it "with user-defined render options" do
|
119
|
+
render_expected :fields=>['f1'], :foo=>true
|
120
|
+
args = ["--foo --fields f1 ab"]
|
121
|
+
basic_command({:render_options=>{:foo=>:boolean, :fields=>{:values=>['f1', 'f2']}} }, args)
|
122
|
+
end
|
123
|
+
|
124
|
+
it "with non-hash user-defined render options" do
|
125
|
+
render_expected :fields=>['f1'], :foo=>true
|
126
|
+
args = ["--foo --fields f1 ab"]
|
127
|
+
basic_command({:render_options=>{:foo=>:boolean, :fields=>%w{f1 f2 f3}} }, args)
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
it "optionless command renders" do
|
132
|
+
render_expected :fields=>['f1']
|
133
|
+
command({:args=>2, :options=>nil, :render_options=>{:fields=>:array}}, ["--fields f1 ab ok"])
|
134
|
+
end
|
135
|
+
|
136
|
+
describe "global options:" do
|
137
|
+
def local_and_global(*args)
|
138
|
+
Scientist.stubs(:can_render?).returns(false) # turn off rendering caused by :render_options
|
139
|
+
@non_opts = basic_command(@command_options, args)
|
140
|
+
@non_opts.slice!(-1,1) << Scientist.global_options
|
141
|
+
end
|
142
|
+
|
143
|
+
before_all {
|
144
|
+
@command_options = {:options=>{:do=>:boolean, :foo=>:boolean},
|
145
|
+
:render_options=>{:dude=>:boolean}}
|
146
|
+
@expected_non_opts = [[], ['doh'], ['doh'], [:doh]]
|
147
|
+
}
|
148
|
+
|
149
|
+
it "local option overrides global one" do
|
150
|
+
['-d', 'doh -d','-d doh', [:doh, '-d']].each_with_index do |args, i|
|
151
|
+
local_and_global(*args).should == [{:do=>true}, {}]
|
152
|
+
@non_opts.should == @expected_non_opts[i]
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
it "global option before local one is valid" do
|
157
|
+
args_arr = ['--dude -f', '--dude doh -f', '--dude -f doh', [:doh, '--dude -f']]
|
158
|
+
args_arr.each_with_index do |args, i|
|
159
|
+
local_and_global(*args).should == [{:foo=>true}, {:dude=>true}]
|
160
|
+
@non_opts.should == @expected_non_opts[i]
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
it "delete_options deletes global options" do
|
165
|
+
local_and_global('--delete_options=r,p -rp -f').should ==
|
166
|
+
[{:foo=>true}, {:delete_options=>["r", "p"]}]
|
167
|
+
end
|
168
|
+
|
169
|
+
it "global option after local one is invalid" do
|
170
|
+
args_arr = ['-f --dude', '-f doh --dude', '-f --dude doh', [:doh, '-f --dude'] ]
|
171
|
+
args_arr.each_with_index do |args, i|
|
172
|
+
capture_stderr {
|
173
|
+
local_and_global(*args).should == [{:foo=>true}, {}]
|
174
|
+
@non_opts.should == @expected_non_opts[i]
|
175
|
+
}.should =~ /invalid.*dude/
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
it "global option after local one and -" do
|
180
|
+
local_and_global("doh -r -f - --dude").should == [{:foo=>true}, {:dude=>true, :render=>true}]
|
181
|
+
end
|
182
|
+
|
183
|
+
it "conflicting global option after -" do
|
184
|
+
local_and_global('doh - -f=1,2').should == [{}, {:fields=>["1", "2"]}]
|
185
|
+
end
|
186
|
+
|
187
|
+
it "no options parsed after --" do
|
188
|
+
local_and_global('doh -f -- -r').should == [{:foo=>true}, {}]
|
189
|
+
local_and_global('doh -- -r -f').should == [{}, {}]
|
190
|
+
local_and_global('-- -r -f').should == [{}, {}]
|
191
|
+
local_and_global('doh -r -- -f').should == [{}, {:render=>true}]
|
192
|
+
end
|
193
|
+
end
|
194
|
+
after_all { Boson.in_shell = false }
|
195
|
+
end
|