clasp-ruby 0.20.1 → 0.22.0.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 +5 -5
- data/README.md +43 -21
- data/examples/cr-example.rb +2 -11
- data/examples/flag_and_option_specifications.md +15 -0
- data/lib/clasp/arguments.rb +70 -21
- data/lib/clasp/clasp.rb +9 -0
- data/lib/clasp/cli.rb +29 -25
- data/lib/clasp/specifications.rb +108 -16
- data/lib/clasp/util/exceptions.rb +82 -0
- data/lib/clasp/util/value_parser.rb +222 -0
- data/lib/clasp/version.rb +4 -2
- data/test/unit/tc_cli.rb +4 -0
- data/test/unit/tc_default_value.rb +21 -3
- data/test/unit/tc_option_required.rb +3 -3
- data/test/unit/tc_typed_options.rb +310 -0
- data/test/unit/tc_with_action.rb +50 -0
- metadata +8 -3
@@ -0,0 +1,82 @@
|
|
1
|
+
|
2
|
+
# ######################################################################## #
|
3
|
+
# File: clasp/util/exceptions.rb
|
4
|
+
#
|
5
|
+
# Purpose: Exception classes
|
6
|
+
#
|
7
|
+
# Created: 20th April 2019
|
8
|
+
# Updated: 28th April 2019
|
9
|
+
#
|
10
|
+
# Home: http://github.com/synesissoftware/CLASP.Ruby
|
11
|
+
#
|
12
|
+
# Author: Matthew Wilson
|
13
|
+
#
|
14
|
+
# Copyright (c) 2019, Matthew Wilson and Synesis Software
|
15
|
+
# All rights reserved.
|
16
|
+
#
|
17
|
+
# Redistribution and use in source and binary forms, with or without
|
18
|
+
# modification, are permitted provided that the following conditions are
|
19
|
+
# met:
|
20
|
+
#
|
21
|
+
# * Redistributions of source code must retain the above copyright
|
22
|
+
# notice, this list of conditions and the following disclaimer.
|
23
|
+
#
|
24
|
+
# * Redistributions in binary form must reproduce the above copyright
|
25
|
+
# notice, this list of conditions and the following disclaimer in the
|
26
|
+
# documentation and/or other materials provided with the distribution.
|
27
|
+
#
|
28
|
+
# * Neither the names of the copyright holder nor the names of its
|
29
|
+
# contributors may be used to endorse or promote products derived from
|
30
|
+
# this software without specific prior written permission.
|
31
|
+
#
|
32
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
33
|
+
# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
34
|
+
# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
35
|
+
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
36
|
+
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
37
|
+
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
38
|
+
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
39
|
+
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
40
|
+
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
41
|
+
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
42
|
+
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
43
|
+
#
|
44
|
+
# ######################################################################## #
|
45
|
+
|
46
|
+
|
47
|
+
|
48
|
+
=begin
|
49
|
+
=end
|
50
|
+
|
51
|
+
module CLASP # :nodoc:
|
52
|
+
|
53
|
+
# Exceptions
|
54
|
+
module Exceptions
|
55
|
+
|
56
|
+
# Root exception for CLASP
|
57
|
+
class CLASPException < RuntimeError; end
|
58
|
+
|
59
|
+
# Root exception for value parsing
|
60
|
+
class ValueParserException < CLASPException; end
|
61
|
+
|
62
|
+
# No value specified (and no default value) for an option
|
63
|
+
class MissingValueException < ValueParserException; end
|
64
|
+
|
65
|
+
# Exception class indicating invalid values (as opposed to types)
|
66
|
+
class InvalidValueException < ValueParserException; end
|
67
|
+
|
68
|
+
# The given value could not be recognised as a (properly-formatted) number
|
69
|
+
class InvalidNumberException < InvalidValueException; end
|
70
|
+
|
71
|
+
# The given value could not be recognised as a (properly-formatted) integer
|
72
|
+
class InvalidIntegerException < InvalidNumberException; end
|
73
|
+
|
74
|
+
# The value was a valid integer but is out of range
|
75
|
+
class IntegerOutOfRangeException < InvalidValueException; end
|
76
|
+
|
77
|
+
end # module Exceptions
|
78
|
+
end # module CLASP
|
79
|
+
|
80
|
+
# ############################## end of file ############################# #
|
81
|
+
|
82
|
+
|
@@ -0,0 +1,222 @@
|
|
1
|
+
|
2
|
+
# ######################################################################## #
|
3
|
+
# File: clasp/util/value_parser.rb
|
4
|
+
#
|
5
|
+
# Purpose: Utility component for typed values
|
6
|
+
#
|
7
|
+
# Created: 20th April 2019
|
8
|
+
# Updated: 28th April 2019
|
9
|
+
#
|
10
|
+
# Home: http://github.com/synesissoftware/CLASP.Ruby
|
11
|
+
#
|
12
|
+
# Author: Matthew Wilson
|
13
|
+
#
|
14
|
+
# Copyright (c) 2019, Matthew Wilson and Synesis Software
|
15
|
+
# All rights reserved.
|
16
|
+
#
|
17
|
+
# Redistribution and use in source and binary forms, with or without
|
18
|
+
# modification, are permitted provided that the following conditions are
|
19
|
+
# met:
|
20
|
+
#
|
21
|
+
# * Redistributions of source code must retain the above copyright
|
22
|
+
# notice, this list of conditions and the following disclaimer.
|
23
|
+
#
|
24
|
+
# * Redistributions in binary form must reproduce the above copyright
|
25
|
+
# notice, this list of conditions and the following disclaimer in the
|
26
|
+
# documentation and/or other materials provided with the distribution.
|
27
|
+
#
|
28
|
+
# * Neither the names of the copyright holder nor the names of its
|
29
|
+
# contributors may be used to endorse or promote products derived from
|
30
|
+
# this software without specific prior written permission.
|
31
|
+
#
|
32
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
33
|
+
# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
34
|
+
# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
35
|
+
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
36
|
+
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
37
|
+
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
38
|
+
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
39
|
+
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
40
|
+
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
41
|
+
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
42
|
+
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
43
|
+
#
|
44
|
+
# ######################################################################## #
|
45
|
+
|
46
|
+
|
47
|
+
|
48
|
+
require File.join(File.dirname(__FILE__), 'exceptions')
|
49
|
+
|
50
|
+
=begin
|
51
|
+
=end
|
52
|
+
|
53
|
+
module CLASP # :nodoc:
|
54
|
+
module Util # :nodoc:
|
55
|
+
|
56
|
+
# @!visibility private
|
57
|
+
module ValueParser # :nodoc: all
|
58
|
+
|
59
|
+
module Internal_ # :nodoc: all
|
60
|
+
|
61
|
+
include Exceptions
|
62
|
+
|
63
|
+
def self.is_integer? type
|
64
|
+
|
65
|
+
h = {}
|
66
|
+
|
67
|
+
return true if Integer == type
|
68
|
+
return true if :integer == type
|
69
|
+
|
70
|
+
false
|
71
|
+
end
|
72
|
+
|
73
|
+
def self.obtain_integer value, constraint, argument_spec
|
74
|
+
|
75
|
+
# If no value is given, then use the default (and don't do any
|
76
|
+
# range testing)
|
77
|
+
|
78
|
+
if (value || '').empty?
|
79
|
+
|
80
|
+
def_value = argument_spec.default_value
|
81
|
+
|
82
|
+
if (def_value || '').to_s.empty?
|
83
|
+
|
84
|
+
msg = "no value specified for the option '#{argument_spec.name}', which has no default value either"
|
85
|
+
|
86
|
+
warn msg if $DEBUG
|
87
|
+
|
88
|
+
raise MissingValueException, msg
|
89
|
+
end
|
90
|
+
|
91
|
+
begin
|
92
|
+
|
93
|
+
return Integer(def_value)
|
94
|
+
rescue ArgumentError => x
|
95
|
+
|
96
|
+
msg = "default value '#{def_value}' specified for option '#{argument_spec.name}' that requires the value to be an integer"
|
97
|
+
|
98
|
+
warn msg if $DEBUG
|
99
|
+
|
100
|
+
raise InvalidIntegerException, msg
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
# obtain the integer from the value
|
105
|
+
|
106
|
+
v = nil
|
107
|
+
|
108
|
+
begin
|
109
|
+
|
110
|
+
v = Integer(value)
|
111
|
+
rescue ArgumentError => x
|
112
|
+
|
113
|
+
msg = "value '#{value}' specified for option '#{argument_spec.name}' that requires the value to be an integer"
|
114
|
+
|
115
|
+
warn msg if $DEBUG
|
116
|
+
|
117
|
+
raise InvalidIntegerException, msg
|
118
|
+
end
|
119
|
+
|
120
|
+
# Is there a value constraint?:
|
121
|
+
#
|
122
|
+
# - values (obtained from argument_spec#values)
|
123
|
+
# - range
|
124
|
+
# - minimum & maximum
|
125
|
+
|
126
|
+
values_range = argument_spec.values_range
|
127
|
+
|
128
|
+
unless values_range.empty?
|
129
|
+
|
130
|
+
v_s = v.to_s
|
131
|
+
|
132
|
+
v_s = '+' + v_s unless '-' == v_s[0]
|
133
|
+
|
134
|
+
vr_s = values_range.map { |x| x.to_s }.map { |x| '-' == x[0] ? x : '+' + x }
|
135
|
+
|
136
|
+
unless vr_s.include? v_s
|
137
|
+
|
138
|
+
msg = "given value '#{value}' specified for option '#{argument_spec.name}' does not fall within the required range"
|
139
|
+
|
140
|
+
raise IntegerOutOfRangeException, msg
|
141
|
+
end
|
142
|
+
else
|
143
|
+
|
144
|
+
case range = constraint[:range]
|
145
|
+
when :negative
|
146
|
+
|
147
|
+
if v >= 0
|
148
|
+
|
149
|
+
msg = "given value '#{value}' specified for option '#{argument_spec.name}' must be a negative integer"
|
150
|
+
|
151
|
+
raise IntegerOutOfRangeException, msg
|
152
|
+
end
|
153
|
+
when :positive
|
154
|
+
|
155
|
+
if v < 1
|
156
|
+
|
157
|
+
msg = "given value '#{value}' specified for option '#{argument_spec.name}' must be a positive integer"
|
158
|
+
|
159
|
+
raise IntegerOutOfRangeException, msg
|
160
|
+
end
|
161
|
+
when :non_positive
|
162
|
+
|
163
|
+
if v > 0
|
164
|
+
|
165
|
+
msg = "given value '#{value}' specified for option '#{argument_spec.name}' must be a non-positive integer"
|
166
|
+
|
167
|
+
raise IntegerOutOfRangeException, msg
|
168
|
+
end
|
169
|
+
when :non_negative
|
170
|
+
|
171
|
+
if v < 0
|
172
|
+
|
173
|
+
msg = "given value '#{value}' specified for option '#{argument_spec.name}' must be a non-negative integer"
|
174
|
+
|
175
|
+
raise IntegerOutOfRangeException, msg
|
176
|
+
end
|
177
|
+
when Range
|
178
|
+
|
179
|
+
unless range.include?
|
180
|
+
|
181
|
+
msg = "given value '#{value}' specified for option '#{argument_spec.name}' does not fall within the required range"
|
182
|
+
|
183
|
+
raise IntegerOutOfRangeException, msg
|
184
|
+
end
|
185
|
+
else
|
186
|
+
|
187
|
+
;
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
191
|
+
v
|
192
|
+
end
|
193
|
+
end # module Internal_
|
194
|
+
|
195
|
+
def value_from_Proc(constraint, value, arg, given_index, given_name, argument_spec, extras)
|
196
|
+
|
197
|
+
value
|
198
|
+
end
|
199
|
+
|
200
|
+
def value_from_Hash(constraint, value, arg, given_index, given_name, argument_spec, extras)
|
201
|
+
|
202
|
+
# Check if type is specified; if not, String is assumed
|
203
|
+
|
204
|
+
type = constraint[:type]
|
205
|
+
|
206
|
+
|
207
|
+
if Internal_.is_integer?(type)
|
208
|
+
|
209
|
+
return Internal_.obtain_integer(value, constraint, argument_spec)
|
210
|
+
end
|
211
|
+
|
212
|
+
|
213
|
+
value
|
214
|
+
end
|
215
|
+
end # module ValueParser
|
216
|
+
|
217
|
+
end # module util
|
218
|
+
end # module CLASP
|
219
|
+
|
220
|
+
# ############################## end of file ############################# #
|
221
|
+
|
222
|
+
|
data/lib/clasp/version.rb
CHANGED
@@ -5,12 +5,13 @@
|
|
5
5
|
# Purpose: Version for CLASP.Ruby library
|
6
6
|
#
|
7
7
|
# Created: 16th November 2014
|
8
|
-
# Updated:
|
8
|
+
# Updated: 22nd August 2020
|
9
9
|
#
|
10
10
|
# Home: http://github.com/synesissoftware/CLASP.Ruby
|
11
11
|
#
|
12
12
|
# Author: Matthew Wilson
|
13
13
|
#
|
14
|
+
# Copyright (c) 2019-2020, Matthew Wilson and Synesis Information Systems
|
14
15
|
# Copyright (c) 2014-2019, Matthew Wilson and Synesis Software
|
15
16
|
# All rights reserved.
|
16
17
|
#
|
@@ -51,9 +52,10 @@
|
|
51
52
|
module CLASP
|
52
53
|
|
53
54
|
# Current version of the CLASP.Ruby library
|
54
|
-
VERSION = '0.
|
55
|
+
VERSION = '0.22.0.1'
|
55
56
|
|
56
57
|
private
|
58
|
+
# @!visibility private
|
57
59
|
VERSION_PARTS_ = VERSION.split(/[.]/).collect { |n| n.to_i } # :nodoc:
|
58
60
|
public
|
59
61
|
# Major version of the CLASP.Ruby library
|
data/test/unit/tc_cli.rb
CHANGED
@@ -6,8 +6,6 @@ require 'clasp'
|
|
6
6
|
|
7
7
|
require 'test/unit'
|
8
8
|
|
9
|
-
require 'xqsr3/extensions/test/unit'
|
10
|
-
|
11
9
|
class Test_DefaultValue < Test::Unit::TestCase
|
12
10
|
|
13
11
|
def test_long_form_without_default
|
@@ -30,7 +28,27 @@ class Test_DefaultValue < Test::Unit::TestCase
|
|
30
28
|
assert_nil option0.value
|
31
29
|
end
|
32
30
|
|
33
|
-
def
|
31
|
+
def test_long_form_with_default_empty_value
|
32
|
+
|
33
|
+
specifications = [
|
34
|
+
|
35
|
+
CLASP.Option('--verbosity', values: [ 'silent', 'terse', 'normal', 'chatty', 'verbose' ], default_value: 'normal')
|
36
|
+
]
|
37
|
+
|
38
|
+
argv = [ '--verbosity=' ]
|
39
|
+
args = CLASP::Arguments.new(argv, specifications)
|
40
|
+
|
41
|
+
assert_equal 0, args.flags.size
|
42
|
+
assert_equal 1, args.options.size
|
43
|
+
assert_equal 0, args.values.size
|
44
|
+
|
45
|
+
option0 = args.options[0]
|
46
|
+
|
47
|
+
assert_equal '--verbosity', option0.name
|
48
|
+
assert_equal 'normal', option0.value
|
49
|
+
end
|
50
|
+
|
51
|
+
def test_long_form_with_default_missing_value
|
34
52
|
|
35
53
|
specifications = [
|
36
54
|
|
@@ -17,7 +17,7 @@ class Test_Option_required < Test::Unit::TestCase
|
|
17
17
|
assert_equal [], o.values_range
|
18
18
|
assert_equal nil, o.default_value
|
19
19
|
assert_equal ({}), o.extras
|
20
|
-
|
20
|
+
assert !o.required?
|
21
21
|
assert_equal "'--verbose' not specified; use --help for usage", o.required_message
|
22
22
|
end
|
23
23
|
|
@@ -30,7 +30,7 @@ class Test_Option_required < Test::Unit::TestCase
|
|
30
30
|
assert_equal [], o.values_range
|
31
31
|
assert_equal nil, o.default_value
|
32
32
|
assert_equal ({}), o.extras
|
33
|
-
|
33
|
+
assert !o.required?
|
34
34
|
assert_equal "Verbosity not specified; use --help for usage", o.required_message
|
35
35
|
end
|
36
36
|
|
@@ -43,7 +43,7 @@ class Test_Option_required < Test::Unit::TestCase
|
|
43
43
|
assert_equal [], o.values_range
|
44
44
|
assert_equal nil, o.default_value
|
45
45
|
assert_equal ({}), o.extras
|
46
|
-
|
46
|
+
assert o.required?
|
47
47
|
assert_equal "Verbosity not given", o.required_message
|
48
48
|
end
|
49
49
|
end
|
@@ -0,0 +1,310 @@
|
|
1
|
+
#! /usr/bin/env ruby
|
2
|
+
|
3
|
+
$:.unshift File.join(File.dirname(__FILE__), '../..', 'lib')
|
4
|
+
|
5
|
+
require 'clasp'
|
6
|
+
|
7
|
+
require 'xqsr3/extensions/test/unit' if RUBY_VERSION >= '2'
|
8
|
+
|
9
|
+
require 'test/unit'
|
10
|
+
|
11
|
+
class Test_TypedOptionValues < Test::Unit::TestCase
|
12
|
+
|
13
|
+
if RUBY_VERSION < '2'
|
14
|
+
|
15
|
+
def assert_raise_with_message(type_spec, message_spec, *args, &block)
|
16
|
+
|
17
|
+
assert_raise(type_spec, *args, &block)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_Integer_no_range
|
22
|
+
|
23
|
+
specifications = [
|
24
|
+
|
25
|
+
CLASP.Option('--level', default_value: 1234, constraint: { type: Integer })
|
26
|
+
]
|
27
|
+
|
28
|
+
# with no arguments
|
29
|
+
begin
|
30
|
+
|
31
|
+
argv = []
|
32
|
+
args = CLASP.parse argv, specifications
|
33
|
+
|
34
|
+
assert_equal 0, args.flags.size
|
35
|
+
assert_equal 0, args.options.size
|
36
|
+
assert_equal 0, args.values.size
|
37
|
+
end
|
38
|
+
|
39
|
+
# with default value
|
40
|
+
begin
|
41
|
+
|
42
|
+
argv = [ '--level=' ]
|
43
|
+
|
44
|
+
args = CLASP.parse argv, specifications
|
45
|
+
|
46
|
+
assert_equal 0, args.flags.size
|
47
|
+
assert_equal 1, args.options.size
|
48
|
+
assert_equal 0, args.values.size
|
49
|
+
|
50
|
+
opt = args.options[0]
|
51
|
+
|
52
|
+
assert_equal 0, opt.given_index
|
53
|
+
assert_equal specifications[0], opt.argument_specification
|
54
|
+
assert_equal '--level', opt.name
|
55
|
+
assert_equal '', opt.given_value
|
56
|
+
assert_equal 1234, opt.value
|
57
|
+
end
|
58
|
+
|
59
|
+
# with explicit value 0
|
60
|
+
begin
|
61
|
+
|
62
|
+
argv = [ '--level=0' ]
|
63
|
+
|
64
|
+
args = CLASP.parse argv, specifications
|
65
|
+
|
66
|
+
assert_equal 0, args.flags.size
|
67
|
+
assert_equal 1, args.options.size
|
68
|
+
assert_equal 0, args.values.size
|
69
|
+
|
70
|
+
opt = args.options[0]
|
71
|
+
|
72
|
+
assert_equal 0, opt.given_index
|
73
|
+
assert_equal specifications[0], opt.argument_specification
|
74
|
+
assert_equal '--level', opt.name
|
75
|
+
assert_equal '0', opt.given_value
|
76
|
+
assert_equal 0, opt.value
|
77
|
+
end
|
78
|
+
|
79
|
+
# with explicit value -100
|
80
|
+
begin
|
81
|
+
|
82
|
+
argv = [ '--level=-100' ]
|
83
|
+
|
84
|
+
args = CLASP.parse argv, specifications
|
85
|
+
|
86
|
+
assert_equal 0, args.flags.size
|
87
|
+
assert_equal 1, args.options.size
|
88
|
+
assert_equal 0, args.values.size
|
89
|
+
|
90
|
+
opt = args.options[0]
|
91
|
+
|
92
|
+
assert_equal 0, opt.given_index
|
93
|
+
assert_equal specifications[0], opt.argument_specification
|
94
|
+
assert_equal '--level', opt.name
|
95
|
+
assert_equal '-100', opt.given_value
|
96
|
+
assert_equal -100, opt.value
|
97
|
+
end
|
98
|
+
|
99
|
+
# with explicit value 123456789
|
100
|
+
begin
|
101
|
+
|
102
|
+
argv = [ '--level=123456789' ]
|
103
|
+
|
104
|
+
args = CLASP.parse argv, specifications
|
105
|
+
|
106
|
+
assert_equal 0, args.flags.size
|
107
|
+
assert_equal 1, args.options.size
|
108
|
+
assert_equal 0, args.values.size
|
109
|
+
|
110
|
+
opt = args.options[0]
|
111
|
+
|
112
|
+
assert_equal 0, opt.given_index
|
113
|
+
assert_equal specifications[0], opt.argument_specification
|
114
|
+
assert_equal '--level', opt.name
|
115
|
+
assert_equal '123456789', opt.given_value
|
116
|
+
assert_equal 123456789, opt.value
|
117
|
+
end
|
118
|
+
|
119
|
+
# with explicit value +123456789
|
120
|
+
begin
|
121
|
+
|
122
|
+
argv = [ '--level=+123456789' ]
|
123
|
+
|
124
|
+
args = CLASP.parse argv, specifications
|
125
|
+
|
126
|
+
assert_equal 0, args.flags.size
|
127
|
+
assert_equal 1, args.options.size
|
128
|
+
assert_equal 0, args.values.size
|
129
|
+
|
130
|
+
opt = args.options[0]
|
131
|
+
|
132
|
+
assert_equal 0, opt.given_index
|
133
|
+
assert_equal specifications[0], opt.argument_specification
|
134
|
+
assert_equal '--level', opt.name
|
135
|
+
assert_equal '+123456789', opt.given_value
|
136
|
+
assert_equal 123456789, opt.value
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
def test_Integer_positive
|
141
|
+
|
142
|
+
specifications = [
|
143
|
+
|
144
|
+
CLASP.Option('--level', default_value: 1234, constraint: { type: Integer, range: :positive })
|
145
|
+
]
|
146
|
+
|
147
|
+
# with no arguments
|
148
|
+
begin
|
149
|
+
|
150
|
+
argv = []
|
151
|
+
args = CLASP.parse argv, specifications
|
152
|
+
|
153
|
+
assert_equal 0, args.flags.size
|
154
|
+
assert_equal 0, args.options.size
|
155
|
+
assert_equal 0, args.values.size
|
156
|
+
end
|
157
|
+
|
158
|
+
# with default value
|
159
|
+
begin
|
160
|
+
|
161
|
+
argv = [ '--level=' ]
|
162
|
+
|
163
|
+
args = CLASP.parse argv, specifications
|
164
|
+
|
165
|
+
assert_equal 0, args.flags.size
|
166
|
+
assert_equal 1, args.options.size
|
167
|
+
assert_equal 0, args.values.size
|
168
|
+
|
169
|
+
opt = args.options[0]
|
170
|
+
|
171
|
+
assert_equal 0, opt.given_index
|
172
|
+
assert_equal specifications[0], opt.argument_specification
|
173
|
+
assert_equal '--level', opt.name
|
174
|
+
assert_equal '', opt.given_value
|
175
|
+
assert_equal 1234, opt.value
|
176
|
+
end
|
177
|
+
|
178
|
+
# with explicit value 0
|
179
|
+
begin
|
180
|
+
|
181
|
+
argv = [ '--level=0' ]
|
182
|
+
|
183
|
+
assert_raise_with_message(CLASP::Exceptions::IntegerOutOfRangeException, /\b0\b.*--level.*must be a positive integer/) { CLASP.parse argv, specifications }
|
184
|
+
end
|
185
|
+
|
186
|
+
# with explicit value -100
|
187
|
+
begin
|
188
|
+
|
189
|
+
argv = [ '--level=-100' ]
|
190
|
+
|
191
|
+
assert_raise_with_message(CLASP::Exceptions::IntegerOutOfRangeException, /-100\b.*--level.*must be a positive integer/) { CLASP.parse argv, specifications }
|
192
|
+
end
|
193
|
+
|
194
|
+
# with explicit value 123456789
|
195
|
+
begin
|
196
|
+
|
197
|
+
argv = [ '--level=123456789' ]
|
198
|
+
|
199
|
+
args = CLASP.parse argv, specifications
|
200
|
+
|
201
|
+
assert_equal 0, args.flags.size
|
202
|
+
assert_equal 1, args.options.size
|
203
|
+
assert_equal 0, args.values.size
|
204
|
+
|
205
|
+
opt = args.options[0]
|
206
|
+
|
207
|
+
assert_equal 0, opt.given_index
|
208
|
+
assert_equal specifications[0], opt.argument_specification
|
209
|
+
assert_equal '--level', opt.name
|
210
|
+
assert_equal '123456789', opt.given_value
|
211
|
+
assert_equal 123456789, opt.value
|
212
|
+
end
|
213
|
+
|
214
|
+
# with explicit value +123456789
|
215
|
+
begin
|
216
|
+
|
217
|
+
argv = [ '--level=+123456789' ]
|
218
|
+
|
219
|
+
args = CLASP.parse argv, specifications
|
220
|
+
|
221
|
+
assert_equal 0, args.flags.size
|
222
|
+
assert_equal 1, args.options.size
|
223
|
+
assert_equal 0, args.values.size
|
224
|
+
|
225
|
+
opt = args.options[0]
|
226
|
+
|
227
|
+
assert_equal 0, opt.given_index
|
228
|
+
assert_equal specifications[0], opt.argument_specification
|
229
|
+
assert_equal '--level', opt.name
|
230
|
+
assert_equal '+123456789', opt.given_value
|
231
|
+
assert_equal 123456789, opt.value
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
235
|
+
def test_Integer_range_values_range
|
236
|
+
|
237
|
+
specifications = [
|
238
|
+
|
239
|
+
CLASP.Option('--level', default_value: 1234, values_range: [ 1234, -1234, 7, 19 ], constraint: { type: Integer })
|
240
|
+
]
|
241
|
+
|
242
|
+
# with no arguments
|
243
|
+
begin
|
244
|
+
|
245
|
+
argv = []
|
246
|
+
args = CLASP.parse argv, specifications
|
247
|
+
|
248
|
+
assert_equal 0, args.flags.size
|
249
|
+
assert_equal 0, args.options.size
|
250
|
+
assert_equal 0, args.values.size
|
251
|
+
end
|
252
|
+
|
253
|
+
# with default value
|
254
|
+
begin
|
255
|
+
|
256
|
+
argv = [ '--level=' ]
|
257
|
+
|
258
|
+
args = CLASP.parse argv, specifications
|
259
|
+
|
260
|
+
assert_equal 0, args.flags.size
|
261
|
+
assert_equal 1, args.options.size
|
262
|
+
assert_equal 0, args.values.size
|
263
|
+
|
264
|
+
opt = args.options[0]
|
265
|
+
|
266
|
+
assert_equal 0, opt.given_index
|
267
|
+
assert_equal specifications[0], opt.argument_specification
|
268
|
+
assert_equal '--level', opt.name
|
269
|
+
assert_equal '', opt.given_value
|
270
|
+
assert_equal 1234, opt.value
|
271
|
+
end
|
272
|
+
|
273
|
+
# with explicit value 0
|
274
|
+
begin
|
275
|
+
|
276
|
+
argv = [ '--level=0' ]
|
277
|
+
|
278
|
+
assert_raise_with_message(CLASP::Exceptions::IntegerOutOfRangeException, /\b0\b.*--level.*does not fall within the required range/) { CLASP.parse argv, specifications }
|
279
|
+
end
|
280
|
+
|
281
|
+
spec0 = specifications[0]
|
282
|
+
values = spec0.values_range.sort[0]..spec0.values_range.sort[-1]
|
283
|
+
|
284
|
+
values.each do |val|
|
285
|
+
|
286
|
+
argv = [ "--level=#{val}" ]
|
287
|
+
|
288
|
+
if spec0.values_range.include? val
|
289
|
+
|
290
|
+
args = CLASP.parse argv, specifications
|
291
|
+
|
292
|
+
assert_equal 0, args.flags.size
|
293
|
+
assert_equal 1, args.options.size
|
294
|
+
assert_equal 0, args.values.size
|
295
|
+
|
296
|
+
opt = args.options[0]
|
297
|
+
|
298
|
+
assert_equal 0, opt.given_index
|
299
|
+
assert_equal specifications[0], opt.argument_specification
|
300
|
+
assert_equal '--level', opt.name
|
301
|
+
assert_equal val.to_s, opt.given_value
|
302
|
+
assert_equal val, opt.value
|
303
|
+
else
|
304
|
+
|
305
|
+
assert_raise_with_message(CLASP::Exceptions::IntegerOutOfRangeException, /#{val}\b.*--level.*does not fall within the required range/) { CLASP.parse argv, specifications }
|
306
|
+
end
|
307
|
+
end
|
308
|
+
end
|
309
|
+
end
|
310
|
+
|