parameters 0.3.1 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,3 +1,8 @@
1
+ ### 0.4.0 / 2011-12-29
2
+
3
+ * Added {Parameters::Options}.
4
+ * Added {Parameters::Types} which handles type coercion for Parameters.
5
+
1
6
  ### 0.3.1 / 2011-12-16
2
7
 
3
8
  * Do not coerce `nil` values.
@@ -4,16 +4,14 @@ require 'parameters/extensions/meta'
4
4
 
5
5
  module Parameters
6
6
  module ClassMethods
7
- def included(base)
8
- base.extend ClassMethods
9
- end
10
-
11
7
  #
12
8
  # @return [Hash]
13
9
  # Parameters for the class.
14
10
  #
11
+ # @api semipublic
12
+ #
15
13
  def params
16
- @_params ||= {}
14
+ @parameters ||= {}
17
15
  end
18
16
 
19
17
  #
@@ -26,6 +24,8 @@ module Parameters
26
24
  # Test.params = {:x => 5, :y => 2}
27
25
  # # => {:x=>5, :y=>2}
28
26
  #
27
+ # @api semipublic
28
+ #
29
29
  def params=(values)
30
30
  values.each do |name,value|
31
31
  if has_param?(name)
@@ -64,6 +64,8 @@ module Parameters
64
64
  # @example
65
65
  # parameter 'var', :default => 3, :description => 'my variable'
66
66
  #
67
+ # @api public
68
+ #
67
69
  def parameter(name,options={})
68
70
  name = name.to_sym
69
71
 
@@ -77,6 +79,11 @@ module Parameters
77
79
  get_param(name).value = value
78
80
  end
79
81
 
82
+ # define the ? method, to determine if the parameter is set
83
+ meta_def("#{name}?") do
84
+ !!get_param(name).value
85
+ end
86
+
80
87
  # define the reader instance methods for the parameter
81
88
  define_method(name) do
82
89
  get_param(name).value
@@ -87,6 +94,11 @@ module Parameters
87
94
  get_param(name).value = value
88
95
  end
89
96
 
97
+ # define the ? method, to determine if the parameter is set
98
+ define_method("#{name}?") do
99
+ !!get_param(name).value
100
+ end
101
+
90
102
  # create the new parameter
91
103
  new_param = Parameters::ClassParam.new(
92
104
  name,
@@ -107,6 +119,8 @@ module Parameters
107
119
  # Specifies whether or not there is a class parameter with the
108
120
  # specified name.
109
121
  #
122
+ # @api semipublic
123
+ #
110
124
  def has_param?(name)
111
125
  name = name.to_sym
112
126
 
@@ -131,6 +145,8 @@ module Parameters
131
145
  # @raise [ParamNotFound]
132
146
  # No class parameter with the specified name could be found.
133
147
  #
148
+ # @api semipublic
149
+ #
134
150
  def get_param(name)
135
151
  name = name.to_sym
136
152
 
@@ -162,6 +178,8 @@ module Parameters
162
178
  #
163
179
  # @since 0.3.0
164
180
  #
181
+ # @api semipublic
182
+ #
165
183
  def set_param(name,value)
166
184
  name = name.to_sym
167
185
 
@@ -182,8 +200,10 @@ module Parameters
182
200
  # @yield [param]
183
201
  # The block that will be passed each class parameter.
184
202
  #
203
+ # @api semipublic
204
+ #
185
205
  def each_param(&block)
186
- ancestors.each do |ancestor|
206
+ ancestors.reverse_each do |ancestor|
187
207
  if ancestor.included_modules.include?(Parameters)
188
208
  ancestor.params.each_value(&block)
189
209
  end
@@ -201,6 +221,8 @@ module Parameters
201
221
  # @raise [ParamNotFound]
202
222
  # No class parameter with the specified name could be found.
203
223
  #
224
+ # @api semipublic
225
+ #
204
226
  def describe_param(name)
205
227
  get_param(name).description
206
228
  end
@@ -214,6 +236,8 @@ module Parameters
214
236
  # @raise [ParamNotFound]
215
237
  # No class parameter with the specified name could be found.
216
238
  #
239
+ # @api semipublic
240
+ #
217
241
  def param_value(name)
218
242
  get_param(name).value
219
243
  end
@@ -72,8 +72,8 @@ module Parameters
72
72
  def to_s
73
73
  text = @name.to_s
74
74
 
75
- text << " [#{@value.inspect}]" if @value
76
- text << "\t#{@description}" if @description
75
+ text << "\t[#{@value.inspect}]" if @value
76
+ text << "\t#{@description}" if @description
77
77
 
78
78
  return text
79
79
  end
@@ -25,6 +25,8 @@ module Parameters
25
25
  # @param [Object] value
26
26
  # The initial value for the instance parameter.
27
27
  #
28
+ # @api semipublic
29
+ #
28
30
  def initialize(object,name,type=nil,description=nil,value=nil)
29
31
  super(name,type,description)
30
32
 
@@ -76,8 +78,8 @@ module Parameters
76
78
  def to_s
77
79
  text = @name.to_s
78
80
 
79
- text << " [#{value.inspect}]" if value
80
- text << "\t#{@description}" if @description
81
+ text << "\t[#{value.inspect}]" if value
82
+ text << "\t#{@description}" if @description
81
83
 
82
84
  return text
83
85
  end
@@ -0,0 +1,28 @@
1
+ require 'parameters/class_methods'
2
+
3
+ module Parameters
4
+ module ModuleMethods
5
+ #
6
+ # Ensures that the module will re-extend Parameters::ClassMethods,
7
+ # when included.
8
+ #
9
+ def included(base)
10
+ base.extend ClassMethods
11
+
12
+ if base.kind_of?(Module)
13
+ # re-extend the ModuleMethods
14
+ base.extend ModuleMethods
15
+ end
16
+ end
17
+
18
+ #
19
+ # Ensures that the module will initialize parameters, when extended
20
+ # into an Object.
21
+ #
22
+ def extended(object)
23
+ each_param do |param|
24
+ object.params[param.name] = param.to_instance(object)
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,222 @@
1
+ require 'parameters/param'
2
+ require 'parameters/types'
3
+
4
+ require 'optparse'
5
+
6
+ module Parameters
7
+ #
8
+ # @since 0.4.0
9
+ #
10
+ module Options
11
+ # The usage messages for various Parameter {Types}.
12
+ USAGES = {
13
+ Types::Integer => 'NUM',
14
+ Types::Float => 'DEC',
15
+ Types::Symbol => 'NAME',
16
+ Types::Time => 'TIME',
17
+ Types::DateTime => 'DATE|TIME',
18
+ Types::Date => 'DATE',
19
+ Types::Regexp => 'REGEXP',
20
+ Types::URI => 'URI',
21
+ Types::Array => 'VALUE [...]',
22
+ Types::Set => 'VALUE [...]',
23
+ Types::Hash => 'NAME:VALUE [...]'
24
+ }
25
+
26
+ # The OptionParser acceptance classes for various Parameter {Types}.
27
+ ACCEPTS = {
28
+ Types::Object => Object,
29
+ Types::Boolean => TrueClass,
30
+ Types::Integer => Integer,
31
+ Types::Float => Float,
32
+ Types::Symbol => Symbol,
33
+ Types::String => String,
34
+ Types::Time => String,
35
+ Types::DateTime => String,
36
+ Types::Date => String,
37
+ Types::URI => String
38
+ }
39
+
40
+ #
41
+ # Returns the option flag for the given parameter.
42
+ #
43
+ # @param [Param] param
44
+ # The parameter.
45
+ #
46
+ # @return [String]
47
+ # The option flag.
48
+ #
49
+ # @api semipublic
50
+ #
51
+ def self.flag(param)
52
+ name = param.name.to_s.gsub('_','-')
53
+
54
+ if param.type == Types::Boolean
55
+ "--[no-]#{name}"
56
+ else
57
+ "--#{name}"
58
+ end
59
+ end
60
+
61
+ #
62
+ # Returns the Usage String for the parameter.
63
+ #
64
+ # @param [Param] param
65
+ # The parameter.
66
+ #
67
+ # @return [String]
68
+ # The Usage String.
69
+ #
70
+ # @api semipublic
71
+ #
72
+ def self.usage(param)
73
+ name = param.name.to_s
74
+
75
+ type_usage = lambda { |type|
76
+ if type.class == Types::Hash
77
+ type_usage[type.key_type] + ':' +
78
+ type_usage[type.value_type] + ' [...]'
79
+ elsif type.class <= Types::Array
80
+ type_usage[type.element_type] + ' [...]'
81
+ elsif (type == Types::String) ||
82
+ (type == Types::Object)
83
+ name.upcase
84
+ else
85
+ USAGES[type]
86
+ end
87
+ }
88
+
89
+ return type_usage[param.type]
90
+ end
91
+
92
+ #
93
+ # Returns the OptionParser acceptance class for the parameter.
94
+ #
95
+ # @param [Param] param
96
+ # The parameter.
97
+ #
98
+ # @return [Class]
99
+ # The acceptance class.
100
+ #
101
+ # @api semipublic
102
+ #
103
+ def self.accepts(param)
104
+ type = param.type
105
+
106
+ if type <= Types::Hash
107
+ Hash
108
+ elsif type <= Types::Array
109
+ Array
110
+ else
111
+ ACCEPTS[type]
112
+ end
113
+ end
114
+
115
+ #
116
+ # Defines an option for the parameter.
117
+ #
118
+ # @param [OptionParser] opts
119
+ # The option parser.
120
+ #
121
+ # @param [Param] param
122
+ # The parameter.
123
+ #
124
+ # @param [Hash] options
125
+ # Additional options for the option.
126
+ #
127
+ # @option options [String] :flag
128
+ # The short flag for the option.
129
+ #
130
+ # @option options [String] :usage
131
+ # The USAGE String for the option.
132
+ #
133
+ # @api public
134
+ #
135
+ def self.define(opts,param,options={})
136
+ short_flag = options[:flag]
137
+ long_flag = flag(param)
138
+ usage = (options[:usage] || self.usage(param))
139
+
140
+ args = []
141
+
142
+ args << short_flag if short_flag
143
+ args << if usage
144
+ "#{long_flag} [#{usage}]"
145
+ else
146
+ long_flag
147
+ end
148
+
149
+ args << accepts(param)
150
+
151
+ args << "#{param.description}." if param.description
152
+ args << "Default: #{param.value.inspect}" if param.value
153
+
154
+ if param.type <= Types::Hash
155
+ opts.on(*args) do |value|
156
+ if param.value.nil?
157
+ param.value = value
158
+ else
159
+ param.value.merge!(param.coerce(value))
160
+ end
161
+ end
162
+ elsif param.type <= Types::Array
163
+ opts.on(*args) do |value|
164
+ if param.value.nil?
165
+ param.value = value
166
+ else
167
+ param.value += param.coerce(value)
168
+ end
169
+ end
170
+ else
171
+ opts.on(*args) do |value|
172
+ param.value = value
173
+ end
174
+ end
175
+ end
176
+
177
+ #
178
+ # Defines an OptionParser for a set of parameters.
179
+ #
180
+ # @param [Parameter] object
181
+ # The Class or Object which included Parameters.
182
+ #
183
+ # @param [OptionParser] opts
184
+ # The option parser to define the parameter options within.
185
+ #
186
+ # @yield [opts]
187
+ # If a block is given, it will be passed the newly created OptionParser.
188
+ #
189
+ # @yieldparam [OptionParser] opts
190
+ # The newly created OptionParser.
191
+ #
192
+ # @return [OptionParser]
193
+ # The defined OptionParser.
194
+ #
195
+ # @api public
196
+ #
197
+ def self.parser(object)
198
+ OptionParser.new do |opts|
199
+ object.each_param do |param|
200
+ define(opts,param)
201
+ end
202
+
203
+ yield opts if block_given?
204
+ end
205
+ end
206
+
207
+ protected
208
+
209
+ # accept pattern for Symbols
210
+ OptionParser.accept(Symbol, /[A-Za-z][A-Za-z0-9_-]*/) do |s,|
211
+ s.to_sym if s
212
+ end
213
+
214
+ # accept pattern for Hashes
215
+ OptionParser.accept(Hash, /[^\s:]*:[^\s:]*(\s+[^\s:]*:[^\s:])*/) do |s,|
216
+ if s
217
+ Hash[s.split.map { |key_value| key_value.split(':',2) }]
218
+ end
219
+ end
220
+
221
+ end
222
+ end
@@ -24,6 +24,8 @@ module Parameters
24
24
  # @param [String, nil] description
25
25
  # The description of the parameter.
26
26
  #
27
+ # @api semipublic
28
+ #
27
29
  def initialize(name,type=nil,description=nil)
28
30
  @name = name.to_sym
29
31
  @type = if (type.kind_of?(Types::Type)) ||
@@ -36,8 +38,6 @@ module Parameters
36
38
  @description = description
37
39
  end
38
40
 
39
- protected
40
-
41
41
  #
42
42
  # Coerces the value into the param type.
43
43
  #
@@ -47,6 +47,8 @@ module Parameters
47
47
  # @return [Object]
48
48
  # The coerced value.
49
49
  #
50
+ # @api semipublic
51
+ #
50
52
  def coerce(value)
51
53
  if (value.nil? || (@type === value))
52
54
  value
@@ -1,5 +1,6 @@
1
1
  require 'parameters/exceptions'
2
2
  require 'parameters/class_methods'
3
+ require 'parameters/module_methods'
3
4
  require 'parameters/class_param'
4
5
  require 'parameters/instance_param'
5
6
  require 'parameters/exceptions'
@@ -8,6 +9,11 @@ require 'parameters/extensions/meta'
8
9
  module Parameters
9
10
  def self.included(base)
10
11
  base.extend ClassMethods
12
+
13
+ if base.kind_of?(Module)
14
+ # add Module specific methods
15
+ base.extend Parameters::ModuleMethods
16
+ end
11
17
  end
12
18
 
13
19
  #
@@ -17,9 +23,13 @@ module Parameters
17
23
  # @param [Hash] values
18
24
  # The names and values to initialize the instance parameters to.
19
25
  #
26
+ # @api public
27
+ #
20
28
  def initialize_params(values={})
21
- self.class.each_param do |param|
22
- self.params[param.name] = param.to_instance(self)
29
+ if self.class.included_modules.include?(Parameters)
30
+ self.class.each_param do |param|
31
+ self.params[param.name] = param.to_instance(self)
32
+ end
23
33
  end
24
34
 
25
35
  self.params = values if values.kind_of?(Hash)
@@ -30,6 +40,8 @@ module Parameters
30
40
  # is passed in as the first argument, it will be used to set the values
31
41
  # of parameters described within the `Hash`.
32
42
  #
43
+ # @api public
44
+ #
33
45
  def initialize(*args,&block)
34
46
  initialize_params(args.first)
35
47
  end
@@ -61,6 +73,8 @@ module Parameters
61
73
  # @example
62
74
  # obj.parameter('var',:default => 3, :description => 'my variable')
63
75
  #
76
+ # @api public
77
+ #
64
78
  def parameter(name,options={})
65
79
  name = name.to_sym
66
80
 
@@ -74,6 +88,10 @@ module Parameters
74
88
  def #{name}=(new_value)
75
89
  get_param(#{name.inspect}).value = new_value
76
90
  end
91
+
92
+ def #{name}?
93
+ !!get_param(#{name.inspect}).value
94
+ end
77
95
  }
78
96
 
79
97
  # create the new parameter
@@ -94,6 +112,8 @@ module Parameters
94
112
  # @return [Hash]
95
113
  # The parameteres of the class and it's ancestors.
96
114
  #
115
+ # @api semipublic
116
+ #
97
117
  def class_params
98
118
  self.class.params
99
119
  end
@@ -102,8 +122,10 @@ module Parameters
102
122
  # @return [Hash]
103
123
  # The instance parameters of the object.
104
124
  #
125
+ # @api semipublic
126
+ #
105
127
  def params
106
- @_params ||= {}
128
+ @parameters ||= {}
107
129
  end
108
130
 
109
131
  #
@@ -116,6 +138,8 @@ module Parameters
116
138
  # obj.params = {:x => 5, :y => 2}
117
139
  # # => {:x=>5, :y=>2}
118
140
  #
141
+ # @api semipublic
142
+ #
119
143
  def params=(values)
120
144
  values.each do |name,value|
121
145
  name = name.to_sym
@@ -138,6 +162,8 @@ module Parameters
138
162
  # @yield [param]
139
163
  # The block that will be passed each instance parameter.
140
164
  #
165
+ # @api semipublic
166
+ #
141
167
  def each_param(&block)
142
168
  self.params.each_value(&block)
143
169
  end
@@ -150,6 +176,8 @@ module Parameters
150
176
  # @example
151
177
  # obj.has_param?('rhost') # => true
152
178
  #
179
+ # @api semipublic
180
+ #
153
181
  def has_param?(name)
154
182
  self.params.has_key?(name.to_sym)
155
183
  end
@@ -169,6 +197,8 @@ module Parameters
169
197
  # @example
170
198
  # obj.get_param('var') # => InstanceParam
171
199
  #
200
+ # @api semipublic
201
+ #
172
202
  def get_param(name)
173
203
  name = name.to_sym
174
204
 
@@ -200,6 +230,8 @@ module Parameters
200
230
  #
201
231
  # @since 0.3.0
202
232
  #
233
+ # @api semipublic
234
+ #
203
235
  def set_param(name,value)
204
236
  name = name.to_sym
205
237
 
@@ -225,6 +257,8 @@ module Parameters
225
257
  # @example
226
258
  # obj.describe_param('rhost') # => "remote host"
227
259
  #
260
+ # @api semipublic
261
+ #
228
262
  def describe_param(name)
229
263
  get_param(name).description
230
264
  end
@@ -244,6 +278,8 @@ module Parameters
244
278
  # @example
245
279
  # obj.param_value('rhost') # => 80
246
280
  #
281
+ # @api semipublic
282
+ #
247
283
  def param_value(name)
248
284
  get_param(name).value
249
285
  end
@@ -260,6 +296,8 @@ module Parameters
260
296
  # @raise [MissingParam]
261
297
  # One of the instance parameters was not set.
262
298
  #
299
+ # @api public
300
+ #
263
301
  def require_params(*names)
264
302
  names.each do |name|
265
303
  name = name.to_s
@@ -17,6 +17,18 @@ module Parameters
17
17
  @element_type = element_type
18
18
  end
19
19
 
20
+ #
21
+ # The element type of the Array type.
22
+ #
23
+ # @return [Object]
24
+ # The default element type.
25
+ #
26
+ # @since 0.4.0
27
+ #
28
+ def self.element_type
29
+ Object
30
+ end
31
+
20
32
  #
21
33
  # Coerces a value into an Array.
22
34
  #
@@ -46,6 +58,22 @@ module Parameters
46
58
  self.class.to_ruby[@element_type.to_ruby]
47
59
  end
48
60
 
61
+ #
62
+ # Compares the instance type with another type.
63
+ #
64
+ # @param [Array, Type] other
65
+ # The other type to compare against.
66
+ #
67
+ # @return [::Boolean]
68
+ # Specificies whether the instance type has the same element type
69
+ # as the other Array instance type.
70
+ #
71
+ # @since 0.4.0
72
+ #
73
+ def ==(other)
74
+ super(other) && (@element_type == other.element_type)
75
+ end
76
+
49
77
  #
50
78
  # Determines if the value is an Array.
51
79
  #
@@ -15,11 +15,35 @@ module Parameters
15
15
  #
16
16
  # @param [Type] value_type
17
17
  #
18
- def initialize(key_type,value_type)
18
+ def initialize(key_type=Object,value_type=Object)
19
19
  @key_type = key_type
20
20
  @value_type = value_type
21
21
  end
22
22
 
23
+ #
24
+ # The key type of the Hash type.
25
+ #
26
+ # @return [Object]
27
+ # The default key type.
28
+ #
29
+ # @since 0.4.0
30
+ #
31
+ def self.key_type
32
+ Object
33
+ end
34
+
35
+ #
36
+ # The value type of the Hash type.
37
+ #
38
+ # @return [Object]
39
+ # The default value type.
40
+ #
41
+ # @since 0.4.0
42
+ #
43
+ def self.value_type
44
+ Object
45
+ end
46
+
23
47
  #
24
48
  # Coerces a value into a Hash.
25
49
  #
@@ -54,6 +78,25 @@ module Parameters
54
78
  ::Hash[@key_type.to_ruby => @value_type.to_ruby]
55
79
  end
56
80
 
81
+ #
82
+ # Compares the instance type with another type.
83
+ #
84
+ # @param [Hash, Type] other
85
+ # The other type to compare against.
86
+ #
87
+ # @return [::Boolean]
88
+ # Specificies whether the instance type has the same key/value
89
+ # types as the other Hash instance type.
90
+ #
91
+ # @since 0.4.0
92
+ #
93
+ def ==(other)
94
+ super(other) && (
95
+ (@key_type == other.key_type) &&
96
+ (@value_type == other.value_type)
97
+ )
98
+ end
99
+
57
100
  #
58
101
  # Determines if the Hash, and all keys/values, are related to the Type.
59
102
  #
@@ -46,6 +46,58 @@ module Parameters
46
46
  def self.coerce(value)
47
47
  end
48
48
 
49
+ #
50
+ # Compares the instance type to another instance type.
51
+ #
52
+ # @param [Type] other
53
+ # The other instance type.
54
+ #
55
+ # @return [::Boolean]
56
+ # Specifies that the type has the same class as the other instance
57
+ # type.
58
+ #
59
+ # @since 0.4.0
60
+ #
61
+ def ==(other)
62
+ self.class == other.class
63
+ end
64
+
65
+ #
66
+ # Determines if the instance of the type is related to another Type.
67
+ #
68
+ # @param [Type] type
69
+ # The other type class.
70
+ #
71
+ # @return [::Boolean]
72
+ # Specifies whether the instance of the type inherites from another
73
+ # type.
74
+ #
75
+ # @since 0.4.0
76
+ #
77
+ def <(other)
78
+ if other.kind_of?(Type)
79
+ self.class <= other.class
80
+ else
81
+ self.class <= other
82
+ end
83
+ end
84
+
85
+ #
86
+ # Compares the type to another instance or class type.
87
+ #
88
+ # @param [Type] type
89
+ # The other instance or class type.
90
+ #
91
+ # @return [::Boolean]
92
+ # Specifies whether the instance type inherits from the other
93
+ # class type, or shares the same class as the other instance type.
94
+ #
95
+ # @since 0.4.0
96
+ #
97
+ def <=(other)
98
+ (self < other) || (self == other)
99
+ end
100
+
49
101
  #
50
102
  # @see ===
51
103
  #
@@ -1,4 +1,4 @@
1
1
  module Parameters
2
2
  # The version of parameters
3
- VERSION = '0.3.1'
3
+ VERSION = '0.4.0'
4
4
  end
@@ -0,0 +1,30 @@
1
+ require 'parameters'
2
+
3
+ class OptionParameters
4
+
5
+ include Parameters
6
+
7
+ parameter :path, :description => 'Path to the file'
8
+
9
+ parameter :with_foo, :description => 'Multiword param name'
10
+
11
+ parameter :type, :type => Symbol,
12
+ :description => 'Type to use'
13
+
14
+ parameter :count, :type => Integer,
15
+ :default => 100,
16
+ :description => 'Max count'
17
+
18
+ parameter :names, :type => Array[String],
19
+ :description => 'Names to search for'
20
+
21
+ parameter :ids, :type => Set[Integer],
22
+ :description => 'IDs to search for'
23
+
24
+ parameter :verbose, :type => true,
25
+ :description => 'Enable version'
26
+
27
+ parameter :mapping, :type => Hash[Symbol => Integer],
28
+ :description => 'Mapping of names to integers'
29
+
30
+ end
@@ -0,0 +1,142 @@
1
+ require 'spec_helper'
2
+ require 'classes/option_parameters'
3
+ require 'parameters/options'
4
+
5
+ describe Parameters::Options do
6
+ let(:object) { OptionParameters.new }
7
+ let(:params) { object.params }
8
+
9
+ describe "flag" do
10
+ it "should prefix the name with '--'" do
11
+ subject.flag(params[:path]).should == '--path'
12
+ end
13
+
14
+ it "should replace '_' characters with '-'" do
15
+ subject.flag(params[:with_foo]).should == '--with-foo'
16
+ end
17
+
18
+ it "should include '[no-]' for Boolean params" do
19
+ subject.flag(params[:verbose]).should == '--[no-]verbose'
20
+ end
21
+ end
22
+
23
+ describe "usage" do
24
+ it "should use the param name for params without a type" do
25
+ subject.usage(params[:path]).should == 'PATH'
26
+ end
27
+
28
+ it "should use the param type to derive the USAGE String" do
29
+ subject.usage(params[:count]).should == 'NUM'
30
+ end
31
+
32
+ context "complex types" do
33
+ it "should recognize Array params" do
34
+ subject.usage(params[:names]).should == 'NAMES [...]'
35
+ end
36
+
37
+ it "should recognize Set params" do
38
+ subject.usage(params[:ids]).should == 'NUM [...]'
39
+ end
40
+
41
+ it "should recognize Hash params" do
42
+ subject.usage(params[:mapping]).should == 'NAME:NUM [...]'
43
+ end
44
+ end
45
+ end
46
+
47
+ describe "accepts" do
48
+ it "should map Object params to Object" do
49
+ subject.accepts(params[:path]).should == Object
50
+ end
51
+
52
+ it "should map Boolean params to TrueClass" do
53
+ subject.accepts(params[:verbose]).should == TrueClass
54
+ end
55
+
56
+ it "should map Array params to Array" do
57
+ subject.accepts(params[:names]).should == Array
58
+ end
59
+
60
+ it "should map Set params to Array" do
61
+ subject.accepts(params[:ids]).should == Array
62
+ end
63
+
64
+ it "should map Hash params to Hash" do
65
+ subject.accepts(params[:mapping]).should == Hash
66
+ end
67
+ end
68
+
69
+ describe "parser" do
70
+ subject { Parameters::Options.parser(object) }
71
+
72
+ it "should set the param values" do
73
+ path = 'foo.rb'
74
+
75
+ subject.parse(['--path', path])
76
+
77
+ object.path.should == path
78
+ end
79
+
80
+ context "Symbol params" do
81
+ it "should accept identifier values" do
82
+ type = :foo
83
+
84
+ subject.parse(['--type', type.to_s])
85
+
86
+ object.type.should == type
87
+ end
88
+
89
+ it "should reject non-identifier values" do
90
+ lambda {
91
+ subject.parse(['--type', '10'])
92
+ }.should raise_error(OptionParser::InvalidArgument)
93
+ end
94
+ end
95
+
96
+ context "Array params" do
97
+ it "should merge multiple values together" do
98
+ name1 = 'foo'
99
+ name2 = 'bar'
100
+
101
+ subject.parse(['--names', name1, '--names', name2])
102
+
103
+ object.names.should == [name1, name2]
104
+ end
105
+ end
106
+
107
+ context "Set params" do
108
+ it "should merge multiple values together" do
109
+ id1 = 10
110
+ id2 = 20
111
+
112
+ subject.parse(['--ids', id1.to_s, '--ids', id2.to_s])
113
+
114
+ object.ids.should == Set[id1, id2]
115
+ end
116
+ end
117
+
118
+ context "Hash params" do
119
+ it "should accept 'key:value' pairs" do
120
+ hash = {:foo => 1}
121
+
122
+ subject.parse(['--mapping', 'foo:1'])
123
+
124
+ object.mapping.should == hash
125
+ end
126
+
127
+ it "should reject non 'key:value' pairs" do
128
+ lambda {
129
+ subject.parse(['--mapping', 'foo'])
130
+ }.should raise_error(OptionParser::InvalidArgument)
131
+ end
132
+
133
+ it "should merge multiple values together" do
134
+ hash = {:foo => 1, :bar => 2}
135
+
136
+ subject.parse(['--mapping', 'foo:1', '--mapping', 'bar:2'])
137
+
138
+ object.mapping.should == hash
139
+ end
140
+ end
141
+ end
142
+ end
@@ -36,11 +36,19 @@ describe Parameters do
36
36
  subject.param_value(:var_with_default).should == 'thing'
37
37
  end
38
38
 
39
- it "should provide class methods for paremters" do
39
+ it "should provide class reader/writter methods for paremters" do
40
40
  subject.var = 1
41
41
  subject.var.should == 1
42
42
  end
43
43
 
44
+ it "should provide class ? method to check if the parameter is set" do
45
+ subject.var = nil
46
+ subject.var?.should == false
47
+
48
+ subject.var = 2
49
+ subject.var?.should == true
50
+ end
51
+
44
52
  it "should inherite the super-classes parameters" do
45
53
  inherited_class.has_param?(:var).should == true
46
54
  inherited_class.has_param?(:child_var).should == true
@@ -111,11 +119,19 @@ describe Parameters do
111
119
  subject.param_value(:var_with_default).should == 'thing'
112
120
  end
113
121
 
114
- it "should provide instance methods for parameters" do
122
+ it "should provide instance reader/writter methods for parameters" do
115
123
  subject.var = 2
116
124
  subject.var.should == 2
117
125
  end
118
126
 
127
+ it "should provide instance ? methods to check if the parameter was set" do
128
+ subject.var = nil
129
+ subject.var?.should == false
130
+
131
+ subject.var = 2
132
+ subject.var?.should == true
133
+ end
134
+
119
135
  it "should set instance variables for paramters" do
120
136
  subject.instance_variable_get(:@var_with_default).should == 'thing'
121
137
 
@@ -226,6 +242,14 @@ describe Parameters do
226
242
  subject.new_param.should == 10
227
243
  end
228
244
 
245
+ it "should define ? method to determine if the parameter is set" do
246
+ subject.new_param = nil
247
+ subject.new_param?.should == false
248
+
249
+ subject.new_param = 10
250
+ subject.new_param?.should == true
251
+ end
252
+
229
253
  it "should set the instance variables of parameters" do
230
254
  subject.instance_variable_get(:@new_param_with_default).should == 5
231
255
 
@@ -14,14 +14,23 @@ describe Parameters::Types::Array do
14
14
  end
15
15
 
16
16
  context "instance" do
17
- let(:numbers) { %w[1 2 3] }
17
+ let(:element_type) { Parameters::Types::Integer }
18
+ let(:numbers) { %w[1 2 3] }
18
19
 
19
- subject { described_class.new(Parameters::Types::Integer.new) }
20
+ subject { described_class.new(element_type) }
20
21
 
21
22
  it "should have a Ruby type" do
22
23
  subject.to_ruby.should == Array[Integer]
23
24
  end
24
25
 
26
+ it "should be equal to another Array type with the same element-type" do
27
+ subject.should == described_class.new(element_type)
28
+ end
29
+
30
+ it "should be related to the Array type" do
31
+ subject.should < described_class
32
+ end
33
+
25
34
  describe "#===" do
26
35
  it "should check the type of each element" do
27
36
  subject.should_not === numbers
@@ -20,10 +20,20 @@ describe Parameters::Types::Hash do
20
20
  end
21
21
 
22
22
  context "instance" do
23
+ it "should be related to the Array type" do
24
+ subject.should < described_class
25
+ end
26
+
23
27
  context "with key-type" do
24
- let(:string_keys) { {'a' => 1, 'b' => 2} }
28
+ let(:key_type) { Parameters::Types::Symbol }
29
+ let(:value_type) { Parameters::Types::Object }
30
+ let(:string_keys) { {'a' => 1, 'b' => 2} }
31
+
32
+ subject { described_class.new(key_type,value_type) }
25
33
 
26
- subject { described_class.new(Parameters::Types::Symbol,Parameters::Types::Object) }
34
+ it "should be equal to another Hash type with the same key/value types" do
35
+ subject.should == described_class.new(key_type,value_type)
36
+ end
27
37
 
28
38
  it "should have a Ruby type" do
29
39
  subject.to_ruby.should == Hash[Symbol => Object]
@@ -45,9 +55,15 @@ describe Parameters::Types::Hash do
45
55
  end
46
56
 
47
57
  context "with value-type" do
48
- let(:string_values) { {:a => '1', :b => '2'} }
58
+ let(:key_type) { Parameters::Types::Object }
59
+ let(:value_type) { Parameters::Types::Integer }
60
+ let(:string_values) { {:a => '1', :b => '2'} }
61
+
62
+ subject { described_class.new(key_type,value_type) }
49
63
 
50
- subject { described_class.new(Parameters::Types::Object,Parameters::Types::Integer) }
64
+ it "should be equal to another Hash type with the same key/value types" do
65
+ subject.should == described_class.new(key_type,value_type)
66
+ end
51
67
 
52
68
  it "should have a Ruby type" do
53
69
  subject.to_ruby.should == Hash[Object => Integer]
@@ -15,14 +15,23 @@ describe Parameters::Types::Set do
15
15
  end
16
16
 
17
17
  context "instance" do
18
- let(:numbers) { %w[1 2 3] }
18
+ let(:element_type) { Parameters::Types::Integer }
19
+ let(:numbers) { %w[1 2 3] }
19
20
 
20
- subject { described_class.new(Parameters::Types::Integer.new) }
21
+ subject { described_class.new(element_type) }
21
22
 
22
23
  it "should have a Ruby type" do
23
24
  subject.to_ruby.should == Set[Integer]
24
25
  end
25
26
 
27
+ it "should be equal to another Set type with the same element-type" do
28
+ subject.should == described_class.new(element_type)
29
+ end
30
+
31
+ it "should be related to the Array type" do
32
+ subject.should < described_class
33
+ end
34
+
26
35
  describe "#===" do
27
36
  it "should check the type of each element" do
28
37
  subject.should_not === numbers
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: parameters
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
4
+ version: 0.4.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-12-16 00:00:00.000000000 Z
12
+ date: 2011-12-30 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: ore-tasks
16
- requirement: &14692280 !ruby/object:Gem::Requirement
16
+ requirement: &23003040 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ~>
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '0.4'
22
22
  type: :development
23
23
  prerelease: false
24
- version_requirements: *14692280
24
+ version_requirements: *23003040
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: rspec
27
- requirement: &14691740 !ruby/object:Gem::Requirement
27
+ requirement: &23002520 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ~>
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '2.4'
33
33
  type: :development
34
34
  prerelease: false
35
- version_requirements: *14691740
35
+ version_requirements: *23002520
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: yard
38
- requirement: &14691220 !ruby/object:Gem::Requirement
38
+ requirement: &23002020 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ~>
@@ -43,7 +43,7 @@ dependencies:
43
43
  version: '0.7'
44
44
  type: :development
45
45
  prerelease: false
46
- version_requirements: *14691220
46
+ version_requirements: *23002020
47
47
  description: Parameters allows you to add annotated variables to your classes which
48
48
  may have configurable default values.
49
49
  email: postmodern.mod3@gmail.com
@@ -73,6 +73,8 @@ files:
73
73
  - lib/parameters/extensions/meta.rb
74
74
  - lib/parameters/extensions/meta/object.rb
75
75
  - lib/parameters/instance_param.rb
76
+ - lib/parameters/module_methods.rb
77
+ - lib/parameters/options.rb
76
78
  - lib/parameters/param.rb
77
79
  - lib/parameters/parameters.rb
78
80
  - lib/parameters/types.rb
@@ -101,9 +103,11 @@ files:
101
103
  - spec/classes/custom_type.rb
102
104
  - spec/classes/inherited_parameters.rb
103
105
  - spec/classes/module_parameters.rb
106
+ - spec/classes/option_parameters.rb
104
107
  - spec/classes/other_parameters.rb
105
108
  - spec/classes/test_parameters.rb
106
109
  - spec/instance_param_spec.rb
110
+ - spec/options_spec.rb
107
111
  - spec/parameters_spec.rb
108
112
  - spec/spec_helper.rb
109
113
  - spec/types/array_spec.rb
@@ -151,6 +155,7 @@ summary: Allows you to add annotated variables to your classes
151
155
  test_files:
152
156
  - spec/class_param_spec.rb
153
157
  - spec/instance_param_spec.rb
158
+ - spec/options_spec.rb
154
159
  - spec/parameters_spec.rb
155
160
  - spec/types/array_spec.rb
156
161
  - spec/types/boolean_spec.rb