optimist 3.1.0 → 3.2.1
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 +4 -4
- data/.codeclimate.yml +1 -1
- data/.github/workflows/ci.yaml +4 -5
- data/CHANGELOG.md +235 -2
- data/examples/a_basic_example.rb +9 -0
- data/examples/alt_names.rb +20 -0
- data/examples/banners1.rb +11 -0
- data/examples/banners2.rb +12 -0
- data/examples/banners3.rb +14 -0
- data/examples/boolean.rb +9 -0
- data/examples/constraints.rb +28 -0
- data/examples/didyoumean.rb +26 -0
- data/examples/medium_example.rb +15 -0
- data/examples/partialmatch.rb +18 -0
- data/examples/permitted.rb +29 -0
- data/examples/types_custom.rb +43 -0
- data/lib/optimist.rb +347 -93
- data/optimist.gemspec +4 -4
- data/renovate.json +5 -0
- data/test/optimist/alt_names_test.rb +168 -0
- data/test/optimist/command_line_error_test.rb +2 -2
- data/test/optimist/help_needed_test.rb +2 -2
- data/test/optimist/parser_constraint_test.rb +141 -0
- data/test/optimist/parser_educate_test.rb +45 -12
- data/test/optimist/parser_opt_test.rb +2 -2
- data/test/optimist/parser_parse_test.rb +4 -4
- data/test/optimist/parser_permitted_test.rb +121 -0
- data/test/optimist/parser_test.rb +277 -176
- data/test/optimist/version_needed_test.rb +2 -2
- data/test/optimist_test.rb +6 -4
- data/test/support/assert_helpers.rb +10 -3
- metadata +27 -9
- data/History.txt +0 -175
data/optimist.gemspec
CHANGED
@@ -22,7 +22,7 @@ specify."
|
|
22
22
|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
23
23
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
24
24
|
spec.metadata = {
|
25
|
-
"changelog_uri"
|
25
|
+
"changelog_uri" => "https://github.com/ManageIQ/optimist/blob/master/CHANGELOG.md",
|
26
26
|
"source_code_uri" => "https://github.com/ManageIQ/optimist/",
|
27
27
|
"bug_tracker_uri" => "https://github.com/ManageIQ/optimist/issues",
|
28
28
|
}
|
@@ -30,7 +30,7 @@ specify."
|
|
30
30
|
spec.require_paths = ["lib"]
|
31
31
|
|
32
32
|
spec.add_development_dependency "chronic"
|
33
|
-
spec.add_development_dependency "manageiq-style"
|
34
|
-
spec.add_development_dependency "minitest",
|
35
|
-
spec.add_development_dependency "rake",
|
33
|
+
spec.add_development_dependency "manageiq-style", ">= 1.5.3"
|
34
|
+
spec.add_development_dependency "minitest", "~> 5.25"
|
35
|
+
spec.add_development_dependency "rake", ">= 10.0"
|
36
36
|
end
|
data/renovate.json
ADDED
@@ -0,0 +1,168 @@
|
|
1
|
+
require_relative '../test_helper'
|
2
|
+
|
3
|
+
module Optimist
|
4
|
+
|
5
|
+
class AlternateNamesTest < ::Minitest::Test
|
6
|
+
|
7
|
+
def setup
|
8
|
+
@p = Parser.new
|
9
|
+
end
|
10
|
+
|
11
|
+
def get_help_string
|
12
|
+
assert_raises(Optimist::HelpNeeded) do
|
13
|
+
@p.parse(%w(--help))
|
14
|
+
end
|
15
|
+
sio = StringIO.new
|
16
|
+
@p.educate sio
|
17
|
+
sio.string
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_altshort
|
21
|
+
@p.opt :catarg, "desc", :short => ["c", "-C"]
|
22
|
+
opts = @p.parse %w(-c)
|
23
|
+
assert_equal true, opts[:catarg]
|
24
|
+
opts = @p.parse %w(-C)
|
25
|
+
assert_equal true, opts[:catarg]
|
26
|
+
err_regex = /option '-C' specified multiple times/
|
27
|
+
assert_raises_errmatch(CommandlineError, err_regex) { @p.parse %w(-c -C) }
|
28
|
+
assert_raises_errmatch(CommandlineError, err_regex) { @p.parse %w(-cC) }
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_altshort_invalid_none
|
32
|
+
err_regex = /Cannot use :none with any other values in short option:/
|
33
|
+
assert_raises_errmatch(ArgumentError, err_regex) {
|
34
|
+
@p.opt :something, "some opt", :short => [:s, :none]
|
35
|
+
}
|
36
|
+
assert_raises_errmatch(ArgumentError, err_regex) {
|
37
|
+
@p.opt :something, "some opt", :short => [:none, :s]
|
38
|
+
}
|
39
|
+
assert_raises_errmatch(ArgumentError, err_regex) {
|
40
|
+
@p.opt :zumthing, "some opt", :short => [:none, :none]
|
41
|
+
}
|
42
|
+
end
|
43
|
+
|
44
|
+
def test_altshort_with_multi
|
45
|
+
@p.opt :flag, "desc", :short => ["-c", "C", :x], :multi => true
|
46
|
+
@p.opt :num, "desc", :short => ["-n", "N"], :multi => true, type: Integer
|
47
|
+
@p.parse %w(-c)
|
48
|
+
@p.parse %w(-C -c -x)
|
49
|
+
@p.parse %w(-c -C)
|
50
|
+
@p.parse %w(-c -C -c -C)
|
51
|
+
opts = @p.parse %w(-ccCx)
|
52
|
+
assert_equal true, opts[:flag]
|
53
|
+
@p.parse %w(-c)
|
54
|
+
@p.parse %w(-N 1 -n 3)
|
55
|
+
@p.parse %w(-n 2 -N 4)
|
56
|
+
opts = @p.parse %w(-n 4 -N 3 -n 2 -N 1)
|
57
|
+
assert_equal [4, 3, 2, 1], opts[:num]
|
58
|
+
end
|
59
|
+
|
60
|
+
def test_altlong
|
61
|
+
@p.opt "goodarg0", "desc", :alt => "zero"
|
62
|
+
@p.opt "goodarg1", "desc", :long => "newone", :alt => "one"
|
63
|
+
@p.opt "goodarg2", "desc", :alt => "--two"
|
64
|
+
@p.opt "goodarg3", "desc", :alt => ["three", "--four", :five]
|
65
|
+
|
66
|
+
[%w[--goodarg0], %w[--zero]].each do |a|
|
67
|
+
opts = @p.parse(a)
|
68
|
+
assert opts.goodarg0
|
69
|
+
end
|
70
|
+
|
71
|
+
[%w[--newone], %w[-n], %w[--one]].each do |a|
|
72
|
+
opts = @p.parse(a)
|
73
|
+
assert opts.goodarg1
|
74
|
+
end
|
75
|
+
|
76
|
+
[%w[--two]].each do |a|
|
77
|
+
opts = @p.parse(a)
|
78
|
+
assert opts.goodarg2
|
79
|
+
end
|
80
|
+
|
81
|
+
[%w[--three], %w[--four], %w[--five]].each do |a|
|
82
|
+
opts = @p.parse(a)
|
83
|
+
assert opts.goodarg3
|
84
|
+
end
|
85
|
+
|
86
|
+
[%w[--goodarg1], %w[--missing], %w[-a]].each do |a|
|
87
|
+
assert_raises_errmatch(Optimist::CommandlineError, /unknown argument/) { @p.parse(a) }
|
88
|
+
end
|
89
|
+
|
90
|
+
["", '--', '-bad', '---threedash'].each do |altitem|
|
91
|
+
assert_raises_errmatch(ArgumentError, /invalid long option name/) { @p.opt "badarg", "desc", :alt => altitem }
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def test_altshort_help
|
96
|
+
@p.opt :cat, 'cat', short: ['c','C','a','T']
|
97
|
+
outstring = get_help_string
|
98
|
+
# expect mutliple short-opts to be in the help
|
99
|
+
assert_match(/-c, -C, -a, -T, --cat/, outstring)
|
100
|
+
end
|
101
|
+
|
102
|
+
|
103
|
+
def test_altlong_help
|
104
|
+
@p.opt :cat, 'a cat', alt: :feline
|
105
|
+
@p.opt :dog, 'a dog', alt: ['Pooch', :canine]
|
106
|
+
@p.opt :fruit, 'a fruit', long: :fig, alt: ['peach', :pear, "--apple"], short: :none
|
107
|
+
@p.opt :veg, "gemuse", long: :gemuse, alt: [:groente]
|
108
|
+
outstring = get_help_string
|
109
|
+
|
110
|
+
assert_match(/^\s*-c, --cat, --feline/, outstring)
|
111
|
+
assert_match(/^\s*-d, --dog, --Pooch, --canine/, outstring)
|
112
|
+
|
113
|
+
# expect long-opt to shadow the actual name
|
114
|
+
assert_match(/^\s*--fig, --peach, --pear, --apple/, outstring)
|
115
|
+
assert_match(/^\s*-g, --gemuse, --groente/, outstring)
|
116
|
+
|
117
|
+
end
|
118
|
+
|
119
|
+
def test_alt_duplicates
|
120
|
+
# alt duplicates named option
|
121
|
+
err_regex = /long option name "cat" is already taken; please specify a \(different\) :long\/:alt/
|
122
|
+
assert_raises_errmatch(ArgumentError, err_regex) {
|
123
|
+
@p.opt :cat, 'desc', :alt => :cat
|
124
|
+
}
|
125
|
+
# alt duplicates :long
|
126
|
+
err_regex = /long option name "feline" is already taken; please specify a \(different\) :long\/:alt/
|
127
|
+
assert_raises_errmatch(ArgumentError, err_regex) {
|
128
|
+
@p.opt :cat, 'desc', :long => :feline, :alt => [:feline]
|
129
|
+
}
|
130
|
+
# alt duplicates itself
|
131
|
+
err_regex = /long option name "aaa" is already taken; please specify a \(different\) :long\/:alt/
|
132
|
+
assert_raises_errmatch(ArgumentError, err_regex) {
|
133
|
+
@p.opt :abc, 'desc', :alt => [:aaa, :aaa]
|
134
|
+
}
|
135
|
+
end
|
136
|
+
|
137
|
+
def test_altlong_collisions
|
138
|
+
@p.opt :fat, 'desc'
|
139
|
+
@p.opt :raton, 'desc', :long => :rat
|
140
|
+
@p.opt :bat, 'desc', :alt => [:baton, :twirl]
|
141
|
+
|
142
|
+
# :alt collision with named option
|
143
|
+
err_regex = /long option name "fat" is already taken; please specify a \(different\) :long\/:alt/
|
144
|
+
assert_raises_errmatch(ArgumentError, err_regex) {
|
145
|
+
@p.opt :cat, 'desc', :alt => :fat
|
146
|
+
}
|
147
|
+
|
148
|
+
# :alt collision with :long option
|
149
|
+
err_regex = /long option name "cat" is already taken; please specify a \(different\) :long\/:alt/
|
150
|
+
assert_raises_errmatch(ArgumentError, err_regex) {
|
151
|
+
@p.opt :cat, 'desc', :alt => :rat
|
152
|
+
}
|
153
|
+
|
154
|
+
# :named option collision with existing :alt option
|
155
|
+
err_regex = /long option name "baton" is already taken; please specify a \(different\) :long\/:alt/
|
156
|
+
assert_raises_errmatch(ArgumentError, err_regex) {
|
157
|
+
@p.opt :baton, 'desc'
|
158
|
+
}
|
159
|
+
|
160
|
+
# :long option collision with existing :alt option
|
161
|
+
err_regex = /long option name "twirl" is already taken; please specify a \(different\) :long\/:alt/
|
162
|
+
assert_raises_errmatch(ArgumentError, err_regex) {
|
163
|
+
@p.opt :whirl, 'desc', :long => 'twirl'
|
164
|
+
}
|
165
|
+
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
@@ -0,0 +1,141 @@
|
|
1
|
+
require_relative '../test_helper'
|
2
|
+
|
3
|
+
module Optimist
|
4
|
+
|
5
|
+
class ParserConstraintTest < ::Minitest::Test
|
6
|
+
def setup
|
7
|
+
@p = Parser.new
|
8
|
+
end
|
9
|
+
|
10
|
+
def parser
|
11
|
+
@p ||= Parser.new
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_conflicts
|
15
|
+
@p.opt :one
|
16
|
+
err_regex = /unknown option 'two'/
|
17
|
+
assert_raises_errmatch(ArgumentError, err_regex) { @p.conflicts :one, :two }
|
18
|
+
@p.opt :two
|
19
|
+
@p.conflicts :one, :two
|
20
|
+
@p.parse %w(--one)
|
21
|
+
@p.parse %w(--two)
|
22
|
+
err_regex = /only one of --one, --two can be given/
|
23
|
+
|
24
|
+
assert_raises_errmatch(CommandlineError, err_regex) { @p.parse %w(--one --two) }
|
25
|
+
|
26
|
+
@p.opt :hello
|
27
|
+
@p.opt :yellow
|
28
|
+
@p.opt :mellow
|
29
|
+
@p.opt :jello
|
30
|
+
@p.conflicts :hello, :yellow, :mellow, :jello
|
31
|
+
err_regex = /only one of --hello, --yellow, --mellow, --jello can be given/
|
32
|
+
assert_raises_errmatch(CommandlineError, err_regex) { @p.parse %w(--hello --yellow --mellow --jello) }
|
33
|
+
assert_raises_errmatch(CommandlineError, err_regex) { @p.parse %w(--hello --mellow --jello) }
|
34
|
+
assert_raises_errmatch(CommandlineError, err_regex) { @p.parse %w(--hello --jello) }
|
35
|
+
|
36
|
+
@p.parse %w(--hello)
|
37
|
+
@p.parse %w(--jello)
|
38
|
+
@p.parse %w(--yellow)
|
39
|
+
@p.parse %w(--mellow)
|
40
|
+
|
41
|
+
@p.parse %w(--mellow --one)
|
42
|
+
@p.parse %w(--mellow --two)
|
43
|
+
|
44
|
+
assert_raises_errmatch(CommandlineError, err_regex) { @p.parse %w(--mellow --two --jello) }
|
45
|
+
err_regex = /only one of --one, --two can be given/
|
46
|
+
assert_raises_errmatch(CommandlineError, err_regex) { @p.parse %w(--one --mellow --two --jello) }
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_conflict_error_messages
|
50
|
+
@p.opt :one
|
51
|
+
@p.opt "two"
|
52
|
+
@p.conflicts :one, "two"
|
53
|
+
err_regex = %r/only one of --one, --two can be given/
|
54
|
+
assert_raises_errmatch(CommandlineError, err_regex) { @p.parse %w(--one --two) }
|
55
|
+
end
|
56
|
+
|
57
|
+
def test_either
|
58
|
+
@p.opt :one
|
59
|
+
err_regex = /unknown option 'two'/
|
60
|
+
assert_raises_errmatch(ArgumentError, err_regex) { @p.either :one, :two }
|
61
|
+
@p.opt :two
|
62
|
+
@p.either :one, :two
|
63
|
+
@p.parse %w(--one)
|
64
|
+
@p.parse %w(--two)
|
65
|
+
err_regex = /one and only one of --one, --two is required/
|
66
|
+
assert_raises_errmatch(CommandlineError, err_regex) { @p.parse %w(--one --two) }
|
67
|
+
assert_raises_errmatch(CommandlineError, err_regex) { @p.parse %w() }
|
68
|
+
|
69
|
+
@p.opt :hello
|
70
|
+
@p.opt :yellow
|
71
|
+
@p.opt :mellow
|
72
|
+
@p.opt :jello
|
73
|
+
@p.either :hello, :yellow, :mellow, :jello
|
74
|
+
err_regex = /one and only one of --hello, --yellow, --mellow, --jello is required/
|
75
|
+
assert_raises_errmatch(CommandlineError, err_regex) { @p.parse %w(--one --hello --yellow --mellow --jello) }
|
76
|
+
assert_raises_errmatch(CommandlineError, err_regex) { @p.parse %w(--two --hello --mellow --jello) }
|
77
|
+
assert_raises_errmatch(CommandlineError, err_regex) { @p.parse %w(--one --hello --jello) }
|
78
|
+
|
79
|
+
@p.parse %w(--hello --one)
|
80
|
+
@p.parse %w(--jello --two)
|
81
|
+
@p.parse %w(--mellow --one)
|
82
|
+
@p.parse %w(--mellow --two)
|
83
|
+
|
84
|
+
err_regex = /one and only one of/
|
85
|
+
assert_raises_errmatch(CommandlineError, err_regex) { @p.parse %w(--mellow --two --jello) }
|
86
|
+
assert_raises_errmatch(CommandlineError, err_regex) { @p.parse %w(--one --mellow --two --jello) }
|
87
|
+
end
|
88
|
+
|
89
|
+
def test_either_error_messages
|
90
|
+
@p.opt :one
|
91
|
+
@p.opt :two
|
92
|
+
@p.opt :three
|
93
|
+
@p.either :one, :two, :three
|
94
|
+
err_regex = %r/one and only one of --one, --two, --three is required/
|
95
|
+
assert_raises_errmatch(CommandlineError, err_regex) { @p.parse %w(--one --two) }
|
96
|
+
assert_raises_errmatch(CommandlineError, err_regex) { @p.parse %w(--three --two --one) }
|
97
|
+
end
|
98
|
+
|
99
|
+
def test_depends
|
100
|
+
@p.opt :one
|
101
|
+
err_regex = /unknown option 'two'/
|
102
|
+
assert_raises_errmatch(ArgumentError, err_regex) { @p.depends :one, :two }
|
103
|
+
@p.opt :two
|
104
|
+
@p.depends :one, :two
|
105
|
+
@p.parse %w(--one --two)
|
106
|
+
err_regex = /--one, --two have a dependency and must be given together/
|
107
|
+
assert_raises_errmatch(CommandlineError, err_regex) { @p.parse %w(--one) }
|
108
|
+
assert_raises_errmatch(CommandlineError, err_regex) { @p.parse %w(--two) }
|
109
|
+
|
110
|
+
@p.opt :hello
|
111
|
+
@p.opt :yellow
|
112
|
+
@p.opt :mellow
|
113
|
+
@p.opt :jello
|
114
|
+
@p.depends :hello, :yellow, :mellow, :jello
|
115
|
+
@p.parse %w(--hello --yellow --mellow --jello)
|
116
|
+
err_regex = /-hello, --yellow, --mellow, --jello have a dependency and must be given together/
|
117
|
+
|
118
|
+
assert_raises_errmatch(CommandlineError, err_regex) { @p.parse %w(--hello --mellow --jello) }
|
119
|
+
assert_raises_errmatch(CommandlineError, err_regex) { @p.parse %w(--hello --jello) }
|
120
|
+
|
121
|
+
assert_raises_errmatch(CommandlineError, err_regex) { @p.parse %w(--hello) }
|
122
|
+
assert_raises_errmatch(CommandlineError, err_regex) { @p.parse %w(--mellow) }
|
123
|
+
|
124
|
+
@p.parse %w(--hello --yellow --mellow --jello --one --two)
|
125
|
+
@p.parse %w(--hello --yellow --mellow --jello --one --two a b c)
|
126
|
+
|
127
|
+
assert_raises_errmatch(CommandlineError, err_regex) { @p.parse %w(--mellow --two --jello --one) }
|
128
|
+
end
|
129
|
+
|
130
|
+
def test_depends_error_messages
|
131
|
+
@p.opt :one
|
132
|
+
@p.opt "two"
|
133
|
+
@p.depends :one, "two"
|
134
|
+
|
135
|
+
@p.parse %w(--one --two)
|
136
|
+
err_regex = %r/--one, --two have a dependency and must be given together/
|
137
|
+
assert_raises_errmatch(CommandlineError, err_regex) { @p.parse %w(--one) }
|
138
|
+
assert_raises_errmatch(CommandlineError, err_regex) { @p.parse %w(--two) }
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
@@ -1,8 +1,8 @@
|
|
1
1
|
require 'stringio'
|
2
|
-
|
2
|
+
require_relative '../test_helper'
|
3
3
|
|
4
4
|
module Optimist
|
5
|
-
class ParserEduateTest < ::
|
5
|
+
class ParserEduateTest < ::Minitest::Test
|
6
6
|
def setup
|
7
7
|
end
|
8
8
|
|
@@ -40,7 +40,7 @@ module Optimist
|
|
40
40
|
# pulled out of optimist_test for now
|
41
41
|
def test_help_has_default_banner
|
42
42
|
@p = Parser.new
|
43
|
-
sio = StringIO.new
|
43
|
+
sio = StringIO.new
|
44
44
|
@p.parse []
|
45
45
|
@p.educate sio
|
46
46
|
help = sio.string.split "\n"
|
@@ -49,7 +49,7 @@ module Optimist
|
|
49
49
|
|
50
50
|
@p = Parser.new
|
51
51
|
@p.version "my version"
|
52
|
-
sio = StringIO.new
|
52
|
+
sio = StringIO.new
|
53
53
|
@p.parse []
|
54
54
|
@p.educate sio
|
55
55
|
help = sio.string.split "\n"
|
@@ -58,7 +58,7 @@ module Optimist
|
|
58
58
|
|
59
59
|
@p = Parser.new
|
60
60
|
@p.banner "my own banner"
|
61
|
-
sio = StringIO.new
|
61
|
+
sio = StringIO.new
|
62
62
|
@p.parse []
|
63
63
|
@p.educate sio
|
64
64
|
help = sio.string.split "\n"
|
@@ -67,7 +67,7 @@ module Optimist
|
|
67
67
|
|
68
68
|
@p = Parser.new
|
69
69
|
@p.text "my own text banner"
|
70
|
-
sio = StringIO.new
|
70
|
+
sio = StringIO.new
|
71
71
|
@p.parse []
|
72
72
|
@p.educate sio
|
73
73
|
help = sio.string.split "\n"
|
@@ -78,7 +78,7 @@ module Optimist
|
|
78
78
|
def test_help_has_optional_usage
|
79
79
|
@p = Parser.new
|
80
80
|
@p.usage "OPTIONS FILES"
|
81
|
-
sio = StringIO.new
|
81
|
+
sio = StringIO.new
|
82
82
|
@p.parse []
|
83
83
|
@p.educate sio
|
84
84
|
help = sio.string.split "\n"
|
@@ -89,7 +89,7 @@ module Optimist
|
|
89
89
|
def test_help_has_optional_synopsis
|
90
90
|
@p = Parser.new
|
91
91
|
@p.synopsis "About this program"
|
92
|
-
sio = StringIO.new
|
92
|
+
sio = StringIO.new
|
93
93
|
@p.parse []
|
94
94
|
@p.educate sio
|
95
95
|
help = sio.string.split "\n"
|
@@ -101,7 +101,7 @@ module Optimist
|
|
101
101
|
@p = Parser.new
|
102
102
|
@p.usage "OPTIONS FILES"
|
103
103
|
@p.synopsis "About this program"
|
104
|
-
sio = StringIO.new
|
104
|
+
sio = StringIO.new
|
105
105
|
@p.parse []
|
106
106
|
@p.educate sio
|
107
107
|
help = sio.string.split "\n"
|
@@ -113,7 +113,7 @@ module Optimist
|
|
113
113
|
def test_help_preserves_positions
|
114
114
|
parser.opt :zzz, "zzz"
|
115
115
|
parser.opt :aaa, "aaa"
|
116
|
-
sio = StringIO.new
|
116
|
+
sio = StringIO.new
|
117
117
|
parser.educate sio
|
118
118
|
|
119
119
|
help = sio.string.split "\n"
|
@@ -132,7 +132,7 @@ module Optimist
|
|
132
132
|
parser.opt :arg8, 'arg', :type => :ios
|
133
133
|
parser.opt :arg9, 'arg', :type => :date
|
134
134
|
parser.opt :arg10, 'arg', :type => :dates
|
135
|
-
sio = StringIO.new
|
135
|
+
sio = StringIO.new
|
136
136
|
parser.educate sio
|
137
137
|
|
138
138
|
help = sio.string.split "\n"
|
@@ -148,16 +148,49 @@ module Optimist
|
|
148
148
|
assert help[10] =~ /<date\+>/
|
149
149
|
end
|
150
150
|
|
151
|
+
def test_help_handles_boolean_flags
|
152
|
+
parser.opt :default_false, 'default-false', :default => false
|
153
|
+
parser.opt :default_true, 'default-true', :default => true
|
154
|
+
sio = StringIO.new
|
155
|
+
parser.educate sio
|
156
|
+
|
157
|
+
help = sio.string.split "\n"
|
158
|
+
assert help[1] =~ /--default-false/
|
159
|
+
assert help[2] =~ /--default-true, --no-default-true/
|
160
|
+
assert help[2] =~ /\(default: true\)/
|
161
|
+
end
|
162
|
+
|
151
163
|
def test_help_has_grammatical_default_text
|
152
164
|
parser.opt :arg1, 'description with period.', :default => 'hello'
|
153
165
|
parser.opt :arg2, 'description without period', :default => 'world'
|
154
|
-
sio = StringIO.new
|
166
|
+
sio = StringIO.new
|
155
167
|
parser.educate sio
|
156
168
|
|
157
169
|
help = sio.string.split "\n"
|
158
170
|
assert help[1] =~ /Default/
|
159
171
|
assert help[2] =~ /default/
|
160
172
|
end
|
173
|
+
|
174
|
+
def test_help_has_grammatical_permitted_text
|
175
|
+
parser.opt :arg1, 'description with period.', :type => :strings, :permitted => %w(foo bar)
|
176
|
+
parser.opt :arg2, 'description without period', :type => :strings, :permitted => %w(foo bar)
|
177
|
+
sio = StringIO.new
|
178
|
+
parser.educate sio
|
179
|
+
|
180
|
+
help = sio.string.split "\n"
|
181
|
+
assert help[1] =~ /Permitted/
|
182
|
+
assert help[2] =~ /permitted/
|
183
|
+
end
|
184
|
+
|
185
|
+
def test_help_with_permitted_range
|
186
|
+
parser.opt :rating, 'rating', permitted: 1..5
|
187
|
+
parser.opt :hex, 'hexadecimal', permitted: /^[0-9a-f]/i
|
188
|
+
sio = StringIO.new
|
189
|
+
parser.educate sio
|
190
|
+
help = sio.string.split "\n"
|
191
|
+
assert_match %r{rating \(permitted: 1\.\.5\)}, help[1]
|
192
|
+
assert_match %r{hexadecimal \(permitted: \/\^\[0-9a-f\]\/i\)}, help[2]
|
193
|
+
end
|
161
194
|
############
|
162
195
|
|
163
196
|
private
|
@@ -1,8 +1,8 @@
|
|
1
1
|
require 'stringio'
|
2
|
-
|
2
|
+
require_relative '../test_helper'
|
3
3
|
|
4
4
|
module Optimist
|
5
|
-
class ParserParseTest < ::
|
5
|
+
class ParserParseTest < ::Minitest::Test
|
6
6
|
|
7
7
|
# TODO: parse
|
8
8
|
# resolve_default_short_options!
|
@@ -37,7 +37,7 @@ module Optimist
|
|
37
37
|
|
38
38
|
def test_version_needed_unset
|
39
39
|
parser.opt "arg"
|
40
|
-
|
40
|
+
assert_raises_errmatch(CommandlineError, /unknown argument '-v'/) { parser.parse %w(-v) }
|
41
41
|
end
|
42
42
|
|
43
43
|
def test_version_needed
|
@@ -54,7 +54,7 @@ module Optimist
|
|
54
54
|
|
55
55
|
def test_version_only_appears_if_set
|
56
56
|
parser.opt "arg"
|
57
|
-
|
57
|
+
assert_raises_errmatch(CommandlineError, /unknown argument '-v'/) { parser.parse %w(-v) }
|
58
58
|
end
|
59
59
|
|
60
60
|
def test_version_with_other_args
|
@@ -0,0 +1,121 @@
|
|
1
|
+
require 'stringio'
|
2
|
+
require_relative '../test_helper'
|
3
|
+
|
4
|
+
module Optimist
|
5
|
+
|
6
|
+
class ParserPermittedTest < ::Minitest::Test
|
7
|
+
def setup
|
8
|
+
@p = Parser.new
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_permitted_flags_filter_inputs
|
12
|
+
@p.opt "arg", "desc", :type => :strings, :permitted => %w(foo bar)
|
13
|
+
|
14
|
+
result = @p.parse(%w(--arg foo))
|
15
|
+
assert_equal ["foo"], result["arg"]
|
16
|
+
assert_raises_errmatch(CommandlineError, /option '--arg' only accepts one of: foo, bar/) { @p.parse(%w(--arg baz)) }
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_permitted_invalid_scalar_value
|
20
|
+
err_regexp = /permitted values for option "(bad|mad|sad)" must be either nil, Range, Regexp or an Array/
|
21
|
+
assert_raises_errmatch(ArgumentError, err_regexp) {
|
22
|
+
@p.opt 'bad', 'desc', :permitted => 1
|
23
|
+
}
|
24
|
+
assert_raises_errmatch(ArgumentError, err_regexp) {
|
25
|
+
@p.opt 'mad', 'desc', :permitted => "A"
|
26
|
+
}
|
27
|
+
assert_raises_errmatch(ArgumentError, err_regexp) {
|
28
|
+
@p.opt 'sad', 'desc', :permitted => :abcd
|
29
|
+
}
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_permitted_with_string_array
|
33
|
+
@p.opt 'fiz', 'desc', :type => 'string', :permitted => ['foo', 'bar']
|
34
|
+
@p.parse(%w(--fiz foo))
|
35
|
+
assert_raises_errmatch(CommandlineError, /option '--fiz' only accepts one of: foo, bar/) {
|
36
|
+
@p.parse(%w(--fiz buz))
|
37
|
+
}
|
38
|
+
end
|
39
|
+
def test_permitted_with_symbol_array
|
40
|
+
@p.opt 'fiz', 'desc', :type => 'string', :permitted => %i[dog cat]
|
41
|
+
@p.parse(%w(--fiz dog))
|
42
|
+
@p.parse(%w(--fiz cat))
|
43
|
+
assert_raises_errmatch(CommandlineError, /option '--fiz' only accepts one of: dog, cat/) {
|
44
|
+
@p.parse(%w(--fiz rat))
|
45
|
+
}
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_permitted_with_numeric_array
|
49
|
+
@p.opt 'mynum', 'desc', :type => Integer, :permitted => [1,2,4]
|
50
|
+
@p.parse(%w(--mynum 1))
|
51
|
+
@p.parse(%w(--mynum 4))
|
52
|
+
assert_raises_errmatch(CommandlineError, /option '--mynum' only accepts one of: 1, 2, 4/) {
|
53
|
+
@p.parse(%w(--mynum 3))
|
54
|
+
}
|
55
|
+
end
|
56
|
+
|
57
|
+
def test_permitted_with_string_range
|
58
|
+
@p.opt 'fiz', 'desc', :type => String, :permitted => 'A'..'z'
|
59
|
+
opts = @p.parse(%w(--fiz B))
|
60
|
+
assert_equal opts['fiz'], "B"
|
61
|
+
opts = @p.parse(%w(--fiz z))
|
62
|
+
assert_equal opts['fiz'], "z"
|
63
|
+
assert_raises_errmatch(CommandlineError, /option '--fiz' only accepts value in range of: A\.\.z/) {
|
64
|
+
@p.parse(%w(--fiz @))
|
65
|
+
}
|
66
|
+
end
|
67
|
+
|
68
|
+
def test_permitted_with_integer_range
|
69
|
+
@p.opt 'fiz', 'desc', :type => Integer, :permitted => 1..3
|
70
|
+
opts = @p.parse(%w(--fiz 1))
|
71
|
+
assert_equal opts['fiz'], 1
|
72
|
+
opts = @p.parse(%w(--fiz 3))
|
73
|
+
assert_equal opts['fiz'], 3
|
74
|
+
assert_raises_errmatch(CommandlineError, /option '--fiz' only accepts value in range of: 1\.\.3/) {
|
75
|
+
@p.parse(%w(--fiz 4))
|
76
|
+
}
|
77
|
+
end
|
78
|
+
|
79
|
+
def test_permitted_with_float_range
|
80
|
+
@p.opt 'fiz', 'desc', :type => Float, :permitted => 1.2 .. 3.5
|
81
|
+
opts = @p.parse(%w(--fiz 1.2))
|
82
|
+
assert_in_epsilon opts['fiz'], 1.2
|
83
|
+
opts = @p.parse(%w(--fiz 2.7))
|
84
|
+
assert_in_epsilon opts['fiz'], 2.7
|
85
|
+
opts = @p.parse(%w(--fiz 3.5))
|
86
|
+
assert_in_epsilon opts['fiz'], 3.5
|
87
|
+
err_regexp = /option '--fiz' only accepts value in range of: 1\.2\.\.3\.5/
|
88
|
+
assert_raises_errmatch(CommandlineError, err_regexp) {
|
89
|
+
@p.parse(%w(--fiz 3.51))
|
90
|
+
}
|
91
|
+
assert_raises_errmatch(CommandlineError, err_regexp) {
|
92
|
+
@p.parse(%w(--fiz 1.19))
|
93
|
+
}
|
94
|
+
end
|
95
|
+
|
96
|
+
def test_permitted_with_regexp
|
97
|
+
@p.opt 'zipcode', 'desc', :type => String, :permitted => /^[0-9]{5}$/
|
98
|
+
@p.parse(%w(--zipcode 39762))
|
99
|
+
err_regexp = %r|option '--zipcode' only accepts value matching: /\^\[0-9\]\{5\}\$/|
|
100
|
+
assert_raises_errmatch(CommandlineError, err_regexp) {
|
101
|
+
@p.parse(%w(--zipcode A9A9AA))
|
102
|
+
}
|
103
|
+
end
|
104
|
+
def test_permitted_with_reason
|
105
|
+
# test all keys passed into the formatter for the permitted_response
|
106
|
+
@p.opt 'zipcode', 'desc', type: String, permitted: /^[0-9]{5}$/,
|
107
|
+
permitted_response: "opt %{arg} should be a zipcode but you have %{value}"
|
108
|
+
@p.opt :wig, 'wig', type: Integer, permitted: 1..4,
|
109
|
+
permitted_response: "opt %{arg} exceeded four wigs (%{valid_string}), %{permitted}, but you gave '%{given}'"
|
110
|
+
err_regexp = %r|opt --zipcode should be a zipcode but you have A9A9AA|
|
111
|
+
assert_raises_errmatch(CommandlineError, err_regexp) {
|
112
|
+
@p.parse(%w(--zipcode A9A9AA))
|
113
|
+
}
|
114
|
+
err_regexp = %r|opt --wig exceeded four wigs \(value in range of: 1\.\.4\), 1\.\.4, but you gave '5'|
|
115
|
+
assert_raises_errmatch(CommandlineError, err_regexp) {
|
116
|
+
@p.parse(%w(--wig 5))
|
117
|
+
}
|
118
|
+
end
|
119
|
+
|
120
|
+
end
|
121
|
+
end
|