gli 1.6.0 → 2.0.0.rc3
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/.gitignore +11 -0
- data/.rvmrc +1 -0
- data/.travis.yml +10 -0
- data/Gemfile +8 -0
- data/LICENSE.txt +201 -0
- data/ObjectModel.graffle +1191 -0
- data/README.rdoc +60 -10
- data/Rakefile +145 -0
- data/bin/gli +12 -30
- data/bin/report_on_rake_results +10 -0
- data/bin/test_all_rubies.sh +6 -0
- data/features/gli_executable.feature +84 -0
- data/features/gli_init.feature +219 -0
- data/features/step_definitions/gli_executable_steps.rb +12 -0
- data/features/step_definitions/gli_init_steps.rb +11 -0
- data/features/step_definitions/todo_steps.rb +69 -0
- data/features/support/env.rb +49 -0
- data/features/todo.feature +182 -0
- data/gli.cheat +95 -0
- data/gli.gemspec +34 -0
- data/lib/gli.rb +11 -571
- data/lib/gli/app.rb +184 -0
- data/lib/gli/app_support.rb +226 -0
- data/lib/gli/command.rb +107 -95
- data/lib/gli/command_line_option.rb +34 -0
- data/lib/gli/command_line_token.rb +13 -9
- data/lib/gli/command_support.rb +200 -0
- data/lib/gli/commands/compound_command.rb +42 -0
- data/lib/gli/commands/help.rb +63 -0
- data/lib/gli/commands/help_modules/command_help_format.rb +134 -0
- data/lib/gli/commands/help_modules/global_help_format.rb +61 -0
- data/lib/gli/commands/help_modules/list_formatter.rb +22 -0
- data/lib/gli/commands/help_modules/options_formatter.rb +50 -0
- data/lib/gli/commands/help_modules/text_wrapper.rb +53 -0
- data/lib/gli/commands/initconfig.rb +67 -0
- data/lib/{support → gli/commands}/scaffold.rb +150 -34
- data/lib/gli/dsl.rb +194 -0
- data/lib/gli/exceptions.rb +13 -4
- data/lib/gli/flag.rb +30 -41
- data/lib/gli/gli_option_parser.rb +98 -0
- data/lib/gli/option_parser_factory.rb +44 -0
- data/lib/gli/options.rb +2 -1
- data/lib/gli/switch.rb +19 -51
- data/lib/gli/terminal.rb +30 -20
- data/lib/gli/version.rb +5 -0
- data/test/apps/README.md +2 -0
- data/test/apps/todo/Gemfile +2 -0
- data/test/apps/todo/README.rdoc +6 -0
- data/test/apps/todo/Rakefile +23 -0
- data/test/apps/todo/bin/todo +52 -0
- data/test/apps/todo/lib/todo/commands/create.rb +22 -0
- data/test/apps/todo/lib/todo/commands/list.rb +53 -0
- data/test/apps/todo/lib/todo/commands/ls.rb +47 -0
- data/test/apps/todo/lib/todo/version.rb +3 -0
- data/test/apps/todo/test/tc_nothing.rb +14 -0
- data/test/apps/todo/todo.gemspec +23 -0
- data/test/apps/todo/todo.rdoc +5 -0
- data/test/config.yaml +10 -0
- data/test/fake_std_out.rb +30 -0
- data/test/gli.reek +122 -0
- data/test/init_simplecov.rb +8 -0
- data/test/option_test_helper.rb +13 -0
- data/test/roodi.yaml +18 -0
- data/test/tc_command.rb +260 -0
- data/test/tc_compount_command.rb +22 -0
- data/test/tc_flag.rb +56 -0
- data/test/tc_gli.rb +611 -0
- data/test/tc_help.rb +223 -0
- data/test/tc_options.rb +31 -0
- data/test/tc_subcommands.rb +162 -0
- data/test/tc_switch.rb +57 -0
- data/test/tc_terminal.rb +97 -0
- data/test/test_helper.rb +13 -0
- metadata +318 -49
- data/lib/gli_version.rb +0 -3
- data/lib/support/help.rb +0 -179
- data/lib/support/initconfig.rb +0 -34
- data/lib/support/rdoc.rb +0 -119
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'tempfile'
|
3
|
+
|
4
|
+
class TC_testCompounCommand < Clean::Test::TestCase
|
5
|
+
include TestHelper
|
6
|
+
|
7
|
+
test_that "when we create a CompoundCommand where some commands are missing, we get an exception" do
|
8
|
+
Given {
|
9
|
+
@name = any_string
|
10
|
+
@unknown_name = any_string
|
11
|
+
@existing_command = OpenStruct.new(:name => @name)
|
12
|
+
@base = OpenStruct.new( :commands => { @name => @existing_command })
|
13
|
+
}
|
14
|
+
When {
|
15
|
+
@code = lambda { GLI::Commands::CompoundCommand.new(@base,{:foo => [@name,@unknown_name]}) }
|
16
|
+
}
|
17
|
+
Then {
|
18
|
+
ex = assert_raises(RuntimeError,&@code)
|
19
|
+
assert_match /#{@unknown_name}/,ex.message
|
20
|
+
}
|
21
|
+
end
|
22
|
+
end
|
data/test/tc_flag.rb
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class TC_testFlag < Clean::Test::TestCase
|
4
|
+
include TestHelper
|
5
|
+
include GLI
|
6
|
+
|
7
|
+
def test_basics_simple
|
8
|
+
Given flag_with_names(:f)
|
9
|
+
Then attributes_should_be_set
|
10
|
+
And name_should_be(:f)
|
11
|
+
And aliases_should_be(nil)
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_basics_kinda_complex
|
15
|
+
Given flag_with_names([:f])
|
16
|
+
Then attributes_should_be_set
|
17
|
+
And name_should_be(:f)
|
18
|
+
And aliases_should_be(nil)
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_basics_complex
|
22
|
+
Given flag_with_names([:f,:file,:filename])
|
23
|
+
Then attributes_should_be_set
|
24
|
+
And name_should_be(:f)
|
25
|
+
And aliases_should_be([:file,:filename])
|
26
|
+
And {
|
27
|
+
assert_equal ["-f VAL","--file VAL","--filename VAL",/foobar/,Float],@flag.arguments_for_option_parser
|
28
|
+
}
|
29
|
+
end
|
30
|
+
|
31
|
+
def flag_with_names(names)
|
32
|
+
lambda do
|
33
|
+
@options = {
|
34
|
+
:desc => 'Filename',
|
35
|
+
:long_desc => 'The Filename',
|
36
|
+
:arg_name => 'file',
|
37
|
+
:default_value => '~/.blah.rc',
|
38
|
+
:must_match => /foobar/,
|
39
|
+
:type => Float,
|
40
|
+
}
|
41
|
+
@flag = Flag.new(names,@options)
|
42
|
+
@cli_option = @flag
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def attributes_should_be_set
|
47
|
+
lambda {
|
48
|
+
assert_equal(@options[:desc],@flag.description)
|
49
|
+
assert_equal(@options[:long_desc],@flag.long_description)
|
50
|
+
assert_equal(@options[:default_value],@flag.default_value)
|
51
|
+
assert_equal(@options[:must_match],@flag.must_match)
|
52
|
+
assert_equal(@options[:type],@flag.type)
|
53
|
+
assert(@flag.usage != nil)
|
54
|
+
}
|
55
|
+
end
|
56
|
+
end
|
data/test/tc_gli.rb
ADDED
@@ -0,0 +1,611 @@
|
|
1
|
+
# 1.9 adds realpath to resolve symlinks; 1.8 doesn't
|
2
|
+
# have this method, so we add it so we get resolved symlinks
|
3
|
+
# and compatibility
|
4
|
+
unless File.respond_to? :realpath
|
5
|
+
class File
|
6
|
+
def self.realpath path
|
7
|
+
return realpath(File.readlink(path)) if symlink?(path)
|
8
|
+
path
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
require 'test_helper'
|
14
|
+
|
15
|
+
class TC_testGLI < Clean::Test::TestCase
|
16
|
+
include TestHelper
|
17
|
+
include GLI
|
18
|
+
|
19
|
+
def setup
|
20
|
+
@app = CLIApp.new
|
21
|
+
@config_file = File.expand_path(File.dirname(File.realpath(__FILE__)) + '/new_config.yaml')
|
22
|
+
@gli_debug = ENV['GLI_DEBUG']
|
23
|
+
@fake_stderr = FakeStdOut.new
|
24
|
+
@app.error_device=@fake_stderr
|
25
|
+
ENV.delete('GLI_DEBUG')
|
26
|
+
end
|
27
|
+
|
28
|
+
def teardown
|
29
|
+
File.delete(@config_file) if File.exist?(@config_file)
|
30
|
+
ENV['GLI_DEBUG'] = @gli_debug
|
31
|
+
@app.error_device=$stderr
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_flag_create
|
35
|
+
@app.reset
|
36
|
+
do_test_flag_create(@app)
|
37
|
+
do_test_flag_create(Command.new(:names => :f))
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_create_commands_using_strings
|
41
|
+
@app.reset
|
42
|
+
@app.flag ['f','flag']
|
43
|
+
@app.switch ['s','some-switch']
|
44
|
+
@app.command 'command','command-with-dash' do |c|
|
45
|
+
end
|
46
|
+
assert @app.commands.include? :command
|
47
|
+
assert @app.flags.include? :f
|
48
|
+
assert @app.switches.include? :s
|
49
|
+
assert @app.commands[:command].aliases.include? :'command-with-dash'
|
50
|
+
assert @app.flags[:f].aliases.include? :flag
|
51
|
+
assert @app.switches[:s].aliases.include? :'some-switch'
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_flag_with_space_barfs
|
55
|
+
@app.reset
|
56
|
+
assert_raises(ArgumentError) { @app.flag ['some flag'] }
|
57
|
+
assert_raises(ArgumentError) { @app.flag ['f','some flag'] }
|
58
|
+
assert_raises(ArgumentError) { @app.switch ['some switch'] }
|
59
|
+
assert_raises(ArgumentError) { @app.switch ['f','some switch'] }
|
60
|
+
assert_raises(ArgumentError) { @app.command ['some command'] }
|
61
|
+
assert_raises(ArgumentError) { @app.command ['f','some command'] }
|
62
|
+
end
|
63
|
+
|
64
|
+
def test_init_from_config
|
65
|
+
failure = nil
|
66
|
+
@app.reset
|
67
|
+
@app.config_file(File.expand_path(File.dirname(File.realpath(__FILE__)) + '/config.yaml'))
|
68
|
+
@app.flag :f
|
69
|
+
@app.switch :s
|
70
|
+
@app.flag :g
|
71
|
+
called = false
|
72
|
+
@app.command :command do |c|
|
73
|
+
c.flag :f
|
74
|
+
c.switch :s
|
75
|
+
c.flag :g
|
76
|
+
c.action do |g,o,a|
|
77
|
+
begin
|
78
|
+
called = true
|
79
|
+
assert_equal "foo",g[:f]
|
80
|
+
assert_equal "bar",o[:g]
|
81
|
+
assert !g[:g]
|
82
|
+
assert !o[:f]
|
83
|
+
assert !g[:s]
|
84
|
+
assert o[:s]
|
85
|
+
rescue Exception => ex
|
86
|
+
failure = ex
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
@app.run(['command'])
|
91
|
+
assert called
|
92
|
+
raise failure if !failure.nil?
|
93
|
+
end
|
94
|
+
|
95
|
+
def test_command_line_overrides_config
|
96
|
+
failure = nil
|
97
|
+
@app.reset
|
98
|
+
@app.config_file(File.expand_path(File.dirname(File.realpath(__FILE__)) + '/config.yaml'))
|
99
|
+
@app.flag :f
|
100
|
+
@app.switch :s
|
101
|
+
@app.flag :g
|
102
|
+
@app.switch :bleorgh
|
103
|
+
called = false
|
104
|
+
@app.command :command do |c|
|
105
|
+
c.flag :f
|
106
|
+
c.switch :s
|
107
|
+
c.flag :g
|
108
|
+
c.action do |g,o,a|
|
109
|
+
begin
|
110
|
+
called = true
|
111
|
+
assert_equal "baaz",o[:g]
|
112
|
+
assert_equal "bar",g[:f]
|
113
|
+
assert !g[:g],o.inspect
|
114
|
+
assert !o[:f],o.inspect
|
115
|
+
assert !g[:s],o.inspect
|
116
|
+
assert o[:s],o.inspect
|
117
|
+
assert g[:bleorgh] != nil,"Expected :bleorgh to have a value"
|
118
|
+
assert g[:bleorgh] == false,"Expected :bleorgh to be false"
|
119
|
+
rescue Exception => ex
|
120
|
+
failure = ex
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
assert_equal 0,@app.run(%w(-f bar --no-bleorgh command -g baaz)),@fake_stderr.to_s
|
125
|
+
assert called
|
126
|
+
raise failure if !failure.nil?
|
127
|
+
end
|
128
|
+
|
129
|
+
def test_no_overwrite_config
|
130
|
+
config_file = File.expand_path(File.dirname(File.realpath(__FILE__)) + '/config.yaml')
|
131
|
+
config_file_contents = File.read(config_file)
|
132
|
+
@app.reset
|
133
|
+
@app.config_file(config_file)
|
134
|
+
assert_equal 1,@app.run(['initconfig'])
|
135
|
+
assert @fake_stderr.strings.grep(/--force/),@fake_stderr.strings.inspect
|
136
|
+
config_file_contents_after = File.read(config_file)
|
137
|
+
assert_equal(config_file_contents,config_file_contents_after)
|
138
|
+
end
|
139
|
+
|
140
|
+
def test_config_file_name
|
141
|
+
@app.reset
|
142
|
+
file = @app.config_file("foo")
|
143
|
+
assert_equal(Etc.getpwuid.dir + "/foo",file)
|
144
|
+
file = @app.config_file("/foo")
|
145
|
+
assert_equal "/foo",file
|
146
|
+
init_command = @app.commands[:initconfig]
|
147
|
+
assert init_command
|
148
|
+
end
|
149
|
+
|
150
|
+
def test_initconfig_command
|
151
|
+
@app.reset
|
152
|
+
@app.config_file(@config_file)
|
153
|
+
@app.flag :f
|
154
|
+
@app.switch :s
|
155
|
+
@app.switch :w
|
156
|
+
@app.flag :bigflag
|
157
|
+
@app.flag :biggestflag
|
158
|
+
@app.command :foo do |c|
|
159
|
+
end
|
160
|
+
@app.command :bar do |c|
|
161
|
+
end
|
162
|
+
@app.command :blah do |c|
|
163
|
+
end
|
164
|
+
@app.on_error do |ex|
|
165
|
+
raise ex
|
166
|
+
end
|
167
|
+
@app.run(['-f','foo','-s','--bigflag=bleorgh','initconfig'])
|
168
|
+
|
169
|
+
written_config = File.open(@config_file) { |f| YAML::load(f) }
|
170
|
+
|
171
|
+
assert_equal 'foo',written_config[:f]
|
172
|
+
assert_equal 'bleorgh',written_config[:bigflag]
|
173
|
+
assert written_config[:s]
|
174
|
+
assert !written_config[:w]
|
175
|
+
assert_nil written_config[:biggestflag]
|
176
|
+
assert written_config[GLI::InitConfig::COMMANDS_KEY]
|
177
|
+
assert written_config[GLI::InitConfig::COMMANDS_KEY][:foo]
|
178
|
+
assert written_config[GLI::InitConfig::COMMANDS_KEY][:bar]
|
179
|
+
assert written_config[GLI::InitConfig::COMMANDS_KEY][:blah]
|
180
|
+
|
181
|
+
end
|
182
|
+
|
183
|
+
def test_initconfig_permissions
|
184
|
+
@app.reset
|
185
|
+
@app.config_file(@config_file)
|
186
|
+
@app.run(['initconfig'])
|
187
|
+
oct_mode = "%o" % File.stat(@config_file).mode
|
188
|
+
assert_match /0600$/, oct_mode
|
189
|
+
end
|
190
|
+
|
191
|
+
def do_test_flag_create(object)
|
192
|
+
description = 'this is a description'
|
193
|
+
long_desc = 'this is a very long description'
|
194
|
+
object.desc description
|
195
|
+
object.long_desc long_desc
|
196
|
+
object.arg_name 'filename'
|
197
|
+
object.default_value '~/.blah.rc'
|
198
|
+
object.flag :f
|
199
|
+
assert (object.flags[:f] )
|
200
|
+
assert_equal(description,object.flags[:f].description)
|
201
|
+
assert_equal(long_desc,object.flags[:f].long_description)
|
202
|
+
assert(nil != object.flags[:f].usage)
|
203
|
+
assert(object.usage != nil) if object.respond_to? :usage;
|
204
|
+
end
|
205
|
+
|
206
|
+
def test_switch_create
|
207
|
+
@app.reset
|
208
|
+
do_test_switch_create(@app)
|
209
|
+
do_test_switch_create(Command.new(:names => :f))
|
210
|
+
end
|
211
|
+
|
212
|
+
def test_switch_create_twice
|
213
|
+
@app.reset
|
214
|
+
do_test_switch_create_twice(@app)
|
215
|
+
do_test_switch_create_twice(Command.new(:names => :f))
|
216
|
+
end
|
217
|
+
|
218
|
+
def test_all_aliases_in_options
|
219
|
+
@app.reset
|
220
|
+
@app.on_error { |ex| raise ex }
|
221
|
+
@app.flag [:f,:flag,:'big-flag-name']
|
222
|
+
@app.switch [:s,:switch,:'big-switch-name']
|
223
|
+
@app.command [:com,:command] do |c|
|
224
|
+
c.flag [:g,:gflag]
|
225
|
+
c.switch [:h,:hswitch]
|
226
|
+
c.action do |global,options,args|
|
227
|
+
assert_equal 'foo',global[:f]
|
228
|
+
assert_equal global[:f],global[:flag]
|
229
|
+
assert_equal global[:f],global[:'big-flag-name']
|
230
|
+
|
231
|
+
assert global[:s]
|
232
|
+
assert global[:switch]
|
233
|
+
assert global[:'big-switch-name']
|
234
|
+
|
235
|
+
assert_equal 'bar',options[:g]
|
236
|
+
assert_equal options[:g],options[:gflag]
|
237
|
+
|
238
|
+
assert options[:h]
|
239
|
+
assert options[:hswitch]
|
240
|
+
end
|
241
|
+
end
|
242
|
+
@app.run(%w(-f foo -s command -g bar -h some_arg))
|
243
|
+
end
|
244
|
+
|
245
|
+
def test_use_hash_by_default
|
246
|
+
@app.reset
|
247
|
+
@app.switch :g
|
248
|
+
@app.command :command do |c|
|
249
|
+
c.switch :f
|
250
|
+
c.action do |global,options,args|
|
251
|
+
assert_equal Hash,global.class
|
252
|
+
assert_equal Hash,options.class
|
253
|
+
end
|
254
|
+
end
|
255
|
+
@app.run(%w(-g command -f))
|
256
|
+
end
|
257
|
+
|
258
|
+
def test_flag_array_of_options_global
|
259
|
+
@app.reset
|
260
|
+
@app.flag :foo, :must_match => ['bar','blah','baz']
|
261
|
+
@app.command :command do |c|
|
262
|
+
c.action do
|
263
|
+
end
|
264
|
+
end
|
265
|
+
assert_equal 64,@app.run(%w(--foo=cruddo command)),@fake_stderr.to_s
|
266
|
+
assert @fake_stderr.contained?(/error: invalid argument: --foo=cruddo/),"STDERR was:\n" + @fake_stderr.to_s
|
267
|
+
assert_equal 0,@app.run(%w(--foo=blah command)),@fake_stderr.to_s
|
268
|
+
end
|
269
|
+
|
270
|
+
def test_flag_hash_of_options_global
|
271
|
+
@app.reset
|
272
|
+
@app.flag :foo, :must_match => { 'bar' => "BAR", 'blah' => "BLAH" }
|
273
|
+
@foo_arg_value = nil
|
274
|
+
@app.command :command do |c|
|
275
|
+
c.action do |g,o,a|
|
276
|
+
@foo_arg_value = g[:foo]
|
277
|
+
end
|
278
|
+
end
|
279
|
+
assert_equal 64,@app.run(%w(--foo=cruddo command)),@fake_stderr.to_s
|
280
|
+
assert @fake_stderr.contained?(/error: invalid argument: --foo=cruddo/),"STDERR was:\n" + @fake_stderr.to_s
|
281
|
+
assert_equal 0,@app.run(%w(--foo=blah command)),@fake_stderr.to_s
|
282
|
+
assert_equal 'BLAH',@foo_arg_value
|
283
|
+
end
|
284
|
+
|
285
|
+
def test_flag_regexp_global
|
286
|
+
@app.reset
|
287
|
+
@app.flag :foo, :must_match => /bar/
|
288
|
+
@app.command :command do |c|
|
289
|
+
c.action do
|
290
|
+
end
|
291
|
+
end
|
292
|
+
assert_equal 64,@app.run(%w(--foo=cruddo command)),@fake_stderr.to_s
|
293
|
+
assert @fake_stderr.contained?(/error: invalid argument: --foo=cruddo/),"STDERR was:\n" + @fake_stderr.to_s
|
294
|
+
end
|
295
|
+
|
296
|
+
def test_flag_regexp_global_short_form
|
297
|
+
@app.reset
|
298
|
+
@app.flag :f, :must_match => /bar/
|
299
|
+
@app.command :command do |c|
|
300
|
+
c.action do
|
301
|
+
end
|
302
|
+
end
|
303
|
+
assert_equal 64,@app.run(%w(-f cruddo command)),@fake_stderr.to_s
|
304
|
+
assert @fake_stderr.contained?(/error: invalid argument: -f cruddo/),"STDERR was:\n" + @fake_stderr.to_s
|
305
|
+
end
|
306
|
+
|
307
|
+
def test_flag_regexp_command
|
308
|
+
@app.reset
|
309
|
+
@app.command :command do |c|
|
310
|
+
c.flag :foo, :must_match => /bar/
|
311
|
+
c.action do
|
312
|
+
end
|
313
|
+
end
|
314
|
+
assert_equal 64,@app.run(%w(command --foo=cruddo)),@fake_stderr.to_s
|
315
|
+
assert @fake_stderr.contained?(/error: invalid argument: --foo=cruddo/),"STDERR was:\n" + @fake_stderr.to_s
|
316
|
+
end
|
317
|
+
|
318
|
+
def test_use_openstruct
|
319
|
+
@app.reset
|
320
|
+
@app.switch :g
|
321
|
+
@app.use_openstruct true
|
322
|
+
@app.command :command do |c|
|
323
|
+
c.switch :f
|
324
|
+
c.action do |global,options,args|
|
325
|
+
assert_equal GLI::Options,global.class
|
326
|
+
assert_equal GLI::Options,options.class
|
327
|
+
end
|
328
|
+
end
|
329
|
+
@app.run(%w(-g command -f))
|
330
|
+
end
|
331
|
+
|
332
|
+
def test_repeated_option_names
|
333
|
+
@app.reset
|
334
|
+
@app.on_error { |ex| raise ex }
|
335
|
+
@app.flag [:f,:flag]
|
336
|
+
assert_raises(ArgumentError) { @app.switch [:foo,:flag] }
|
337
|
+
assert_raises(ArgumentError) { @app.switch [:f] }
|
338
|
+
|
339
|
+
@app.switch [:x,:y]
|
340
|
+
assert_raises(ArgumentError) { @app.flag [:x] }
|
341
|
+
assert_raises(ArgumentError) { @app.flag [:y] }
|
342
|
+
|
343
|
+
# This shouldn't raise; :help is special
|
344
|
+
@app.switch :help
|
345
|
+
end
|
346
|
+
|
347
|
+
def test_repeated_option_names_on_command
|
348
|
+
@app.reset
|
349
|
+
@app.on_error { |ex| raise ex }
|
350
|
+
@app.command :command do |c|
|
351
|
+
c.flag [:f,:flag]
|
352
|
+
assert_raises(ArgumentError) { c.switch [:foo,:flag] }
|
353
|
+
assert_raises(ArgumentError) { c.switch [:f] }
|
354
|
+
assert_raises(ArgumentError) { c.flag [:foo,:flag] }
|
355
|
+
assert_raises(ArgumentError) { c.flag [:f] }
|
356
|
+
end
|
357
|
+
@app.command :command3 do |c|
|
358
|
+
c.switch [:s,:switch]
|
359
|
+
assert_raises(ArgumentError) { c.switch [:switch] }
|
360
|
+
assert_raises(ArgumentError) { c.switch [:s] }
|
361
|
+
assert_raises(ArgumentError) { c.flag [:switch] }
|
362
|
+
assert_raises(ArgumentError) { c.flag [:s] }
|
363
|
+
end
|
364
|
+
end
|
365
|
+
|
366
|
+
def test_two_flags
|
367
|
+
@app.reset
|
368
|
+
@app.on_error do |ex|
|
369
|
+
raise ex
|
370
|
+
end
|
371
|
+
@app.command [:foo] do |c|
|
372
|
+
c.flag :i
|
373
|
+
c.flag :s
|
374
|
+
c.action do |g,o,a|
|
375
|
+
assert_equal "5", o[:i]
|
376
|
+
assert_equal "a", o[:s]
|
377
|
+
end
|
378
|
+
end
|
379
|
+
@app.run(['foo', '-i','5','-s','a'])
|
380
|
+
end
|
381
|
+
|
382
|
+
def test_two_flags_with_a_default
|
383
|
+
@app.reset
|
384
|
+
@app.on_error do |ex|
|
385
|
+
raise ex
|
386
|
+
end
|
387
|
+
@app.command [:foo] do |c|
|
388
|
+
c.default_value "1"
|
389
|
+
c.flag :i
|
390
|
+
c.flag :s
|
391
|
+
c.action do |g,o,a|
|
392
|
+
assert_equal "5", o[:i]
|
393
|
+
assert_equal "a", o[:s]
|
394
|
+
end
|
395
|
+
end
|
396
|
+
@app.run(['foo', '-i','5','-s','a'])
|
397
|
+
end
|
398
|
+
|
399
|
+
def test_two_flags_using_equals_with_a_default
|
400
|
+
@app.reset
|
401
|
+
@app.on_error do |ex|
|
402
|
+
raise ex
|
403
|
+
end
|
404
|
+
@app.command [:foo] do |c|
|
405
|
+
c.default_value "1"
|
406
|
+
c.flag :i
|
407
|
+
c.flag :s
|
408
|
+
c.action do |g,o,a|
|
409
|
+
assert_equal "5", o[:i],o.inspect
|
410
|
+
assert_equal "a", o[:s],o.inspect
|
411
|
+
end
|
412
|
+
end
|
413
|
+
@app.run(['foo', '-i5','-sa'])
|
414
|
+
end
|
415
|
+
|
416
|
+
def test_exits_zero_on_success
|
417
|
+
assert_equal 0,@app.run([]),@fake_stderr.to_s
|
418
|
+
end
|
419
|
+
|
420
|
+
def test_exits_nonzero_on_bad_command_line
|
421
|
+
@app.reset
|
422
|
+
@app.on_error { true }
|
423
|
+
assert_equal 64,@app.run(['asdfasdfasdf'])
|
424
|
+
end
|
425
|
+
|
426
|
+
def test_exists_nonzero_on_raise_from_command
|
427
|
+
@app.reset
|
428
|
+
@app.on_error { true }
|
429
|
+
@app.command(:foo) do |c|
|
430
|
+
c.action do |g,o,a|
|
431
|
+
raise "Problem"
|
432
|
+
end
|
433
|
+
end
|
434
|
+
assert_equal 1,@app.run(['foo'])
|
435
|
+
end
|
436
|
+
|
437
|
+
def test_exits_nonzero_with_custom_exception
|
438
|
+
@app.reset
|
439
|
+
@app.on_error { true }
|
440
|
+
@app.command(:foo) do |c|
|
441
|
+
c.action do |g,o,a|
|
442
|
+
raise CustomExit.new("Problem",45)
|
443
|
+
end
|
444
|
+
end
|
445
|
+
assert_equal 45,@app.run(['foo'])
|
446
|
+
end
|
447
|
+
|
448
|
+
def test_exits_nonzero_with_exit_method
|
449
|
+
@app.reset
|
450
|
+
@app.on_error { true }
|
451
|
+
@app.command(:foo) do |c|
|
452
|
+
c.action do |g,o,a|
|
453
|
+
@app.exit_now!("Problem",45)
|
454
|
+
end
|
455
|
+
end
|
456
|
+
assert_equal 45,@app.run(['foo'])
|
457
|
+
end
|
458
|
+
|
459
|
+
def test_exits_nonzero_with_exit_method_by_default
|
460
|
+
@app.reset
|
461
|
+
@app.on_error { true }
|
462
|
+
@app.command(:foo) do |c|
|
463
|
+
c.action do |g,o,a|
|
464
|
+
@app.exit_now!("Problem")
|
465
|
+
end
|
466
|
+
end
|
467
|
+
assert_equal 1,@app.run(['foo'])
|
468
|
+
end
|
469
|
+
|
470
|
+
def test_help_now_exits_and_shows_help
|
471
|
+
@app.reset
|
472
|
+
@app.on_error { true }
|
473
|
+
@app.command(:foo) do |c|
|
474
|
+
c.action do |g,o,a|
|
475
|
+
@app.help_now!("Problem")
|
476
|
+
end
|
477
|
+
end
|
478
|
+
assert_equal 64,@app.run(['foo']),@fake_stderr.strings.join("\n")
|
479
|
+
end
|
480
|
+
|
481
|
+
def test_custom_exception_causes_error_to_be_printed_to_stderr
|
482
|
+
@app.reset
|
483
|
+
@app.on_error { true }
|
484
|
+
error_message = "Something went wrong"
|
485
|
+
@app.command(:foo) do |c|
|
486
|
+
c.action do |g,o,a|
|
487
|
+
raise error_message
|
488
|
+
end
|
489
|
+
end
|
490
|
+
@app.run(['foo'])
|
491
|
+
assert @fake_stderr.strings.include?("error: #{error_message}"),"STDERR was:\n" + @fake_stderr.to_s
|
492
|
+
end
|
493
|
+
|
494
|
+
def test_gli_debug_overrides_error_hiding
|
495
|
+
ENV['GLI_DEBUG'] = 'true'
|
496
|
+
|
497
|
+
@app.reset
|
498
|
+
@app.on_error { true }
|
499
|
+
@app.command(:foo) do |c|
|
500
|
+
c.action do |g,o,a|
|
501
|
+
@app.exit_now!("Problem",45)
|
502
|
+
end
|
503
|
+
end
|
504
|
+
|
505
|
+
assert_raises(CustomExit) { @app.run(['foo']) }
|
506
|
+
end
|
507
|
+
|
508
|
+
class ConvertMe
|
509
|
+
attr_reader :value
|
510
|
+
def initialize(value)
|
511
|
+
@value = value
|
512
|
+
end
|
513
|
+
end
|
514
|
+
|
515
|
+
def test_that_we_can_add_new_casts_for_flags
|
516
|
+
@app.reset
|
517
|
+
@app.accept(ConvertMe) do |value|
|
518
|
+
ConvertMe.new(value)
|
519
|
+
end
|
520
|
+
@app.flag :foo, :type => ConvertMe
|
521
|
+
|
522
|
+
@foo = nil
|
523
|
+
@baz = nil
|
524
|
+
|
525
|
+
@app.command(:bar) do |c|
|
526
|
+
c.flag :baz, :type => ConvertMe
|
527
|
+
c.action do |g,o,a|
|
528
|
+
@foo = g[:foo]
|
529
|
+
@baz = o[:baz]
|
530
|
+
end
|
531
|
+
end
|
532
|
+
|
533
|
+
assert_equal 0,@app.run(['--foo','blah','bar','--baz=crud']),@fake_stderr.to_s
|
534
|
+
|
535
|
+
assert @foo.kind_of?(ConvertMe),"Expected a ConvertMe, but get a #{@foo.class}"
|
536
|
+
assert_equal 'blah',@foo.value
|
537
|
+
|
538
|
+
assert @baz.kind_of?(ConvertMe),"Expected a ConvertMe, but get a #{@foo.class}"
|
539
|
+
assert_equal 'crud',@baz.value
|
540
|
+
end
|
541
|
+
|
542
|
+
private
|
543
|
+
|
544
|
+
def do_test_flag_create(object)
|
545
|
+
description = 'this is a description'
|
546
|
+
long_desc = 'this is a very long description'
|
547
|
+
object.desc description
|
548
|
+
object.long_desc long_desc
|
549
|
+
object.arg_name 'filename'
|
550
|
+
object.default_value '~/.blah.rc'
|
551
|
+
object.flag :f
|
552
|
+
assert (object.flags[:f] )
|
553
|
+
assert_equal(description,object.flags[:f].description)
|
554
|
+
assert_equal(long_desc,object.flags[:f].long_description)
|
555
|
+
assert(nil != object.flags[:f].usage)
|
556
|
+
assert(object.usage != nil) if object.respond_to? :usage
|
557
|
+
end
|
558
|
+
|
559
|
+
def do_test_switch_create(object)
|
560
|
+
do_test_switch_create_classic(object)
|
561
|
+
do_test_switch_create_compact(object)
|
562
|
+
end
|
563
|
+
|
564
|
+
def some_descriptions
|
565
|
+
lambda {
|
566
|
+
@description = 'this is a description'
|
567
|
+
@long_description = 'this is a very long description'
|
568
|
+
}
|
569
|
+
end
|
570
|
+
|
571
|
+
def assert_switch_was_made(object,switch)
|
572
|
+
lambda {
|
573
|
+
assert object.switches[switch]
|
574
|
+
assert_equal @description,object.switches[switch].description,"For switch #{switch}"
|
575
|
+
assert_equal @long_description,object.switches[switch].long_description,"For switch #{switch}"
|
576
|
+
assert(object.usage != nil) if object.respond_to? :usage
|
577
|
+
}
|
578
|
+
end
|
579
|
+
|
580
|
+
def do_test_switch_create_classic(object)
|
581
|
+
Given some_descriptions
|
582
|
+
When {
|
583
|
+
object.desc @description
|
584
|
+
object.long_desc @long_description
|
585
|
+
object.switch :f
|
586
|
+
}
|
587
|
+
Then assert_switch_was_made(object,:f)
|
588
|
+
end
|
589
|
+
|
590
|
+
def do_test_switch_create_compact(object)
|
591
|
+
Given some_descriptions
|
592
|
+
When {
|
593
|
+
object.switch :g, :desc => @description, :long_desc => @long_description
|
594
|
+
}
|
595
|
+
Then assert_switch_was_made(object,:g)
|
596
|
+
end
|
597
|
+
|
598
|
+
def do_test_switch_create_twice(object)
|
599
|
+
description = 'this is a description'
|
600
|
+
object.desc description
|
601
|
+
object.switch :f
|
602
|
+
assert (object.switches[:f] )
|
603
|
+
assert_equal(description,object.switches[:f].description)
|
604
|
+
object.switch :g
|
605
|
+
assert (object.switches[:g])
|
606
|
+
assert_equal(nil,object.switches[:g].description)
|
607
|
+
assert(object.usage != nil) if object.respond_to? :usage
|
608
|
+
end
|
609
|
+
|
610
|
+
|
611
|
+
end
|