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
@@ -1,2 +1,2 @@
1
- source :rubygems
1
+ source 'https://rubygems.org'
2
2
  gemspec
@@ -1,17 +1,17 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  # These would not be in a real GLI app; we do this so we can easily run this on the command line
4
- $: << File.expand_path(File.join(File.dirname(__FILE__),'..','..','..','lib'))
4
+ $: << File.expand_path(File.join(File.dirname(__FILE__),'..','..','..','..','lib'))
5
5
  $: << File.expand_path(File.join(File.dirname(__FILE__),'..','lib'))
6
6
 
7
7
  require 'gli'
8
8
  require 'todo/version'
9
9
 
10
-
10
+ class App
11
11
  if ENV['GLI1_COMPATIBILITY']
12
- include GLI
12
+ extend GLI
13
13
  else
14
- include GLI::App
14
+ extend GLI::App
15
15
  end
16
16
 
17
17
  sort_help (ENV['TODO_SORT_HELP'] || 'alpha').to_sym
@@ -20,6 +20,7 @@ synopsis_format (ENV['SYNOPSES'] || 'full').to_sym
20
20
  hide_commands_without_desc ENV['HIDE_COMMANDS_WITHOUT_DESC'] === 'true'
21
21
 
22
22
  subcommand_option_handling :normal
23
+ arguments :strict
23
24
 
24
25
  program_desc 'Manages tasks'
25
26
  program_long_desc "A test program that has a sophisticated UI that can be used to exercise a lot of GLI's power"
@@ -41,7 +42,12 @@ command :first do |c| c.action { |g,o,a| puts "first: #{a.join(',')}" } end
41
42
  arg :argument, :optional
42
43
  command :second do |c| c.action { |g,o,a| puts "second: #{a.join(',')}" } end
43
44
 
45
+ arg :first
46
+ arg :second
44
47
  command :chained => [ :first, :second ]
48
+
49
+ arg :first
50
+ arg :second
45
51
  command [:chained2,:ch2] => [ :second, :first ]
46
52
 
47
53
  pre do |global,command,options,args|
@@ -64,5 +70,5 @@ on_error do |exception|
64
70
  # return false to skip default error handling
65
71
  true
66
72
  end
67
-
68
- exit run(ARGV)
73
+ end
74
+ exit App.run(ARGV)
@@ -1,53 +1,54 @@
1
- desc "Create a new task or context"
2
- command [:create,:new] do |c|
3
- c.desc "Make a new task"
4
- c.arg_name 'task_name', :multiple
5
- c.arg :should_ignore_this
6
- c.command :tasks do |tasks|
7
- tasks.action do |global,options,args|
8
- puts "#{args}"
1
+ class App
2
+ desc "Create a new task or context"
3
+ command [:create,:new] do |c|
4
+ c.desc "Make a new task"
5
+ c.arg_name 'task_name', :multiple
6
+ c.arg :should_ignore_this
7
+ c.command :tasks do |tasks|
8
+ tasks.action do |global,options,args|
9
+ puts "#{args}"
10
+ end
9
11
  end
10
- end
11
12
 
12
- c.desc "Make a new context"
13
- c.arg :should_ignore_this
14
- c.arg_name 'context_name', :optional
15
- c.command :contexts do |contexts|
16
- contexts.action do |global,options,args|
17
- puts "#{args}"
13
+ c.desc "Make a new context"
14
+ c.arg :should_ignore_this
15
+ c.arg_name 'context_name', :optional
16
+ c.command :contexts do |contexts|
17
+ contexts.action do |global,options,args|
18
+ puts "#{args}"
19
+ end
18
20
  end
19
- end
20
21
 
21
- c.default_desc "Makes a new task"
22
- c.action do
23
- puts "default action"
24
- end
22
+ c.default_desc "Makes a new task"
23
+ c.action do
24
+ puts "default action"
25
+ end
25
26
 
26
- c.arg "first"
27
- c.arg "second"
28
- c.arg "name", :optional
29
- c.command :"relation_1-1" do |remote|
30
- remote.action do |global,options,args|
31
- puts "relation: #{args}"
27
+ c.arg "first"
28
+ c.arg "second"
29
+ c.arg "name", :optional
30
+ c.command :"relation_1-1" do |remote|
31
+ remote.action do |global,options,args|
32
+ puts "relation: #{args}"
33
+ end
32
34
  end
33
- end
34
35
 
35
- c.arg "first", :multiple
36
- c.arg "second"
37
- c.arg "name", :optional
38
- c.command :"relation_n-1" do |remote|
39
- remote.action do |global,options,args|
40
- puts "relation: #{args}"
36
+ c.arg "first", :multiple
37
+ c.arg "second"
38
+ c.arg "name", :optional
39
+ c.command :"relation_n-1" do |remote|
40
+ remote.action do |global,options,args|
41
+ puts "relation: #{args}"
42
+ end
41
43
  end
42
- end
43
44
 
44
- c.arg "first"
45
- c.arg "second", :multiple
46
- c.arg "name", :optional
47
- c.command :"relation_1-n" do |remote|
48
- remote.action do |global,options,args|
49
- puts "relation: #{args}"
45
+ c.arg "first"
46
+ c.arg "second", :multiple
47
+ c.arg "name", :optional
48
+ c.command :"relation_1-n" do |remote|
49
+ remote.action do |global,options,args|
50
+ puts "relation: #{args}"
51
+ end
50
52
  end
51
53
  end
52
54
  end
53
-
@@ -1,5 +1,6 @@
1
- desc "List things, such as tasks or contexts"
2
- long_desc %(
1
+ class App
2
+ desc "List things, such as tasks or contexts"
3
+ long_desc %(
3
4
  List a whole lot of things that you might be keeping track of
4
5
  in your overall todo list.
5
6
 
@@ -8,59 +9,70 @@ long_desc %(
8
9
  stored in
9
10
  your todo databases.
10
11
  )
11
- command [:list] do |c|
12
- c.default_command :tasks
13
12
 
14
- c.desc "Show long form"
15
- c.switch [:l,:long]
13
+ command [:list] do |c|
14
+ c.default_command :tasks
16
15
 
17
- c.flag :required_flag, :required => true
18
- c.flag :required_flag2, :required => true
16
+ c.desc "Show long form"
17
+ c.switch [:l,:long]
19
18
 
20
- c.desc "List tasks"
21
- c.long_desc %(
19
+ c.flag :required_flag, :required => true
20
+ c.flag :required_flag2, :required => true
21
+
22
+ c.desc "List tasks"
23
+ c.long_desc %(
22
24
  Lists all of your tasks that you have, in varying orders, and
23
25
  all that stuff. Yes, this is long, but I need a long description.
24
26
  )
25
- c.command :tasks do |tasks|
26
- tasks.desc "blah blah crud x whatever"
27
- tasks.flag [:x], :must_match => Array
28
27
 
29
- tasks.flag :flag
28
+ c.arg :task, [:optional, :multiple]
29
+ c.command :tasks do |tasks|
30
+ tasks.desc "blah blah crud x whatever"
31
+ tasks.flag [:x], :must_match => Array
30
32
 
31
- tasks.action do |global,options,args|
32
- puts options[:x].inspect
33
- puts "list tasks: #{args.join(',')}"
34
- end
33
+ tasks.flag :flag
35
34
 
36
- tasks.desc 'list open tasks'
37
- tasks.command :open do |open|
38
- open.action do |global,options,args|
39
- puts "tasks open"
35
+ tasks.action do |global,options,args|
36
+ puts options[:x].inspect
37
+ puts "list tasks: #{args.join(',')}"
40
38
  end
41
- end
42
39
 
43
- tasks.default_desc 'list all tasks'
44
- end
40
+ tasks.desc 'list open tasks'
41
+ tasks.command :open do |open|
42
+ open.desc "blah blah crud x whatever"
43
+ open.flag [:x], :must_match => Array
44
+
45
+ open.flag :flag
46
+
47
+ open.example "todo list tasks open --flag=blah", desc: "example number 1"
48
+ open.example "todo list tasks open -x foo"
45
49
 
46
- c.desc "List contexts"
47
- c.long_desc %(
50
+ open.action do |global,options,args|
51
+ puts "tasks open"
52
+ end
53
+ end
54
+
55
+ tasks.default_desc 'list all tasks'
56
+ end
57
+
58
+ c.desc "List contexts"
59
+ c.long_desc %(
48
60
  Lists all of your contexts, which are places you might be
49
61
  where you can do stuff and all that.
50
62
  )
51
- c.command :contexts do |contexts|
63
+ c.command :contexts do |contexts|
52
64
 
53
- contexts.desc "Foobar"
54
- contexts.switch [:f,'foobar']
65
+ contexts.desc "Foobar"
66
+ contexts.switch [:f,'foobar']
55
67
 
56
- contexts.desc "Blah"
57
- contexts.switch [:b]
68
+ contexts.desc "Blah"
69
+ contexts.switch [:b]
58
70
 
59
- contexts.flag :otherflag
71
+ contexts.flag :otherflag
60
72
 
61
- contexts.action do |global,options,args|
62
- puts "list contexts: #{args.join(',')}"
73
+ contexts.action do |global,options,args|
74
+ puts "list contexts: #{args.join(',')}"
75
+ end
63
76
  end
64
77
  end
65
78
  end
66
-
@@ -1,6 +1,7 @@
1
- # This is copied so I can have two slightly different versions of the same thing
2
- desc "LS things, such as tasks or contexts"
3
- long_desc %(
1
+ class App
2
+ # This is copied so I can have two slightly different versions of the same thing
3
+ desc "LS things, such as tasks or contexts"
4
+ long_desc %(
4
5
  List a whole lot of things that you might be keeping track of
5
6
  in your overall todo list.
6
7
 
@@ -9,39 +10,39 @@ long_desc %(
9
10
  stored in
10
11
  your todo databases.
11
12
  )
12
- command [:ls] do |c|
13
- c.desc "Show long form"
14
- c.switch [:l,:long]
13
+ command [:ls] do |c|
14
+ c.desc "Show long form"
15
+ c.switch [:l,:long]
15
16
 
16
- c.desc "List tasks"
17
- c.long_desc %(
17
+ c.desc "List tasks"
18
+ c.long_desc %(
18
19
  Lists all of your tasks that you have, in varying orders, and
19
20
  all that stuff. Yes, this is long, but I need a long description.
20
21
  )
21
- c.command :tasks do |tasks|
22
- tasks.desc "blah blah crud x whatever"
23
- tasks.flag [:x]
24
- tasks.action do |global,options,args|
25
- puts "ls tasks: #{args.join(',')}"
22
+ c.command :tasks do |tasks|
23
+ tasks.desc "blah blah crud x whatever"
24
+ tasks.flag [:x]
25
+ tasks.action do |global,options,args|
26
+ puts "ls tasks: #{args.join(',')}"
27
+ end
26
28
  end
27
- end
28
29
 
29
- c.desc "List contexts"
30
- c.long_desc %(
30
+ c.desc "List contexts"
31
+ c.long_desc %(
31
32
  Lists all of your contexts, which are places you might be
32
33
  where you can do stuff and all that.
33
34
  )
34
- c.command :contexts do |contexts|
35
+ c.command :contexts do |contexts|
35
36
 
36
- contexts.desc "Foobar"
37
- contexts.switch [:f,'foobar']
37
+ contexts.desc "Foobar"
38
+ contexts.switch [:f,'foobar']
38
39
 
39
- contexts.desc "Blah"
40
- contexts.switch [:b]
40
+ contexts.desc "Blah"
41
+ contexts.switch [:b]
41
42
 
42
- contexts.action do |global,options,args|
43
- puts "ls contexts: #{args.join(',')}"
43
+ contexts.action do |global,options,args|
44
+ puts "ls contexts: #{args.join(',')}"
45
+ end
44
46
  end
45
47
  end
46
48
  end
47
-
@@ -1,52 +1,55 @@
1
- command [:make] do |c|
2
- c.desc "Show long form"
3
- c.flag [:l,:long]
1
+ class App
2
+ command [:make] do |c|
3
+ c.desc "Show long form"
4
+ c.flag [:l,:long]
4
5
 
5
- c.desc 'make a new task'
6
- c.command :task do |task|
7
- task.desc 'make the task a long task'
8
- task.flag [:l,:long]
6
+ c.desc 'make a new task'
7
+ c.command :task do |task|
8
+ task.desc 'make the task a long task'
9
+ task.flag [:l,:long]
9
10
 
10
- task.action do |g,o,a|
11
- puts 'new task'
12
- puts a.join(',')
13
- puts o[:long]
11
+ task.action do |g,o,a|
12
+ puts 'new task'
13
+ puts a.join(',')
14
+ puts o[:long]
15
+ end
16
+
17
+ task.desc 'make a bug'
18
+ task.arg :argument, [:multiple, :optional]
19
+ task.command :bug do |bug|
20
+ bug.desc 'make this bug in the legacy system'
21
+ bug.flag [:l,:legacy]
22
+
23
+ bug.action do |g,o,a|
24
+ puts 'new task bug'
25
+ puts a.join(',')
26
+ # All this .to_s is to make sure 1.8.7/REE don't convert nil to the string "nil"
27
+ puts o[:legacy].to_s
28
+ puts o[:long].to_s
29
+ puts o[:l].to_s
30
+ puts o[GLI::Command::PARENT][:l].to_s
31
+ puts o[GLI::Command::PARENT][:long].to_s
32
+ puts o[GLI::Command::PARENT][:legacy].to_s
33
+ puts o[GLI::Command::PARENT][GLI::Command::PARENT][:l].to_s
34
+ puts o[GLI::Command::PARENT][GLI::Command::PARENT][:long].to_s
35
+ puts o[GLI::Command::PARENT][GLI::Command::PARENT][:legacy].to_s
36
+ end
37
+ end
14
38
  end
15
39
 
16
- desc 'make a bug'
17
- task.command :bug do |bug|
18
- bug.desc 'make this bug in the legacy system'
19
- bug.flag [:l,:legacy]
40
+ c.desc 'make a new context'
41
+ c.command :context do |context|
42
+ context.desc 'make the context a local context'
43
+ context.flag [:l,:local]
20
44
 
21
- bug.action do |g,o,a|
22
- puts 'new task bug'
45
+ context.action do |g,o,a|
46
+ puts 'new context'
23
47
  puts a.join(',')
24
- # All this .to_s is to make sure 1.8.7/REE don't convert nil to the string "nil"
25
- puts o[:legacy].to_s
48
+ puts o[:local].to_s
26
49
  puts o[:long].to_s
27
50
  puts o[:l].to_s
28
- puts o[GLI::Command::PARENT][:l].to_s
29
- puts o[GLI::Command::PARENT][:long].to_s
30
- puts o[GLI::Command::PARENT][:legacy].to_s
31
- puts o[GLI::Command::PARENT][GLI::Command::PARENT][:l].to_s
32
- puts o[GLI::Command::PARENT][GLI::Command::PARENT][:long].to_s
33
- puts o[GLI::Command::PARENT][GLI::Command::PARENT][:legacy].to_s
34
51
  end
35
52
  end
36
- end
37
-
38
- c.desc 'make a new context'
39
- c.command :context do |context|
40
- context.desc 'make the context a local context'
41
- context.flag [:l,:local]
42
53
 
43
- context.action do |g,o,a|
44
- puts 'new context'
45
- puts a.join(',')
46
- puts o[:local].to_s
47
- puts o[:long].to_s
48
- puts o[:l].to_s
49
- end
50
54
  end
51
-
52
55
  end
@@ -1,6 +1,6 @@
1
1
  # Ensure we require the local version and not one we might have installed already
2
2
  require File.join([File.dirname(__FILE__),'lib','todo','version.rb'])
3
- spec = Gem::Specification.new do |s|
3
+ spec = Gem::Specification.new do |s|
4
4
  s.name = 'todo'
5
5
  s.version = Todo::VERSION
6
6
  s.author = 'Your Name Here'
@@ -13,7 +13,6 @@ spec = Gem::Specification.new do |s|
13
13
  bin/todo
14
14
  )
15
15
  s.require_paths << 'lib'
16
- s.has_rdoc = true
17
16
  s.extra_rdoc_files = ['README.rdoc','todo.rdoc']
18
17
  s.rdoc_options << '--title' << 'todo' << '--main' << 'README.rdoc' << '-ri'
19
18
  s.bindir = 'bin'
@@ -1,6 +1,6 @@
1
1
  # Ensure we require the local version and not one we might have installed already
2
2
  require File.join([File.dirname(__FILE__),'lib','todo','version.rb'])
3
- spec = Gem::Specification.new do |s|
3
+ spec = Gem::Specification.new do |s|
4
4
  s.name = 'todo'
5
5
  s.version = Todo::VERSION
6
6
  s.author = 'Your Name Here'
@@ -13,7 +13,6 @@ spec = Gem::Specification.new do |s|
13
13
  bin/todo
14
14
  )
15
15
  s.require_paths << 'lib'
16
- s.has_rdoc = true
17
16
  s.extra_rdoc_files = ['README.rdoc','todo.rdoc']
18
17
  s.rdoc_options << '--title' << 'todo' << '--main' << 'README.rdoc' << '-ri'
19
18
  s.bindir = 'bin'
@@ -1 +1,3 @@
1
+ class App
1
2
  command :third do |c| c.action { |g,o,a| puts "third: #{a.join(',')}" } end
3
+ end
@@ -0,0 +1,69 @@
1
+ require_relative "test_helper"
2
+ require "open3"
3
+
4
+ class GLICLITest < MiniTest::Test
5
+ include TestHelper
6
+
7
+ class AppHelp < GLICLITest
8
+ def test_running_with_no_options_produces_help
9
+ out = run_gli
10
+ assert_output_looks_like_help out
11
+ end
12
+
13
+ def test_running_with_help_command_produces_help
14
+ out = run_gli("help")
15
+ assert_output_looks_like_help out
16
+ end
17
+
18
+ def test_running_with_help_switch_produces_help
19
+ out = run_gli("--help")
20
+ assert_output_looks_like_help out
21
+ end
22
+
23
+ private
24
+
25
+ def assert_output_looks_like_help(out)
26
+ assert_match /gli - create scaffolding for a GLI-powered application/,out
27
+ assert_match /SYNOPSIS/,out
28
+ assert_match /GLOBAL OPTIONS/,out
29
+ assert_match /COMMANDS/,out
30
+ end
31
+
32
+ end
33
+
34
+ class Scaffolding < GLICLITest
35
+ def test_help_on_scaffold_command
36
+ out = run_gli("help scaffold")
37
+ assert_output_looks_like_help(out)
38
+ end
39
+ def test_help_on_scaffold_command_as_init
40
+ out = run_gli("help init")
41
+ assert_output_looks_like_help(out)
42
+ end
43
+
44
+ private
45
+
46
+ def assert_output_looks_like_help(out)
47
+ assert_match /init - Create a new GLI-based project/,out
48
+ assert_match /SYNOPSIS/,out
49
+ assert_match /COMMAND OPTIONS/,out
50
+ end
51
+ end
52
+
53
+ private
54
+
55
+ def run_gli(args="", return_err_and_status: false, expect_failure: false)
56
+ command_line_invocation = "bin/gli #{args}"
57
+ stdout_string, stderr_string, status = Open3.capture3(command_line_invocation)
58
+ if expect_failure
59
+ refute_equal 0,status.exitstatus,"Expected failure for '#{command_line_invocation}' but it succeeded"
60
+ else
61
+ assert_equal 0,status.exitstatus,"Expected success for '#{command_line_invocation}' but it failed"
62
+ end
63
+ if return_err_and_status
64
+ [ stdout_string, stderr_string, status ]
65
+ else
66
+ stdout_string
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,52 @@
1
+ require_relative "test_helper"
2
+ require "open3"
3
+
4
+ class GLIPoweredAppTest < MiniTest::Test
5
+ include TestHelper
6
+
7
+ def teardown
8
+ FileUtils.rm_f("todo.rdoc")
9
+ end
10
+
11
+ def test_help_works
12
+ out = run_app("help")
13
+ assert_top_level_help(out)
14
+ end
15
+
16
+ def test_unknown_command_exits_nonzero
17
+ out, err, status = run_app("asdfasdfasdf", expect_failure: true, return_err_and_status: true)
18
+ assert_match /Unknown command 'asdfasdfasdf'/,err
19
+ assert_equal 64, status.exitstatus
20
+ assert_top_level_help(out)
21
+ end
22
+
23
+ def test_unknown_switch_exits_nonzero
24
+ out, err, status = run_app("list --foo", expect_failure: true, return_err_and_status: true)
25
+ assert_match /Unknown option \-\-foo/,err
26
+ assert_equal 64, status.exitstatus
27
+ assert_match /COMMAND OPTIONS/, out
28
+ end
29
+
30
+ def test_missing_args_exits_nonzero
31
+ out, err, status = run_app("list", expect_failure: true, return_err_and_status: true)
32
+ assert_match /required_flag is required, required_flag2 is required/,err
33
+ assert_equal 64, status.exitstatus
34
+ assert_match /COMMAND OPTIONS/, out
35
+ end
36
+
37
+ def test_doc_generation
38
+ out, err, status = run_app("_doc", return_err_and_status: true)
39
+ assert File.exists?("todo.rdoc")
40
+ end
41
+
42
+ private
43
+ def assert_top_level_help(out)
44
+ assert_match /SYNOPSIS/, out
45
+ assert_match /GLOBAL OPTIONS/, out
46
+ assert_match /COMMANDS/, out
47
+ end
48
+
49
+ def run_app(args="", return_err_and_status: false, expect_failure: false)
50
+ run_command("test/apps/todo/bin/todo",args,return_err_and_status:return_err_and_status,expect_failure:expect_failure)
51
+ end
52
+ end
@@ -0,0 +1,30 @@
1
+ require_relative "test_helper"
2
+ require "open3"
3
+
4
+ class ScaffoldCommandTest < MiniTest::Test
5
+ include TestHelper
6
+
7
+ def test_scaffolded_app_has_reasonable_setup
8
+ FileUtils.rm_rf "scaffold_test"
9
+ run_gli("init scaffold_test")
10
+ assert Dir.exist? "scaffold_test"
11
+ FileUtils.chdir "scaffold_test" do
12
+ run_command("bundle install", "", return_err_and_status: false, expect_failure: false)
13
+
14
+ scaffold_lib = "lib:../lib"
15
+
16
+ # help works
17
+ out = run_command("bin/scaffold_test","--help", return_err_and_status: false, expect_failure: false, rubylib: scaffold_lib)
18
+ assert_match /SYNOPSIS/,out
19
+ assert_match /GLOBAL OPTIONS/,out
20
+ assert_match /COMMANDS/,out
21
+
22
+ # can run unit tests
23
+ out = run_command("bundle exec ","rake test", return_err_and_status: false, expect_failure: false, rubylib: scaffold_lib)
24
+ assert_match /0 failures/,out
25
+ assert_match /0 errors/,out
26
+ assert_match /0 skips/,out
27
+ end
28
+ end
29
+
30
+ end
@@ -0,0 +1,52 @@
1
+ require "minitest/autorun"
2
+ require "pathname"
3
+ require "fileutils"
4
+
5
+ # Copied from https://github.com/splattael/minitest-around
6
+ # so as to avoid an explicit dependency
7
+ Minitest::Test.class_eval do
8
+ alias_method :run_without_around, :run
9
+ def run(*args)
10
+ if defined?(around)
11
+ result = nil
12
+ around { result = run_without_around(*args) }
13
+ result
14
+ else
15
+ run_without_around(*args)
16
+ end
17
+ end
18
+ end
19
+
20
+ module TestHelper
21
+ def around(&block)
22
+ Bundler.with_original_env do
23
+ root = Pathname(__FILE__).dirname / ".." / ".."
24
+ FileUtils.chdir root do
25
+ block.()
26
+ end
27
+ end
28
+ end
29
+
30
+ def run_gli(args="", return_err_and_status: false, expect_failure: false)
31
+ run_command("bin/gli",args,return_err_and_status:return_err_and_status,expect_failure:expect_failure)
32
+ end
33
+
34
+ def run_command(command,args,return_err_and_status:,expect_failure:,rubylib:nil)
35
+ command_line_invocation = "#{command} #{args}"
36
+ env = {}
37
+ if !rubylib.nil?
38
+ env["RUBYLIB"] = rubylib
39
+ end
40
+ stdout_string, stderr_string, status = Open3.capture3(env,command_line_invocation)
41
+ if expect_failure
42
+ refute_equal 0,status.exitstatus,"Expected failure for '#{command_line_invocation}' but it succeeded"
43
+ else
44
+ assert_equal 0,status.exitstatus,"Expected success for '#{command_line_invocation}' but it failed:\n#{stdout_string}\n\n#{stderr_string}\n\n"
45
+ end
46
+ if return_err_and_status
47
+ [ stdout_string, stderr_string, status ]
48
+ else
49
+ stdout_string
50
+ end
51
+ end
52
+ end