optparse-plus 3.0.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 (69) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/.ruby-gemset +1 -0
  4. data/.ruby-version +1 -0
  5. data/.travis.yml +7 -0
  6. data/CHANGES.md +66 -0
  7. data/Gemfile +5 -0
  8. data/LICENSE.txt +201 -0
  9. data/README.rdoc +173 -0
  10. data/Rakefile +94 -0
  11. data/bin/optparse_plus +130 -0
  12. data/fix.rb +29 -0
  13. data/lib/optparse-plus.rb +1 -0
  14. data/lib/optparse_plus.rb +15 -0
  15. data/lib/optparse_plus/argv_parser.rb +50 -0
  16. data/lib/optparse_plus/cli.rb +116 -0
  17. data/lib/optparse_plus/cli_logger.rb +133 -0
  18. data/lib/optparse_plus/cli_logging.rb +138 -0
  19. data/lib/optparse_plus/cucumber.rb +119 -0
  20. data/lib/optparse_plus/error.rb +32 -0
  21. data/lib/optparse_plus/execution_strategy/base.rb +34 -0
  22. data/lib/optparse_plus/execution_strategy/jvm.rb +37 -0
  23. data/lib/optparse_plus/execution_strategy/mri.rb +16 -0
  24. data/lib/optparse_plus/execution_strategy/open_3.rb +16 -0
  25. data/lib/optparse_plus/execution_strategy/open_4.rb +22 -0
  26. data/lib/optparse_plus/execution_strategy/rbx_open_4.rb +12 -0
  27. data/lib/optparse_plus/exit_now.rb +40 -0
  28. data/lib/optparse_plus/main.rb +603 -0
  29. data/lib/optparse_plus/process_status.rb +45 -0
  30. data/lib/optparse_plus/sh.rb +223 -0
  31. data/lib/optparse_plus/test/base_integration_test.rb +31 -0
  32. data/lib/optparse_plus/test/integration_test_assertions.rb +65 -0
  33. data/lib/optparse_plus/version.rb +3 -0
  34. data/optparse_plus.gemspec +28 -0
  35. data/templates/full/.gitignore.erb +4 -0
  36. data/templates/full/README.rdoc.erb +24 -0
  37. data/templates/full/Rakefile.erb +71 -0
  38. data/templates/full/_license_head.txt.erb +2 -0
  39. data/templates/full/apache_LICENSE.txt.erb +203 -0
  40. data/templates/full/bin/executable.erb +45 -0
  41. data/templates/full/custom_LICENSE.txt.erb +0 -0
  42. data/templates/full/gplv2_LICENSE.txt.erb +14 -0
  43. data/templates/full/gplv3_LICENSE.txt.erb +14 -0
  44. data/templates/full/mit_LICENSE.txt.erb +7 -0
  45. data/templates/rspec/spec/something_spec.rb.erb +5 -0
  46. data/templates/test_unit/test/integration/test_cli.rb.erb +11 -0
  47. data/templates/test_unit/test/unit/test_something.rb.erb +7 -0
  48. data/test/integration/base_integration_test.rb +60 -0
  49. data/test/integration/test_bootstrap.rb +150 -0
  50. data/test/integration/test_cli.rb +21 -0
  51. data/test/integration/test_license.rb +56 -0
  52. data/test/integration/test_readme.rb +53 -0
  53. data/test/integration/test_rspec.rb +28 -0
  54. data/test/integration/test_version.rb +21 -0
  55. data/test/unit/base_test.rb +19 -0
  56. data/test/unit/command_for_tests.sh +7 -0
  57. data/test/unit/execution_strategy/test_base.rb +24 -0
  58. data/test/unit/execution_strategy/test_jvm.rb +77 -0
  59. data/test/unit/execution_strategy/test_mri.rb +32 -0
  60. data/test/unit/execution_strategy/test_open_3.rb +70 -0
  61. data/test/unit/execution_strategy/test_open_4.rb +86 -0
  62. data/test/unit/execution_strategy/test_rbx_open_4.rb +25 -0
  63. data/test/unit/test/test_integration_test_assertions.rb +211 -0
  64. data/test/unit/test_cli_logger.rb +219 -0
  65. data/test/unit/test_cli_logging.rb +243 -0
  66. data/test/unit/test_exit_now.rb +37 -0
  67. data/test/unit/test_main.rb +840 -0
  68. data/test/unit/test_sh.rb +404 -0
  69. metadata +260 -0
@@ -0,0 +1,21 @@
1
+ require_relative "base_integration_test"
2
+
3
+ include FileUtils
4
+
5
+ class TestCli < BaseIntegrationTest
6
+ test_that "optparse_plus CLI is properly documented" do
7
+ When { @stdout, _, __ = optparse_plus "--help" }
8
+ Then {
9
+ assert_banner(@stdout, "optparse_plus", takes_options: true, takes_arguments: { app_name: :required })
10
+ }
11
+ And {
12
+ assert_option(@stdout, "--force")
13
+ assert_option(@stdout, "--[no-]readme")
14
+ assert_option(@stdout, "-l", "--license")
15
+ assert_option(@stdout, "--log-level")
16
+ }
17
+ And {
18
+ assert_oneline_summary(@stdout)
19
+ }
20
+ end
21
+ end
@@ -0,0 +1,56 @@
1
+ require_relative "base_integration_test"
2
+
3
+ include FileUtils
4
+
5
+ class TestLicense < BaseIntegrationTest
6
+ test_that "omitting a license generates a warning" do
7
+ When { _, @stderr, __ = optparse_plus "newgem" }
8
+ Then {
9
+ assert_match(/warning: your app has no license/,@stderr)
10
+ }
11
+ end
12
+
13
+ test_that "explicitly omitting a license does not generate a warning" do
14
+ When { _, @stderr, __ = optparse_plus "newgem -l NONE" }
15
+ Then {
16
+ refute_match(/warning: your app has no license/,@stderr)
17
+ }
18
+ end
19
+
20
+ [
21
+ "apache",
22
+ "mit",
23
+ "gplv2",
24
+ "gplv3",
25
+ ].each do |license|
26
+ test_that "the #{license} license can be included" do
27
+ When { optparse_plus "newgem -l #{license}" }
28
+ Then {
29
+ assert File.exist?("newgem/LICENSE.txt")
30
+ }
31
+ And {
32
+ assert_file("newgem/newgem.gemspec", contains: /#{license.upcase}/)
33
+ }
34
+ end
35
+ end
36
+
37
+ test_that "a custom license can be included" do
38
+ When { optparse_plus "newgem -l custom" }
39
+ Then {
40
+ assert File.exist?("newgem/LICENSE.txt")
41
+ }
42
+ And {
43
+ assert_equal "", File.read("newgem/LICENSE.txt").strip
44
+ }
45
+ end
46
+
47
+ test_that "a non-custom non-supported license causes an error" do
48
+ When { _, @stderr, @result = optparse_plus "newgem -l foobar", allow_failure: true }
49
+ Then {
50
+ refute @result.success?
51
+ }
52
+ And {
53
+ assert_match(/invalid argument: -l foobar/,@stderr)
54
+ }
55
+ end
56
+ end
@@ -0,0 +1,53 @@
1
+ require_relative "base_integration_test"
2
+ class TestReadme < BaseIntegrationTest
3
+ test_that "a reasonable README is created" do
4
+ When {
5
+ optparse_plus "newgem --readme"
6
+ }
7
+ Then {
8
+ assert File.exist?("newgem/README.rdoc")
9
+ }
10
+ And {
11
+ readmes = Dir["newgem/README*"].to_a
12
+ assert_equal 1, readmes.size,"Found more than one README: #{readmes.inspect}"
13
+ }
14
+ And {
15
+ rakefile_contents = File.read("newgem/Rakefile")
16
+ assert_match(/README.rdoc/,rakefile_contents)
17
+ assert_match(/rd.main = ["']README.rdoc["']/,rakefile_contents)
18
+ }
19
+ And {
20
+ assert_file("newgem/README.rdoc",
21
+ contains: [
22
+ /newgem/,
23
+ /Author:: YOUR NAME \(YOUR EMAIL\)/,
24
+ /\* \{Source on Github\}\[LINK TO GITHUB\]/,
25
+ /RDoc\[LINK TO RDOC.INFO\]/,
26
+ /^== Install/,
27
+ /^== Examples/,
28
+ /^== Contributing/,
29
+ ])
30
+ }
31
+ end
32
+
33
+ test_that "a readme is created by default" do
34
+ When {
35
+ optparse_plus "newgem"
36
+ }
37
+ Then {
38
+ assert File.exist?("newgem/README.rdoc")
39
+ }
40
+ end
41
+
42
+ test_that "we can omit a README" do
43
+ When {
44
+ optparse_plus "--no-readme newgem"
45
+ }
46
+ Then {
47
+ refute File.exist?("newgem/README.rdoc")
48
+ }
49
+ And {
50
+ refute_match(/README/,File.read("newgem/Rakefile"))
51
+ }
52
+ end
53
+ end
@@ -0,0 +1,28 @@
1
+ require_relative "base_integration_test"
2
+
3
+ include FileUtils
4
+
5
+ class TestRSpec < BaseIntegrationTest
6
+ test_that "we can generate an app using RSpec instead of Test::Unit" do
7
+ When { optparse_plus "--rspec newgem" }
8
+ Then {
9
+ refute Dir.exist?("newgem/test")
10
+ assert Dir.exist?("newgem/spec")
11
+ assert File.exist?("newgem/spec/something_spec.rb")
12
+ }
13
+ And {
14
+ assert_file("newgem/newgem.gemspec", contains: /add_development_dependency\(["']rspec["']/)
15
+ }
16
+ And {
17
+ stdout,_ = rake("newgem", "-T")
18
+ assert_match(/rake spec/,stdout)
19
+ refute_match(/rake testa/,stdout)
20
+ }
21
+ When {
22
+ @stdout, _ = rake("newgem","spec")
23
+ }
24
+ Then {
25
+ assert_match(/1 example,.*0 failures/,@stdout)
26
+ }
27
+ end
28
+ end
@@ -0,0 +1,21 @@
1
+ require_relative "base_integration_test"
2
+
3
+ include FileUtils
4
+
5
+ class TestVersion < BaseIntegrationTest
6
+ test_that "--help shows the gem version" do
7
+ Given { optparse_plus "newgem" }
8
+ When { @stdout, _, = run_app "newgem", "--help" }
9
+ Then {
10
+ assert_match(/v\d+\.\d+\.\d+/, @stdout)
11
+ }
12
+ end
13
+
14
+ test_that "--version shows the gem version" do
15
+ Given { optparse_plus "newgem" }
16
+ When { @stdout, _, = run_app "newgem", "--version" }
17
+ Then {
18
+ assert_match(/v\d+\.\d+\.\d+/, @stdout)
19
+ }
20
+ end
21
+ end
@@ -0,0 +1,19 @@
1
+ if RUBY_PLATFORM == 'java'
2
+ puts "Simplecov seems to cause JRuby to barf, so use another ruby if you want to check coverage"
3
+ else
4
+ require 'simplecov'
5
+ SimpleCov.start do
6
+ add_filter "/test"
7
+ end
8
+ end
9
+
10
+ require 'test/unit'
11
+ require 'rspec/expectations'
12
+ require 'clean_test/test_case'
13
+ require 'ostruct'
14
+
15
+ RSpec::Matchers.configuration.syntax = :should
16
+
17
+ class BaseTest < Clean::Test::TestCase
18
+ include RSpec::Matchers
19
+ end
@@ -0,0 +1,7 @@
1
+ #!/bin/sh
2
+
3
+ echo "standard output"
4
+ if [ $# -gt 0 ]; then
5
+ echo "standard error" 1>&2
6
+ fi
7
+ exit $#
@@ -0,0 +1,24 @@
1
+ require 'base_test'
2
+
3
+ module ExecutionStrategy
4
+ class TestBase < BaseTest
5
+ include OptparsePlus::ExecutionStrategy
6
+
7
+ [
8
+ [:run_command,["ls"]],
9
+ [:exception_meaning_command_not_found,[]],
10
+ ].each do |(method,args)|
11
+ test_that "#{method} isn't implemented" do
12
+ Given {
13
+ @strategy = Base.new
14
+ }
15
+ When {
16
+ @code = lambda { @strategy.send(method,*args) }
17
+ }
18
+ Then {
19
+ assert_raises(RuntimeError,&@code)
20
+ }
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,77 @@
1
+ require 'base_test'
2
+ require 'mocha/test_unit'
3
+
4
+ # Defined by JRuby, but this test must pass on any Ruby
5
+ class NativeException
6
+ end
7
+
8
+ module ExecutionStrategy
9
+ class TestJVM < BaseTest
10
+ include OptparsePlus::ExecutionStrategy
11
+
12
+ test_that "run_command proxies to Open3.capture3" do
13
+ Given {
14
+ @process = mock('java.lang.Process')
15
+ @runtime = mock('java.lang.Runtime')
16
+ @command = "ls"
17
+ @stdout = any_string
18
+ @stderr = any_string
19
+ @exitstatus = any_int :min => 1, :max => 127
20
+ }
21
+ When the_test_runs
22
+ Then {
23
+ expects_lang = mock()
24
+ JVM.any_instance.expects(:java).returns(expects_lang)
25
+ expects_Runtime = mock()
26
+ expects_lang.expects(:lang).returns(expects_Runtime)
27
+ runtime_klass = mock()
28
+ expects_Runtime.expects(:Runtime).returns(runtime_klass)
29
+ runtime_klass.expects(:get_runtime).returns(@runtime)
30
+ @runtime.expects(:exec).with(@command).returns(@process)
31
+
32
+ stdin = mock()
33
+ @process.expects(:get_output_stream).returns(stdin)
34
+ stdin.expects(:close)
35
+
36
+ stdout_input_stream = mock('InputStream')
37
+ @process.expects(:get_input_stream).returns(stdout_input_stream)
38
+ stdout_input_stream.expects(:read).times(2).returns(
39
+ @stdout,
40
+ -1)
41
+
42
+ stderr_input_stream = mock('InputStream')
43
+ @process.expects(:get_error_stream).returns(stderr_input_stream)
44
+ stderr_input_stream.expects(:read).times(2).returns(
45
+ @stderr,
46
+ -1)
47
+
48
+ @process.expects(:wait_for).returns(@exitstatus)
49
+ }
50
+
51
+ Given new_jvm_strategy
52
+ When {
53
+ @results = @strategy.run_command(@command)
54
+ }
55
+ Then {
56
+ @results[0].should be == @stdout
57
+ @results[1].should be == @stderr
58
+ @results[2].exitstatus.should be == @exitstatus
59
+ }
60
+ end
61
+
62
+ test_that "exception_meaning_command_not_found returns NativeException" do
63
+ Given new_jvm_strategy
64
+ When {
65
+ @klass = @strategy.exception_meaning_command_not_found
66
+ }
67
+ Then {
68
+ @klass.should be == NativeException
69
+ }
70
+ end
71
+
72
+ private
73
+ def new_jvm_strategy
74
+ lambda { @strategy = JVM.new }
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,32 @@
1
+ require 'base_test'
2
+
3
+ module ExecutionStrategy
4
+ class TestMRI < BaseTest
5
+ include OptparsePlus::ExecutionStrategy
6
+
7
+ test_that "run_command isn't implemented" do
8
+ Given new_mri_strategy
9
+ When {
10
+ @code = lambda { @strategy.run_command("ls") }
11
+ }
12
+ Then {
13
+ assert_raises(RuntimeError,&@code)
14
+ }
15
+ end
16
+
17
+ test_that "exception_meaning_command_not_found returns Errno::ENOENT" do
18
+ Given new_mri_strategy
19
+ When {
20
+ @klass = @strategy.exception_meaning_command_not_found
21
+ }
22
+ Then {
23
+ @klass.should == Errno::ENOENT
24
+ }
25
+ end
26
+
27
+ private
28
+ def new_mri_strategy
29
+ lambda { @strategy = MRI.new }
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,70 @@
1
+ require 'base_test'
2
+ require 'mocha/test_unit'
3
+ require 'open3'
4
+
5
+ module ExecutionStrategy
6
+ class TestOpen_3 < BaseTest
7
+ include OptparsePlus::ExecutionStrategy
8
+
9
+ test_that "run_command proxies to Open3.capture3" do
10
+ Given {
11
+ @command = any_string
12
+ @stdout = any_string
13
+ @stderr = any_string
14
+ @status = stub('Process::Status')
15
+ }
16
+ When the_test_runs
17
+ Then {
18
+ Open3.expects(:capture3).with(@command).returns([@stdout,@stderr,@status])
19
+ }
20
+
21
+ Given new_open_3_strategy
22
+ When {
23
+ @results = @strategy.run_command(@command)
24
+ }
25
+ Then {
26
+ @results[0].should be == @stdout
27
+ @results[1].should be == @stderr
28
+ @results[2].should be @status
29
+ }
30
+ end
31
+
32
+ test_that "run_command handles array arguments properly" do
33
+ Given {
34
+ @command = [any_string, any_string, any_string]
35
+ @stdout = any_string
36
+ @stderr = any_string
37
+ @status = stub('Process::Status')
38
+ }
39
+ When the_test_runs
40
+ Then {
41
+ Open3.expects(:capture3).with(*@command).returns([@stdout,@stderr,@status])
42
+ }
43
+
44
+ Given new_open_3_strategy
45
+ When {
46
+ @results = @strategy.run_command(@command)
47
+ }
48
+ Then {
49
+ @results[0].should be == @stdout
50
+ @results[1].should be == @stderr
51
+ @results[2].should be @status
52
+ }
53
+ end
54
+
55
+ test_that "exception_meaning_command_not_found returns Errno::ENOENT" do
56
+ Given new_open_3_strategy
57
+ When {
58
+ @klass = @strategy.exception_meaning_command_not_found
59
+ }
60
+ Then {
61
+ @klass.should be == Errno::ENOENT
62
+ }
63
+ end
64
+
65
+ private
66
+ def new_open_3_strategy
67
+ lambda { @strategy = Open_3.new }
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,86 @@
1
+ require 'base_test'
2
+ require 'mocha/test_unit'
3
+
4
+ # Define this symbol without requiring the library;
5
+ # all we're goingn to do is mock calls to it
6
+ module Open4
7
+ end
8
+
9
+ module ExecutionStrategy
10
+ class TestOpen_4 < BaseTest
11
+ include OptparsePlus::ExecutionStrategy
12
+
13
+ test_that "run_command proxies to Open4.capture4" do
14
+ Given {
15
+ @command = any_string
16
+ @stdin_io = mock("IO")
17
+ @stdout = any_string
18
+ @stdout_io = StringIO.new(@stdout)
19
+ @stderr = any_string
20
+ @stderr_io = StringIO.new(@stderr)
21
+ @pid = any_int :min => 2, :max => 65536
22
+ @status = stub('Process::Status')
23
+ }
24
+ When the_test_runs
25
+ Then {
26
+ Open4.expects(:popen4).with(@command).returns([@pid,@stdin_io,@stdout_io,@stderr_io])
27
+ @stdin_io.expects(:close)
28
+ Process.expects(:waitpid2).with(@pid).returns([any_string,@status])
29
+ }
30
+
31
+ Given new_open_4_strategy
32
+ When {
33
+ @results = @strategy.run_command(@command)
34
+ }
35
+ Then {
36
+ @results[0].should be == @stdout
37
+ @results[1].should be == @stderr
38
+ @results[2].should be @status
39
+ }
40
+ end
41
+
42
+ test_that "run_command handles array arguments properly" do
43
+ Given {
44
+ @command = [any_string, any_string, any_string]
45
+ @stdin_io = mock("IO")
46
+ @stdout = any_string
47
+ @stdout_io = StringIO.new(@stdout)
48
+ @stderr = any_string
49
+ @stderr_io = StringIO.new(@stderr)
50
+ @pid = any_int :min => 2, :max => 65536
51
+ @status = stub('Process::Status')
52
+ }
53
+ When the_test_runs
54
+ Then {
55
+ Open4.expects(:popen4).with(*@command).returns([@pid,@stdin_io,@stdout_io,@stderr_io])
56
+ @stdin_io.expects(:close)
57
+ Process.expects(:waitpid2).with(@pid).returns([any_string,@status])
58
+ }
59
+
60
+ Given new_open_4_strategy
61
+ When {
62
+ @results = @strategy.run_command(@command)
63
+ }
64
+ Then {
65
+ @results[0].should be == @stdout
66
+ @results[1].should be == @stderr
67
+ @results[2].should be @status
68
+ }
69
+ end
70
+
71
+ test_that "exception_meaning_command_not_found returns Errno::ENOENT" do
72
+ Given new_open_4_strategy
73
+ When {
74
+ @klass = @strategy.exception_meaning_command_not_found
75
+ }
76
+ Then {
77
+ @klass.should be == Errno::ENOENT
78
+ }
79
+ end
80
+
81
+ private
82
+ def new_open_4_strategy
83
+ lambda { @strategy = Open_4.new }
84
+ end
85
+ end
86
+ end