optimist 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.
- checksums.yaml +7 -0
- data/.gitignore +15 -0
- data/.travis.yml +11 -0
- data/FAQ.txt +92 -0
- data/Gemfile +4 -0
- data/History.txt +168 -0
- data/README.md +60 -0
- data/Rakefile +15 -0
- data/lib/optimist.rb +1014 -0
- data/optimist.gemspec +35 -0
- data/test/optimist/command_line_error_test.rb +27 -0
- data/test/optimist/help_needed_test.rb +19 -0
- data/test/optimist/parser_educate_test.rb +175 -0
- data/test/optimist/parser_opt_test.rb +14 -0
- data/test/optimist/parser_parse_test.rb +79 -0
- data/test/optimist/parser_test.rb +1220 -0
- data/test/optimist/version_needed_test.rb +19 -0
- data/test/optimist_test.rb +190 -0
- data/test/support/assert_helpers.rb +46 -0
- data/test/test_helper.rb +22 -0
- metadata +125 -0
data/optimist.gemspec
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
|
5
|
+
require 'optimist'
|
6
|
+
|
7
|
+
Gem::Specification.new do |spec|
|
8
|
+
spec.name = "optimist"
|
9
|
+
spec.version = Optimist::VERSION
|
10
|
+
spec.authors = ["William Morgan", "Keenan Brock", "Jason Frey"]
|
11
|
+
spec.email = "keenan@thebrocks.net"
|
12
|
+
spec.summary = "Optimist is a commandline option parser for Ruby that just gets out of your way."
|
13
|
+
spec.description = "Optimist is a commandline option parser for Ruby that just
|
14
|
+
gets out of your way. One line of code per option is all you need to write.
|
15
|
+
For that, you get a nice automatically-generated help page, robust option
|
16
|
+
parsing, command subcompletion, and sensible defaults for everything you don't
|
17
|
+
specify."
|
18
|
+
spec.homepage = "http://manageiq.github.io/optimist/"
|
19
|
+
spec.license = "MIT"
|
20
|
+
|
21
|
+
spec.files = `git ls-files -z`.split("\x0")
|
22
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
23
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
24
|
+
spec.metadata = {
|
25
|
+
"changelog_uri" => "https://github.com/ManageIQ/optimist/blob/master/History.txt",
|
26
|
+
"source_code_uri" => "https://github.com/ManageIQ/optimist/",
|
27
|
+
"bug_tracker_uri" => "https://github.com/ManageIQ/optimist/issues",
|
28
|
+
}
|
29
|
+
|
30
|
+
spec.require_paths = ["lib"]
|
31
|
+
|
32
|
+
spec.add_development_dependency "minitest", "~> 5.4.3"
|
33
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
34
|
+
spec.add_development_dependency "chronic"
|
35
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module Optimist
|
4
|
+
class CommandlineErrorTest < ::MiniTest::Test
|
5
|
+
def test_class
|
6
|
+
assert_kind_of Exception, cle("message")
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_message
|
10
|
+
assert "message", cle("message").message
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_error_code_default
|
14
|
+
assert_nil cle("message").error_code
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_error_code_custom
|
18
|
+
assert_equal(-3, cle("message", -3).error_code)
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def cle(*args)
|
24
|
+
CommandlineError.new(*args)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module Optimist
|
4
|
+
class HelpNeededTest < ::MiniTest::Test
|
5
|
+
def test_class
|
6
|
+
assert_kind_of Exception, hn("message")
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_message
|
10
|
+
assert "message", hn("message").message
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def hn(*args)
|
16
|
+
HelpNeeded.new(*args)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,175 @@
|
|
1
|
+
require 'stringio'
|
2
|
+
require 'test_helper'
|
3
|
+
|
4
|
+
module Optimist
|
5
|
+
class ParserEduateTest < ::MiniTest::Test
|
6
|
+
def setup
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_no_arguments_to_stdout
|
10
|
+
assert_stdout(/Options:/) do
|
11
|
+
parser.educate
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_argument_to_stringio
|
16
|
+
assert_educates(/Options:/)
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_no_headers
|
20
|
+
assert_educates(/^Options:/)
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_usage
|
24
|
+
parser.usage("usage string")
|
25
|
+
assert_educates(/^Usage: \w* usage string\n\nOptions:/)
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_usage_synopsis_version
|
29
|
+
end
|
30
|
+
|
31
|
+
# def test_banner
|
32
|
+
# def test_text
|
33
|
+
|
34
|
+
# width, legacy_width
|
35
|
+
# wrap
|
36
|
+
# wrap_lines
|
37
|
+
|
38
|
+
############
|
39
|
+
# convert these into multiple tests
|
40
|
+
# pulled out of optimist_test for now
|
41
|
+
def test_help_has_default_banner
|
42
|
+
@p = Parser.new
|
43
|
+
sio = StringIO.new "w"
|
44
|
+
@p.parse []
|
45
|
+
@p.educate sio
|
46
|
+
help = sio.string.split "\n"
|
47
|
+
assert help[0] =~ /options/i
|
48
|
+
assert_equal 2, help.length # options, then -h
|
49
|
+
|
50
|
+
@p = Parser.new
|
51
|
+
@p.version "my version"
|
52
|
+
sio = StringIO.new "w"
|
53
|
+
@p.parse []
|
54
|
+
@p.educate sio
|
55
|
+
help = sio.string.split "\n"
|
56
|
+
assert help[0] =~ /my version/i
|
57
|
+
assert_equal 4, help.length # version, options, -h, -v
|
58
|
+
|
59
|
+
@p = Parser.new
|
60
|
+
@p.banner "my own banner"
|
61
|
+
sio = StringIO.new "w"
|
62
|
+
@p.parse []
|
63
|
+
@p.educate sio
|
64
|
+
help = sio.string.split "\n"
|
65
|
+
assert help[0] =~ /my own banner/i
|
66
|
+
assert_equal 2, help.length # banner, -h
|
67
|
+
|
68
|
+
@p = Parser.new
|
69
|
+
@p.text "my own text banner"
|
70
|
+
sio = StringIO.new "w"
|
71
|
+
@p.parse []
|
72
|
+
@p.educate sio
|
73
|
+
help = sio.string.split "\n"
|
74
|
+
assert help[0] =~ /my own text banner/i
|
75
|
+
assert_equal 2, help.length # banner, -h
|
76
|
+
end
|
77
|
+
|
78
|
+
def test_help_has_optional_usage
|
79
|
+
@p = Parser.new
|
80
|
+
@p.usage "OPTIONS FILES"
|
81
|
+
sio = StringIO.new "w"
|
82
|
+
@p.parse []
|
83
|
+
@p.educate sio
|
84
|
+
help = sio.string.split "\n"
|
85
|
+
assert help[0] =~ /OPTIONS FILES/i
|
86
|
+
assert_equal 4, help.length # line break, options, then -h
|
87
|
+
end
|
88
|
+
|
89
|
+
def test_help_has_optional_synopsis
|
90
|
+
@p = Parser.new
|
91
|
+
@p.synopsis "About this program"
|
92
|
+
sio = StringIO.new "w"
|
93
|
+
@p.parse []
|
94
|
+
@p.educate sio
|
95
|
+
help = sio.string.split "\n"
|
96
|
+
assert help[0] =~ /About this program/i
|
97
|
+
assert_equal 4, help.length # line break, options, then -h
|
98
|
+
end
|
99
|
+
|
100
|
+
def test_help_has_specific_order_for_usage_and_synopsis
|
101
|
+
@p = Parser.new
|
102
|
+
@p.usage "OPTIONS FILES"
|
103
|
+
@p.synopsis "About this program"
|
104
|
+
sio = StringIO.new "w"
|
105
|
+
@p.parse []
|
106
|
+
@p.educate sio
|
107
|
+
help = sio.string.split "\n"
|
108
|
+
assert help[0] =~ /OPTIONS FILES/i
|
109
|
+
assert help[1] =~ /About this program/i
|
110
|
+
assert_equal 5, help.length # line break, options, then -h
|
111
|
+
end
|
112
|
+
|
113
|
+
def test_help_preserves_positions
|
114
|
+
parser.opt :zzz, "zzz"
|
115
|
+
parser.opt :aaa, "aaa"
|
116
|
+
sio = StringIO.new "w"
|
117
|
+
parser.educate sio
|
118
|
+
|
119
|
+
help = sio.string.split "\n"
|
120
|
+
assert help[1] =~ /zzz/
|
121
|
+
assert help[2] =~ /aaa/
|
122
|
+
end
|
123
|
+
|
124
|
+
def test_help_includes_option_types
|
125
|
+
parser.opt :arg1, 'arg', :type => :int
|
126
|
+
parser.opt :arg2, 'arg', :type => :ints
|
127
|
+
parser.opt :arg3, 'arg', :type => :string
|
128
|
+
parser.opt :arg4, 'arg', :type => :strings
|
129
|
+
parser.opt :arg5, 'arg', :type => :float
|
130
|
+
parser.opt :arg6, 'arg', :type => :floats
|
131
|
+
parser.opt :arg7, 'arg', :type => :io
|
132
|
+
parser.opt :arg8, 'arg', :type => :ios
|
133
|
+
parser.opt :arg9, 'arg', :type => :date
|
134
|
+
parser.opt :arg10, 'arg', :type => :dates
|
135
|
+
sio = StringIO.new "w"
|
136
|
+
parser.educate sio
|
137
|
+
|
138
|
+
help = sio.string.split "\n"
|
139
|
+
assert help[1] =~ /<i>/
|
140
|
+
assert help[2] =~ /<i\+>/
|
141
|
+
assert help[3] =~ /<s>/
|
142
|
+
assert help[4] =~ /<s\+>/
|
143
|
+
assert help[5] =~ /<f>/
|
144
|
+
assert help[6] =~ /<f\+>/
|
145
|
+
assert help[7] =~ /<filename\/uri>/
|
146
|
+
assert help[8] =~ /<filename\/uri\+>/
|
147
|
+
assert help[9] =~ /<date>/
|
148
|
+
assert help[10] =~ /<date\+>/
|
149
|
+
end
|
150
|
+
|
151
|
+
def test_help_has_grammatical_default_text
|
152
|
+
parser.opt :arg1, 'description with period.', :default => 'hello'
|
153
|
+
parser.opt :arg2, 'description without period', :default => 'world'
|
154
|
+
sio = StringIO.new 'w'
|
155
|
+
parser.educate sio
|
156
|
+
|
157
|
+
help = sio.string.split "\n"
|
158
|
+
assert help[1] =~ /Default/
|
159
|
+
assert help[2] =~ /default/
|
160
|
+
end
|
161
|
+
############
|
162
|
+
|
163
|
+
private
|
164
|
+
|
165
|
+
def parser
|
166
|
+
@p ||= Parser.new
|
167
|
+
end
|
168
|
+
|
169
|
+
def assert_educates(output)
|
170
|
+
str = StringIO.new
|
171
|
+
parser.educate str
|
172
|
+
assert_match output, str.string
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
require 'stringio'
|
2
|
+
require 'test_helper'
|
3
|
+
|
4
|
+
module Optimist
|
5
|
+
class ParserParseTest < ::MiniTest::Test
|
6
|
+
|
7
|
+
# TODO: parse
|
8
|
+
# resolve_default_short_options!
|
9
|
+
# parse_date_parameter
|
10
|
+
# parse_integer_parameter(param, arg)
|
11
|
+
# parse_float_parameter(param, arg)
|
12
|
+
# parse_io_parameter(param, arg)
|
13
|
+
# each_arg
|
14
|
+
# collect_argument_parameters
|
15
|
+
|
16
|
+
def test_help_needed
|
17
|
+
parser.opt "arg"
|
18
|
+
assert_raises(HelpNeeded) { parser.parse %w(-h) }
|
19
|
+
assert_raises(HelpNeeded) { parser.parse %w(--help) }
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_help_overridden
|
23
|
+
parser.opt :arg1, "desc", :long => "help"
|
24
|
+
assert parser.parse(%w(-h))[:arg1]
|
25
|
+
assert parser.parse(%w(--help))[:arg1]
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_help_with_other_args
|
29
|
+
parser.opt :arg1
|
30
|
+
assert_raises(HelpNeeded) { @p.parse %w(--arg1 --help) }
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_help_with_arg_error
|
34
|
+
parser.opt :arg1, :type => String
|
35
|
+
assert_raises(HelpNeeded) { @p.parse %w(--arg1 --help) }
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_version_needed_unset
|
39
|
+
parser.opt "arg"
|
40
|
+
assert_raises(CommandlineError) { parser.parse %w(-v) }
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_version_needed
|
44
|
+
parser.version "optimist 5.2.3"
|
45
|
+
assert_raises(VersionNeeded) { parser.parse %w(-v) }
|
46
|
+
assert_raises(VersionNeeded) { parser.parse %w(--version) }
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_version_overridden
|
50
|
+
parser.opt "version"
|
51
|
+
assert parser.parse(%w(-v))["version"]
|
52
|
+
assert parser.parse(%w(-v))[:version_given]
|
53
|
+
end
|
54
|
+
|
55
|
+
def test_version_only_appears_if_set
|
56
|
+
parser.opt "arg"
|
57
|
+
assert_raises(CommandlineError) { parser.parse %w(-v) }
|
58
|
+
end
|
59
|
+
|
60
|
+
def test_version_with_other_args
|
61
|
+
parser.opt :arg1
|
62
|
+
parser.version "1.1"
|
63
|
+
assert_raises(VersionNeeded) { parser.parse %w(--arg1 --version) }
|
64
|
+
end
|
65
|
+
|
66
|
+
def test_version_with_arg_error
|
67
|
+
parser.opt :arg1, :type => String
|
68
|
+
parser.version "1.1"
|
69
|
+
assert_raises(VersionNeeded) { parser.parse %w(--arg1 --version) }
|
70
|
+
end
|
71
|
+
|
72
|
+
|
73
|
+
private
|
74
|
+
|
75
|
+
def parser
|
76
|
+
@p ||= Parser.new
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,1220 @@
|
|
1
|
+
require 'stringio'
|
2
|
+
require 'test_helper'
|
3
|
+
|
4
|
+
module Optimist
|
5
|
+
|
6
|
+
class ParserTest < ::MiniTest::Test
|
7
|
+
def setup
|
8
|
+
@p = Parser.new
|
9
|
+
end
|
10
|
+
|
11
|
+
def parser
|
12
|
+
@p ||= Parser.new
|
13
|
+
end
|
14
|
+
|
15
|
+
# initialize
|
16
|
+
# cloaker
|
17
|
+
|
18
|
+
def test_version
|
19
|
+
assert_nil parser.version
|
20
|
+
assert_equal "optimist 5.2.3", parser.version("optimist 5.2.3")
|
21
|
+
assert_equal "optimist 5.2.3", parser.version
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_usage
|
25
|
+
assert_nil parser.usage
|
26
|
+
|
27
|
+
assert_equal "usage string", parser.usage("usage string")
|
28
|
+
assert_equal "usage string", parser.usage
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_synopsis
|
32
|
+
assert_nil parser.synopsis
|
33
|
+
|
34
|
+
assert_equal "synopsis string", parser.synopsis("synopsis string")
|
35
|
+
assert_equal "synopsis string", parser.synopsis
|
36
|
+
end
|
37
|
+
|
38
|
+
# def test_depends
|
39
|
+
# def test_conflicts
|
40
|
+
# def test_stop_on
|
41
|
+
# def test_stop_on_unknown
|
42
|
+
|
43
|
+
# die
|
44
|
+
# def test_die_educate_on_error
|
45
|
+
|
46
|
+
|
47
|
+
def test_unknown_arguments
|
48
|
+
assert_raises(CommandlineError) { @p.parse(%w(--arg)) }
|
49
|
+
@p.opt "arg"
|
50
|
+
@p.parse(%w(--arg))
|
51
|
+
assert_raises(CommandlineError) { @p.parse(%w(--arg2)) }
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_syntax_check
|
55
|
+
@p.opt "arg"
|
56
|
+
|
57
|
+
@p.parse(%w(--arg))
|
58
|
+
@p.parse(%w(arg))
|
59
|
+
assert_raises(CommandlineError) { @p.parse(%w(---arg)) }
|
60
|
+
assert_raises(CommandlineError) { @p.parse(%w(-arg)) }
|
61
|
+
end
|
62
|
+
|
63
|
+
def test_required_flags_are_required
|
64
|
+
@p.opt "arg", "desc", :required => true
|
65
|
+
@p.opt "arg2", "desc", :required => false
|
66
|
+
@p.opt "arg3", "desc", :required => false
|
67
|
+
|
68
|
+
@p.parse(%w(--arg))
|
69
|
+
@p.parse(%w(--arg --arg2))
|
70
|
+
assert_raises(CommandlineError) { @p.parse(%w(--arg2)) }
|
71
|
+
assert_raises(CommandlineError) { @p.parse(%w(--arg2 --arg3)) }
|
72
|
+
end
|
73
|
+
|
74
|
+
## flags that take an argument error unless given one
|
75
|
+
def test_argflags_demand_args
|
76
|
+
@p.opt "goodarg", "desc", :type => String
|
77
|
+
@p.opt "goodarg2", "desc", :type => String
|
78
|
+
|
79
|
+
@p.parse(%w(--goodarg goat))
|
80
|
+
assert_raises(CommandlineError) { @p.parse(%w(--goodarg --goodarg2 goat)) }
|
81
|
+
assert_raises(CommandlineError) { @p.parse(%w(--goodarg)) }
|
82
|
+
end
|
83
|
+
|
84
|
+
## flags that don't take arguments ignore them
|
85
|
+
def test_arglessflags_refuse_args
|
86
|
+
@p.opt "goodarg"
|
87
|
+
@p.opt "goodarg2"
|
88
|
+
@p.parse(%w(--goodarg))
|
89
|
+
@p.parse(%w(--goodarg --goodarg2))
|
90
|
+
opts = @p.parse %w(--goodarg a)
|
91
|
+
assert_equal true, opts["goodarg"]
|
92
|
+
assert_equal ["a"], @p.leftovers
|
93
|
+
end
|
94
|
+
|
95
|
+
## flags that require args of a specific type refuse args of other
|
96
|
+
## types
|
97
|
+
def test_typed_args_refuse_args_of_other_types
|
98
|
+
@p.opt "goodarg", "desc", :type => :int
|
99
|
+
assert_raises(ArgumentError) { @p.opt "badarg", "desc", :type => :asdf }
|
100
|
+
|
101
|
+
@p.parse(%w(--goodarg 3))
|
102
|
+
assert_raises(CommandlineError) { @p.parse(%w(--goodarg 4.2)) }
|
103
|
+
assert_raises(CommandlineError) { @p.parse(%w(--goodarg hello)) }
|
104
|
+
end
|
105
|
+
|
106
|
+
## type is correctly derived from :default
|
107
|
+
def test_type_correctly_derived_from_default
|
108
|
+
assert_raises(ArgumentError) { @p.opt "badarg", "desc", :default => [] }
|
109
|
+
assert_raises(ArgumentError) { @p.opt "badarg3", "desc", :default => [{1 => 2}] }
|
110
|
+
assert_raises(ArgumentError) { @p.opt "badarg4", "desc", :default => Hash.new }
|
111
|
+
|
112
|
+
# single arg: int
|
113
|
+
@p.opt "argsi", "desc", :default => 0
|
114
|
+
opts = @p.parse(%w(--))
|
115
|
+
assert_equal 0, opts["argsi"]
|
116
|
+
opts = @p.parse(%w(--argsi 4))
|
117
|
+
assert_equal 4, opts["argsi"]
|
118
|
+
opts = @p.parse(%w(--argsi=4))
|
119
|
+
assert_equal 4, opts["argsi"]
|
120
|
+
opts = @p.parse(%w(--argsi=-4))
|
121
|
+
assert_equal( -4, opts["argsi"])
|
122
|
+
|
123
|
+
assert_raises(CommandlineError) { @p.parse(%w(--argsi 4.2)) }
|
124
|
+
assert_raises(CommandlineError) { @p.parse(%w(--argsi hello)) }
|
125
|
+
|
126
|
+
# single arg: float
|
127
|
+
@p.opt "argsf", "desc", :default => 3.14
|
128
|
+
opts = @p.parse(%w(--))
|
129
|
+
assert_equal 3.14, opts["argsf"]
|
130
|
+
opts = @p.parse(%w(--argsf 2.41))
|
131
|
+
assert_equal 2.41, opts["argsf"]
|
132
|
+
opts = @p.parse(%w(--argsf 2))
|
133
|
+
assert_equal 2, opts["argsf"]
|
134
|
+
opts = @p.parse(%w(--argsf 1.0e-2))
|
135
|
+
assert_equal 1.0e-2, opts["argsf"]
|
136
|
+
assert_raises(CommandlineError) { @p.parse(%w(--argsf hello)) }
|
137
|
+
|
138
|
+
# single arg: date
|
139
|
+
date = Date.today
|
140
|
+
@p.opt "argsd", "desc", :default => date
|
141
|
+
opts = @p.parse(%w(--))
|
142
|
+
assert_equal Date.today, opts["argsd"]
|
143
|
+
opts = @p.parse(['--argsd', 'Jan 4, 2007'])
|
144
|
+
assert_equal Date.civil(2007, 1, 4), opts["argsd"]
|
145
|
+
assert_raises(CommandlineError) { @p.parse(%w(--argsd hello)) }
|
146
|
+
|
147
|
+
# single arg: string
|
148
|
+
@p.opt "argss", "desc", :default => "foobar"
|
149
|
+
opts = @p.parse(%w(--))
|
150
|
+
assert_equal "foobar", opts["argss"]
|
151
|
+
opts = @p.parse(%w(--argss 2.41))
|
152
|
+
assert_equal "2.41", opts["argss"]
|
153
|
+
opts = @p.parse(%w(--argss hello))
|
154
|
+
assert_equal "hello", opts["argss"]
|
155
|
+
|
156
|
+
# multi args: ints
|
157
|
+
@p.opt "argmi", "desc", :default => [3, 5]
|
158
|
+
opts = @p.parse(%w(--))
|
159
|
+
assert_equal [3, 5], opts["argmi"]
|
160
|
+
opts = @p.parse(%w(--argmi 4))
|
161
|
+
assert_equal [4], opts["argmi"]
|
162
|
+
assert_raises(CommandlineError) { @p.parse(%w(--argmi 4.2)) }
|
163
|
+
assert_raises(CommandlineError) { @p.parse(%w(--argmi hello)) }
|
164
|
+
|
165
|
+
# multi args: floats
|
166
|
+
@p.opt "argmf", "desc", :default => [3.34, 5.21]
|
167
|
+
opts = @p.parse(%w(--))
|
168
|
+
assert_equal [3.34, 5.21], opts["argmf"]
|
169
|
+
opts = @p.parse(%w(--argmf 2))
|
170
|
+
assert_equal [2], opts["argmf"]
|
171
|
+
opts = @p.parse(%w(--argmf 4.0))
|
172
|
+
assert_equal [4.0], opts["argmf"]
|
173
|
+
assert_raises(CommandlineError) { @p.parse(%w(--argmf hello)) }
|
174
|
+
|
175
|
+
# multi args: dates
|
176
|
+
dates = [Date.today, Date.civil(2007, 1, 4)]
|
177
|
+
@p.opt "argmd", "desc", :default => dates
|
178
|
+
opts = @p.parse(%w(--))
|
179
|
+
assert_equal dates, opts["argmd"]
|
180
|
+
opts = @p.parse(['--argmd', 'Jan 4, 2007'])
|
181
|
+
assert_equal [Date.civil(2007, 1, 4)], opts["argmd"]
|
182
|
+
assert_raises(CommandlineError) { @p.parse(%w(--argmd hello)) }
|
183
|
+
|
184
|
+
# multi args: strings
|
185
|
+
@p.opt "argmst", "desc", :default => %w(hello world)
|
186
|
+
opts = @p.parse(%w(--))
|
187
|
+
assert_equal %w(hello world), opts["argmst"]
|
188
|
+
opts = @p.parse(%w(--argmst 3.4))
|
189
|
+
assert_equal ["3.4"], opts["argmst"]
|
190
|
+
opts = @p.parse(%w(--argmst goodbye))
|
191
|
+
assert_equal ["goodbye"], opts["argmst"]
|
192
|
+
end
|
193
|
+
|
194
|
+
## :type and :default must match if both are specified
|
195
|
+
def test_type_and_default_must_match
|
196
|
+
assert_raises(ArgumentError) { @p.opt "badarg", "desc", :type => :int, :default => "hello" }
|
197
|
+
assert_raises(ArgumentError) { @p.opt "badarg2", "desc", :type => :String, :default => 4 }
|
198
|
+
assert_raises(ArgumentError) { @p.opt "badarg2", "desc", :type => :String, :default => ["hi"] }
|
199
|
+
assert_raises(ArgumentError) { @p.opt "badarg2", "desc", :type => :ints, :default => [3.14] }
|
200
|
+
|
201
|
+
@p.opt "argsi", "desc", :type => :int, :default => 4
|
202
|
+
@p.opt "argsf", "desc", :type => :float, :default => 3.14
|
203
|
+
@p.opt "argsd", "desc", :type => :date, :default => Date.today
|
204
|
+
@p.opt "argss", "desc", :type => :string, :default => "yo"
|
205
|
+
@p.opt "argmi", "desc", :type => :ints, :default => [4]
|
206
|
+
@p.opt "argmf", "desc", :type => :floats, :default => [3.14]
|
207
|
+
@p.opt "argmd", "desc", :type => :dates, :default => [Date.today]
|
208
|
+
@p.opt "argmst", "desc", :type => :strings, :default => ["yo"]
|
209
|
+
end
|
210
|
+
|
211
|
+
##
|
212
|
+
def test_flags_with_defaults_and_no_args_act_as_switches
|
213
|
+
@p.opt :argd, "desc", :default => "default_string"
|
214
|
+
|
215
|
+
opts = @p.parse(%w(--))
|
216
|
+
assert !opts[:argd_given]
|
217
|
+
assert_equal "default_string", opts[:argd]
|
218
|
+
|
219
|
+
opts = @p.parse(%w( --argd ))
|
220
|
+
assert opts[:argd_given]
|
221
|
+
assert_equal "default_string", opts[:argd]
|
222
|
+
|
223
|
+
opts = @p.parse(%w(--argd different_string))
|
224
|
+
assert opts[:argd_given]
|
225
|
+
assert_equal "different_string", opts[:argd]
|
226
|
+
end
|
227
|
+
|
228
|
+
def test_flag_with_no_defaults_and_no_args_act_as_switches_array
|
229
|
+
opts = nil
|
230
|
+
|
231
|
+
@p.opt :argd, "desc", :type => :strings, :default => ["default_string"]
|
232
|
+
|
233
|
+
opts = @p.parse(%w(--argd))
|
234
|
+
assert_equal ["default_string"], opts[:argd]
|
235
|
+
end
|
236
|
+
|
237
|
+
def test_type_and_empty_array
|
238
|
+
@p.opt "argmi", "desc", :type => :ints, :default => []
|
239
|
+
@p.opt "argmf", "desc", :type => :floats, :default => []
|
240
|
+
@p.opt "argmd", "desc", :type => :dates, :default => []
|
241
|
+
@p.opt "argms", "desc", :type => :strings, :default => []
|
242
|
+
assert_raises(ArgumentError) { @p.opt "badi", "desc", :type => :int, :default => [] }
|
243
|
+
assert_raises(ArgumentError) { @p.opt "badf", "desc", :type => :float, :default => [] }
|
244
|
+
assert_raises(ArgumentError) { @p.opt "badd", "desc", :type => :date, :default => [] }
|
245
|
+
assert_raises(ArgumentError) { @p.opt "bads", "desc", :type => :string, :default => [] }
|
246
|
+
opts = @p.parse([])
|
247
|
+
assert_equal(opts["argmi"], [])
|
248
|
+
assert_equal(opts["argmf"], [])
|
249
|
+
assert_equal(opts["argmd"], [])
|
250
|
+
assert_equal(opts["argms"], [])
|
251
|
+
end
|
252
|
+
|
253
|
+
def test_long_detects_bad_names
|
254
|
+
@p.opt "goodarg", "desc", :long => "none"
|
255
|
+
@p.opt "goodarg2", "desc", :long => "--two"
|
256
|
+
assert_raises(ArgumentError) { @p.opt "badarg", "desc", :long => "" }
|
257
|
+
assert_raises(ArgumentError) { @p.opt "badarg2", "desc", :long => "--" }
|
258
|
+
assert_raises(ArgumentError) { @p.opt "badarg3", "desc", :long => "-one" }
|
259
|
+
assert_raises(ArgumentError) { @p.opt "badarg4", "desc", :long => "---toomany" }
|
260
|
+
end
|
261
|
+
|
262
|
+
def test_short_detects_bad_names
|
263
|
+
@p.opt "goodarg", "desc", :short => "a"
|
264
|
+
@p.opt "goodarg2", "desc", :short => "-b"
|
265
|
+
assert_raises(ArgumentError) { @p.opt "badarg", "desc", :short => "" }
|
266
|
+
assert_raises(ArgumentError) { @p.opt "badarg2", "desc", :short => "-ab" }
|
267
|
+
assert_raises(ArgumentError) { @p.opt "badarg3", "desc", :short => "--t" }
|
268
|
+
end
|
269
|
+
|
270
|
+
def test_short_names_created_automatically
|
271
|
+
@p.opt "arg"
|
272
|
+
@p.opt "arg2"
|
273
|
+
@p.opt "arg3"
|
274
|
+
opts = @p.parse %w(-a -g)
|
275
|
+
assert_equal true, opts["arg"]
|
276
|
+
assert_equal false, opts["arg2"]
|
277
|
+
assert_equal true, opts["arg3"]
|
278
|
+
end
|
279
|
+
|
280
|
+
def test_short_autocreation_skips_dashes_and_numbers
|
281
|
+
@p.opt :arg # auto: a
|
282
|
+
@p.opt :arg_potato # auto: r
|
283
|
+
@p.opt :arg_muffin # auto: g
|
284
|
+
@p.opt :arg_daisy # auto: d (not _)!
|
285
|
+
@p.opt :arg_r2d2f # auto: f (not 2)!
|
286
|
+
|
287
|
+
opts = @p.parse %w(-f -d)
|
288
|
+
assert_equal true, opts[:arg_daisy]
|
289
|
+
assert_equal true, opts[:arg_r2d2f]
|
290
|
+
assert_equal false, opts[:arg]
|
291
|
+
assert_equal false, opts[:arg_potato]
|
292
|
+
assert_equal false, opts[:arg_muffin]
|
293
|
+
end
|
294
|
+
|
295
|
+
def test_short_autocreation_is_ok_with_running_out_of_chars
|
296
|
+
@p.opt :arg1 # auto: a
|
297
|
+
@p.opt :arg2 # auto: r
|
298
|
+
@p.opt :arg3 # auto: g
|
299
|
+
@p.opt :arg4 # auto: uh oh!
|
300
|
+
@p.parse []
|
301
|
+
end
|
302
|
+
|
303
|
+
def test_short_can_be_nothing
|
304
|
+
@p.opt "arg", "desc", :short => :none
|
305
|
+
@p.parse []
|
306
|
+
|
307
|
+
sio = StringIO.new "w"
|
308
|
+
@p.educate sio
|
309
|
+
assert sio.string =~ /--arg\s+desc/
|
310
|
+
|
311
|
+
assert_raises(CommandlineError) { @p.parse %w(-a) }
|
312
|
+
end
|
313
|
+
|
314
|
+
## two args can't have the same name
|
315
|
+
def test_conflicting_names_are_detected
|
316
|
+
@p.opt "goodarg"
|
317
|
+
assert_raises(ArgumentError) { @p.opt "goodarg" }
|
318
|
+
end
|
319
|
+
|
320
|
+
## two args can't have the same :long
|
321
|
+
def test_conflicting_longs_detected
|
322
|
+
@p.opt "goodarg", "desc", :long => "--goodarg"
|
323
|
+
assert_raises(ArgumentError) { @p.opt "badarg", "desc", :long => "--goodarg" }
|
324
|
+
end
|
325
|
+
|
326
|
+
## two args can't have the same :short
|
327
|
+
def test_conflicting_shorts_detected
|
328
|
+
@p.opt "goodarg", "desc", :short => "-g"
|
329
|
+
assert_raises(ArgumentError) { @p.opt "badarg", "desc", :short => "-g" }
|
330
|
+
end
|
331
|
+
|
332
|
+
## note: this behavior has changed in optimist 2.0!
|
333
|
+
def test_flag_parameters
|
334
|
+
@p.opt :defaultnone, "desc"
|
335
|
+
@p.opt :defaultfalse, "desc", :default => false
|
336
|
+
@p.opt :defaulttrue, "desc", :default => true
|
337
|
+
|
338
|
+
## default state
|
339
|
+
opts = @p.parse []
|
340
|
+
assert_equal false, opts[:defaultnone]
|
341
|
+
assert_equal false, opts[:defaultfalse]
|
342
|
+
assert_equal true, opts[:defaulttrue]
|
343
|
+
|
344
|
+
## specifying turns them on, regardless of default
|
345
|
+
opts = @p.parse %w(--defaultfalse --defaulttrue --defaultnone)
|
346
|
+
assert_equal true, opts[:defaultnone]
|
347
|
+
assert_equal true, opts[:defaultfalse]
|
348
|
+
assert_equal true, opts[:defaulttrue]
|
349
|
+
|
350
|
+
## using --no- form turns them off, regardless of default
|
351
|
+
opts = @p.parse %w(--no-defaultfalse --no-defaulttrue --no-defaultnone)
|
352
|
+
assert_equal false, opts[:defaultnone]
|
353
|
+
assert_equal false, opts[:defaultfalse]
|
354
|
+
assert_equal false, opts[:defaulttrue]
|
355
|
+
end
|
356
|
+
|
357
|
+
## note: this behavior has changed in optimist 2.0!
|
358
|
+
def test_flag_parameters_for_inverted_flags
|
359
|
+
@p.opt :no_default_none, "desc"
|
360
|
+
@p.opt :no_default_false, "desc", :default => false
|
361
|
+
@p.opt :no_default_true, "desc", :default => true
|
362
|
+
|
363
|
+
## default state
|
364
|
+
opts = @p.parse []
|
365
|
+
assert_equal false, opts[:no_default_none]
|
366
|
+
assert_equal false, opts[:no_default_false]
|
367
|
+
assert_equal true, opts[:no_default_true]
|
368
|
+
|
369
|
+
## specifying turns them all on, regardless of default
|
370
|
+
opts = @p.parse %w(--no-default-false --no-default-true --no-default-none)
|
371
|
+
assert_equal true, opts[:no_default_none]
|
372
|
+
assert_equal true, opts[:no_default_false]
|
373
|
+
assert_equal true, opts[:no_default_true]
|
374
|
+
|
375
|
+
## using dropped-no form turns them all off, regardless of default
|
376
|
+
opts = @p.parse %w(--default-false --default-true --default-none)
|
377
|
+
assert_equal false, opts[:no_default_none]
|
378
|
+
assert_equal false, opts[:no_default_false]
|
379
|
+
assert_equal false, opts[:no_default_true]
|
380
|
+
|
381
|
+
## disallow double negatives for reasons of sanity preservation
|
382
|
+
assert_raises(CommandlineError) { @p.parse %w(--no-no-default-true) }
|
383
|
+
end
|
384
|
+
|
385
|
+
def test_short_options_combine
|
386
|
+
@p.opt :arg1, "desc", :short => "a"
|
387
|
+
@p.opt :arg2, "desc", :short => "b"
|
388
|
+
@p.opt :arg3, "desc", :short => "c", :type => :int
|
389
|
+
|
390
|
+
opts = @p.parse %w(-a -b)
|
391
|
+
assert_equal true, opts[:arg1]
|
392
|
+
assert_equal true, opts[:arg2]
|
393
|
+
assert_equal nil, opts[:arg3]
|
394
|
+
|
395
|
+
opts = @p.parse %w(-ab)
|
396
|
+
assert_equal true, opts[:arg1]
|
397
|
+
assert_equal true, opts[:arg2]
|
398
|
+
assert_equal nil, opts[:arg3]
|
399
|
+
|
400
|
+
opts = @p.parse %w(-ac 4 -b)
|
401
|
+
assert_equal true, opts[:arg1]
|
402
|
+
assert_equal true, opts[:arg2]
|
403
|
+
assert_equal 4, opts[:arg3]
|
404
|
+
|
405
|
+
assert_raises(CommandlineError) { @p.parse %w(-cab 4) }
|
406
|
+
assert_raises(CommandlineError) { @p.parse %w(-cba 4) }
|
407
|
+
end
|
408
|
+
|
409
|
+
def test_doubledash_ends_option_processing
|
410
|
+
@p.opt :arg1, "desc", :short => "a", :default => 0
|
411
|
+
@p.opt :arg2, "desc", :short => "b", :default => 0
|
412
|
+
opts = @p.parse %w(-- -a 3 -b 2)
|
413
|
+
assert_equal opts[:arg1], 0
|
414
|
+
assert_equal opts[:arg2], 0
|
415
|
+
assert_equal %w(-a 3 -b 2), @p.leftovers
|
416
|
+
opts = @p.parse %w(-a 3 -- -b 2)
|
417
|
+
assert_equal opts[:arg1], 3
|
418
|
+
assert_equal opts[:arg2], 0
|
419
|
+
assert_equal %w(-b 2), @p.leftovers
|
420
|
+
opts = @p.parse %w(-a 3 -b 2 --)
|
421
|
+
assert_equal opts[:arg1], 3
|
422
|
+
assert_equal opts[:arg2], 2
|
423
|
+
assert_equal %w(), @p.leftovers
|
424
|
+
end
|
425
|
+
|
426
|
+
def test_wrap
|
427
|
+
assert_equal [""], @p.wrap("")
|
428
|
+
assert_equal ["a"], @p.wrap("a")
|
429
|
+
assert_equal ["one two", "three"], @p.wrap("one two three", :width => 8)
|
430
|
+
assert_equal ["one two three"], @p.wrap("one two three", :width => 80)
|
431
|
+
assert_equal ["one", "two", "three"], @p.wrap("one two three", :width => 3)
|
432
|
+
assert_equal ["onetwothree"], @p.wrap("onetwothree", :width => 3)
|
433
|
+
assert_equal [
|
434
|
+
"Test is an awesome program that does something very, very important.",
|
435
|
+
"",
|
436
|
+
"Usage:",
|
437
|
+
" test [options] <filenames>+",
|
438
|
+
"where [options] are:"], @p.wrap(<<EOM, :width => 100)
|
439
|
+
Test is an awesome program that does something very, very important.
|
440
|
+
|
441
|
+
Usage:
|
442
|
+
test [options] <filenames>+
|
443
|
+
where [options] are:
|
444
|
+
EOM
|
445
|
+
end
|
446
|
+
|
447
|
+
def test_multi_line_description
|
448
|
+
out = StringIO.new
|
449
|
+
@p.opt :arg, <<-EOM, :type => :int
|
450
|
+
This is an arg
|
451
|
+
with a multi-line description
|
452
|
+
EOM
|
453
|
+
@p.educate(out)
|
454
|
+
assert_equal <<-EOM, out.string
|
455
|
+
Options:
|
456
|
+
--arg=<i> This is an arg
|
457
|
+
with a multi-line description
|
458
|
+
EOM
|
459
|
+
end
|
460
|
+
|
461
|
+
def test_integer_formatting
|
462
|
+
@p.opt :arg, "desc", :type => :integer, :short => "i"
|
463
|
+
opts = @p.parse %w(-i 5)
|
464
|
+
assert_equal 5, opts[:arg]
|
465
|
+
end
|
466
|
+
|
467
|
+
def test_integer_formatting
|
468
|
+
@p.opt :arg, "desc", :type => :integer, :short => "i", :default => 3
|
469
|
+
opts = @p.parse %w(-i)
|
470
|
+
assert_equal 3, opts[:arg]
|
471
|
+
end
|
472
|
+
|
473
|
+
def test_floating_point_formatting
|
474
|
+
@p.opt :arg, "desc", :type => :float, :short => "f"
|
475
|
+
opts = @p.parse %w(-f 1)
|
476
|
+
assert_equal 1.0, opts[:arg]
|
477
|
+
opts = @p.parse %w(-f 1.0)
|
478
|
+
assert_equal 1.0, opts[:arg]
|
479
|
+
opts = @p.parse %w(-f 0.1)
|
480
|
+
assert_equal 0.1, opts[:arg]
|
481
|
+
opts = @p.parse %w(-f .1)
|
482
|
+
assert_equal 0.1, opts[:arg]
|
483
|
+
opts = @p.parse %w(-f .99999999999999999999)
|
484
|
+
assert_equal 1.0, opts[:arg]
|
485
|
+
opts = @p.parse %w(-f -1)
|
486
|
+
assert_equal(-1.0, opts[:arg])
|
487
|
+
opts = @p.parse %w(-f -1.0)
|
488
|
+
assert_equal(-1.0, opts[:arg])
|
489
|
+
opts = @p.parse %w(-f -0.1)
|
490
|
+
assert_equal(-0.1, opts[:arg])
|
491
|
+
opts = @p.parse %w(-f -.1)
|
492
|
+
assert_equal(-0.1, opts[:arg])
|
493
|
+
assert_raises(CommandlineError) { @p.parse %w(-f a) }
|
494
|
+
assert_raises(CommandlineError) { @p.parse %w(-f 1a) }
|
495
|
+
assert_raises(CommandlineError) { @p.parse %w(-f 1.a) }
|
496
|
+
assert_raises(CommandlineError) { @p.parse %w(-f a.1) }
|
497
|
+
assert_raises(CommandlineError) { @p.parse %w(-f 1.0.0) }
|
498
|
+
assert_raises(CommandlineError) { @p.parse %w(-f .) }
|
499
|
+
assert_raises(CommandlineError) { @p.parse %w(-f -.) }
|
500
|
+
end
|
501
|
+
|
502
|
+
def test_floating_point_formatting_default
|
503
|
+
@p.opt :arg, "desc", :type => :float, :short => "f", :default => 5.5
|
504
|
+
opts = @p.parse %w(-f)
|
505
|
+
assert_equal 5.5, opts[:arg]
|
506
|
+
end
|
507
|
+
|
508
|
+
def test_date_formatting
|
509
|
+
@p.opt :arg, "desc", :type => :date, :short => 'd'
|
510
|
+
opts = @p.parse(['-d', 'Jan 4, 2007'])
|
511
|
+
assert_equal Date.civil(2007, 1, 4), opts[:arg]
|
512
|
+
opts = @p.parse(['-d', 'today'])
|
513
|
+
assert_equal Date.today, opts[:arg]
|
514
|
+
end
|
515
|
+
|
516
|
+
def test_short_options_cant_be_numeric
|
517
|
+
assert_raises(ArgumentError) { @p.opt :arg, "desc", :short => "-1" }
|
518
|
+
@p.opt :a1b, "desc"
|
519
|
+
@p.opt :a2b, "desc"
|
520
|
+
assert @p.specs[:a2b].short.to_i == 0
|
521
|
+
end
|
522
|
+
|
523
|
+
def test_short_options_can_be_weird
|
524
|
+
@p.opt :arg1, "desc", :short => "#"
|
525
|
+
@p.opt :arg2, "desc", :short => "."
|
526
|
+
assert_raises(ArgumentError) { @p.opt :arg3, "desc", :short => "-" }
|
527
|
+
end
|
528
|
+
|
529
|
+
def test_options_cant_be_set_multiple_times_if_not_specified
|
530
|
+
@p.opt :arg, "desc", :short => "-x"
|
531
|
+
@p.parse %w(-x)
|
532
|
+
assert_raises(CommandlineError) { @p.parse %w(-x -x) }
|
533
|
+
assert_raises(CommandlineError) { @p.parse %w(-xx) }
|
534
|
+
end
|
535
|
+
|
536
|
+
def test_options_can_be_set_multiple_times_if_specified
|
537
|
+
@p.opt :arg, "desc", :short => "-x", :multi => true
|
538
|
+
@p.parse %w(-x)
|
539
|
+
@p.parse %w(-x -x)
|
540
|
+
@p.parse %w(-xx)
|
541
|
+
end
|
542
|
+
|
543
|
+
def test_short_options_with_multiple_options
|
544
|
+
@p.opt :xarg, "desc", :short => "-x", :type => String, :multi => true
|
545
|
+
opts = @p.parse %w(-x a -x b)
|
546
|
+
assert_equal %w(a b), opts[:xarg]
|
547
|
+
assert_equal [], @p.leftovers
|
548
|
+
end
|
549
|
+
|
550
|
+
def test_short_options_with_multiple_options_does_not_affect_flags_type
|
551
|
+
@p.opt :xarg, "desc", :short => "-x", :type => :flag, :multi => true
|
552
|
+
|
553
|
+
opts = @p.parse %w(-x a)
|
554
|
+
assert_equal true, opts[:xarg]
|
555
|
+
assert_equal %w(a), @p.leftovers
|
556
|
+
|
557
|
+
opts = @p.parse %w(-x a -x b)
|
558
|
+
assert_equal true, opts[:xarg]
|
559
|
+
assert_equal %w(a b), @p.leftovers
|
560
|
+
|
561
|
+
opts = @p.parse %w(-xx a -x b)
|
562
|
+
assert_equal true, opts[:xarg]
|
563
|
+
assert_equal %w(a b), @p.leftovers
|
564
|
+
end
|
565
|
+
|
566
|
+
def test_short_options_with_multiple_arguments
|
567
|
+
@p.opt :xarg, "desc", :type => :ints
|
568
|
+
opts = @p.parse %w(-x 3 4 0)
|
569
|
+
assert_equal [3, 4, 0], opts[:xarg]
|
570
|
+
assert_equal [], @p.leftovers
|
571
|
+
|
572
|
+
@p.opt :yarg, "desc", :type => :floats
|
573
|
+
opts = @p.parse %w(-y 3.14 4.21 0.66)
|
574
|
+
assert_equal [3.14, 4.21, 0.66], opts[:yarg]
|
575
|
+
assert_equal [], @p.leftovers
|
576
|
+
|
577
|
+
@p.opt :zarg, "desc", :type => :strings
|
578
|
+
opts = @p.parse %w(-z a b c)
|
579
|
+
assert_equal %w(a b c), opts[:zarg]
|
580
|
+
assert_equal [], @p.leftovers
|
581
|
+
end
|
582
|
+
|
583
|
+
def test_short_options_with_multiple_options_and_arguments
|
584
|
+
@p.opt :xarg, "desc", :type => :ints, :multi => true
|
585
|
+
opts = @p.parse %w(-x 3 4 5 -x 6 7)
|
586
|
+
assert_equal [[3, 4, 5], [6, 7]], opts[:xarg]
|
587
|
+
assert_equal [], @p.leftovers
|
588
|
+
|
589
|
+
@p.opt :yarg, "desc", :type => :floats, :multi => true
|
590
|
+
opts = @p.parse %w(-y 3.14 4.21 5.66 -y 6.99 7.01)
|
591
|
+
assert_equal [[3.14, 4.21, 5.66], [6.99, 7.01]], opts[:yarg]
|
592
|
+
assert_equal [], @p.leftovers
|
593
|
+
|
594
|
+
@p.opt :zarg, "desc", :type => :strings, :multi => true
|
595
|
+
opts = @p.parse %w(-z a b c -z d e)
|
596
|
+
assert_equal [%w(a b c), %w(d e)], opts[:zarg]
|
597
|
+
assert_equal [], @p.leftovers
|
598
|
+
end
|
599
|
+
|
600
|
+
def test_combined_short_options_with_multiple_arguments
|
601
|
+
@p.opt :arg1, "desc", :short => "a"
|
602
|
+
@p.opt :arg2, "desc", :short => "b"
|
603
|
+
@p.opt :arg3, "desc", :short => "c", :type => :ints
|
604
|
+
@p.opt :arg4, "desc", :short => "d", :type => :floats
|
605
|
+
|
606
|
+
opts = @p.parse %w(-abc 4 6 9)
|
607
|
+
assert_equal true, opts[:arg1]
|
608
|
+
assert_equal true, opts[:arg2]
|
609
|
+
assert_equal [4, 6, 9], opts[:arg3]
|
610
|
+
|
611
|
+
opts = @p.parse %w(-ac 4 6 9 -bd 3.14 2.41)
|
612
|
+
assert_equal true, opts[:arg1]
|
613
|
+
assert_equal true, opts[:arg2]
|
614
|
+
assert_equal [4, 6, 9], opts[:arg3]
|
615
|
+
assert_equal [3.14, 2.41], opts[:arg4]
|
616
|
+
|
617
|
+
assert_raises(CommandlineError) { opts = @p.parse %w(-abcd 3.14 2.41) }
|
618
|
+
end
|
619
|
+
|
620
|
+
def test_long_options_with_multiple_options
|
621
|
+
@p.opt :xarg, "desc", :type => String, :multi => true
|
622
|
+
opts = @p.parse %w(--xarg=a --xarg=b)
|
623
|
+
assert_equal %w(a b), opts[:xarg]
|
624
|
+
assert_equal [], @p.leftovers
|
625
|
+
opts = @p.parse %w(--xarg a --xarg b)
|
626
|
+
assert_equal %w(a b), opts[:xarg]
|
627
|
+
assert_equal [], @p.leftovers
|
628
|
+
end
|
629
|
+
|
630
|
+
def test_long_options_with_multiple_arguments
|
631
|
+
@p.opt :xarg, "desc", :type => :ints
|
632
|
+
opts = @p.parse %w(--xarg 3 2 5)
|
633
|
+
assert_equal [3, 2, 5], opts[:xarg]
|
634
|
+
assert_equal [], @p.leftovers
|
635
|
+
opts = @p.parse %w(--xarg=3)
|
636
|
+
assert_equal [3], opts[:xarg]
|
637
|
+
assert_equal [], @p.leftovers
|
638
|
+
|
639
|
+
@p.opt :yarg, "desc", :type => :floats
|
640
|
+
opts = @p.parse %w(--yarg 3.14 2.41 5.66)
|
641
|
+
assert_equal [3.14, 2.41, 5.66], opts[:yarg]
|
642
|
+
assert_equal [], @p.leftovers
|
643
|
+
opts = @p.parse %w(--yarg=3.14)
|
644
|
+
assert_equal [3.14], opts[:yarg]
|
645
|
+
assert_equal [], @p.leftovers
|
646
|
+
|
647
|
+
@p.opt :zarg, "desc", :type => :strings
|
648
|
+
opts = @p.parse %w(--zarg a b c)
|
649
|
+
assert_equal %w(a b c), opts[:zarg]
|
650
|
+
assert_equal [], @p.leftovers
|
651
|
+
opts = @p.parse %w(--zarg=a)
|
652
|
+
assert_equal %w(a), opts[:zarg]
|
653
|
+
assert_equal [], @p.leftovers
|
654
|
+
end
|
655
|
+
|
656
|
+
def test_long_options_with_multiple_options_and_arguments
|
657
|
+
@p.opt :xarg, "desc", :type => :ints, :multi => true
|
658
|
+
opts = @p.parse %w(--xarg 3 2 5 --xarg 2 1)
|
659
|
+
assert_equal [[3, 2, 5], [2, 1]], opts[:xarg]
|
660
|
+
assert_equal [], @p.leftovers
|
661
|
+
opts = @p.parse %w(--xarg=3 --xarg=2)
|
662
|
+
assert_equal [[3], [2]], opts[:xarg]
|
663
|
+
assert_equal [], @p.leftovers
|
664
|
+
|
665
|
+
@p.opt :yarg, "desc", :type => :floats, :multi => true
|
666
|
+
opts = @p.parse %w(--yarg 3.14 2.72 5 --yarg 2.41 1.41)
|
667
|
+
assert_equal [[3.14, 2.72, 5], [2.41, 1.41]], opts[:yarg]
|
668
|
+
assert_equal [], @p.leftovers
|
669
|
+
opts = @p.parse %w(--yarg=3.14 --yarg=2.41)
|
670
|
+
assert_equal [[3.14], [2.41]], opts[:yarg]
|
671
|
+
assert_equal [], @p.leftovers
|
672
|
+
|
673
|
+
@p.opt :zarg, "desc", :type => :strings, :multi => true
|
674
|
+
opts = @p.parse %w(--zarg a b c --zarg d e)
|
675
|
+
assert_equal [%w(a b c), %w(d e)], opts[:zarg]
|
676
|
+
assert_equal [], @p.leftovers
|
677
|
+
opts = @p.parse %w(--zarg=a --zarg=d)
|
678
|
+
assert_equal [%w(a), %w(d)], opts[:zarg]
|
679
|
+
assert_equal [], @p.leftovers
|
680
|
+
end
|
681
|
+
|
682
|
+
def test_long_options_also_take_equals
|
683
|
+
@p.opt :arg, "desc", :long => "arg", :type => String, :default => "hello"
|
684
|
+
opts = @p.parse %w()
|
685
|
+
assert_equal "hello", opts[:arg]
|
686
|
+
opts = @p.parse %w(--arg goat)
|
687
|
+
assert_equal "goat", opts[:arg]
|
688
|
+
opts = @p.parse %w(--arg=goat)
|
689
|
+
assert_equal "goat", opts[:arg]
|
690
|
+
## actually, this next one is valid. empty string for --arg, and goat as a
|
691
|
+
## leftover.
|
692
|
+
## assert_raises(CommandlineError) { opts = @p.parse %w(--arg= goat) }
|
693
|
+
end
|
694
|
+
|
695
|
+
def test_auto_generated_long_names_convert_underscores_to_hyphens
|
696
|
+
@p.opt :hello_there
|
697
|
+
assert_equal "hello-there", @p.specs[:hello_there].long
|
698
|
+
end
|
699
|
+
|
700
|
+
def test_arguments_passed_through_block
|
701
|
+
@goat = 3
|
702
|
+
boat = 4
|
703
|
+
Parser.new(@goat) do |goat|
|
704
|
+
boat = goat
|
705
|
+
end
|
706
|
+
assert_equal @goat, boat
|
707
|
+
end
|
708
|
+
|
709
|
+
def test_version_and_help_override_errors
|
710
|
+
@p.opt :asdf, "desc", :type => String
|
711
|
+
@p.version "version"
|
712
|
+
@p.parse %w(--asdf goat)
|
713
|
+
assert_raises(CommandlineError) { @p.parse %w(--asdf) }
|
714
|
+
assert_raises(HelpNeeded) { @p.parse %w(--asdf --help) }
|
715
|
+
assert_raises(VersionNeeded) { @p.parse %w(--asdf --version) }
|
716
|
+
end
|
717
|
+
|
718
|
+
def test_conflicts
|
719
|
+
@p.opt :one
|
720
|
+
assert_raises(ArgumentError) { @p.conflicts :one, :two }
|
721
|
+
@p.opt :two
|
722
|
+
@p.conflicts :one, :two
|
723
|
+
@p.parse %w(--one)
|
724
|
+
@p.parse %w(--two)
|
725
|
+
assert_raises(CommandlineError) { @p.parse %w(--one --two) }
|
726
|
+
|
727
|
+
@p.opt :hello
|
728
|
+
@p.opt :yellow
|
729
|
+
@p.opt :mellow
|
730
|
+
@p.opt :jello
|
731
|
+
@p.conflicts :hello, :yellow, :mellow, :jello
|
732
|
+
assert_raises(CommandlineError) { @p.parse %w(--hello --yellow --mellow --jello) }
|
733
|
+
assert_raises(CommandlineError) { @p.parse %w(--hello --mellow --jello) }
|
734
|
+
assert_raises(CommandlineError) { @p.parse %w(--hello --jello) }
|
735
|
+
|
736
|
+
@p.parse %w(--hello)
|
737
|
+
@p.parse %w(--jello)
|
738
|
+
@p.parse %w(--yellow)
|
739
|
+
@p.parse %w(--mellow)
|
740
|
+
|
741
|
+
@p.parse %w(--mellow --one)
|
742
|
+
@p.parse %w(--mellow --two)
|
743
|
+
|
744
|
+
assert_raises(CommandlineError) { @p.parse %w(--mellow --two --jello) }
|
745
|
+
assert_raises(CommandlineError) { @p.parse %w(--one --mellow --two --jello) }
|
746
|
+
end
|
747
|
+
|
748
|
+
def test_conflict_error_messages
|
749
|
+
@p.opt :one
|
750
|
+
@p.opt "two"
|
751
|
+
@p.conflicts :one, "two"
|
752
|
+
|
753
|
+
assert_raises(CommandlineError, /--one.*--two/) { @p.parse %w(--one --two) }
|
754
|
+
end
|
755
|
+
|
756
|
+
def test_depends
|
757
|
+
@p.opt :one
|
758
|
+
assert_raises(ArgumentError) { @p.depends :one, :two }
|
759
|
+
@p.opt :two
|
760
|
+
@p.depends :one, :two
|
761
|
+
@p.parse %w(--one --two)
|
762
|
+
assert_raises(CommandlineError) { @p.parse %w(--one) }
|
763
|
+
assert_raises(CommandlineError) { @p.parse %w(--two) }
|
764
|
+
|
765
|
+
@p.opt :hello
|
766
|
+
@p.opt :yellow
|
767
|
+
@p.opt :mellow
|
768
|
+
@p.opt :jello
|
769
|
+
@p.depends :hello, :yellow, :mellow, :jello
|
770
|
+
@p.parse %w(--hello --yellow --mellow --jello)
|
771
|
+
assert_raises(CommandlineError) { @p.parse %w(--hello --mellow --jello) }
|
772
|
+
assert_raises(CommandlineError) { @p.parse %w(--hello --jello) }
|
773
|
+
|
774
|
+
assert_raises(CommandlineError) { @p.parse %w(--hello) }
|
775
|
+
assert_raises(CommandlineError) { @p.parse %w(--mellow) }
|
776
|
+
|
777
|
+
@p.parse %w(--hello --yellow --mellow --jello --one --two)
|
778
|
+
@p.parse %w(--hello --yellow --mellow --jello --one --two a b c)
|
779
|
+
|
780
|
+
assert_raises(CommandlineError) { @p.parse %w(--mellow --two --jello --one) }
|
781
|
+
end
|
782
|
+
|
783
|
+
def test_depend_error_messages
|
784
|
+
@p.opt :one
|
785
|
+
@p.opt "two"
|
786
|
+
@p.depends :one, "two"
|
787
|
+
|
788
|
+
@p.parse %w(--one --two)
|
789
|
+
|
790
|
+
assert_raises(CommandlineError, /--one.*--two/) { @p.parse %w(--one) }
|
791
|
+
assert_raises(CommandlineError, /--one.*--two/) { @p.parse %w(--two) }
|
792
|
+
end
|
793
|
+
|
794
|
+
## courtesy neill zero
|
795
|
+
def test_two_required_one_missing_accuses_correctly
|
796
|
+
@p.opt "arg1", "desc1", :required => true
|
797
|
+
@p.opt "arg2", "desc2", :required => true
|
798
|
+
|
799
|
+
assert_raises(CommandlineError, /arg2/) { @p.parse(%w(--arg1)) }
|
800
|
+
assert_raises(CommandlineError, /arg1/) { @p.parse(%w(--arg2)) }
|
801
|
+
@p.parse(%w(--arg1 --arg2))
|
802
|
+
end
|
803
|
+
|
804
|
+
def test_stopwords_mixed
|
805
|
+
@p.opt "arg1", :default => false
|
806
|
+
@p.opt "arg2", :default => false
|
807
|
+
@p.stop_on %w(happy sad)
|
808
|
+
|
809
|
+
opts = @p.parse %w(--arg1 happy --arg2)
|
810
|
+
assert_equal true, opts["arg1"]
|
811
|
+
assert_equal false, opts["arg2"]
|
812
|
+
|
813
|
+
## restart parsing
|
814
|
+
@p.leftovers.shift
|
815
|
+
opts = @p.parse @p.leftovers
|
816
|
+
assert_equal false, opts["arg1"]
|
817
|
+
assert_equal true, opts["arg2"]
|
818
|
+
end
|
819
|
+
|
820
|
+
def test_stopwords_no_stopwords
|
821
|
+
@p.opt "arg1", :default => false
|
822
|
+
@p.opt "arg2", :default => false
|
823
|
+
@p.stop_on %w(happy sad)
|
824
|
+
|
825
|
+
opts = @p.parse %w(--arg1 --arg2)
|
826
|
+
assert_equal true, opts["arg1"]
|
827
|
+
assert_equal true, opts["arg2"]
|
828
|
+
|
829
|
+
## restart parsing
|
830
|
+
@p.leftovers.shift
|
831
|
+
opts = @p.parse @p.leftovers
|
832
|
+
assert_equal false, opts["arg1"]
|
833
|
+
assert_equal false, opts["arg2"]
|
834
|
+
end
|
835
|
+
|
836
|
+
def test_stopwords_multiple_stopwords
|
837
|
+
@p.opt "arg1", :default => false
|
838
|
+
@p.opt "arg2", :default => false
|
839
|
+
@p.stop_on %w(happy sad)
|
840
|
+
|
841
|
+
opts = @p.parse %w(happy sad --arg1 --arg2)
|
842
|
+
assert_equal false, opts["arg1"]
|
843
|
+
assert_equal false, opts["arg2"]
|
844
|
+
|
845
|
+
## restart parsing
|
846
|
+
@p.leftovers.shift
|
847
|
+
opts = @p.parse @p.leftovers
|
848
|
+
assert_equal false, opts["arg1"]
|
849
|
+
assert_equal false, opts["arg2"]
|
850
|
+
|
851
|
+
## restart parsing again
|
852
|
+
@p.leftovers.shift
|
853
|
+
opts = @p.parse @p.leftovers
|
854
|
+
assert_equal true, opts["arg1"]
|
855
|
+
assert_equal true, opts["arg2"]
|
856
|
+
end
|
857
|
+
|
858
|
+
def test_stopwords_with_short_args
|
859
|
+
@p.opt :global_option, "This is a global option", :short => "-g"
|
860
|
+
@p.stop_on %w(sub-command-1 sub-command-2)
|
861
|
+
|
862
|
+
global_opts = @p.parse %w(-g sub-command-1 -c)
|
863
|
+
cmd = @p.leftovers.shift
|
864
|
+
|
865
|
+
@q = Parser.new
|
866
|
+
@q.opt :cmd_option, "This is an option only for the subcommand", :short => "-c"
|
867
|
+
cmd_opts = @q.parse @p.leftovers
|
868
|
+
|
869
|
+
assert_equal true, global_opts[:global_option]
|
870
|
+
assert_nil global_opts[:cmd_option]
|
871
|
+
|
872
|
+
assert_equal true, cmd_opts[:cmd_option]
|
873
|
+
assert_nil cmd_opts[:global_option]
|
874
|
+
|
875
|
+
assert_equal cmd, "sub-command-1"
|
876
|
+
assert_equal @q.leftovers, []
|
877
|
+
end
|
878
|
+
|
879
|
+
def test_unknown_subcommand
|
880
|
+
@p.opt :global_flag, "Global flag", :short => "-g", :type => :flag
|
881
|
+
@p.opt :global_param, "Global parameter", :short => "-p", :default => 5
|
882
|
+
@p.stop_on_unknown
|
883
|
+
|
884
|
+
expected_opts = { :global_flag => true, :help => false, :global_param => 5, :global_flag_given => true }
|
885
|
+
expected_leftovers = [ "my_subcommand", "-c" ]
|
886
|
+
|
887
|
+
assert_parses_correctly @p, %w(--global-flag my_subcommand -c), \
|
888
|
+
expected_opts, expected_leftovers
|
889
|
+
assert_parses_correctly @p, %w(-g my_subcommand -c), \
|
890
|
+
expected_opts, expected_leftovers
|
891
|
+
|
892
|
+
expected_opts = { :global_flag => false, :help => false, :global_param => 5, :global_param_given => true }
|
893
|
+
expected_leftovers = [ "my_subcommand", "-c" ]
|
894
|
+
|
895
|
+
assert_parses_correctly @p, %w(-p 5 my_subcommand -c), \
|
896
|
+
expected_opts, expected_leftovers
|
897
|
+
assert_parses_correctly @p, %w(--global-param 5 my_subcommand -c), \
|
898
|
+
expected_opts, expected_leftovers
|
899
|
+
end
|
900
|
+
|
901
|
+
def test_alternate_args
|
902
|
+
args = %w(-a -b -c)
|
903
|
+
|
904
|
+
opts = ::Optimist.options(args) do
|
905
|
+
opt :alpher, "Ralph Alpher", :short => "-a"
|
906
|
+
opt :bethe, "Hans Bethe", :short => "-b"
|
907
|
+
opt :gamow, "George Gamow", :short => "-c"
|
908
|
+
end
|
909
|
+
|
910
|
+
physicists_with_humor = [:alpher, :bethe, :gamow]
|
911
|
+
physicists_with_humor.each do |physicist|
|
912
|
+
assert_equal true, opts[physicist]
|
913
|
+
end
|
914
|
+
end
|
915
|
+
|
916
|
+
def test_date_arg_type
|
917
|
+
temp = Date.new
|
918
|
+
@p.opt :arg, 'desc', :type => :date
|
919
|
+
@p.opt :arg2, 'desc', :type => Date
|
920
|
+
@p.opt :arg3, 'desc', :default => temp
|
921
|
+
|
922
|
+
opts = @p.parse []
|
923
|
+
assert_equal temp, opts[:arg3]
|
924
|
+
|
925
|
+
opts = @p.parse %w(--arg 5/1/2010)
|
926
|
+
assert_kind_of Date, opts[:arg]
|
927
|
+
assert_equal Date.new(2010, 5, 1), opts[:arg]
|
928
|
+
|
929
|
+
opts = @p.parse %w(--arg2 5/1/2010)
|
930
|
+
assert_kind_of Date, opts[:arg2]
|
931
|
+
assert_equal Date.new(2010, 5, 1), opts[:arg2]
|
932
|
+
|
933
|
+
opts = @p.parse %w(--arg3)
|
934
|
+
assert_equal temp, opts[:arg3]
|
935
|
+
end
|
936
|
+
|
937
|
+
def test_unknown_arg_class_type
|
938
|
+
assert_raises ArgumentError do
|
939
|
+
@p.opt :arg, 'desc', :type => Hash
|
940
|
+
end
|
941
|
+
end
|
942
|
+
|
943
|
+
def test_io_arg_type
|
944
|
+
@p.opt :arg, "desc", :type => :io
|
945
|
+
@p.opt :arg2, "desc", :type => IO
|
946
|
+
@p.opt :arg3, "desc", :default => $stdout
|
947
|
+
|
948
|
+
opts = @p.parse []
|
949
|
+
assert_equal $stdout, opts[:arg3]
|
950
|
+
|
951
|
+
opts = @p.parse %w(--arg /dev/null)
|
952
|
+
assert_kind_of File, opts[:arg]
|
953
|
+
assert_equal "/dev/null", opts[:arg].path
|
954
|
+
|
955
|
+
#TODO: move to mocks
|
956
|
+
#opts = @p.parse %w(--arg2 http://google.com/)
|
957
|
+
#assert_kind_of StringIO, opts[:arg2]
|
958
|
+
|
959
|
+
opts = @p.parse %w(--arg3 stdin)
|
960
|
+
assert_equal $stdin, opts[:arg3]
|
961
|
+
|
962
|
+
assert_raises(CommandlineError) { opts = @p.parse %w(--arg /fdasfasef/fessafef/asdfasdfa/fesasf) }
|
963
|
+
end
|
964
|
+
|
965
|
+
def test_openstruct_style_access
|
966
|
+
@p.opt "arg1", "desc", :type => :int
|
967
|
+
@p.opt :arg2, "desc", :type => :int
|
968
|
+
|
969
|
+
opts = @p.parse(%w(--arg1 3 --arg2 4))
|
970
|
+
|
971
|
+
opts.arg1
|
972
|
+
opts.arg2
|
973
|
+
assert_equal 3, opts.arg1
|
974
|
+
assert_equal 4, opts.arg2
|
975
|
+
end
|
976
|
+
|
977
|
+
def test_multi_args_autobox_defaults
|
978
|
+
@p.opt :arg1, "desc", :default => "hello", :multi => true
|
979
|
+
@p.opt :arg2, "desc", :default => ["hello"], :multi => true
|
980
|
+
|
981
|
+
opts = @p.parse []
|
982
|
+
assert_equal ["hello"], opts[:arg1]
|
983
|
+
assert_equal ["hello"], opts[:arg2]
|
984
|
+
|
985
|
+
opts = @p.parse %w(--arg1 hello)
|
986
|
+
assert_equal ["hello"], opts[:arg1]
|
987
|
+
assert_equal ["hello"], opts[:arg2]
|
988
|
+
|
989
|
+
opts = @p.parse %w(--arg1 hello --arg1 there)
|
990
|
+
assert_equal ["hello", "there"], opts[:arg1]
|
991
|
+
end
|
992
|
+
|
993
|
+
def test_ambigious_multi_plus_array_default_resolved_as_specified_by_documentation
|
994
|
+
@p.opt :arg1, "desc", :default => ["potato"], :multi => true
|
995
|
+
@p.opt :arg2, "desc", :default => ["potato"], :multi => true, :type => :strings
|
996
|
+
@p.opt :arg3, "desc", :default => ["potato"]
|
997
|
+
@p.opt :arg4, "desc", :default => ["potato", "rhubarb"], :short => :none, :multi => true
|
998
|
+
|
999
|
+
## arg1 should be multi-occurring but not multi-valued
|
1000
|
+
opts = @p.parse %w(--arg1 one two)
|
1001
|
+
assert_equal ["one"], opts[:arg1]
|
1002
|
+
assert_equal ["two"], @p.leftovers
|
1003
|
+
|
1004
|
+
opts = @p.parse %w(--arg1 one --arg1 two)
|
1005
|
+
assert_equal ["one", "two"], opts[:arg1]
|
1006
|
+
assert_equal [], @p.leftovers
|
1007
|
+
|
1008
|
+
## arg2 should be multi-valued and multi-occurring
|
1009
|
+
opts = @p.parse %w(--arg2 one two)
|
1010
|
+
assert_equal [["one", "two"]], opts[:arg2]
|
1011
|
+
assert_equal [], @p.leftovers
|
1012
|
+
|
1013
|
+
## arg3 should be multi-valued but not multi-occurring
|
1014
|
+
opts = @p.parse %w(--arg3 one two)
|
1015
|
+
assert_equal ["one", "two"], opts[:arg3]
|
1016
|
+
assert_equal [], @p.leftovers
|
1017
|
+
|
1018
|
+
## arg4 should be multi-valued but not multi-occurring
|
1019
|
+
opts = @p.parse %w()
|
1020
|
+
assert_equal ["potato", "rhubarb"], opts[:arg4]
|
1021
|
+
end
|
1022
|
+
|
1023
|
+
def test_given_keys
|
1024
|
+
@p.opt :arg1
|
1025
|
+
@p.opt :arg2
|
1026
|
+
|
1027
|
+
opts = @p.parse %w(--arg1)
|
1028
|
+
assert opts[:arg1_given]
|
1029
|
+
assert !opts[:arg2_given]
|
1030
|
+
|
1031
|
+
opts = @p.parse %w(--arg2)
|
1032
|
+
assert !opts[:arg1_given]
|
1033
|
+
assert opts[:arg2_given]
|
1034
|
+
|
1035
|
+
opts = @p.parse []
|
1036
|
+
assert !opts[:arg1_given]
|
1037
|
+
assert !opts[:arg2_given]
|
1038
|
+
|
1039
|
+
opts = @p.parse %w(--arg1 --arg2)
|
1040
|
+
assert opts[:arg1_given]
|
1041
|
+
assert opts[:arg2_given]
|
1042
|
+
end
|
1043
|
+
|
1044
|
+
def test_default_shorts_assigned_only_after_user_shorts
|
1045
|
+
@p.opt :aab, "aaa" # should be assigned to -b
|
1046
|
+
@p.opt :ccd, "bbb" # should be assigned to -d
|
1047
|
+
@p.opt :user1, "user1", :short => 'a'
|
1048
|
+
@p.opt :user2, "user2", :short => 'c'
|
1049
|
+
|
1050
|
+
opts = @p.parse %w(-a -b)
|
1051
|
+
assert opts[:user1]
|
1052
|
+
assert !opts[:user2]
|
1053
|
+
assert opts[:aab]
|
1054
|
+
assert !opts[:ccd]
|
1055
|
+
|
1056
|
+
opts = @p.parse %w(-c -d)
|
1057
|
+
assert !opts[:user1]
|
1058
|
+
assert opts[:user2]
|
1059
|
+
assert !opts[:aab]
|
1060
|
+
assert opts[:ccd]
|
1061
|
+
end
|
1062
|
+
|
1063
|
+
def test_accepts_arguments_with_spaces
|
1064
|
+
@p.opt :arg1, "arg", :type => String
|
1065
|
+
@p.opt :arg2, "arg2", :type => String
|
1066
|
+
|
1067
|
+
opts = @p.parse ["--arg1", "hello there", "--arg2=hello there"]
|
1068
|
+
assert_equal "hello there", opts[:arg1]
|
1069
|
+
assert_equal "hello there", opts[:arg2]
|
1070
|
+
assert_equal 0, @p.leftovers.size
|
1071
|
+
end
|
1072
|
+
|
1073
|
+
def test_multi_args_default_to_empty_array
|
1074
|
+
@p.opt :arg1, "arg", :multi => true
|
1075
|
+
opts = @p.parse []
|
1076
|
+
assert_equal [], opts[:arg1]
|
1077
|
+
end
|
1078
|
+
|
1079
|
+
def test_simple_interface_handles_help
|
1080
|
+
assert_stdout(/Options:/) do
|
1081
|
+
assert_raises(SystemExit) do
|
1082
|
+
::Optimist::options(%w(-h)) do
|
1083
|
+
opt :potato
|
1084
|
+
end
|
1085
|
+
end
|
1086
|
+
end
|
1087
|
+
|
1088
|
+
# ensure regular status is returned
|
1089
|
+
|
1090
|
+
assert_stdout do
|
1091
|
+
begin
|
1092
|
+
::Optimist::options(%w(-h)) do
|
1093
|
+
opt :potato
|
1094
|
+
end
|
1095
|
+
rescue SystemExit => e
|
1096
|
+
assert_equal 0, e.status
|
1097
|
+
end
|
1098
|
+
end
|
1099
|
+
end
|
1100
|
+
|
1101
|
+
def test_simple_interface_handles_version
|
1102
|
+
assert_stdout(/1.2/) do
|
1103
|
+
assert_raises(SystemExit) do
|
1104
|
+
::Optimist::options(%w(-v)) do
|
1105
|
+
version "1.2"
|
1106
|
+
opt :potato
|
1107
|
+
end
|
1108
|
+
end
|
1109
|
+
end
|
1110
|
+
end
|
1111
|
+
|
1112
|
+
def test_simple_interface_handles_regular_usage
|
1113
|
+
opts = ::Optimist::options(%w(--potato)) do
|
1114
|
+
opt :potato
|
1115
|
+
end
|
1116
|
+
assert opts[:potato]
|
1117
|
+
end
|
1118
|
+
|
1119
|
+
def test_simple_interface_handles_die
|
1120
|
+
assert_stderr do
|
1121
|
+
::Optimist::options(%w(--potato)) do
|
1122
|
+
opt :potato
|
1123
|
+
end
|
1124
|
+
assert_raises(SystemExit) { ::Optimist::die :potato, "is invalid" }
|
1125
|
+
end
|
1126
|
+
end
|
1127
|
+
|
1128
|
+
def test_simple_interface_handles_die_without_message
|
1129
|
+
assert_stderr(/Error:/) do
|
1130
|
+
::Optimist::options(%w(--potato)) do
|
1131
|
+
opt :potato
|
1132
|
+
end
|
1133
|
+
assert_raises(SystemExit) { ::Optimist::die :potato }
|
1134
|
+
end
|
1135
|
+
end
|
1136
|
+
|
1137
|
+
def test_invalid_option_with_simple_interface
|
1138
|
+
assert_stderr do
|
1139
|
+
assert_raises(SystemExit) do
|
1140
|
+
::Optimist.options(%w(--potato))
|
1141
|
+
end
|
1142
|
+
end
|
1143
|
+
|
1144
|
+
assert_stderr do
|
1145
|
+
begin
|
1146
|
+
::Optimist.options(%w(--potato))
|
1147
|
+
rescue SystemExit => e
|
1148
|
+
assert_equal(-1, e.status)
|
1149
|
+
end
|
1150
|
+
end
|
1151
|
+
end
|
1152
|
+
|
1153
|
+
def test_supports_callback_inline
|
1154
|
+
assert_raises(RuntimeError, "good") do
|
1155
|
+
@p.opt :cb1 do |vals|
|
1156
|
+
raise "good"
|
1157
|
+
end
|
1158
|
+
@p.parse(%w(--cb1))
|
1159
|
+
end
|
1160
|
+
end
|
1161
|
+
|
1162
|
+
def test_supports_callback_param
|
1163
|
+
assert_raises(RuntimeError, "good") do
|
1164
|
+
@p.opt :cb1, "with callback", :callback => lambda { |vals| raise "good" }
|
1165
|
+
@p.parse(%w(--cb1))
|
1166
|
+
end
|
1167
|
+
end
|
1168
|
+
|
1169
|
+
def test_ignore_invalid_options
|
1170
|
+
@p.opt :arg1, "desc", :type => String
|
1171
|
+
@p.opt :b, "desc", :type => String
|
1172
|
+
@p.opt :c, "desc", :type => :flag
|
1173
|
+
@p.opt :d, "desc", :type => :flag
|
1174
|
+
@p.ignore_invalid_options = true
|
1175
|
+
opts = @p.parse %w{unknown -S param --arg1 potato -fb daisy --foo -ecg --bar baz -z}
|
1176
|
+
assert_equal "potato", opts[:arg1]
|
1177
|
+
assert_equal "daisy", opts[:b]
|
1178
|
+
assert opts[:c]
|
1179
|
+
refute opts[:d]
|
1180
|
+
assert_equal %w{unknown -S param -f --foo -eg --bar baz -z}, @p.leftovers
|
1181
|
+
end
|
1182
|
+
|
1183
|
+
def test_ignore_invalid_options_stop_on_unknown_long
|
1184
|
+
@p.opt :arg1, "desc", :type => String
|
1185
|
+
@p.ignore_invalid_options = true
|
1186
|
+
@p.stop_on_unknown
|
1187
|
+
opts = @p.parse %w{--unk --arg1 potato}
|
1188
|
+
refute opts[:arg1]
|
1189
|
+
assert_equal %w{--unk --arg1 potato}, @p.leftovers
|
1190
|
+
end
|
1191
|
+
|
1192
|
+
def test_ignore_invalid_options_stop_on_unknown_short
|
1193
|
+
@p.opt :arg1, "desc", :type => String
|
1194
|
+
@p.ignore_invalid_options = true
|
1195
|
+
@p.stop_on_unknown
|
1196
|
+
opts = @p.parse %w{-ua potato}
|
1197
|
+
refute opts[:arg1]
|
1198
|
+
assert_equal %w{-ua potato}, @p.leftovers
|
1199
|
+
end
|
1200
|
+
|
1201
|
+
def test_ignore_invalid_options_stop_on_unknown_partial_end_short
|
1202
|
+
@p.opt :arg1, "desc", :type => :flag
|
1203
|
+
@p.ignore_invalid_options = true
|
1204
|
+
@p.stop_on_unknown
|
1205
|
+
opts = @p.parse %w{-au potato}
|
1206
|
+
assert opts[:arg1]
|
1207
|
+
assert_equal %w{-u potato}, @p.leftovers
|
1208
|
+
end
|
1209
|
+
|
1210
|
+
def test_ignore_invalid_options_stop_on_unknown_partial_mid_short
|
1211
|
+
@p.opt :arg1, "desc", :type => :flag
|
1212
|
+
@p.ignore_invalid_options = true
|
1213
|
+
@p.stop_on_unknown
|
1214
|
+
opts = @p.parse %w{-abu potato}
|
1215
|
+
assert opts[:arg1]
|
1216
|
+
assert_equal %w{-bu potato}, @p.leftovers
|
1217
|
+
end
|
1218
|
+
end
|
1219
|
+
|
1220
|
+
end
|