clasp-ruby 0.20.3 → 0.21.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 5d4b4a9b8453b84575f693c6c1cf3d58c0af5999843c360295f799d60dc6b57d
4
+ data.tar.gz: 2089b0ead4ef6161d6cdda4d2129f2361567d434ea5aa3bcb257918093bdad7a
5
+ SHA512:
6
+ metadata.gz: c24103543ec9d290ae1731ab49a8937e02148b48e567c199ed1c3bb7a12edda0c892b4cd36eeb0fa6a8232fd9936db2fbae254e8db1a835bdf054a3df0f82af0
7
+ data.tar.gz: c1ea7534927c52c7c138da6da8f43c2c28f13222f35ff751c5d6b4a6aa456d18b6e655de5eaec3373d21aee864913d4ae6dc70d32e7d6e0b33815dc3fe40f57e
@@ -46,7 +46,8 @@
46
46
 
47
47
 
48
48
 
49
- require File.join(File.dirname(__FILE__), 'specifications.rb')
49
+ require File.join(File.dirname(__FILE__), 'specifications')
50
+ require File.join(File.dirname(__FILE__), 'util', 'value_parser')
50
51
 
51
52
  require 'yaml'
52
53
 
@@ -136,17 +137,40 @@ class Arguments
136
137
  # Class that represents a parsed option
137
138
  class OptionArgument
138
139
 
140
+ include ::CLASP::Util::ValueParser
141
+
139
142
  # @!visibility private
140
143
  #
141
144
  # [PRIVATE] This method is subject to changed between versions and
142
145
  # should not be called directly from application code
143
146
  def initialize(arg, given_index, given_name, resolved_name, argument_spec, given_hyphens, given_label, value, extras) # :nodoc:
144
147
 
145
- actual_value = value
148
+ resolved_value = nil
149
+
150
+ if argument_spec
151
+
152
+ case constraint = (argument_spec.constraint || {})
153
+ =begin
154
+ when Proc
155
+
156
+ resolved_value = value_from_Proc(constraint, value, arg, given_index, given_name, argument_spec, extras)
157
+ =end
158
+ when Hash
159
+
160
+ if constraint.empty?
161
+
162
+ resolved_value = (value || '').empty? ? argument_spec.default_value : value
163
+ else
164
+
165
+ resolved_value = value_from_Hash(constraint, value, arg, given_index, given_name, argument_spec, extras)
166
+ end
167
+ else
146
168
 
147
- if (value || '').empty? && argument_spec
169
+ warn "unexpected constraint on argument specification #{argument_spec} when parsing argument '#{arg}'"
170
+ end
171
+ else
148
172
 
149
- actual_value = argument_spec.default_value
173
+ resolved_value = value
150
174
  end
151
175
 
152
176
  @arg = arg
@@ -155,7 +179,8 @@ class Arguments
155
179
  @argument_specification = argument_spec
156
180
  @given_hyphens = given_hyphens
157
181
  @given_label = given_label
158
- @value = actual_value
182
+ @given_value = value
183
+ @value = resolved_value
159
184
  @name = resolved_name || given_name
160
185
  @extras = extras.nil? ? {} : extras
161
186
  end
@@ -172,7 +197,9 @@ class Arguments
172
197
  attr_reader :given_label
173
198
  # (String) The resolved name of the argument
174
199
  attr_reader :name
175
- # (String) The value of the option
200
+ # (String) The given value of the option
201
+ attr_reader :given_value
202
+ # (????) The value of the option, which may be of a type other than string subject to the option specification's constraint
176
203
  attr_reader :value
177
204
  # (Object, Hash) The extras associated with the argument
178
205
  attr_reader :extras
@@ -458,7 +485,7 @@ class Arguments
458
485
  values = []
459
486
 
460
487
  forced_value = false
461
- want_option_value = false
488
+ pending_option = nil
462
489
 
463
490
  argv.each_with_index do |arg, index|
464
491
 
@@ -563,15 +590,22 @@ class Arguments
563
590
 
564
591
  if argument_spec and argument_spec.is_a? CLASP::OptionSpecification and not value
565
592
 
566
- want_option_value = true
567
- options << OptionArgument.new(arg, index, given_name, resolved_name, argument_spec, hyphens.size, given_label, nil, argument_spec ? argument_spec.extras : nil)
593
+ pending_option = {
594
+
595
+ arg: arg,
596
+ index: index,
597
+ given_name: given_name,
598
+ resolved_name: resolved_name,
599
+ argument_spec: argument_spec,
600
+ hyphens_size: hyphens.size,
601
+ given_label: given_label,
602
+ extras: argument_spec ? argument_spec.extras : nil,
603
+ }
568
604
  elsif value
569
605
 
570
- want_option_value = false
571
606
  options << OptionArgument.new(arg, index, given_name, resolved_name, argument_spec, hyphens.size, given_label, value, argument_spec ? argument_spec.extras : nil)
572
607
  else
573
608
 
574
- want_option_value = false
575
609
  flags << FlagArgument.new(arg, index, given_name, resolved_name, argument_spec, hyphens.size, given_label, argument_spec ? argument_spec.extras : nil)
576
610
  end
577
611
 
@@ -579,20 +613,31 @@ class Arguments
579
613
  end
580
614
  end
581
615
 
582
- if want_option_value and not forced_value
616
+ if pending_option
583
617
 
584
- option = options[-1]
585
- option.instance_eval("@value='#{arg}'")
586
- want_option_value = false
587
- else
618
+ value = forced_value ? nil : arg
588
619
 
589
- arg = arg.dup
590
- arg_ix = ::Integer === index ? index : index.dup
620
+ options << OptionArgument.new(pending_option[:arg], pending_option[:index], pending_option[:given_name], pending_option[:resolved_name], pending_option[:argument_spec], pending_option[:hyphens_size], pending_option[:given_label], value, pending_option[:extras])
591
621
 
592
- arg.define_singleton_method(:given_index) { arg_ix }
622
+ pending_option = nil
593
623
 
594
- values << arg
624
+ next unless forced_value
595
625
  end
626
+
627
+ arg = arg.dup
628
+ arg_ix = ::Integer === index ? index : index.dup
629
+
630
+ arg.define_singleton_method(:given_index) { arg_ix }
631
+
632
+ values << arg
633
+ end
634
+
635
+ if pending_option
636
+
637
+ value = nil
638
+
639
+ options << OptionArgument.new(pending_option[:arg], pending_option[:index], pending_option[:given_name], pending_option[:resolved_name], pending_option[:argument_spec], pending_option[:hyphens_size], pending_option[:given_label], value, pending_option[:extras])
640
+
596
641
  end
597
642
 
598
643
  return flags, options, values
data/lib/clasp/clasp.rb CHANGED
@@ -50,6 +50,15 @@ require 'clasp/specifications'
50
50
  require 'clasp/cli'
51
51
  require 'clasp/version'
52
52
 
53
+ module CLASP
54
+
55
+ # TBC (but is a shorthand for calling +Arguments.new()+
56
+ def self.parse(argv = ARGV, specifications = nil, options = {})
57
+
58
+ return Arguments.new(argv, specifications, options)
59
+ end
60
+ end # module CLASP
61
+
53
62
  # ############################## end of file ############################# #
54
63
 
55
64
 
@@ -69,6 +69,8 @@ class FlagSpecification
69
69
  # - +aliases+ (+Array+) 0 or more strings specifying short-form or option-value aliases
70
70
  # - +help+ (+String+) The help string, which may be +nil+
71
71
  # - +extras+ An application-defined additional parameter. If +nil+, it is assigned an empty +Hash+
72
+ #
73
+ # *NOTE:* Users should prefer the +CLASP::Flag()+ method
72
74
  def initialize(name, aliases, help, extras = nil)
73
75
 
74
76
  @name = name
@@ -169,8 +171,11 @@ class OptionSpecification
169
171
  # - +default_value+ (+String+) The default value of the option, which will be used in the case where an option is specified without a value. May be +nil+
170
172
  # - +required+ (boolean) Whether the option is required. May be +nil+
171
173
  # - +required_message+ (::String) Message to be used when reporting that a required option is missing. May be +nil+ in which case a message of the form "<option-name> not specified; use --help for usage". If begins with the nul character ("\0"), then is used in the place of the <option-name> and placed into the rest of the standard form message
174
+ # - +constraint+ (Hash) Constraint to be applied to the parsed values of options matching this specification. NOTE: only integer constraints are supported in the current version
172
175
  # - +extras+ An application-defined additional parameter. If +nil+, it is assigned an empty +Hash+
173
- def initialize(name, aliases, help, values_range, default_value, required, required_message, extras = nil)
176
+ #
177
+ # *NOTE:* Users should prefer the +CLASP::Option()+ method
178
+ def initialize(name, aliases, help, values_range, default_value, required, required_message, constraint, extras = nil)
174
179
 
175
180
  @name = name
176
181
  @aliases = (aliases || []).select { |a| a and not a.empty? }
@@ -179,6 +184,7 @@ class OptionSpecification
179
184
  @default_value = default_value
180
185
  @required = required
181
186
  @required_message = nil
187
+ @constraint = constraint || {}
182
188
  @extras = extras || {}
183
189
 
184
190
  rm_name = nil
@@ -214,16 +220,17 @@ class OptionSpecification
214
220
  attr_reader :default_value
215
221
  # Indicates whether the option is required
216
222
  def required?; @required; end
217
- # The message to be used when reporting that a required option is
218
- # missing
223
+ # The message to be used when reporting that a required option is missing
219
224
  attr_reader :required_message
225
+ # The value constraint
226
+ attr_reader :constraint
220
227
  # The option's extras
221
228
  attr_reader :extras
222
229
 
223
230
  # String form of the option
224
231
  def to_s
225
232
 
226
- "{#{name}; aliases=#{aliases.join(', ')}; values_range=[ #{values_range.join(', ')} ]; default_value='#{default_value}'; help='#{help}'; required?=#{required?}; extras=#{extras}}"
233
+ "{#{name}; aliases=#{aliases.join(', ')}; values_range=[ #{values_range.join(', ')} ]; default_value='#{default_value}'; help='#{help}'; required?=#{required?}; required_message=#{required_message}; constraint=#{constraint}; extras=#{extras}}"
227
234
  end
228
235
 
229
236
  # @!visibility private
@@ -366,6 +373,7 @@ end
366
373
  # - +required+ (boolean) Whether the option is required. May be +nil+
367
374
  # - +required_message+ (::String) Message to be used when reporting that a required option is missing. May be +nil+ in which case a message of the form "<option-name> not specified; use --help for usage". If begins with the nul character ("\0"), then is used in the place of the <option-name> and placed into the rest of the standard form message
368
375
  # - +extras+ An application-defined additional parameter. If +nil+, it is assigned an empty +Hash+.
376
+ # - +constraint+ (Hash) Constraint to be applied to the parsed values of options matching this specification. NOTE: only integer constraints are supported in the current version
369
377
  # - +:values_range+ (::Array) An array defining the accepted values for the option
370
378
  # - +:values+ [DEPRECATED] Alternative to +:values_range+
371
379
  def CLASP.Option(name, options = {})
@@ -376,6 +384,7 @@ def CLASP.Option(name, options = {})
376
384
  default_value = nil
377
385
  required = false
378
386
  require_message = nil
387
+ constraint = nil
379
388
  extras = nil
380
389
 
381
390
  options.each do |k, v|
@@ -407,6 +416,9 @@ def CLASP.Option(name, options = {})
407
416
  when :extras
408
417
 
409
418
  extras = v
419
+ when :constraint
420
+
421
+ constraint = v
410
422
  else
411
423
 
412
424
  raise ArgumentError, "invalid option for option: '#{k}' => '#{v}'"
@@ -417,7 +429,7 @@ def CLASP.Option(name, options = {})
417
429
  end
418
430
  end
419
431
 
420
- CLASP::OptionSpecification.new(name, aliases, help, values_range, default_value, required, require_message, extras)
432
+ CLASP::OptionSpecification.new(name, aliases, help, values_range, default_value, required, require_message, constraint, extras)
421
433
  end
422
434
 
423
435
  def CLASP.Alias(name, *args)
@@ -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
@@ -51,7 +51,7 @@
51
51
  module CLASP
52
52
 
53
53
  # Current version of the CLASP.Ruby library
54
- VERSION = '0.20.3'
54
+ VERSION = '0.21.0'
55
55
 
56
56
  private
57
57
  # @!visibility private
@@ -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
+
metadata CHANGED
@@ -1,72 +1,66 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: clasp-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.20.3
5
- prerelease:
4
+ version: 0.21.0
6
5
  platform: ruby
7
6
  authors:
8
7
  - Matt Wilson
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2019-04-20 00:00:00.000000000 Z
11
+ date: 2019-04-28 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: xqsr3
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
- - - ~>
17
+ - - "~>"
20
18
  - !ruby/object:Gem::Version
21
19
  version: '0.30'
22
20
  type: :development
23
21
  prerelease: false
24
22
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
23
  requirements:
27
- - - ~>
24
+ - - "~>"
28
25
  - !ruby/object:Gem::Version
29
26
  version: '0.30'
30
- description: ! 'Command-Line Argument Sorting and Parsing library that provides a
31
- powerful
32
-
33
- abstraction of command-line interpretation facilities. CLASP.Ruby is a Ruby port
34
- of the popular CLASP (C/C++) library, and provides declarative specification of
35
- command-line flags and options, aliasing, flag combination, UNIX de-facto standard
36
- flag processing, and a number of utility functions for expressing usage and version
37
- information.
38
-
39
- '
27
+ description: |
28
+ Command-Line Argument Sorting and Parsing library that provides a powerful
29
+ abstraction of command-line interpretation facilities. CLASP.Ruby is a Ruby port of the popular CLASP (C/C++) library, and provides declarative specification of command-line flags and options, aliasing, flag combination, UNIX de-facto standard flag processing, and a number of utility functions for expressing usage and version information.
40
30
  email: matthew@synesis.com.au
41
31
  executables: []
42
32
  extensions: []
43
33
  extra_rdoc_files: []
44
34
  files:
35
+ - LICENSE
36
+ - README.md
45
37
  - examples/cr-example.rb
46
38
  - examples/flag_and_option_specifications.md
47
39
  - examples/flag_and_option_specifications.rb
48
40
  - examples/show_usage_and_version.md
49
41
  - examples/show_usage_and_version.rb
50
42
  - examples/simple_command_line_no_specifications.rb
43
+ - lib/clasp-ruby.rb
44
+ - lib/clasp.rb
51
45
  - lib/clasp/arguments.rb
52
46
  - lib/clasp/clasp.rb
53
47
  - lib/clasp/cli.rb
54
48
  - lib/clasp/doc_.rb
55
49
  - lib/clasp/old_module.rb
56
50
  - lib/clasp/specifications.rb
51
+ - lib/clasp/util/exceptions.rb
52
+ - lib/clasp/util/value_parser.rb
57
53
  - lib/clasp/version.rb
58
- - lib/clasp-ruby.rb
59
- - lib/clasp.rb
60
54
  - test/scratch/test_list_command_line.rb
61
55
  - test/scratch/test_specifications.rb
62
56
  - test/scratch/test_usage.rb
63
57
  - test/scratch/test_usage_from_DATA.rb
64
58
  - test/scratch/test_usage_with_duplicate_specifications.rb
59
+ - test/unit/tc_ARGV_rewrite.rb
65
60
  - test/unit/tc_arguments_1.rb
66
61
  - test/unit/tc_arguments_2.rb
67
62
  - test/unit/tc_arguments_3.rb
68
63
  - test/unit/tc_arguments_inspect.rb
69
- - test/unit/tc_ARGV_rewrite.rb
70
64
  - test/unit/tc_cli.rb
71
65
  - test/unit/tc_default_value.rb
72
66
  - test/unit/tc_defaults_1.rb
@@ -75,33 +69,31 @@ files:
75
69
  - test/unit/tc_option_required.rb
76
70
  - test/unit/tc_option_value_aliases.rb
77
71
  - test/unit/tc_specifications.rb
72
+ - test/unit/tc_typed_options.rb
78
73
  - test/unit/tc_usage.rb
79
74
  - test/unit/ts_all.rb
80
- - README.md
81
- - LICENSE
82
75
  homepage: http://github.com/synesissoftware/CLASP.Ruby
83
76
  licenses:
84
77
  - BSD-3-Clause
78
+ metadata: {}
85
79
  post_install_message:
86
80
  rdoc_options: []
87
81
  require_paths:
88
82
  - lib
89
83
  required_ruby_version: !ruby/object:Gem::Requirement
90
- none: false
91
84
  requirements:
92
- - - ! '>='
85
+ - - ">="
93
86
  - !ruby/object:Gem::Version
94
87
  version: 1.9.3
95
88
  required_rubygems_version: !ruby/object:Gem::Requirement
96
- none: false
97
89
  requirements:
98
- - - ! '>='
90
+ - - ">="
99
91
  - !ruby/object:Gem::Version
100
92
  version: '0'
101
93
  requirements: []
102
94
  rubyforge_project:
103
- rubygems_version: 1.8.23.2
95
+ rubygems_version: 2.7.6
104
96
  signing_key:
105
- specification_version: 3
97
+ specification_version: 4
106
98
  summary: CLASP.Ruby
107
99
  test_files: []