boson 0.2.3 → 0.2.4
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/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
|