boson 0.2.3 → 0.2.4
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.rdoc +76 -0
- data/README.rdoc +6 -6
- data/Rakefile +24 -41
- data/gemspec +19 -0
- data/lib/boson.rb +4 -4
- data/lib/boson/command.rb +2 -2
- data/lib/boson/commands/core.rb +1 -1
- data/lib/boson/commands/web_core.rb +16 -12
- data/lib/boson/manager.rb +1 -1
- data/lib/boson/pipes.rb +6 -2
- data/lib/boson/repo_index.rb +1 -1
- data/lib/boson/runner.rb +2 -2
- data/lib/boson/runners/bin_runner.rb +72 -29
- data/lib/boson/scientist.rb +22 -4
- data/lib/boson/util.rb +9 -1
- data/lib/boson/version.rb +3 -0
- data/test/argument_inspector_test.rb +47 -51
- data/test/bacon_extensions.rb +26 -0
- data/test/bin_runner_test.rb +160 -160
- data/test/comment_inspector_test.rb +87 -89
- data/test/file_library_test.rb +32 -34
- data/test/loader_test.rb +181 -182
- data/test/manager_test.rb +76 -78
- data/test/method_inspector_test.rb +51 -53
- data/test/option_parser_test.rb +49 -42
- data/test/options_test.rb +168 -168
- data/test/pipes_test.rb +48 -46
- data/test/repo_index_test.rb +117 -113
- data/test/repo_test.rb +17 -17
- data/test/runner_test.rb +31 -34
- data/test/scientist_test.rb +258 -254
- data/test/test_helper.rb +21 -38
- data/test/util_test.rb +40 -42
- metadata +55 -46
- data/VERSION.yml +0 -5
data/test/repo_index_test.rb
CHANGED
@@ -1,118 +1,122 @@
|
|
1
1
|
require File.join(File.dirname(__FILE__), 'test_helper')
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
end
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
end
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
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
|
+
describe "changed_libraries" do
|
79
|
+
before_all { index.instance_eval "@lib_hashes = nil" }
|
80
|
+
|
81
|
+
def changed(string, all_libs=['file1'])
|
82
|
+
index.repo.expects(:all_libraries).returns(all_libs)
|
83
|
+
index.instance_variable_set "@lib_hashes", {"file1"=>Digest::MD5.hexdigest("state1")}
|
84
|
+
File.stubs(:exists?).returns(true)
|
85
|
+
File.expects(:read).returns(string)
|
86
|
+
index.changed_libraries
|
87
|
+
end
|
88
|
+
|
89
|
+
it "detects changed libraries" do
|
90
|
+
changed("state2").should == %w{file1}
|
91
|
+
end
|
92
|
+
|
93
|
+
it "detects new libraries" do
|
94
|
+
changed("state1", ['file2']).should == %w{file2}
|
95
|
+
end
|
96
|
+
|
97
|
+
it "detects no changed libraries" do
|
98
|
+
changed("state1").should == []
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
describe "write" do
|
103
|
+
before_all {
|
104
|
+
reset_boson
|
105
|
+
Boson.commands << Command.new(:name=>'blah', :lib=>'blah', :args=>[['arg1', {}], ['arg2', self.class]])
|
106
|
+
Boson.libraries << Library.new(:name=>'blah', :module=>self.class)
|
107
|
+
index.expects(:latest_hashes)
|
108
|
+
libraries = commands = []
|
109
|
+
index.expects(:save_marshal_index).with {|str| libraries, commands, hashes = Marshal.load(str) ; true}
|
110
|
+
index.write
|
111
|
+
@index_hash = {:libraries=>libraries, :commands=>commands}
|
112
|
+
}
|
113
|
+
|
114
|
+
it "saves library module constants as strings" do
|
115
|
+
@index_hash[:libraries][0].module.class.should == String
|
116
|
+
end
|
117
|
+
|
118
|
+
it "save commands with arg values as strings" do
|
119
|
+
@index_hash[:commands][0].args.each {|e| e[1].class.should == String}
|
116
120
|
end
|
117
121
|
end
|
118
122
|
end
|
data/test/repo_test.rb
CHANGED
@@ -1,23 +1,23 @@
|
|
1
1
|
require File.join(File.dirname(__FILE__), 'test_helper')
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
before(:each) { @repo = Boson::Repo.new(File.dirname(__FILE__)) }
|
3
|
+
describe "config" do
|
4
|
+
before_all { reset }
|
5
|
+
before { @repo = Repo.new(File.dirname(__FILE__)) }
|
7
6
|
|
8
|
-
|
9
|
-
|
10
|
-
|
7
|
+
it "reloads config when passed true" do
|
8
|
+
@repo.config.object_id.should.not == @repo.config(true).object_id
|
9
|
+
end
|
11
10
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
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
|
18
17
|
|
19
|
-
|
20
|
-
|
21
|
-
|
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
|
22
21
|
end
|
23
|
-
|
22
|
+
after_all { FileUtils.rm_r File.dirname(__FILE__)+'/config', :force=>true }
|
23
|
+
end
|
data/test/runner_test.rb
CHANGED
@@ -1,43 +1,40 @@
|
|
1
1
|
require File.join(File.dirname(__FILE__), 'test_helper')
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
Boson.start(hash.merge(:verbose=>false))
|
9
|
-
end
|
3
|
+
describe "repl_runner" do
|
4
|
+
def start(hash={})
|
5
|
+
Hirb.stubs(:enable)
|
6
|
+
Boson.start(hash.merge(:verbose=>false))
|
7
|
+
end
|
10
8
|
|
11
|
-
|
12
|
-
|
9
|
+
before_all { reset }
|
10
|
+
before { ConsoleRunner.instance_eval("@initialized = false") }
|
13
11
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
12
|
+
it "loads default libraries and libraries in :console_defaults config" do
|
13
|
+
defaults = Runner.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
|
21
19
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
20
|
+
it "doesn't call init twice" do
|
21
|
+
capture_stderr { start }
|
22
|
+
ConsoleRunner.expects(:init).never
|
23
|
+
start
|
24
|
+
end
|
27
25
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
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
|
33
31
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
end
|
41
|
-
end
|
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
|
42
38
|
end
|
39
|
+
after_all { FileUtils.rm_r File.dirname(__FILE__)+'/config', :force=>true }
|
43
40
|
end
|
data/test/scientist_test.rb
CHANGED
@@ -1,337 +1,341 @@
|
|
1
1
|
require File.join(File.dirname(__FILE__), 'test_helper')
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
def blah(arg1, options={})
|
11
|
-
[arg1, options]
|
12
|
-
end
|
13
|
-
def splat_blah(*args)
|
14
|
-
args
|
15
|
-
end
|
16
|
-
def default_blah(arg1, arg2=default, options={})
|
17
|
-
[arg1, arg2, options]
|
18
|
-
end
|
19
|
-
def default; 'some default'; end
|
20
|
-
def default_option(options={})
|
21
|
-
options
|
22
|
-
end
|
3
|
+
describe "Scientist" do
|
4
|
+
before_all {
|
5
|
+
Runner.in_shell = nil
|
6
|
+
eval <<-EOF
|
7
|
+
module Blah
|
8
|
+
def blah(arg1, options={})
|
9
|
+
[arg1, options]
|
23
10
|
end
|
24
|
-
|
11
|
+
def splat_blah(*args)
|
12
|
+
args
|
25
13
|
end
|
26
|
-
|
27
|
-
|
28
|
-
|
14
|
+
def default_blah(arg1, arg2=default, options={})
|
15
|
+
[arg1, arg2, options]
|
16
|
+
end
|
17
|
+
def default; 'some default'; end
|
18
|
+
def default_option(options={})
|
19
|
+
options
|
20
|
+
end
|
21
|
+
end
|
22
|
+
EOF
|
23
|
+
@opt_cmd = Object.new.extend Blah
|
24
|
+
}
|
25
|
+
|
26
|
+
def command(hash, args)
|
27
|
+
hash = {:name=>'blah', :lib=>'bling', :options=>{:force=>:boolean, :level=>2}}.merge(hash)
|
28
|
+
@cmd = Command.new hash
|
29
|
+
@cmd.instance_variable_set("@file_parsed_args", true) if hash[:file_parsed_args]
|
30
|
+
Scientist.redefine_command(@opt_cmd, @cmd)
|
31
|
+
@opt_cmd.send(hash[:name], *args)
|
32
|
+
end
|
33
|
+
|
34
|
+
def command_with_arg_size(*args)
|
35
|
+
command({:args=>2}, args)
|
36
|
+
end
|
37
|
+
|
38
|
+
def command_with_args(*args)
|
39
|
+
command({:args=>[['arg1'],['options', {}]]}, args)
|
40
|
+
end
|
41
|
+
|
42
|
+
def basic_command(hash, args)
|
43
|
+
command({:name=>'splat_blah', :args=>'*'}.merge(hash), args)
|
44
|
+
end
|
45
|
+
|
46
|
+
def command_with_splat_args(*args)
|
47
|
+
command({:name=>'splat_blah', :args=>'*'}, args)
|
48
|
+
end
|
49
|
+
|
50
|
+
def command_with_arg_defaults(*args)
|
51
|
+
arg_defaults = [%w{arg1}, %w{arg2 default}, %w{options {}}]
|
52
|
+
command({:name=>'default_blah', :file_parsed_args=>true, :args=>arg_defaults}, args)
|
53
|
+
end
|
54
|
+
|
55
|
+
def args_are_equal(args, array)
|
56
|
+
command_with_args(*args).should == array
|
57
|
+
command_with_arg_size(*args).should == array
|
58
|
+
command_with_splat_args(*args).should == array
|
59
|
+
end
|
60
|
+
|
61
|
+
def all_commands
|
62
|
+
[:command_with_args, :command_with_arg_size, :command_with_splat_args]
|
63
|
+
end
|
29
64
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
@cmd.instance_variable_set("@file_parsed_args", true) if hash[:file_parsed_args]
|
34
|
-
Scientist.redefine_command(@opt_cmd, @cmd)
|
35
|
-
@opt_cmd.send(hash[:name], *args)
|
65
|
+
describe "all commands" do
|
66
|
+
it "translate arg and options as one string" do
|
67
|
+
args_are_equal ['a1 -f'], ['a1', {:force=>true, :level=>2}]
|
36
68
|
end
|
37
69
|
|
38
|
-
|
39
|
-
|
70
|
+
it "translate arg and stringified options" do
|
71
|
+
args_are_equal [:cool, '-l3'], [:cool, {:level=>3}]
|
40
72
|
end
|
41
73
|
|
42
|
-
|
43
|
-
|
74
|
+
it "translate arg and normal hash options" do
|
75
|
+
args_are_equal [:cool, {:ok=>true}], [:cool, {:ok=>true, :level=>2}]
|
44
76
|
end
|
45
77
|
|
46
|
-
|
47
|
-
|
78
|
+
it "translate stringified arg without options sets default options" do
|
79
|
+
args_are_equal ['cool'], ['cool', {:level=>2}]
|
48
80
|
end
|
49
81
|
|
50
|
-
|
51
|
-
|
82
|
+
it "translate arg without options sets default options" do
|
83
|
+
args_are_equal [:cool], [:cool, {:level=>2}]
|
52
84
|
end
|
53
85
|
|
54
|
-
|
55
|
-
|
56
|
-
|
86
|
+
it "with invalid options print errors and delete them" do
|
87
|
+
all_commands.each do |cmd|
|
88
|
+
capture_stderr {
|
89
|
+
send(cmd, 'cool -f -z').should == ['cool', {:force=>true, :level=>2}]
|
90
|
+
}.should =~/invalid.*z/
|
91
|
+
end
|
57
92
|
end
|
58
93
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
94
|
+
it "print help with help option" do
|
95
|
+
all_commands.each do |cmd|
|
96
|
+
Boson.expects(:invoke).with(:usage, anything, anything)
|
97
|
+
send(cmd, '-h')
|
98
|
+
end
|
63
99
|
end
|
100
|
+
end
|
64
101
|
|
65
|
-
|
102
|
+
describe "command" do
|
103
|
+
describe "with arg defaults" do
|
104
|
+
it "sets defaults with stringified args" do
|
105
|
+
command_with_arg_defaults('1').should == ["1", "some default", {:level=>2}]
|
106
|
+
end
|
66
107
|
|
67
|
-
|
68
|
-
|
69
|
-
args_are_equal ['a1 -f'], ['a1', {:force=>true, :level=>2}]
|
108
|
+
it "sets defaults with normal args" do
|
109
|
+
command_with_arg_defaults(1).should == [1, "some default", {:level=>2}]
|
70
110
|
end
|
71
111
|
|
72
|
-
|
73
|
-
|
112
|
+
it "sets default if optional arg is a valid option" do
|
113
|
+
command_with_arg_defaults("cool -f").should == ["cool", "some default", {:level=>2, :force=>true}]
|
74
114
|
end
|
75
115
|
|
76
|
-
|
77
|
-
|
116
|
+
it "doesn't set defaults if not needed" do
|
117
|
+
command_with_arg_defaults(1, 'nada').should == [1, "nada", {:level=>2}]
|
78
118
|
end
|
79
119
|
|
80
|
-
|
81
|
-
|
120
|
+
it "prints error for invalid defaults" do
|
121
|
+
arg_defaults = [%w{arg1}, %w{arg2 invalidzzz}, %w{options {}}]
|
122
|
+
capture_stderr {
|
123
|
+
command({:name=>'default_blah', :file_parsed_args=>true, :args=>arg_defaults}, [1])
|
124
|
+
}.should =~ /Error.*position 2/
|
82
125
|
end
|
126
|
+
end
|
83
127
|
|
84
|
-
|
85
|
-
|
128
|
+
describe "prints error" do
|
129
|
+
it "with option error" do
|
130
|
+
capture_stderr { command_with_args('a1 -l') }.should =~ /Error.*level/
|
86
131
|
end
|
87
132
|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
send(cmd, 'cool -f -z').should == ['cool', {:force=>true, :level=>2}]
|
92
|
-
}.should =~/invalid.*z/
|
93
|
-
end
|
133
|
+
it "with unexpected error in render" do
|
134
|
+
Scientist.expects(:can_render?).raises("unexpected")
|
135
|
+
capture_stderr { command_with_args('a1') }.should =~ /Error.*unexpected/
|
94
136
|
end
|
95
137
|
|
96
|
-
|
97
|
-
|
98
|
-
Boson.expects(:invoke).with(:usage, anything, anything)
|
99
|
-
send(cmd, '-h')
|
100
|
-
end
|
138
|
+
it "with no argument defined for options" do
|
139
|
+
assert_error(OptionCommand::CommandArgumentError, '2 for 1') { command({:args=>1}, 'ok') }
|
101
140
|
end
|
102
141
|
end
|
103
142
|
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
command_with_arg_defaults('1').should == ["1", "some default", {:level=>2}]
|
108
|
-
end
|
109
|
-
|
110
|
-
test "sets defaults with normal args" do
|
111
|
-
command_with_arg_defaults(1).should == [1, "some default", {:level=>2}]
|
112
|
-
end
|
113
|
-
|
114
|
-
test "sets default if optional arg is a valid option" do
|
115
|
-
command_with_arg_defaults("cool -f").should == ["cool", "some default", {:level=>2, :force=>true}]
|
116
|
-
end
|
143
|
+
it "translates stringfied args + options starting at second arg" do
|
144
|
+
command_with_arg_defaults(1, 'nada -l3').should == [1, "nada", {:level=>3}]
|
145
|
+
end
|
117
146
|
|
118
|
-
|
119
|
-
|
120
|
-
|
147
|
+
it "with leading option-like args are translated as arguments" do
|
148
|
+
command_with_args('-z -f').should == ["-z", {:force=>true, :level=>2}]
|
149
|
+
command_with_args('--blah -f').should == ['--blah', {:force=>true, :level=>2}]
|
150
|
+
end
|
121
151
|
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
command({:name=>'default_blah', :file_parsed_args=>true, :args=>arg_defaults}, [1])
|
126
|
-
}.should =~ /Error.*position 2/
|
127
|
-
end
|
152
|
+
it "with splat args does not raise error for too few or many args" do
|
153
|
+
[[], [''], [1,2,3], ['1 2 3']].each do |args|
|
154
|
+
should.not.raise { command_with_splat_args *args }
|
128
155
|
end
|
156
|
+
end
|
129
157
|
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
end
|
158
|
+
it "with debug option prints debug" do
|
159
|
+
capture_stdout { command_with_args("-v ok") }.should =~ /Arguments.*ok/
|
160
|
+
end
|
134
161
|
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
162
|
+
it "with pretend option prints arguments and returns early" do
|
163
|
+
Scientist.expects(:render_or_raw).never
|
164
|
+
capture_stdout { command_with_args("-p ok") }.should =~ /Arguments.*ok/
|
165
|
+
end
|
139
166
|
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
167
|
+
it "with not enough args raises CommandArgumentError" do
|
168
|
+
args = [OptionCommand::CommandArgumentError, '0 for 1']
|
169
|
+
assert_error(*args) { command_with_args }
|
170
|
+
assert_error(*args) { command_with_args '' }
|
171
|
+
assert_error(*args) { command_with_arg_size }
|
172
|
+
assert_error(*args) { command_with_arg_size '' }
|
173
|
+
end
|
144
174
|
|
145
|
-
|
146
|
-
|
147
|
-
|
175
|
+
it "with too many args raises CommandArgumentError" do
|
176
|
+
args3 = [ArgumentError, '3 for 2']
|
177
|
+
args4 = [OptionCommand::CommandArgumentError, '4 for 2']
|
178
|
+
assert_error(*args3) { command_with_args 1,2,3 }
|
179
|
+
assert_error(*args4) { command_with_args '1 2 3' }
|
180
|
+
assert_error(*args3) { command_with_arg_size 1,2,3 }
|
181
|
+
assert_error(*args4) { command_with_arg_size '1 2 3' }
|
182
|
+
end
|
183
|
+
end
|
148
184
|
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
end
|
185
|
+
def command_with_render(*args)
|
186
|
+
basic_command({:render_options=>{:fields=>{:values=>['f1', 'f2']}} }, args)
|
187
|
+
end
|
153
188
|
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
end
|
158
|
-
end
|
189
|
+
def render_expected(options=nil)
|
190
|
+
View.expects(:render).with(anything, options || anything, false)
|
191
|
+
end
|
159
192
|
|
160
|
-
|
161
|
-
|
162
|
-
|
193
|
+
describe "render" do
|
194
|
+
it "called for command with render_options" do
|
195
|
+
render_expected
|
196
|
+
command_with_render('1')
|
197
|
+
end
|
163
198
|
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
199
|
+
it "called for command without render_options and --render" do
|
200
|
+
render_expected
|
201
|
+
command_with_args('--render 1')
|
202
|
+
end
|
168
203
|
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
assert_error(*args) { command_with_arg_size }
|
174
|
-
assert_error(*args) { command_with_arg_size '' }
|
175
|
-
end
|
204
|
+
it "not called for command with render_options and --render" do
|
205
|
+
Boson.expects(:invoke).never
|
206
|
+
command_with_render('--render 1')
|
207
|
+
end
|
176
208
|
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
assert_error(*args3) { command_with_args 1,2,3 }
|
181
|
-
assert_error(*args4) { command_with_args '1 2 3' }
|
182
|
-
assert_error(*args3) { command_with_arg_size 1,2,3 }
|
183
|
-
assert_error(*args4) { command_with_arg_size '1 2 3' }
|
184
|
-
end
|
209
|
+
it "not called for command without render_options" do
|
210
|
+
Boson.expects(:invoke).never
|
211
|
+
command_with_args('1')
|
185
212
|
end
|
213
|
+
end
|
186
214
|
|
187
|
-
|
188
|
-
|
215
|
+
describe "command renders" do
|
216
|
+
it "with basic render options" do
|
217
|
+
render_expected :fields => ['f1', 'f2']
|
218
|
+
command_with_render("--fields f1,f2 ab")
|
189
219
|
end
|
190
220
|
|
191
|
-
|
192
|
-
|
221
|
+
it "without non-render options" do
|
222
|
+
render_expected :fields=>['f1']
|
223
|
+
Scientist.expects(:can_render?).returns(true)
|
224
|
+
args = ["--render --fields f1 ab"]
|
225
|
+
basic_command({:render_options=>{:fields=>{:values=>['f1', 'f2']}} }, args)
|
193
226
|
end
|
194
227
|
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
228
|
+
it "with user-defined render options" do
|
229
|
+
render_expected :fields=>['f1'], :foo=>true
|
230
|
+
args = ["--foo --fields f1 ab"]
|
231
|
+
basic_command({:render_options=>{:foo=>:boolean, :fields=>{:values=>['f1', 'f2']}} }, args)
|
232
|
+
end
|
200
233
|
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
234
|
+
it "with non-hash user-defined render options" do
|
235
|
+
render_expected :fields=>['f1'], :foo=>true
|
236
|
+
args = ["--foo --fields f1 ab"]
|
237
|
+
basic_command({:render_options=>{:foo=>:boolean, :fields=>%w{f1 f2 f3}} }, args)
|
238
|
+
end
|
239
|
+
end
|
205
240
|
|
206
|
-
|
207
|
-
|
208
|
-
command_with_render('--render 1')
|
209
|
-
end
|
241
|
+
describe "command with default option" do
|
242
|
+
before_all { @cmd_attributes = {:name=>'default_option', :default_option=>'level', :args=>1} }
|
210
243
|
|
211
|
-
|
212
|
-
|
213
|
-
command_with_args('1')
|
214
|
-
end
|
244
|
+
it "parses normally from irb" do
|
245
|
+
command(@cmd_attributes, '-f --level=3').should == {:level=>3, :force=>true}
|
215
246
|
end
|
216
247
|
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
end
|
248
|
+
it "parses normally from cmdline" do
|
249
|
+
Runner.expects(:in_shell?).times(2).returns true
|
250
|
+
command(@cmd_attributes, ['--force', '--level=3']).should == {:level=>3, :force=>true}
|
251
|
+
end
|
222
252
|
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
args = ["--render --fields f1 ab"]
|
227
|
-
basic_command({:render_options=>{:fields=>{:values=>['f1', 'f2']}} }, args)
|
228
|
-
end
|
253
|
+
it "parses no arguments normally" do
|
254
|
+
command(@cmd_attributes, '').should == {:level=>2}
|
255
|
+
end
|
229
256
|
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
basic_command({:render_options=>{:foo=>:boolean, :fields=>{:values=>['f1', 'f2']}} }, args)
|
234
|
-
end
|
257
|
+
it "parses ruby arguments normally" do
|
258
|
+
command(@cmd_attributes, [{:force=>true, :level=>10}]).should == {:level=>10, :force=>true}
|
259
|
+
end
|
235
260
|
|
236
|
-
|
237
|
-
|
238
|
-
args = ["--foo --fields f1 ab"]
|
239
|
-
basic_command({:render_options=>{:foo=>:boolean, :fields=>%w{f1 f2 f3}} }, args)
|
240
|
-
end
|
261
|
+
it "prepends correctly from irb" do
|
262
|
+
command(@cmd_attributes, '3 -f').should == {:level=>3, :force=>true}
|
241
263
|
end
|
242
264
|
|
243
|
-
|
244
|
-
|
265
|
+
it "prepends correctly from cmdline" do
|
266
|
+
Runner.expects(:in_shell?).times(2).returns true
|
267
|
+
command(@cmd_attributes, ['3','-f']).should == {:level=>3, :force=>true}
|
268
|
+
end
|
269
|
+
end
|
245
270
|
|
246
|
-
|
247
|
-
|
248
|
-
|
271
|
+
it "optionless command renders" do
|
272
|
+
render_expected :fields=>['f1']
|
273
|
+
command({:args=>2, :options=>nil, :render_options=>{:fields=>:array}}, ["--fields f1 ab ok"])
|
274
|
+
end
|
249
275
|
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
276
|
+
it "redefine_command prints error for command with nonexistant method" do
|
277
|
+
capture_stderr {
|
278
|
+
Scientist.redefine_command Object.new, Command.new(:name=>'blah', :lib=>'blah')
|
279
|
+
}.should =~ /Error: No method.*'blah'/
|
280
|
+
end
|
254
281
|
|
255
|
-
|
256
|
-
|
257
|
-
|
282
|
+
describe "global options:" do
|
283
|
+
def local_and_global(*args)
|
284
|
+
Scientist.stubs(:can_render?).returns(false) # turn off rendering caused by :render_options
|
285
|
+
@non_opts = basic_command(@command_options, args)
|
286
|
+
@non_opts.slice!(-1,1) << Scientist.global_options
|
287
|
+
end
|
258
288
|
|
259
|
-
|
260
|
-
|
261
|
-
|
289
|
+
before_all {
|
290
|
+
@command_options = {:options=>{:do=>:boolean, :foo=>:boolean},
|
291
|
+
:render_options=>{:dude=>:boolean}}
|
292
|
+
@expected_non_opts = [[], ['doh'], ['doh'], [:doh]]
|
293
|
+
}
|
262
294
|
|
263
|
-
|
264
|
-
|
295
|
+
it "local option overrides global one" do
|
296
|
+
['-d', 'doh -d','-d doh', [:doh, '-d']].each_with_index do |args, i|
|
297
|
+
local_and_global(*args).should == [{:do=>true}, {}]
|
298
|
+
@non_opts.should == @expected_non_opts[i]
|
265
299
|
end
|
300
|
+
end
|
266
301
|
|
267
|
-
|
268
|
-
|
269
|
-
|
302
|
+
it "global option before local one is valid" do
|
303
|
+
args_arr = ['--dude -f', '--dude doh -f', '--dude -f doh', [:doh, '--dude -f']]
|
304
|
+
args_arr.each_with_index do |args, i|
|
305
|
+
local_and_global(*args).should == [{:foo=>true}, {:dude=>true}]
|
306
|
+
@non_opts.should == @expected_non_opts[i]
|
270
307
|
end
|
271
308
|
end
|
272
309
|
|
273
|
-
|
274
|
-
|
275
|
-
|
310
|
+
it "delete_options deletes global options" do
|
311
|
+
local_and_global('--delete_options=r,p -rp -f').should ==
|
312
|
+
[{:foo=>true}, {:delete_options=>["r", "p"]}]
|
276
313
|
end
|
277
314
|
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
end
|
284
|
-
|
285
|
-
before(:all) {
|
286
|
-
@command_options = {:options=>{:do=>:boolean, :foo=>:boolean},
|
287
|
-
:render_options=>{:dude=>:boolean}}
|
288
|
-
@expected_non_opts = [[], ['doh'], ['doh'], [:doh]]
|
289
|
-
}
|
290
|
-
|
291
|
-
test "local option overrides global one" do
|
292
|
-
['-d', 'doh -d','-d doh', [:doh, '-d']].each_with_index do |args, i|
|
293
|
-
local_and_global(*args).should == [{:do=>true}, {}]
|
315
|
+
it "global option after local one is invalid" do
|
316
|
+
args_arr = ['-f --dude', '-f doh --dude', '-f --dude doh', [:doh, '-f --dude'] ]
|
317
|
+
args_arr.each_with_index do |args, i|
|
318
|
+
capture_stderr {
|
319
|
+
local_and_global(*args).should == [{:foo=>true}, {}]
|
294
320
|
@non_opts.should == @expected_non_opts[i]
|
295
|
-
|
296
|
-
end
|
297
|
-
|
298
|
-
test "global option before local one is valid" do
|
299
|
-
args_arr = ['--dude -f', '--dude doh -f', '--dude -f doh', [:doh, '--dude -f']]
|
300
|
-
args_arr.each_with_index do |args, i|
|
301
|
-
local_and_global(*args).should == [{:foo=>true}, {:dude=>true}]
|
302
|
-
@non_opts.should == @expected_non_opts[i]
|
303
|
-
end
|
304
|
-
end
|
305
|
-
|
306
|
-
test "delete_options deletes global options" do
|
307
|
-
local_and_global('--delete_options=r,p -rp -f').should ==
|
308
|
-
[{:foo=>true}, {:delete_options=>["r", "p"]}]
|
309
|
-
end
|
310
|
-
|
311
|
-
test "global option after local one is invalid" do
|
312
|
-
args_arr = ['-f --dude', '-f doh --dude', '-f --dude doh', [:doh, '-f --dude'] ]
|
313
|
-
args_arr.each_with_index do |args, i|
|
314
|
-
capture_stderr {
|
315
|
-
local_and_global(*args).should == [{:foo=>true}, {}]
|
316
|
-
@non_opts.should == @expected_non_opts[i]
|
317
|
-
}.should =~ /invalid.*dude/
|
318
|
-
end
|
321
|
+
}.should =~ /invalid.*dude/
|
319
322
|
end
|
323
|
+
end
|
320
324
|
|
321
|
-
|
322
|
-
|
323
|
-
|
325
|
+
it "global option after local one and -" do
|
326
|
+
local_and_global("doh -r -f - --dude").should == [{:foo=>true}, {:dude=>true, :render=>true}]
|
327
|
+
end
|
324
328
|
|
325
|
-
|
326
|
-
|
327
|
-
|
329
|
+
it "conflicting global option after -" do
|
330
|
+
local_and_global('doh - -f=1,2').should == [{}, {:fields=>["1", "2"]}]
|
331
|
+
end
|
328
332
|
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
end
|
333
|
+
it "no options parsed after --" do
|
334
|
+
local_and_global('doh -f -- -r').should == [{:foo=>true}, {}]
|
335
|
+
local_and_global('doh -- -r -f').should == [{}, {}]
|
336
|
+
local_and_global('-- -r -f').should == [{}, {}]
|
337
|
+
local_and_global('doh -r -- -f').should == [{}, {:render=>true}]
|
335
338
|
end
|
336
339
|
end
|
337
|
-
|
340
|
+
after_all { Runner.in_shell = false }
|
341
|
+
end
|