parameters 0.3.1 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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