gli 2.11.0 → 2.20.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (92) hide show
  1. checksums.yaml +5 -5
  2. data/.circleci/config.yml +28 -0
  3. data/.gitignore +3 -3
  4. data/.tool-versions +1 -0
  5. data/Gemfile +0 -2
  6. data/README.rdoc +29 -19
  7. data/Rakefile +15 -37
  8. data/bin/ci +29 -0
  9. data/bin/gli +24 -54
  10. data/bin/rake +29 -0
  11. data/bin/setup +5 -0
  12. data/exe/gli +68 -0
  13. data/gli.gemspec +20 -24
  14. data/gli.rdoc +9 -9
  15. data/lib/gli/app.rb +31 -8
  16. data/lib/gli/app_support.rb +15 -3
  17. data/lib/gli/command.rb +24 -2
  18. data/lib/gli/command_finder.rb +42 -25
  19. data/lib/gli/command_support.rb +7 -6
  20. data/lib/gli/commands/doc.rb +9 -3
  21. data/lib/gli/commands/help.rb +2 -1
  22. data/lib/gli/commands/help_modules/arg_name_formatter.rb +2 -2
  23. data/lib/gli/commands/help_modules/command_help_format.rb +19 -1
  24. data/lib/gli/commands/help_modules/full_synopsis_formatter.rb +3 -2
  25. data/lib/gli/commands/help_modules/global_help_format.rb +1 -1
  26. data/lib/gli/commands/help_modules/options_formatter.rb +4 -6
  27. data/lib/gli/commands/initconfig.rb +3 -6
  28. data/lib/gli/commands/rdoc_document_listener.rb +2 -1
  29. data/lib/gli/commands/scaffold.rb +71 -142
  30. data/lib/gli/dsl.rb +2 -1
  31. data/lib/gli/flag.rb +23 -2
  32. data/lib/gli/gli_option_parser.rb +66 -15
  33. data/lib/gli/option_parser_factory.rb +9 -2
  34. data/lib/gli/options.rb +2 -2
  35. data/lib/gli/switch.rb +4 -0
  36. data/lib/gli/terminal.rb +6 -2
  37. data/lib/gli/version.rb +1 -1
  38. data/lib/gli.rb +1 -0
  39. data/object-model.dot +29 -0
  40. data/object-model.png +0 -0
  41. data/test/apps/todo/Gemfile +1 -1
  42. data/test/apps/todo/bin/todo +12 -6
  43. data/test/apps/todo/lib/todo/commands/create.rb +42 -41
  44. data/test/apps/todo/lib/todo/commands/list.rb +48 -36
  45. data/test/apps/todo/lib/todo/commands/ls.rb +25 -24
  46. data/test/apps/todo/lib/todo/commands/make.rb +42 -39
  47. data/test/apps/todo/todo.gemspec +1 -2
  48. data/test/apps/todo_legacy/todo.gemspec +1 -2
  49. data/test/apps/todo_plugins/commands/third.rb +2 -0
  50. data/test/integration/gli_cli_test.rb +69 -0
  51. data/test/integration/gli_powered_app_test.rb +52 -0
  52. data/test/integration/scaffold_test.rb +30 -0
  53. data/test/integration/test_helper.rb +52 -0
  54. data/test/unit/command_finder_test.rb +54 -0
  55. data/test/{tc_command.rb → unit/command_test.rb} +20 -7
  56. data/test/unit/compound_command_test.rb +17 -0
  57. data/test/{tc_doc.rb → unit/doc_test.rb} +38 -51
  58. data/test/{tc_flag.rb → unit/flag_test.rb} +19 -25
  59. data/test/{tc_gli.rb → unit/gli_test.rb} +78 -50
  60. data/test/{tc_help.rb → unit/help_test.rb} +54 -113
  61. data/test/{tc_options.rb → unit/options_test.rb} +4 -4
  62. data/test/unit/subcommand_parsing_test.rb +263 -0
  63. data/test/unit/subcommands_test.rb +245 -0
  64. data/test/{config.yaml → unit/support/gli_test_config.yml} +1 -0
  65. data/test/unit/switch_test.rb +49 -0
  66. data/test/{tc_terminal.rb → unit/terminal_test.rb} +28 -3
  67. data/test/unit/test_helper.rb +13 -0
  68. data/test/unit/verbatim_wrapper_test.rb +24 -0
  69. metadata +85 -141
  70. data/.ruby-gemset +0 -1
  71. data/.ruby-version +0 -1
  72. data/.travis.yml +0 -12
  73. data/ObjectModel.graffle +0 -1191
  74. data/bin/report_on_rake_results +0 -10
  75. data/bin/test_all_rubies.sh +0 -6
  76. data/features/gli_executable.feature +0 -90
  77. data/features/gli_init.feature +0 -232
  78. data/features/step_definitions/gli_executable_steps.rb +0 -18
  79. data/features/step_definitions/gli_init_steps.rb +0 -11
  80. data/features/step_definitions/todo_steps.rb +0 -100
  81. data/features/support/env.rb +0 -55
  82. data/features/todo.feature +0 -546
  83. data/features/todo_legacy.feature +0 -128
  84. data/test/option_test_helper.rb +0 -13
  85. data/test/tc_compound_command.rb +0 -22
  86. data/test/tc_subcommand_parsing.rb +0 -104
  87. data/test/tc_subcommands.rb +0 -259
  88. data/test/tc_switch.rb +0 -55
  89. data/test/tc_verbatim_wrapper.rb +0 -36
  90. data/test/test_helper.rb +0 -20
  91. /data/test/{init_simplecov.rb → unit/init_simplecov.rb} +0 -0
  92. /data/test/{fake_std_out.rb → unit/support/fake_std_out.rb} +0 -0
@@ -0,0 +1,54 @@
1
+ require_relative "test_helper"
2
+
3
+ class CommandFinderTest < MiniTest::Test
4
+ include TestHelper
5
+
6
+ def setup
7
+ @app = CLIApp.new
8
+ [:status, :deployable, :some_command, :some_similar_command].each do |command|
9
+ @app.commands[command] = GLI::Command.new(:names => command)
10
+ end
11
+ end
12
+
13
+ def teardown
14
+ end
15
+
16
+ def test_unknown_command_name
17
+ assert_raises(GLI::UnknownCommand) do
18
+ GLI::CommandFinder.new(@app.commands, :default_command => :status).find_command(:unfindable_command)
19
+ end
20
+ end
21
+
22
+ def test_no_command_name_without_default
23
+ assert_raises(GLI::UnknownCommand) do
24
+ GLI::CommandFinder.new(@app.commands).find_command(nil)
25
+ end
26
+ end
27
+
28
+ def test_no_command_name_with_default
29
+ actual = GLI::CommandFinder.new(@app.commands, :default_command => :status).find_command(nil)
30
+ expected = @app.commands[:status]
31
+
32
+ assert_equal(actual, expected)
33
+ end
34
+
35
+ def test_ambigous_command
36
+ assert_raises(GLI::AmbiguousCommand) do
37
+ GLI::CommandFinder.new(@app.commands, :default_command => :status).find_command(:some)
38
+ end
39
+ end
40
+
41
+ def test_partial_name_with_autocorrect_enabled
42
+ actual = GLI::CommandFinder.new(@app.commands, :default_command => :status).find_command(:deploy)
43
+ expected = @app.commands[:deployable]
44
+
45
+ assert_equal(actual, expected)
46
+ end
47
+
48
+ def test_partial_name_with_autocorrect_disabled
49
+ assert_raises(GLI::UnknownCommand) do
50
+ GLI::CommandFinder.new(@app.commands, :default_command => :status, :autocomplete => false)
51
+ .find_command(:deploy)
52
+ end
53
+ end
54
+ end
@@ -1,7 +1,7 @@
1
- require 'test_helper'
2
- require 'tempfile'
1
+ require_relative "test_helper"
2
+ require_relative "support/fake_std_out"
3
3
 
4
- class TC_testCommand < Clean::Test::TestCase
4
+ class CommandTest < MiniTest::Test
5
5
  include TestHelper
6
6
  def setup
7
7
  @fake_stdout = FakeStdOut.new
@@ -40,8 +40,6 @@ class TC_testCommand < Clean::Test::TestCase
40
40
 
41
41
  def test_basic_command
42
42
  [false,true].each do |openstruct|
43
- end
44
- [true].each do |openstruct|
45
43
  create_app(openstruct)
46
44
  openstruct_message = openstruct ? ", with use_openstruct" : ""
47
45
  args_args = [%w(-g basic -v -c foo bar baz quux), %w(-g basic -v --configure=foo bar baz quux)]
@@ -61,6 +59,12 @@ class TC_testCommand < Clean::Test::TestCase
61
59
  end
62
60
  end
63
61
 
62
+ def test_openstruct_with_nested_commands
63
+ create_app(true)
64
+ @app.run(["top","nested"])
65
+ assert(!@error_called,"Error block should not have been called: #{@exception_caught.inspect}")
66
+ end
67
+
64
68
  def test_around_filter
65
69
  @around_block_called = false
66
70
  @app.around do |global_options, command, options, arguments, code|
@@ -432,7 +436,7 @@ class TC_testCommand < Clean::Test::TestCase
432
436
  private
433
437
 
434
438
  def assert_contained(output,regexp)
435
- assert_not_nil output.contained?(regexp),
439
+ refute_nil output.contained?(regexp),
436
440
  "Expected output to contain #{regexp.inspect}, output was:\n#{output}"
437
441
  end
438
442
 
@@ -459,9 +463,10 @@ class TC_testCommand < Clean::Test::TestCase
459
463
  @pre_called = false
460
464
  @post_called = false
461
465
  @error_called = false
466
+ @exception_caught = nil
462
467
  @app.pre { |g,c,o,a| @pre_called = true }
463
468
  @app.post { |g,c,o,a| @post_called = true }
464
- @app.on_error { |g,c,o,a| @error_called = true }
469
+ @app.on_error { |exception| @error_called = true; @exception_caught = exception }
465
470
  @glob = nil
466
471
  @verbose = nil
467
472
  @glob_verbose = nil
@@ -503,6 +508,14 @@ class TC_testCommand < Clean::Test::TestCase
503
508
  @app.command [:test_wrap] do |c|
504
509
  c.action {}
505
510
  end
511
+
512
+ @app.desc "A top-level command"
513
+ @app.command [:top] do |c|
514
+ c.desc "A nested command"
515
+ c.command [:nested] do |nested|
516
+ nested.action {}
517
+ end
518
+ end
506
519
  end
507
520
 
508
521
  end
@@ -0,0 +1,17 @@
1
+ require_relative "test_helper"
2
+
3
+ class CompoundCommandFinderTest < MiniTest::Test
4
+ include TestHelper
5
+
6
+ def test_exception_for_missing_commands
7
+ @name = "new"
8
+ @unknown_name = "create"
9
+ @existing_command = OpenStruct.new(:name => @name)
10
+ @base = OpenStruct.new( :commands => { @name => @existing_command })
11
+
12
+ @code = lambda { GLI::Commands::CompoundCommand.new(@base,{:foo => [@name,@unknown_name]}) }
13
+
14
+ ex = assert_raises(RuntimeError,&@code)
15
+ assert_match /#{Regexp.escape(@unknown_name)}/,ex.message
16
+ end
17
+ end
@@ -1,5 +1,4 @@
1
- require 'test_helper'
2
- require 'pp'
1
+ require_relative "test_helper"
3
2
 
4
3
  class String
5
4
  def blank?
@@ -19,7 +18,7 @@ class Object
19
18
  end
20
19
  end
21
20
 
22
- class TC_testDoc < Clean::Test::TestCase
21
+ class DocTest < MiniTest::Test
23
22
  include TestHelper
24
23
 
25
24
  class TestApp
@@ -112,42 +111,30 @@ class TC_testDoc < Clean::Test::TestCase
112
111
  @@counter = -1 # we pre-increment so this makes 0 first
113
112
  end
114
113
 
115
- test_that "a GLI app with documentation gets the callbacks for each element" do
116
- Given :the_test_app
117
- And :the_expected_output
118
- And {
119
- @documenter = GLI::Commands::Doc.new(@app)
120
- @listener = TestListener.new
121
- }
122
- When {
123
- @documenter.document(@listener)
124
- }
125
- Then {
126
- lines_expected = @string.split(/\n/)
127
- lines_got = @listener.to_s.split(/\n/)
128
- lines_expected.zip(lines_got).each_with_index do |(expected,got),index|
129
- assert_equal expected,got,"At index #{index}"
130
- end
131
- }
114
+ def test_app_without_docs_gets_callbacks_for_each_element
115
+ setup_test_app
116
+ construct_expected_output
117
+ @documenter = GLI::Commands::Doc.new(@app)
118
+ @listener = TestListener.new
119
+ @documenter.document(@listener)
120
+ lines_expected = @string.split(/\n/)
121
+ lines_got = @listener.to_s.split(/\n/)
122
+ lines_expected.zip(lines_got).each_with_index do |(expected,got),index|
123
+ assert_equal expected,got,"At index #{index}"
124
+ end
132
125
  end
133
126
 
134
- test_that "the doc command works as a GLI command" do
135
- Given :the_test_app
136
- And :the_expected_output
137
- And {
138
- @documenter = GLI::Commands::Doc.new(@app)
139
- @listener = TestListener.new
140
- }
141
- When {
142
- @documenter.execute({},{:format => "TC_testDoc::TestListener"},[])
143
- }
144
- Then {
145
- lines_expected = @string.split(/\n/)
146
- lines_got = TestListener.last.to_s.split(/\n/)
147
- lines_expected.zip(lines_got).each_with_index do |(expected,got),index|
148
- assert_equal expected,got,"At index #{index}"
149
- end
150
- }
127
+ def test_doc_command_works_as_GLI_command
128
+ setup_test_app
129
+ construct_expected_output
130
+ @documenter = GLI::Commands::Doc.new(@app)
131
+ @listener = TestListener.new
132
+ @documenter.execute({},{:format => "DocTest::TestListener"},[])
133
+ lines_expected = @string.split(/\n/)
134
+ lines_got = TestListener.last.to_s.split(/\n/)
135
+ lines_expected.zip(lines_got).each_with_index do |(expected,got),index|
136
+ assert_equal expected,got,"At index #{index}"
137
+ end
151
138
  end
152
139
 
153
140
  private
@@ -158,36 +145,36 @@ private
158
145
  @@counter
159
146
  end
160
147
 
161
- def the_test_app
148
+ def setup_test_app
162
149
  @app = TestApp.new
163
150
  @app.instance_eval do
164
151
  program_desc "program desc"
165
152
  program_long_desc "program long desc"
166
153
  version "1.3.4"
167
154
 
168
- TC_testDoc.flag_with_everything_specified(self)
169
- TC_testDoc.flag_with_everything_omitted(self)
170
- TC_testDoc.switch_with_everything_specified(self)
171
- TC_testDoc.switch_with_everything_omitted(self)
155
+ DocTest.flag_with_everything_specified(self)
156
+ DocTest.flag_with_everything_omitted(self)
157
+ DocTest.switch_with_everything_specified(self)
158
+ DocTest.switch_with_everything_omitted(self)
172
159
 
173
160
  desc "command desc"
174
161
  long_desc "command long desc"
175
162
  arg_name "cmd_arg_name"
176
163
  command [:command1,:com1] do |c|
177
- TC_testDoc.flag_with_everything_specified(c)
178
- TC_testDoc.flag_with_everything_omitted(c)
179
- TC_testDoc.switch_with_everything_specified(c)
180
- TC_testDoc.switch_with_everything_omitted(c)
164
+ DocTest.flag_with_everything_specified(c)
165
+ DocTest.flag_with_everything_omitted(c)
166
+ DocTest.switch_with_everything_specified(c)
167
+ DocTest.switch_with_everything_omitted(c)
181
168
 
182
169
  c.desc "subcommand desc"
183
170
  c.long_desc "subcommand long desc"
184
171
  c.arg_name "subcmd_arg_name"
185
172
  c.action { |g,o,a| }
186
173
  c.command [:sub,:subcommand] do |sub|
187
- TC_testDoc.flag_with_everything_specified(sub,:subflag)
188
- TC_testDoc.flag_with_everything_omitted(sub,:subflag2)
189
- TC_testDoc.switch_with_everything_specified(sub,:subswitch)
190
- TC_testDoc.switch_with_everything_omitted(sub,:subswitch2)
174
+ DocTest.flag_with_everything_specified(sub,:subflag)
175
+ DocTest.flag_with_everything_omitted(sub,:subflag2)
176
+ DocTest.switch_with_everything_specified(sub,:subswitch)
177
+ DocTest.switch_with_everything_omitted(sub,:subswitch2)
191
178
  sub.action { |g,o,a| }
192
179
  end
193
180
  c.command [:default] do |sub|
@@ -227,7 +214,7 @@ private
227
214
  def self.switch_with_everything_omitted(on,name=[:S,:switch2])
228
215
  on.switch name
229
216
  end
230
- def the_expected_output
217
+ def construct_expected_output
231
218
  # Oh yeah. Creating a string representing the structure of the calls.
232
219
  @string =<<EOS
233
220
  BEGIN
@@ -1,39 +1,36 @@
1
- require 'test_helper'
1
+ require_relative "test_helper"
2
2
 
3
- class TC_testFlag < Clean::Test::TestCase
3
+ class FlagTest < MiniTest::Test
4
4
  include TestHelper
5
5
 
6
6
  def test_basics_simple
7
- Given flag_with_names(:f)
8
- Then attributes_should_be_set
9
- And name_should_be(:f)
10
- And aliases_should_be(nil)
7
+ setup_for_flag_with_names(:f)
8
+ assert_attributes_set
9
+ assert_equal(:f,@cli_option.name)
10
+ assert_nil @cli_option.aliases
11
11
  end
12
12
 
13
13
  def test_basics_kinda_complex
14
- Given flag_with_names([:f])
15
- Then attributes_should_be_set
16
- And name_should_be(:f)
17
- And aliases_should_be(nil)
14
+ setup_for_flag_with_names([:f])
15
+ assert_attributes_set
16
+ assert_equal(:f,@cli_option.name)
17
+ assert_nil @cli_option.aliases
18
18
  end
19
19
 
20
20
  def test_basics_complex
21
- Given flag_with_names([:f,:file,:filename])
22
- Then attributes_should_be_set
23
- And name_should_be(:f)
24
- And aliases_should_be([:file,:filename])
25
- And {
26
- assert_equal ["-f VAL","--file VAL","--filename VAL",/foobar/,Float],@flag.arguments_for_option_parser
27
- }
21
+ setup_for_flag_with_names([:f,:file,:filename])
22
+ assert_attributes_set
23
+ assert_equal(:f,@cli_option.name)
24
+ assert_equal [:file,:filename], @cli_option.aliases
25
+ assert_equal ["-f VAL","--file VAL","--filename VAL",/foobar/,Float],@flag.arguments_for_option_parser
28
26
  end
29
27
 
30
28
  def test_flag_can_mask_its_value
31
- Given flag_with_names(:password, :mask => true)
32
- Then attributes_should_be_set(:safe_default_value => "********")
29
+ setup_for_flag_with_names(:password, :mask => true)
30
+ assert_attributes_set(:safe_default_value => "********")
33
31
  end
34
32
 
35
- def flag_with_names(names,options = {})
36
- lambda do
33
+ def setup_for_flag_with_names(names,options = {})
37
34
  @options = {
38
35
  :desc => 'Filename',
39
36
  :long_desc => 'The Filename',
@@ -45,11 +42,9 @@ class TC_testFlag < Clean::Test::TestCase
45
42
  }.merge(options)
46
43
  @flag = GLI::Flag.new(names,@options)
47
44
  @cli_option = @flag
48
- end
49
45
  end
50
46
 
51
- def attributes_should_be_set(override={})
52
- lambda {
47
+ def assert_attributes_set(override={})
53
48
  expected = @options.merge(override)
54
49
  assert_equal(expected[:desc],@flag.description)
55
50
  assert_equal(expected[:long_desc],@flag.long_description)
@@ -57,6 +52,5 @@ class TC_testFlag < Clean::Test::TestCase
57
52
  assert_equal(expected[:safe_default_value],@flag.safe_default_value)
58
53
  assert_equal(expected[:must_match],@flag.must_match)
59
54
  assert_equal(expected[:type],@flag.type)
60
- }
61
55
  end
62
56
  end
@@ -1,18 +1,7 @@
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
1
+ require_relative "test_helper"
2
+ require_relative "support/fake_std_out"
12
3
 
13
- require 'test_helper'
14
-
15
- class TC_testGLI < Clean::Test::TestCase
4
+ class GLITest < MiniTest::Test
16
5
  include TestHelper
17
6
 
18
7
  def setup
@@ -24,7 +13,7 @@ class TC_testGLI < Clean::Test::TestCase
24
13
  $stderr = @fake_stderr
25
14
  @app = CLIApp.new
26
15
 
27
- @config_file = File.expand_path(File.dirname(File.realpath(__FILE__)) + '/new_config.yaml')
16
+ @config_file = File.expand_path(File.dirname(File.realpath(__FILE__)) + '/support/new_config.yml')
28
17
  @gli_debug = ENV['GLI_DEBUG']
29
18
  @app.error_device=@fake_stderr
30
19
  ENV.delete('GLI_DEBUG')
@@ -141,10 +130,12 @@ class TC_testGLI < Clean::Test::TestCase
141
130
  def test_init_from_config
142
131
  failure = nil
143
132
  @app.reset
144
- @app.config_file(File.expand_path(File.dirname(File.realpath(__FILE__)) + '/config.yaml'))
133
+ @app.config_file(File.expand_path(File.dirname(File.realpath(__FILE__)) + '/support/gli_test_config.yml'))
145
134
  @app.flag :f
146
135
  @app.switch :s
147
136
  @app.flag :g
137
+ @app.default_value true
138
+ @app.switch :t
148
139
  called = false
149
140
  @app.command :command do |c|
150
141
  c.flag :f
@@ -159,6 +150,7 @@ class TC_testGLI < Clean::Test::TestCase
159
150
  assert !o[:f]
160
151
  assert !g[:s]
161
152
  assert o[:s]
153
+ assert !g[:t]
162
154
  rescue Exception => ex
163
155
  failure = ex
164
156
  end
@@ -172,7 +164,7 @@ class TC_testGLI < Clean::Test::TestCase
172
164
  def test_command_line_overrides_config
173
165
  failure = nil
174
166
  @app.reset
175
- @app.config_file(File.expand_path(File.dirname(File.realpath(__FILE__)) + '/config.yaml'))
167
+ @app.config_file(File.expand_path(File.dirname(File.realpath(__FILE__)) + '/support/gli_test_config.yml'))
176
168
  @app.flag :f
177
169
  @app.switch :s
178
170
  @app.flag :g
@@ -204,7 +196,7 @@ class TC_testGLI < Clean::Test::TestCase
204
196
  end
205
197
 
206
198
  def test_no_overwrite_config
207
- config_file = File.expand_path(File.dirname(File.realpath(__FILE__)) + '/config.yaml')
199
+ config_file = File.expand_path(File.dirname(File.realpath(__FILE__)) + '/support/gli_test_config.yml')
208
200
  config_file_contents = File.read(config_file)
209
201
  @app.reset
210
202
  @app.config_file(config_file)
@@ -229,9 +221,9 @@ class TC_testGLI < Clean::Test::TestCase
229
221
  @app.reset
230
222
  @app.config_file(@config_file)
231
223
  @app.flag :f
232
- @app.switch :s
224
+ @app.switch :s, :salias
233
225
  @app.switch :w
234
- @app.flag :bigflag
226
+ @app.flag :bigflag, :bigalias
235
227
  @app.flag :biggestflag
236
228
  @app.command :foo do |c|
237
229
  end
@@ -249,7 +241,9 @@ class TC_testGLI < Clean::Test::TestCase
249
241
 
250
242
  assert_equal 'foo',written_config[:f]
251
243
  assert_equal 'bleorgh',written_config[:bigflag]
244
+ assert !written_config[:bigalias]
252
245
  assert written_config[:s]
246
+ assert !written_config[:salias]
253
247
  assert !written_config[:w]
254
248
  assert_nil written_config[:biggestflag]
255
249
  assert written_config[GLI::InitConfig::COMMANDS_KEY]
@@ -515,7 +509,7 @@ class TC_testGLI < Clean::Test::TestCase
515
509
  end
516
510
  @switch_value = nil
517
511
 
518
- assert_raises(RuntimeError) do
512
+ assert_raises(RuntimeError) do
519
513
  @app.command [:foo] do |c|
520
514
  c.switch :switch, :default_value => true, :negatable => false
521
515
  end
@@ -675,7 +669,11 @@ class TC_testGLI < Clean::Test::TestCase
675
669
  end
676
670
  end
677
671
 
678
- assert_nothing_raised(GLI::CustomExit) { @app.run(['multiply', '--help']) }
672
+ begin
673
+ @app.run(['multiply', '--help'])
674
+ rescue GLI::CustomExit
675
+ assert false, "Expected no exception"
676
+ end
679
677
  end
680
678
 
681
679
  class ConvertMe
@@ -712,6 +710,48 @@ class TC_testGLI < Clean::Test::TestCase
712
710
  assert_equal 'crud',@baz.value
713
711
  end
714
712
 
713
+ def test_that_flags_can_be_used_multiple_times
714
+ @app.reset
715
+ @app.flag :flag, :multiple => true
716
+ @app.command :foo do |c|
717
+ c.action do |options, _, _|
718
+ @flag = options[:flag]
719
+ end
720
+ end
721
+
722
+ assert_equal 0,@app.run(%w(--flag 1 --flag=2 --flag 3 foo)),@fake_stderr.to_s
723
+
724
+ assert_equal ['1','2','3'],@flag
725
+ end
726
+
727
+ def test_that_multiple_use_flags_are_empty_arrays_by_default
728
+ @app.reset
729
+ @app.flag :flag, :multiple => true
730
+ @app.command :foo do |c|
731
+ c.action do |options, _, _|
732
+ @flag = options[:flag]
733
+ end
734
+ end
735
+
736
+ assert_equal 0,@app.run(['foo']),@fake_stderr.to_s
737
+
738
+ assert_equal [],@flag
739
+ end
740
+
741
+ def test_that_multiple_use_flags_can_take_other_defaults
742
+ @app.reset
743
+ @app.flag :flag, :multiple => true, :default_value => ['1']
744
+ @app.command :foo do |c|
745
+ c.action do |options, _, _|
746
+ @flag = options[:flag]
747
+ end
748
+ end
749
+
750
+ assert_equal 0,@app.run(['foo']),@fake_stderr.to_s
751
+
752
+ assert_equal ['1'],@flag
753
+ end
754
+
715
755
  def test_that_we_mutate_ARGV_by_default
716
756
  @app.reset
717
757
  @app.flag :f
@@ -763,38 +803,26 @@ class TC_testGLI < Clean::Test::TestCase
763
803
  do_test_switch_create_compact(object)
764
804
  end
765
805
 
766
- def some_descriptions
767
- lambda {
768
- @description = 'this is a description'
769
- @long_description = 'this is a very long description'
770
- }
771
- end
772
-
773
- def assert_switch_was_made(object,switch)
774
- lambda {
775
- assert object.switches[switch]
776
- assert_equal @description,object.switches[switch].description,"For switch #{switch}"
777
- assert_equal @long_description,object.switches[switch].long_description,"For switch #{switch}"
778
- assert(object.usage != nil) if object.respond_to? :usage
779
- }
780
- end
781
-
782
806
  def do_test_switch_create_classic(object)
783
- Given some_descriptions
784
- When {
785
- object.desc @description
786
- object.long_desc @long_description
787
- object.switch :f
788
- }
789
- Then assert_switch_was_made(object,:f)
807
+ @description = 'this is a description'
808
+ @long_description = 'this is a very long description'
809
+ object.desc @description
810
+ object.long_desc @long_description
811
+ object.switch :f
812
+ assert object.switches[:f]
813
+ assert_equal @description,object.switches[:f].description,"For switch #{:f}"
814
+ assert_equal @long_description,object.switches[:f].long_description,"For switch #{:f}"
815
+ assert(object.usage != nil) if object.respond_to? :usage
790
816
  end
791
817
 
792
818
  def do_test_switch_create_compact(object)
793
- Given some_descriptions
794
- When {
795
- object.switch :g, :desc => @description, :long_desc => @long_description
796
- }
797
- Then assert_switch_was_made(object,:g)
819
+ @description = 'this is a description'
820
+ @long_description = 'this is a very long description'
821
+ object.switch :g, :desc => @description, :long_desc => @long_description
822
+ assert object.switches[:g]
823
+ assert_equal @description,object.switches[:g].description,"For switch #{:g}"
824
+ assert_equal @long_description,object.switches[:g].long_description,"For switch #{:g}"
825
+ assert(object.usage != nil) if object.respond_to? :usage
798
826
  end
799
827
 
800
828
  def do_test_switch_create_twice(object)