/
scientist_test.rb
202 lines (166 loc) · 6.55 KB
/
scientist_test.rb
1
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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
require File.join(File.dirname(__FILE__), 'test_helper')
describe "Scientist" do
before_all {
Boson.in_shell = nil
eval <<-EOF
module Blah
def blah(arg1, options={})
[arg1, options]
end
def splat_blah(*args)
args
end
def default_blah(arg1, arg2=default, options={})
[arg1, arg2, options]
end
def default; 'some default'; end
def default_option(options={})
options
end
end
EOF
@opt_cmd = Object.new.extend Blah
}
def command(hash, args)
hash = {:name=>'blah', :lib=>'bling', :options=>{:force=>:boolean, :level=>2}}.merge(hash)
@cmd = Command.new hash
@cmd.instance_variable_set("@file_parsed_args", true) if hash[:file_parsed_args]
Scientist.redefine_command(@opt_cmd, @cmd)
@opt_cmd.send(hash[:name], *args)
end
def command_with_arg_size(*args)
command({:args=>2}, args)
end
def command_with_args(*args)
command({:args=>[['arg1'],['options', {}]]}, args)
end
def basic_command(hash, args)
command({:name=>'splat_blah', :args=>'*'}.merge(hash), args)
end
def command_with_splat_args(*args)
command({:name=>'splat_blah', :args=>'*'}, args)
end
def command_with_arg_defaults(*args)
arg_defaults = [%w{arg1}, %w{arg2 default}, %w{options {}}]
command({:name=>'default_blah', :file_parsed_args=>true, :args=>arg_defaults}, args)
end
def args_are_equal(args, array)
command_with_args(*args).should == array
command_with_arg_size(*args).should == array
command_with_splat_args(*args).should == array
end
def all_commands
[:command_with_args, :command_with_arg_size, :command_with_splat_args]
end
describe "all commands" do
it "translate arg and options as one string" do
args_are_equal ['a1 -f'], ['a1', {:force=>true, :level=>2}]
end
it "translate arg and stringified options" do
args_are_equal [:cool, '-l3'], [:cool, {:level=>3}]
end
it "translate arg and normal hash options" do
args_are_equal [:cool, {:ok=>true}], [:cool, {:ok=>true, :level=>2}]
end
it "translate stringified arg without options sets default options" do
args_are_equal ['cool'], ['cool', {:level=>2}]
end
it "translate arg without options sets default options" do
args_are_equal [:cool], [:cool, {:level=>2}]
end
it "with invalid options print errors and delete them" do
all_commands.each do |cmd|
capture_stderr {
send(cmd, 'cool -f -z').should == ['cool', {:force=>true, :level=>2}]
}.should =~/invalid.*z/
end
end
end
describe "command" do
describe "with arg defaults" do
it "sets defaults with stringified args" do
command_with_arg_defaults('1').should == ["1", "some default", {:level=>2}]
end
it "sets defaults with normal args" do
command_with_arg_defaults(1).should == [1, "some default", {:level=>2}]
end
it "sets default if optional arg is a valid option" do
command_with_arg_defaults("cool -f").should == ["cool", "some default", {:level=>2, :force=>true}]
end
it "doesn't set defaults if not needed" do
command_with_arg_defaults(1, 'nada').should == [1, "nada", {:level=>2}]
end
it "prints error for invalid defaults" do
arg_defaults = [%w{arg1}, %w{arg2 invalidzzz}, %w{options {}}]
capture_stderr {
command({:name=>'default_blah', :file_parsed_args=>true, :args=>arg_defaults}, [1])
}.should =~ /Error.*position 2/
end
end
describe "prints error" do
it "with option error" do
capture_stderr { command_with_args('a1 -l') }.should =~ /Error.*level/
end
it "with no argument defined for options" do
assert_error(OptionCommand::CommandArgumentError, '2 for 1') { command({:args=>1}, 'ok') }
end
end
it "translates stringfied args + options starting at second arg" do
command_with_arg_defaults(1, 'nada -l3').should == [1, "nada", {:level=>3}]
end
it "with leading option-like args are translated as arguments" do
command_with_args('-z -f').should == ["-z", {:force=>true, :level=>2}]
command_with_args('--blah -f').should == ['--blah', {:force=>true, :level=>2}]
end
it "with splat args does not raise error for too few or many args" do
[[], [''], [1,2,3], ['1 2 3']].each do |args|
should_not_raise { command_with_splat_args *args }
end
end
it "with not enough args raises CommandArgumentError" do
args = [OptionCommand::CommandArgumentError, '0 for 1']
assert_error(*args) { command_with_args }
assert_error(*args) { command_with_args '' }
assert_error(*args) { command_with_arg_size }
assert_error(*args) { command_with_arg_size '' }
end
it "with too many args raises CommandArgumentError" do
args3 = RUBY_ENGINE == 'rbx' ? [ArgumentError, 'given 3, expected 2'] :
RUBY_VERSION >= '2.0.0' ? [ArgumentError, "3 for 1..2"] : [ArgumentError, '3 for 2']
args4 = [OptionCommand::CommandArgumentError, '4 for 2']
assert_error(*args3) { command_with_args 1,2,3 }
assert_error(*args4) { command_with_args '1 2 3' }
assert_error(*args3) { command_with_arg_size 1,2,3 }
assert_error(*args4) { command_with_arg_size '1 2 3' }
end
end
describe "command with default option" do
before_all { @cmd_attributes = {:name=>'default_option', :default_option=>'level', :args=>1} }
it "parses normally from irb" do
command(@cmd_attributes, '-f --level=3').should == {:level=>3, :force=>true}
end
it "parses normally from cmdline" do
Boson.expects(:in_shell).times(2).returns true
command(@cmd_attributes, ['--force', '--level=3']).should == {:level=>3, :force=>true}
end
it "parses no arguments normally" do
command(@cmd_attributes, '').should == {:level=>2}
end
it "parses ruby arguments normally" do
command(@cmd_attributes, [{:force=>true, :level=>10}]).should == {:level=>10, :force=>true}
end
it "prepends correctly from irb" do
command(@cmd_attributes, '3 -f').should == {:level=>3, :force=>true}
end
it "prepends correctly from cmdline" do
Boson.expects(:in_shell).times(2).returns true
command(@cmd_attributes, ['3','-f']).should == {:level=>3, :force=>true}
end
end
it "redefine_command prints error for command with nonexistant method" do
capture_stderr {
Scientist.redefine_command Object.new, Command.new(:name=>'blah', :lib=>'blah')
}.should =~ /Error: No method.*'blah'/
end
after_all { Boson.in_shell = false }
end