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