gli 2.11.0 → 2.20.0

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.
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)