strelka 0.0.1.pre.203 → 0.0.1.pre.214

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.
@@ -186,7 +186,7 @@ module Strelka::Logging
186
186
  :info => colorize( :normal ) {"[%1$s.%2$06d %3$d/%4$s] %5$5s -- %7$s\n"},
187
187
  :warn => colorize( :bold, :yellow ) {"[%1$s.%2$06d %3$d/%4$s] %5$5s -- %7$s\n"},
188
188
  :error => colorize( :red ) {"[%1$s.%2$06d %3$d/%4$s] %5$5s -- %7$s\n"},
189
- :fatal => colorize( :bold, :red, :on_white ) {"[%1$s.%2$06d %3$d/%4$s] %5$5s -- %7$s\n"},
189
+ :fatal => colorize( :bold, :red ) {"[%1$s.%2$06d %3$d/%4$s] %5$5s -- %7$s\n"},
190
190
  }
191
191
 
192
192
 
@@ -305,9 +305,11 @@ module Strelka
305
305
  # include Strelka::MethodUtilities
306
306
  #
307
307
  # singleton_attr_accessor :types
308
+ # singleton_method_alias :kinds, :types
308
309
  # end
309
310
  #
310
311
  # MyClass.types = [ :pheno, :proto, :stereo ]
312
+ # MyClass.kinds # => [:pheno, :proto, :stereo]
311
313
  #
312
314
  module MethodUtilities
313
315
 
@@ -338,6 +340,12 @@ module Strelka
338
340
  end
339
341
  end
340
342
 
343
+ ### Creates an alias for the +original+ method named +newname+.
344
+ def singleton_method_alias( newname, original )
345
+ singleton_class.__send__( :alias_method, newname, original )
346
+ end
347
+
348
+
341
349
  end # module MethodUtilities
342
350
 
343
351
 
@@ -354,6 +362,7 @@ module Strelka
354
362
  status_info = nil
355
363
 
356
364
  if http_status.is_a?( Hash ) && http_status.key?(:status)
365
+ self.log.debug "Re-finishing with a status_info struct: %p." % [ http_status ]
357
366
  status_info = http_status
358
367
  else
359
368
  message ||= HTTP::STATUS_NAME[ http_status ]
@@ -371,7 +371,8 @@ class Strelka::ParamValidator < ::FormValidator
371
371
  args.unshift( block ) if block
372
372
 
373
373
  # Custom validator -- either a callback or a regex
374
- if args.first.is_a?( Regexp ) || args.first.respond_to?( :call )
374
+ if args.first.is_a?( Regexp ) ||
375
+ args.first.respond_to?( :call )
375
376
  self.profile[:constraints][ name ] = args.shift
376
377
 
377
378
  # Builtin match validator, either explicit or implied by the name
@@ -209,6 +209,7 @@ module Strelka
209
209
 
210
210
  extend( cm_mod )
211
211
  cm_mod.instance_variables.each do |ivar|
212
+ next if instance_variable_defined?( ivar )
212
213
  Strelka.log.debug " copying class instance variable %s" % [ ivar ]
213
214
  ival = cm_mod.instance_variable_get( ivar )
214
215
 
@@ -258,17 +259,18 @@ module Strelka
258
259
  end
259
260
 
260
261
 
262
+ ### Return the list of plugin modules that are in effect for the current
263
+ ### app.
264
+ def application_stack
265
+ Strelka.log.debug "Ancestors are: %p" % [ self.class.ancestors ]
266
+ return self.ancestors.select {|mod| mod.respond_to?(:plugin_name) }
267
+ end
268
+
261
269
 
262
270
  ### Output the application stack into the logfile.
263
271
  def dump_application_stack
264
- stack = self.class.ancestors.
265
- reverse.
266
- drop_while {|mod| mod != Strelka::PluginLoader }.
267
- select {|mod| mod.respond_to?(:plugin_name) }.
268
- collect {|mod| mod.plugin_name }.
269
- reverse
270
-
271
- self.log.info "Application stack: request -> %s" % [ stack.join(" -> ") ]
272
+ stack = self.application_stack.map( &:plugin_name )
273
+ Strelka.log.info "Application stack: request -> %s" % [ stack.join(" -> ") ]
272
274
  end
273
275
 
274
276
  end # module PluginLoader
@@ -177,6 +177,29 @@ describe Strelka::App::Errors do
177
177
  res.notes[:status_info][:message].should == "Your sandwich is missing something."
178
178
  end
179
179
 
180
+ it "provides its own exception handler for the request phase" do
181
+ @app.class_eval do
182
+ on_status do |res, info|
183
+ res.body = info[:exception].class.name
184
+ return res
185
+ end
186
+
187
+ get do |req|
188
+ raise "An uncaught exception"
189
+ end
190
+ end
191
+
192
+ req = @request_factory.get( '/foom' )
193
+ res = @app.new.handle( req )
194
+
195
+ res.notes[:status_info].should include( :status, :message, :headers, :exception )
196
+ res.notes[:status_info][:status].should == HTTP::SERVER_ERROR
197
+ res.notes[:status_info][:message].should == "An uncaught exception"
198
+ res.notes[:status_info][:exception].should be_a( RuntimeError )
199
+ res.body.should == "RuntimeError"
200
+ end
201
+
202
+
180
203
  context "template-style handlers" do
181
204
 
182
205
  before( :all ) do
@@ -172,6 +172,25 @@ describe Strelka::App::Templating do
172
172
  res.status.should == 200
173
173
  end
174
174
 
175
+ it "doesn't wrap the layout around non-template responses" do
176
+ @app.class_eval do
177
+ layout 'layout.tmpl'
178
+
179
+ def handle_request( req )
180
+ # Super through the plugins and then load the template into the response
181
+ super do
182
+ res = req.response
183
+ res.body = self.template( :main ).render
184
+ res
185
+ end
186
+ end
187
+ end
188
+
189
+ res = @app.new.handle( @req )
190
+
191
+ res.body.should == "A template for testing the Templating plugin.\n"
192
+ end
193
+
175
194
  end
176
195
 
177
196
  end
@@ -350,6 +350,27 @@ describe Strelka::App do
350
350
  res.body.should =~ /internal server error/i
351
351
  end
352
352
 
353
+ it "isn't in 'developer mode' by default" do
354
+ @app.should_not be_in_devmode()
355
+ end
356
+
357
+ it "can be configured to be in 'developer mode' using the Configurability API" do
358
+ @app.configure( devmode: true )
359
+ @app.should be_in_devmode()
360
+ end
361
+
362
+ it "configures itself to be in 'developer mode' if debugging is enabled" do
363
+ debugsetting = $DEBUG
364
+
365
+ begin
366
+ $DEBUG = true
367
+ @app.configure
368
+ @app.should be_in_devmode()
369
+ ensure
370
+ $DEBUG = debugsetting
371
+ end
372
+ end
373
+
353
374
 
354
375
  describe "process name" do
355
376
 
@@ -38,6 +38,7 @@ describe Strelka::HTTPResponse::Negotiation do
38
38
 
39
39
  before( :each ) do
40
40
  @app = Class.new( Strelka::App ) { plugins :negotiation }
41
+ @app.install_plugins
41
42
  @req = @request_factory.get( '/service/user/estark' )
42
43
  @res = @req.response
43
44
  end
@@ -49,932 +49,1005 @@ describe Strelka::ParamValidator do
49
49
  @validator.should have_args()
50
50
  end
51
51
 
52
- it "allows constraints to be added" do
53
- @validator.add( :a_field, :string )
54
- @validator.param_names.should include( 'a_field' )
55
- end
56
52
 
57
- it "doesn't allow a parameter to be added twice" do
58
- @validator.add( :a_field, :string )
59
- expect {
53
+ describe "profile" do
54
+
55
+ it "allows constraints to be added" do
60
56
  @validator.add( :a_field, :string )
61
- }.to raise_error( /parameter "a_field" is already defined/i )
62
- @validator.param_names.should include( 'a_field' )
63
- end
57
+ @validator.param_names.should include( 'a_field' )
58
+ end
64
59
 
65
- it "re-validates if profile is modified" do
66
- @validator.add( :a_field, :string )
67
- @validator.validate( 'a_field' => 'a string!' )
68
- @validator.should_not have_errors()
69
- @validator.should be_okay()
60
+ it "doesn't allow a constraint to be added twice" do
61
+ @validator.add( :a_field, :string )
62
+ expect {
63
+ @validator.add( :a_field, :string )
64
+ }.to raise_error( /parameter "a_field" is already defined/i )
65
+ @validator.param_names.should include( 'a_field' )
66
+ end
70
67
 
71
- @validator.override( :a_field, :integer )
72
- @validator.should have_errors()
73
- @validator.should_not be_okay()
74
- @validator.error_messages.should include( "Invalid value for 'A Field'" )
75
- end
68
+ it "allows an existing constraint to be overridden" do
69
+ @validator.add( :a_field, :string )
70
+ @validator.override( :a_field, :integer )
71
+ @validator.param_names.should include( 'a_field' )
72
+ @validator.validate( 'a_field' => 'a string!' )
73
+ @validator.should have_errors()
74
+ @validator.should_not be_okay()
75
+ @validator.error_messages.should include( "Invalid value for 'A Field'" )
76
+ end
76
77
 
77
- it "allows an existing constraint to be overridden" do
78
- @validator.add( :a_field, :string )
79
- @validator.override( :a_field, :integer )
80
- @validator.param_names.should include( 'a_field' )
81
- @validator.validate( 'a_field' => 'a string!' )
82
- @validator.should have_errors()
83
- @validator.should_not be_okay()
84
- @validator.error_messages.should include( "Invalid value for 'A Field'" )
85
- end
78
+ it "doesn't allow a non-existant constraint to be overridden" do
79
+ expect {
80
+ @validator.override( :a_field, :string )
81
+ }.to raise_error( /no parameter "a_field" defined/i )
82
+ @validator.param_names.should_not include( 'a_field' )
83
+ end
86
84
 
87
- it "doesn't allow a non-existant parameter to be overridden" do
88
- expect {
89
- @validator.override( :a_field, :string )
90
- }.to raise_error( /no parameter "a_field" defined/i )
91
- @validator.param_names.should_not include( 'a_field' )
92
- end
85
+ it "raises an exception on an unknown constraint type" do
86
+ expect {
87
+ @validator.add( :foo, $stderr )
88
+ }.to raise_error( /no builtin "foo" validator/ )
89
+ end
93
90
 
94
- it "raises an exception on an unknown constraint type" do
95
- expect {
96
- @validator.add( :foo, $stderr )
97
- }.to raise_error( /no builtin "foo" validator/ )
98
- end
91
+ it "retains its profile through a copy" do
92
+ @validator.add( :foo, :string, :required )
93
+ dup = @validator.dup
94
+ @validator.validate( {} )
95
+ @validator.should_not be_okay()
96
+ @validator.should have_errors()
97
+ @validator.error_messages.should == ["Missing value for 'Foo'"]
98
+ end
99
99
 
100
- it "retains its parameters through a copy" do
101
- @validator.add( :foo, :string, :required )
102
- dup = @validator.dup
103
- @validator.validate( {} )
104
- @validator.should_not be_okay()
105
- @validator.should have_errors()
106
- @validator.error_messages.should == ["Missing value for 'Foo'"]
107
- end
100
+ end # describe "profile"
108
101
 
109
- it "provides read and write access to valid args via the index operator" do
110
- @validator.add( :foo, /^\d+$/ )
102
+ describe "validation" do
111
103
 
112
- @validator.validate( {'foo' => "1"} )
113
- @validator[:foo].should == "1"
104
+ it "provides read and write access to valid args via the index operator" do
105
+ @validator.add( :foo, /^\d+$/ )
114
106
 
115
- @validator[:foo] = "bar"
116
- @validator["foo"].should == "bar"
117
- end
107
+ @validator.validate( {'foo' => "1"} )
108
+ @validator[:foo].should == "1"
118
109
 
110
+ @validator[:foo] = "bar"
111
+ @validator["foo"].should == "bar"
112
+ end
119
113
 
120
- it "untaints valid args if told to do so" do
121
- tainted_one = "1"
122
- tainted_one.taint
114
+ it "untaints valid args if told to do so" do
115
+ tainted_one = "1"
116
+ tainted_one.taint
123
117
 
124
- @validator.add( :number, /^\d+$/, :untaint )
125
- @validator.validate( 'number' => tainted_one )
118
+ @validator.add( :number, /^\d+$/, :untaint )
119
+ @validator.validate( 'number' => tainted_one )
126
120
 
127
- @validator[:number].should == "1"
128
- @validator[:number].tainted?.should be_false()
129
- end
121
+ @validator[:number].should == "1"
122
+ @validator[:number].tainted?.should be_false()
123
+ end
130
124
 
125
+ it "knows the names of fields that were required but missing from the parameters" do
126
+ @validator.add( :id, :integer, :required )
127
+ @validator.validate( {} )
131
128
 
132
- it "returns the capture from a regexp constraint if it has only one" do
133
- @validator.add( :treename, /(\w+)/ )
134
- @validator.validate( 'treename' => " ygdrassil " )
135
- @validator[:treename].should == 'ygdrassil'
136
- end
129
+ @validator.should have_errors()
130
+ @validator.should_not be_okay()
137
131
 
138
- it "returns the captures from a regexp constraint as an array if it has more than one" do
139
- @validator.add( :stuff, /(\w+)(\S+)?/ )
140
- @validator.validate( 'stuff' => " the1tree(!) " )
141
- @validator[:stuff].should == ['the1tree', '(!)']
142
- end
132
+ @validator.missing.should have(1).members
133
+ @validator.missing.should == ['id']
134
+ end
143
135
 
144
- it "returns the captures from a regexp constraint with named captures as a Hash" do
145
- @validator.add( :order_number, /(?<category>[[:upper:]]{3})-(?<sku>\d{12})/, :untaint )
146
- @validator.validate( 'order_number' => " JVV-886451300133 ".taint )
136
+ it "knows the names of fields that did not meet their constraints" do
137
+ @validator.add( :number, :integer, :required )
138
+ @validator.validate( 'number' => 'rhinoceros' )
147
139
 
148
- @validator[:order_number].should == {:category => 'JVV', :sku => '886451300133'}
149
- @validator[:order_number][:category].should_not be_tainted()
150
- @validator[:order_number][:sku].should_not be_tainted()
151
- end
140
+ @validator.should have_errors()
141
+ @validator.should_not be_okay()
152
142
 
153
- it "returns the captures from a regexp constraint as an array " +
154
- "even if an optional capture doesn't match anything" do
155
- @validator.add( :amount, /^([\-+])?(\d+(?:\.\d+)?)/ )
156
- @validator.validate( 'amount' => '2.28' )
143
+ @validator.invalid.should have(1).keys
144
+ @validator.invalid.keys.should == ['number']
145
+ end
157
146
 
158
- @validator[:amount].should == [ nil, '2.28' ]
159
- end
147
+ it "can return a combined list of missing and invalid fields" do
148
+ @validator.add( :number, :integer )
149
+ @validator.add( :id, /^(\w{20})$/, :required )
160
150
 
161
- it "knows the names of fields that were required but missing from the parameters" do
162
- @validator.add( :id, :integer, :required )
163
- @validator.validate( {} )
151
+ @validator.validate( 'number' => 'rhinoceros' )
164
152
 
165
- @validator.should have_errors()
166
- @validator.should_not be_okay()
153
+ @validator.should have_errors()
154
+ @validator.should_not be_okay()
167
155
 
168
- @validator.missing.should have(1).members
169
- @validator.missing.should == ['id']
170
- end
156
+ @validator.error_fields.should have(2).members
157
+ @validator.error_fields.should include('number')
158
+ @validator.error_fields.should include('id')
159
+ end
171
160
 
172
- it "knows the names of fields that did not meet their constraints" do
173
- @validator.add( :number, :integer, :required )
174
- @validator.validate( 'number' => 'rhinoceros' )
161
+ it "allows valid parameters to be fetched en masse" do
162
+ @validator.add( :foom, /^\d+$/ )
163
+ @validator.add( :bewm, /^\d+$/ )
164
+ @validator.validate( 'foom' => "1", "bewm" => "2" )
165
+ @validator.values_at( :foom, :bewm ).should == [ '1', '2' ]
166
+ end
175
167
 
176
- @validator.should have_errors()
177
- @validator.should_not be_okay()
168
+ it "re-validates if profile is modified" do
169
+ @validator.add( :a_field, :string )
170
+ @validator.validate( 'a_field' => 'a string!' )
171
+ @validator.should_not have_errors()
172
+ @validator.should be_okay()
178
173
 
179
- @validator.invalid.should have(1).keys
180
- @validator.invalid.keys.should == ['number']
181
- end
174
+ @validator.override( :a_field, :integer )
175
+ @validator.should have_errors()
176
+ @validator.should_not be_okay()
177
+ @validator.error_messages.should include( "Invalid value for 'A Field'" )
178
+ end
182
179
 
183
- it "can return a combined list of all problem parameters, which includes " +
184
- " both missing and invalid fields" do
185
- @validator.add( :number, :integer )
186
- @validator.add( :id, /^(\w{20})$/, :required )
180
+ end # describe "validation"
187
181
 
188
- @validator.validate( 'number' => 'rhinoceros' )
182
+ describe "validation error descriptions" do
189
183
 
190
- @validator.should have_errors()
191
- @validator.should_not be_okay()
184
+ it "can return human descriptions of validation errors" do
185
+ @validator.add( :number, :integer )
186
+ @validator.add( :id, /^(\w{20})$/, :required )
187
+ @validator.validate( 'number' => 'rhinoceros', 'unknown' => "1" )
192
188
 
193
- @validator.error_fields.should have(2).members
194
- @validator.error_fields.should include('number')
195
- @validator.error_fields.should include('id')
196
- end
189
+ @validator.error_messages.should have(2).members
190
+ @validator.error_messages.should include("Missing value for 'Id'")
191
+ @validator.error_messages.should include("Invalid value for 'Number'")
192
+ end
197
193
 
198
- it "can return human descriptions of validation errors" do
199
- @validator.add( :number, :integer )
200
- @validator.add( :id, /^(\w{20})$/, :required )
201
- @validator.validate( 'number' => 'rhinoceros', 'unknown' => "1" )
194
+ it "can include unknown fields in its human descriptions of validation errors" do
195
+ @validator.add( :number, :integer )
196
+ @validator.add( :id, /^(\w{20})$/, :required )
197
+ @validator.validate( 'number' => 'rhinoceros', 'unknown' => "1" )
202
198
 
203
- @validator.error_messages.should have(2).members
204
- @validator.error_messages.should include("Missing value for 'Id'")
205
- @validator.error_messages.should include("Invalid value for 'Number'")
206
- end
199
+ @validator.error_messages(true).should have(3).members
200
+ @validator.error_messages(true).should include("Missing value for 'Id'")
201
+ @validator.error_messages(true).should include("Invalid value for 'Number'")
202
+ @validator.error_messages(true).should include("Unknown parameter 'Unknown'")
203
+ end
207
204
 
208
- it "can include unknown fields in its human descriptions of validation errors" do
209
- @validator.add( :number, :integer )
210
- @validator.add( :id, /^(\w{20})$/, :required )
211
- @validator.validate( 'number' => 'rhinoceros', 'unknown' => "1" )
205
+ it "can use descriptions of parameters when constructing human validation error messages" do
206
+ @validator.add( :number, :integer, "Numeral" )
207
+ @validator.add( :id, /^(\w{20})$/, "Test Name", :required )
208
+ @validator.validate( 'number' => 'rhinoceros', 'unknown' => "1" )
212
209
 
213
- @validator.error_messages(true).should have(3).members
214
- @validator.error_messages(true).should include("Missing value for 'Id'")
215
- @validator.error_messages(true).should include("Invalid value for 'Number'")
216
- @validator.error_messages(true).should include("Unknown parameter 'Unknown'")
217
- end
210
+ @validator.error_messages.should have(2).members
211
+ @validator.error_messages.should include("Missing value for 'Test Name'")
212
+ @validator.error_messages.should include("Invalid value for 'Numeral'")
213
+ end
218
214
 
219
- it "can use provided descriptions of parameters when constructing human " +
220
- "validation error messages" do
221
- @validator.add( :number, :integer, "Numeral" )
222
- @validator.add( :id, /^(\w{20})$/, "Test Name", :required )
223
- @validator.validate( 'number' => 'rhinoceros', 'unknown' => "1" )
215
+ it "can get and set the profile's descriptions directly" do
216
+ @validator.add( :number, :integer )
217
+ @validator.add( :id, /^(\w{20})$/, :required )
224
218
 
225
- @validator.error_messages.should have(2).members
226
- @validator.error_messages.should include("Missing value for 'Test Name'")
227
- @validator.error_messages.should include("Invalid value for 'Numeral'")
228
- end
219
+ @validator.descriptions = {
220
+ number: 'Numeral',
221
+ id: 'Test Name'
222
+ }
223
+ @validator.validate( 'number' => 'rhinoceros', 'unknown' => "1" )
229
224
 
230
- it "can get and set the profile's descriptions directly" do
231
- @validator.add( :number, :integer )
232
- @validator.add( :id, /^(\w{20})$/, :required )
225
+ @validator.descriptions.should have( 2 ).members
226
+ @validator.error_messages.should have( 2 ).members
227
+ @validator.error_messages.should include("Missing value for 'Test Name'")
228
+ @validator.error_messages.should include("Invalid value for 'Numeral'")
229
+ end
233
230
 
234
- @validator.descriptions = {
235
- number: 'Numeral',
236
- id: 'Test Name'
237
- }
238
- @validator.validate( 'number' => 'rhinoceros', 'unknown' => "1" )
231
+ it "capitalizes the names of simple fields for descriptions" do
232
+ @validator.get_description( "required" ).should == 'Required'
233
+ end
239
234
 
240
- @validator.descriptions.should have( 2 ).members
241
- @validator.error_messages.should have( 2 ).members
242
- @validator.error_messages.should include("Missing value for 'Test Name'")
243
- @validator.error_messages.should include("Invalid value for 'Numeral'")
244
- end
235
+ it "splits apart underbarred field names into capitalized words for descriptions" do
236
+ @validator.get_description( "rodent_size" ).should == 'Rodent Size'
237
+ end
245
238
 
246
- it "capitalizes the names of simple fields for descriptions" do
247
- @validator.get_description( "required" ).should == 'Required'
248
- end
239
+ it "uses the key for descriptions of hash fields" do
240
+ @validator.get_description( "rodent[size]" ).should == 'Size'
241
+ end
249
242
 
250
- it "splits apart underbarred field names into capitalized words for descriptions" do
251
- @validator.get_description( "rodent_size" ).should == 'Rodent Size'
252
- end
243
+ it "uses separate capitalized words for descriptions of hash fields with underbarred keys " do
244
+ @validator.get_description( "castle[baron_id]" ).should == 'Baron Id'
245
+ end
253
246
 
254
- it "uses the key for descriptions of hash fields" do
255
- @validator.get_description( "rodent[size]" ).should == 'Size'
256
- end
247
+ end # describe "validation error descriptions"
257
248
 
258
- it "uses separate capitalized words for descriptions of hash fields with underbarred keys " do
259
- @validator.get_description( "castle[baron_id]" ).should == 'Baron Id'
260
- end
249
+ describe "hash parameters" do
261
250
 
262
- it "coalesces simple hash fields into a hash of validated values" do
263
- @validator.add( 'rodent[size]', :string )
264
- @validator.validate( 'rodent[size]' => 'unusual' )
251
+ it "coalesces simple hash fields into a hash of validated values" do
252
+ @validator.add( 'rodent[size]', :string )
253
+ @validator.validate( 'rodent[size]' => 'unusual' )
265
254
 
266
- @validator.valid.should == {'rodent' => {'size' => 'unusual'}}
267
- end
255
+ @validator.valid.should == {'rodent' => {'size' => 'unusual'}}
256
+ end
257
+
258
+ it "coalesces complex hash fields into a nested hash of validated values" do
259
+ @validator.add( 'recipe[ingredient][name]', :string )
260
+ @validator.add( 'recipe[ingredient][cost]', :string )
261
+ @validator.add( 'recipe[yield]', :string )
268
262
 
269
- it "coalesces complex hash fields into a nested hash of validated values" do
270
- @validator.add( 'recipe[ingredient][name]', :string )
271
- @validator.add( 'recipe[ingredient][cost]', :string )
272
- @validator.add( 'recipe[yield]', :string )
273
-
274
- args = {
275
- 'recipe[ingredient][name]' => 'nutmeg',
276
- 'recipe[ingredient][cost]' => '$0.18',
277
- 'recipe[yield]' => '2 loaves',
278
- }
279
- @validator.validate( args )
280
-
281
- @validator.valid.should == {
282
- 'recipe' => {
283
- 'ingredient' => { 'name' => 'nutmeg', 'cost' => '$0.18' },
284
- 'yield' => '2 loaves'
263
+ args = {
264
+ 'recipe[ingredient][name]' => 'nutmeg',
265
+ 'recipe[ingredient][cost]' => '$0.18',
266
+ 'recipe[yield]' => '2 loaves',
285
267
  }
286
- }
287
- end
268
+ @validator.validate( args )
288
269
 
289
- it "untaints both keys and values in complex hash fields if untainting is turned on" do
290
- @validator.add( 'recipe[ingredient][rarity]', /^([\w\-]+)$/, :required )
291
- @validator.add( 'recipe[ingredient][name]', :string )
292
- @validator.add( 'recipe[ingredient][cost]', :string )
293
- @validator.add( 'recipe[yield]', :string )
294
- @validator.untaint_all_constraints
295
-
296
- args = {
297
- 'recipe[ingredient][rarity]'.taint => 'super-rare'.taint,
298
- 'recipe[ingredient][name]'.taint => 'nutmeg'.taint,
299
- 'recipe[ingredient][cost]'.taint => '$0.18'.taint,
300
- 'recipe[yield]'.taint => '2 loaves'.taint,
301
- }
302
- @validator.validate( args )
303
-
304
- @validator.valid.should == {
305
- 'recipe' => {
306
- 'ingredient' => { 'name' => 'nutmeg', 'cost' => '$0.18', 'rarity' => 'super-rare' },
307
- 'yield' => '2 loaves'
270
+ @validator.valid.should == {
271
+ 'recipe' => {
272
+ 'ingredient' => { 'name' => 'nutmeg', 'cost' => '$0.18' },
273
+ 'yield' => '2 loaves'
274
+ }
308
275
  }
309
- }
310
-
311
- @validator.valid.keys.all? {|key| key.should_not be_tainted() }
312
- @validator.valid.values.all? {|key| key.should_not be_tainted() }
313
- @validator.valid['recipe'].keys.all? {|key| key.should_not be_tainted() }
314
- @validator.valid['recipe']['ingredient'].keys.all? {|key| key.should_not be_tainted() }
315
- @validator.valid['recipe']['yield'].should_not be_tainted()
316
- @validator.valid['recipe']['ingredient']['rarity'].should_not be_tainted()
317
- @validator.valid['recipe']['ingredient']['name'].should_not be_tainted()
318
- @validator.valid['recipe']['ingredient']['cost'].should_not be_tainted()
319
- end
276
+ end
320
277
 
321
- it "accepts the value 'true' for fields with boolean constraints" do
322
- @validator.add( :enabled, :boolean )
323
- @validator.validate( 'enabled' => 'true' )
278
+ it "untaints both keys and values in complex hash fields if untainting is turned on" do
279
+ @validator.add( 'recipe[ingredient][rarity]', /^([\w\-]+)$/, :required )
280
+ @validator.add( 'recipe[ingredient][name]', :string )
281
+ @validator.add( 'recipe[ingredient][cost]', :string )
282
+ @validator.add( 'recipe[yield]', :string )
283
+ @validator.untaint_all_constraints
284
+
285
+ args = {
286
+ 'recipe[ingredient][rarity]'.taint => 'super-rare'.taint,
287
+ 'recipe[ingredient][name]'.taint => 'nutmeg'.taint,
288
+ 'recipe[ingredient][cost]'.taint => '$0.18'.taint,
289
+ 'recipe[yield]'.taint => '2 loaves'.taint,
290
+ }
291
+ @validator.validate( args )
324
292
 
325
- @validator.should be_okay()
326
- @validator.should_not have_errors()
293
+ @validator.valid.should == {
294
+ 'recipe' => {
295
+ 'ingredient' => { 'name' => 'nutmeg', 'cost' => '$0.18', 'rarity' => 'super-rare' },
296
+ 'yield' => '2 loaves'
297
+ }
298
+ }
327
299
 
328
- @validator[:enabled].should be_true()
329
- end
300
+ @validator.valid.keys.all? {|key| key.should_not be_tainted() }
301
+ @validator.valid.values.all? {|key| key.should_not be_tainted() }
302
+ @validator.valid['recipe'].keys.all? {|key| key.should_not be_tainted() }
303
+ @validator.valid['recipe']['ingredient'].keys.all? {|key| key.should_not be_tainted() }
304
+ @validator.valid['recipe']['yield'].should_not be_tainted()
305
+ @validator.valid['recipe']['ingredient']['rarity'].should_not be_tainted()
306
+ @validator.valid['recipe']['ingredient']['name'].should_not be_tainted()
307
+ @validator.valid['recipe']['ingredient']['cost'].should_not be_tainted()
308
+ end
330
309
 
331
- it "accepts the value 't' for fields with boolean constraints" do
332
- @validator.add( :enabled, :boolean )
333
- @validator.validate( 'enabled' => 't' )
310
+ end # describe "hash parameters"
334
311
 
335
- @validator.should be_okay()
336
- @validator.should_not have_errors()
312
+ describe "constraints" do
337
313
 
338
- @validator[:enabled].should be_true()
339
- end
314
+ it "treats ArgumentErrors in builtin constraints as validation failures" do
315
+ @validator.add( :integer )
316
+ @validator.validate( 'integer' => 'jalopy' )
317
+ @validator.should_not be_okay()
318
+ @validator.should have_errors()
319
+ @validator[:integer].should be_nil()
320
+ end
340
321
 
341
- it "accepts the value 'yes' for fields with boolean constraints" do
342
- @validator.add( :enabled, :boolean )
343
- @validator.validate( 'enabled' => 'yes' )
322
+ describe "Regexp constraints" do
344
323
 
345
- @validator.should be_okay()
346
- @validator.should_not have_errors()
324
+ it "returns the capture from a regexp constraint if it has only one" do
325
+ @validator.add( :treename, /(\w+)/ )
326
+ @validator.validate( 'treename' => " ygdrassil " )
327
+ @validator[:treename].should == 'ygdrassil'
328
+ end
347
329
 
348
- @validator[:enabled].should be_true()
349
- end
330
+ it "returns the captures from a regexp constraint as an array if it has more than one" do
331
+ @validator.add( :stuff, /(\w+)(\S+)?/ )
332
+ @validator.validate( 'stuff' => " the1tree(!) " )
333
+ @validator[:stuff].should == ['the1tree', '(!)']
334
+ end
350
335
 
351
- it "accepts the value 'y' for fields with boolean constraints" do
352
- @validator.add( :enabled, :boolean )
353
- @validator.validate( 'enabled' => 'y' )
336
+ it "returns the captures from a regexp constraint with named captures as a Hash" do
337
+ @validator.add( :order_number, /(?<category>[[:upper:]]{3})-(?<sku>\d{12})/, :untaint )
338
+ @validator.validate( 'order_number' => " JVV-886451300133 ".taint )
354
339
 
355
- @validator.should be_okay()
356
- @validator.should_not have_errors()
340
+ @validator[:order_number].should == {:category => 'JVV', :sku => '886451300133'}
341
+ @validator[:order_number][:category].should_not be_tainted()
342
+ @validator[:order_number][:sku].should_not be_tainted()
343
+ end
357
344
 
358
- @validator[:enabled].should be_true()
359
- end
345
+ it "returns the captures from a regexp constraint as an array " +
346
+ "even if an optional capture doesn't match anything" do
347
+ @validator.add( :amount, /^([\-+])?(\d+(?:\.\d+)?)/ )
348
+ @validator.validate( 'amount' => '2.28' )
360
349
 
361
- it "accepts the value '1' for fields with boolean constraints" do
362
- @validator.add( :enabled, :boolean )
363
- @validator.validate( 'enabled' => '1' )
350
+ @validator[:amount].should == [ nil, '2.28' ]
351
+ end
364
352
 
365
- @validator.should be_okay()
366
- @validator.should_not have_errors()
353
+ end
367
354
 
368
- @validator[:enabled].should be_true()
369
- end
355
+ describe ":boolean constraints" do
370
356
 
371
- it "accepts the value 'false' for fields with boolean constraints" do
372
- @validator.add( :enabled, :boolean )
373
- @validator.validate( 'enabled' => 'false' )
357
+ before( :each ) do
358
+ @validator.add( :enabled, :boolean )
359
+ end
374
360
 
375
- @validator.should be_okay()
376
- @validator.should_not have_errors()
361
+ it "accepts the value 'true' for fields with boolean constraints" do
362
+ @validator.validate( 'enabled' => 'true' )
377
363
 
378
- @validator[:enabled].should be_false()
379
- end
364
+ @validator.should be_okay()
365
+ @validator.should_not have_errors()
380
366
 
381
- it "accepts the value 'f' for fields with boolean constraints" do
382
- @validator.add( :enabled, :boolean )
383
- @validator.validate( 'enabled' => 'f' )
367
+ @validator[:enabled].should be_true()
368
+ end
384
369
 
385
- @validator.should be_okay()
386
- @validator.should_not have_errors()
370
+ it "accepts the value 't' for fields with boolean constraints" do
371
+ @validator.validate( 'enabled' => 't' )
387
372
 
388
- @validator[:enabled].should be_false()
389
- end
373
+ @validator.should be_okay()
374
+ @validator.should_not have_errors()
390
375
 
391
- it "accepts the value 'no' for fields with boolean constraints" do
392
- @validator.add( :enabled, :boolean )
393
- @validator.validate( 'enabled' => 'no' )
376
+ @validator[:enabled].should be_true()
377
+ end
394
378
 
395
- @validator.should be_okay()
396
- @validator.should_not have_errors()
379
+ it "accepts the value 'yes' for fields with boolean constraints" do
380
+ @validator.validate( 'enabled' => 'yes' )
397
381
 
398
- @validator[:enabled].should be_false()
399
- end
382
+ @validator.should be_okay()
383
+ @validator.should_not have_errors()
400
384
 
401
- it "accepts the value 'n' for fields with boolean constraints" do
402
- @validator.add( :enabled, :boolean )
403
- @validator.validate( 'enabled' => 'n' )
385
+ @validator[:enabled].should be_true()
386
+ end
404
387
 
405
- @validator.should be_okay()
406
- @validator.should_not have_errors()
388
+ it "accepts the value 'y' for fields with boolean constraints" do
389
+ @validator.validate( 'enabled' => 'y' )
407
390
 
408
- @validator[:enabled].should be_false()
409
- end
391
+ @validator.should be_okay()
392
+ @validator.should_not have_errors()
410
393
 
411
- it "accepts the value '0' for fields with boolean constraints" do
412
- @validator.add( :enabled, :boolean )
413
- @validator.validate( 'enabled' => '0' )
394
+ @validator[:enabled].should be_true()
395
+ end
414
396
 
415
- @validator.should be_okay()
416
- @validator.should_not have_errors()
397
+ it "accepts the value '1' for fields with boolean constraints" do
398
+ @validator.validate( 'enabled' => '1' )
417
399
 
418
- @validator[:enabled].should be_false()
419
- end
400
+ @validator.should be_okay()
401
+ @validator.should_not have_errors()
420
402
 
421
- it "rejects non-boolean parameters for fields with boolean constraints" do
422
- @validator.add( :enabled, :boolean )
423
- @validator.validate( 'enabled' => 'peanut' )
403
+ @validator[:enabled].should be_true()
404
+ end
424
405
 
425
- @validator.should_not be_okay()
426
- @validator.should have_errors()
406
+ it "accepts the value 'false' for fields with boolean constraints" do
407
+ @validator.validate( 'enabled' => 'false' )
427
408
 
428
- @validator[:enabled].should be_nil()
429
- end
409
+ @validator.should be_okay()
410
+ @validator.should_not have_errors()
430
411
 
431
- it "accepts simple integers for fields with integer constraints" do
432
- @validator.add( :count, :integer )
433
- @validator.validate( 'count' => '11' )
412
+ @validator[:enabled].should be_false()
413
+ end
434
414
 
435
- @validator.should be_okay()
436
- @validator.should_not have_errors()
415
+ it "accepts the value 'f' for fields with boolean constraints" do
416
+ @validator.validate( 'enabled' => 'f' )
437
417
 
438
- @validator[:count].should == 11
439
- end
418
+ @validator.should be_okay()
419
+ @validator.should_not have_errors()
440
420
 
441
- it "accepts '0' for fields with integer constraints" do
442
- @validator.add( :count, :integer )
443
- @validator.validate( 'count' => '0' )
421
+ @validator[:enabled].should be_false()
422
+ end
444
423
 
445
- @validator.should be_okay()
446
- @validator.should_not have_errors()
424
+ it "accepts the value 'no' for fields with boolean constraints" do
425
+ @validator.validate( 'enabled' => 'no' )
447
426
 
448
- @validator[:count].should == 0
449
- end
427
+ @validator.should be_okay()
428
+ @validator.should_not have_errors()
450
429
 
451
- it "accepts negative integers for fields with integer constraints" do
452
- @validator.add( :count, :integer )
453
- @validator.validate( 'count' => '-407' )
430
+ @validator[:enabled].should be_false()
431
+ end
454
432
 
455
- @validator.should be_okay()
456
- @validator.should_not have_errors()
433
+ it "accepts the value 'n' for fields with boolean constraints" do
434
+ @validator.validate( 'enabled' => 'n' )
457
435
 
458
- @validator[:count].should == -407
459
- end
436
+ @validator.should be_okay()
437
+ @validator.should_not have_errors()
460
438
 
461
- it "rejects non-integers for fields with integer constraints" do
462
- @validator.add( :count, :integer )
463
- @validator.validate( 'count' => '11.1' )
439
+ @validator[:enabled].should be_false()
440
+ end
464
441
 
465
- @validator.should_not be_okay()
466
- @validator.should have_errors()
442
+ it "accepts the value '0' for fields with boolean constraints" do
443
+ @validator.validate( 'enabled' => '0' )
467
444
 
468
- @validator[:count].should be_nil()
469
- end
445
+ @validator.should be_okay()
446
+ @validator.should_not have_errors()
470
447
 
471
- it "rejects integer values with other cruft in them for fields with integer constraints" do
472
- @validator.add( :count, :integer )
473
- @validator.validate( 'count' => '88licks' )
448
+ @validator[:enabled].should be_false()
449
+ end
474
450
 
475
- @validator.should_not be_okay()
476
- @validator.should have_errors()
451
+ it "rejects non-boolean parameters for fields with boolean constraints" do
452
+ @validator.validate( 'enabled' => 'peanut' )
477
453
 
478
- @validator[:count].should be_nil()
479
- end
454
+ @validator.should_not be_okay()
455
+ @validator.should have_errors()
480
456
 
481
- it "accepts simple floats for fields with float constraints" do
482
- @validator.add( :amount, :float )
483
- @validator.validate( 'amount' => '3.14' )
457
+ @validator[:enabled].should be_nil()
458
+ end
484
459
 
485
- @validator.should be_okay()
486
- @validator.should_not have_errors()
460
+ end
487
461
 
488
- @validator[:amount].should == 3.14
489
- end
462
+ describe ":integer constraints" do
490
463
 
491
- it "accepts negative floats for fields with float constraints" do
492
- @validator.add( :amount, :float )
493
- @validator.validate( 'amount' => '-3.14' )
464
+ it "accepts simple integers for fields with integer constraints" do
465
+ @validator.add( :count, :integer )
466
+ @validator.validate( 'count' => '11' )
494
467
 
495
- @validator.should be_okay()
496
- @validator.should_not have_errors()
468
+ @validator.should be_okay()
469
+ @validator.should_not have_errors()
497
470
 
498
- @validator[:amount].should == -3.14
499
- end
471
+ @validator[:count].should == 11
472
+ end
500
473
 
501
- it "accepts positive floats for fields with float constraints" do
502
- @validator.add( :amount, :float )
503
- @validator.validate( 'amount' => '+3.14' )
474
+ it "accepts '0' for fields with integer constraints" do
475
+ @validator.add( :count, :integer )
476
+ @validator.validate( 'count' => '0' )
504
477
 
505
- @validator.should be_okay()
506
- @validator.should_not have_errors()
478
+ @validator.should be_okay()
479
+ @validator.should_not have_errors()
507
480
 
508
- @validator[:amount].should == 3.14
509
- end
481
+ @validator[:count].should == 0
482
+ end
510
483
 
511
- it "accepts floats that begin with '.' for fields with float constraints" do
512
- @validator.add( :amount, :float )
513
- @validator.validate( 'amount' => '.1418' )
484
+ it "accepts negative integers for fields with integer constraints" do
485
+ @validator.add( :count, :integer )
486
+ @validator.validate( 'count' => '-407' )
514
487
 
515
- @validator.should be_okay()
516
- @validator.should_not have_errors()
488
+ @validator.should be_okay()
489
+ @validator.should_not have_errors()
517
490
 
518
- @validator[:amount].should == 0.1418
519
- end
491
+ @validator[:count].should == -407
492
+ end
520
493
 
521
- it "accepts negative floats that begin with '.' for fields with float constraints" do
522
- @validator.add( :amount, :float )
523
- @validator.validate( 'amount' => '-.171' )
494
+ it "rejects non-integers for fields with integer constraints" do
495
+ @validator.add( :count, :integer )
496
+ @validator.validate( 'count' => '11.1' )
524
497
 
525
- @validator.should be_okay()
526
- @validator.should_not have_errors()
498
+ @validator.should_not be_okay()
499
+ @validator.should have_errors()
527
500
 
528
- @validator[:amount].should == -0.171
529
- end
501
+ @validator[:count].should be_nil()
502
+ end
530
503
 
531
- it "accepts positive floats that begin with '.' for fields with float constraints" do
532
- @validator.add( :amount, :float )
533
- @validator.validate( 'amount' => '+.86668001' )
504
+ it "rejects integer values with other cruft in them for fields with integer constraints" do
505
+ @validator.add( :count, :integer )
506
+ @validator.validate( 'count' => '88licks' )
534
507
 
535
- @validator.should be_okay()
536
- @validator.should_not have_errors()
508
+ @validator.should_not be_okay()
509
+ @validator.should have_errors()
537
510
 
538
- @validator[:amount].should == 0.86668001
539
- end
511
+ @validator[:count].should be_nil()
512
+ end
540
513
 
541
- it "accepts floats in exponential notation for fields with float constraints" do
542
- @validator.add( :amount, :float )
543
- @validator.validate( 'amount' => '1756e-5' )
514
+ end
544
515
 
545
- @validator.should be_okay()
546
- @validator.should_not have_errors()
516
+ describe ":float constraints" do
547
517
 
548
- @validator[:amount].should == 1756e-5
549
- end
518
+ before( :each ) do
519
+ @validator.add( :amount, :float )
520
+ end
550
521
 
551
- it "accepts negative floats in exponential notation for fields with float constraints" do
552
- @validator.add( :amount, :float )
553
- @validator.validate( 'amount' => '-28e8' )
522
+ it "accepts simple floats for fields with float constraints" do
523
+ @validator.validate( 'amount' => '3.14' )
554
524
 
555
- @validator.should be_okay()
556
- @validator.should_not have_errors()
525
+ @validator.should be_okay()
526
+ @validator.should_not have_errors()
557
527
 
558
- @validator[:amount].should == -28e8
559
- end
528
+ @validator[:amount].should == 3.14
529
+ end
560
530
 
561
- it "accepts floats that start with '.' in exponential notation for fields with float " +
562
- "constraints" do
563
- @validator.add( :amount, :float )
564
- @validator.validate( 'amount' => '.5552e-10' )
531
+ it "accepts negative floats for fields with float constraints" do
532
+ @validator.validate( 'amount' => '-3.14' )
565
533
 
566
- @validator.should be_okay()
567
- @validator.should_not have_errors()
534
+ @validator.should be_okay()
535
+ @validator.should_not have_errors()
568
536
 
569
- @validator[:amount].should == 0.5552e-10
570
- end
537
+ @validator[:amount].should == -3.14
538
+ end
571
539
 
572
- it "accepts negative floats that start with '.' in exponential notation for fields with " +
573
- "float constraints" do
574
- @validator.add( :amount, :float )
575
- @validator.validate( 'amount' => '-.288088e18' )
540
+ it "accepts positive floats for fields with float constraints" do
541
+ @validator.validate( 'amount' => '+3.14' )
576
542
 
577
- @validator.should be_okay()
578
- @validator.should_not have_errors()
543
+ @validator.should be_okay()
544
+ @validator.should_not have_errors()
579
545
 
580
- @validator[:amount].should == -0.288088e18
581
- end
546
+ @validator[:amount].should == 3.14
547
+ end
582
548
 
583
- it "accepts integers for fields with float constraints" do
584
- @validator.add( :amount, :float )
585
- @validator.validate( 'amount' => '288' )
549
+ it "accepts floats that begin with '.' for fields with float constraints" do
550
+ @validator.validate( 'amount' => '.1418' )
586
551
 
587
- @validator.should be_okay()
588
- @validator.should_not have_errors()
552
+ @validator.should be_okay()
553
+ @validator.should_not have_errors()
589
554
 
590
- @validator[:amount].should == 288.0
591
- end
555
+ @validator[:amount].should == 0.1418
556
+ end
592
557
 
593
- it "accepts negative integers for fields with float constraints" do
594
- @validator.add( :amount, :float )
595
- @validator.validate( 'amount' => '-1606' )
558
+ it "accepts negative floats that begin with '.' for fields with float constraints" do
559
+ @validator.validate( 'amount' => '-.171' )
596
560
 
597
- @validator.should be_okay()
598
- @validator.should_not have_errors()
561
+ @validator.should be_okay()
562
+ @validator.should_not have_errors()
599
563
 
600
- @validator[:amount].should == -1606.0
601
- end
564
+ @validator[:amount].should == -0.171
565
+ end
602
566
 
603
- it "accepts positive integers for fields with float constraints" do
604
- @validator.add( :amount, :float )
605
- @validator.validate( 'amount' => '2600' )
567
+ it "accepts positive floats that begin with '.' for fields with float constraints" do
568
+ @validator.validate( 'amount' => '+.86668001' )
606
569
 
607
- @validator.should be_okay()
608
- @validator.should_not have_errors()
570
+ @validator.should be_okay()
571
+ @validator.should_not have_errors()
609
572
 
610
- @validator[:amount].should == 2600.0
611
- end
573
+ @validator[:amount].should == 0.86668001
574
+ end
612
575
 
576
+ it "accepts floats in exponential notation for fields with float constraints" do
577
+ @validator.validate( 'amount' => '1756e-5' )
613
578
 
614
- it "accepts dates for fields with date constraints" do
615
- @validator.add( :expires, :date )
616
- @validator.validate( 'expires' => '2008-11-18' )
579
+ @validator.should be_okay()
580
+ @validator.should_not have_errors()
617
581
 
618
- @validator.should be_okay()
619
- @validator.should_not have_errors()
582
+ @validator[:amount].should == 1756e-5
583
+ end
620
584
 
621
- @validator[:expires].should == Date.parse( '2008-11-18' )
622
- end
585
+ it "accepts negative floats in exponential notation for fields with float constraints" do
586
+ @validator.validate( 'amount' => '-28e8' )
623
587
 
588
+ @validator.should be_okay()
589
+ @validator.should_not have_errors()
624
590
 
625
- VALID_URIS = %w{
626
- http://127.0.0.1
627
- http://127.0.0.1/
628
- http://[127.0.0.1]/
629
- http://ruby-lang.org/
630
- http://www.rocketboom.com/vlog/rb_08_feb_01
631
- http://del.icio.us/search/?fr=del_icio_us&p=ruby+arrow&type=all
632
- http://[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:8080/index.html
633
- http://[1080:0:0:0:8:800:200C:417A]/index.html
634
- http://[3ffe:2a00:100:7031::1]
635
- http://[1080::8:800:200C:417A]/foo
636
- http://[::192.9.5.5]/ipng
637
- http://[::FFFF:129.144.52.38]:3474/index.html
638
- http://[2010:836B:4179::836B:4179]
639
-
640
- https://mail.google.com/
641
- https://127.0.0.1/
642
- https://r4.com:8080/
643
-
644
- ftp://ftp.ruby-lang.org/pub/ruby/1.0/ruby-0.49.tar.gz
645
- ftp://crashoverride:god@gibson.ellingsonmineral.com/root/.workspace/.garbage.
646
-
647
- ldap:/o=University%20of%20Michigan,c=US
648
- ldap://ldap.itd.umich.edu/o=University%20of%20Michigan,c=US
649
- ldap://ldap.itd.umich.edu/o=University%20of%20Michigan,c=US?postalAddress
650
- ldap://host.com:6666/o=University%20of%20Michigan,c=US??sub?(cn=Babs%20Jensen)
651
- ldap://ldap.itd.umich.edu/c=GB?objectClass?one
652
- ldap://ldap.question.com/o=Question%3f,c=US?mail
653
- ldap://ldap.netscape.com/o=Babsco,c=US??(int=%5c00%5c00%5c00%5c04)
654
- ldap:/??sub??bindname=cn=Manager%2co=Foo
655
- ldap:/??sub??!bindname=cn=Manager%2co=Foo
656
- }
657
-
658
- VALID_URIS.each do |uri_string|
659
- it "accepts #{uri_string} for fields with URI constraints" do
660
- @validator.add( :homepage, :uri )
661
- @validator.validate( 'homepage' => uri_string )
591
+ @validator[:amount].should == -28e8
592
+ end
662
593
 
663
- @validator.should be_okay()
664
- @validator.should_not have_errors()
594
+ it "accepts floats that start with '.' in exponential notation for fields with float " +
595
+ "constraints" do
596
+ @validator.validate( 'amount' => '.5552e-10' )
597
+
598
+ @validator.should be_okay()
599
+ @validator.should_not have_errors()
600
+
601
+ @validator[:amount].should == 0.5552e-10
602
+ end
603
+
604
+ it "accepts negative floats that start with '.' in exponential notation for fields with " +
605
+ "float constraints" do
606
+ @validator.validate( 'amount' => '-.288088e18' )
607
+
608
+ @validator.should be_okay()
609
+ @validator.should_not have_errors()
610
+
611
+ @validator[:amount].should == -0.288088e18
612
+ end
613
+
614
+ it "accepts integers for fields with float constraints" do
615
+ @validator.validate( 'amount' => '288' )
616
+
617
+ @validator.should be_okay()
618
+ @validator.should_not have_errors()
619
+
620
+ @validator[:amount].should == 288.0
621
+ end
622
+
623
+ it "accepts negative integers for fields with float constraints" do
624
+ @validator.validate( 'amount' => '-1606' )
625
+
626
+ @validator.should be_okay()
627
+ @validator.should_not have_errors()
628
+
629
+ @validator[:amount].should == -1606.0
630
+ end
631
+
632
+ it "accepts positive integers for fields with float constraints" do
633
+ @validator.validate( 'amount' => '2600' )
634
+
635
+ @validator.should be_okay()
636
+ @validator.should_not have_errors()
637
+
638
+ @validator[:amount].should == 2600.0
639
+ end
665
640
 
666
- @validator[:homepage].should be_a_kind_of( URI::Generic )
667
- @validator[:homepage].to_s.should == uri_string
668
641
  end
669
- end
670
642
 
671
- # :FIXME: I don't know LDAP uris very well, so I'm not sure how they're likely to
672
- # be invalidly-occurring in the wild
673
- INVALID_URIS = %W{
674
- glark:
675
-
676
- http:
677
- http://
678
- http://_com/vlog/rb_08_feb_01
679
- http://del.icio.us/search/\x20\x14\x18
680
- http://FEDC:BA98:7654:3210:FEDC:BA98:7654:3210/index.html
681
- http://1080:0:0:0:8:800:200C:417A/index.html
682
- http://3ffe:2a00:100:7031::1
683
- http://1080::8:800:200C:417A/foo
684
- http://::192.9.5.5/ipng
685
- http://::FFFF:129.144.52.38:80/index.html
686
- http://2010:836B:4179::836B:4179
687
-
688
- https:
689
- https://user:pass@/
690
- https://r4.com:nonnumericport/
691
-
692
- ftp:
693
- ftp:ruby-0.49.tar.gz
694
- ftp://crashoverride:god@/root/.workspace/.garbage.
695
-
696
- ldap:
697
- ldap:/o=University\x20of\x20Michigan,c=US
698
- ldap://ldap.itd.umich.edu/o=University+\x00of+Michigan
699
- }
700
-
701
- INVALID_URIS.each do |uri_string|
702
- it "rejects #{uri_string} for fields with URI constraints" do
703
- @validator.add( :homepage, :uri )
704
- @validator.validate( 'homepage' => uri_string )
643
+ describe ":date constaints" do
705
644
 
706
- @validator.should_not be_okay()
707
- @validator.should have_errors()
645
+ before( :each ) do
646
+ @validator.add( :expires, :date )
647
+ end
648
+
649
+ it "accepts dates for fields with date constraints" do
650
+ @validator.validate( 'expires' => '2008-11-18' )
651
+
652
+ @validator.should be_okay()
653
+ @validator.should_not have_errors()
654
+
655
+ @validator[:expires].should == Date.parse( '2008-11-18' )
656
+ end
657
+
658
+ it "rejects non-dates for fields with date constraints" do
659
+ @validator.validate( 'expires' => 'Mexico' )
660
+
661
+ @validator.should_not be_okay()
662
+ @validator.should have_errors()
663
+
664
+ @validator[:expires].should be_nil()
665
+ end
708
666
 
709
- @validator[:homepage].should be_nil()
710
667
  end
711
- end
712
668
 
713
- it "accepts simple RFC822 addresses for fields with email constraints" do
714
- @validator.add( :email )
715
- @validator.validate( 'email' => 'jrandom@hacker.ie' )
669
+ describe ":uri constraints" do
670
+ VALID_URIS = %w{
671
+ http://127.0.0.1
672
+ http://127.0.0.1/
673
+ http://[127.0.0.1]/
674
+ http://ruby-lang.org/
675
+ http://www.rocketboom.com/vlog/rb_08_feb_01
676
+ http://del.icio.us/search/?fr=del_icio_us&p=ruby+arrow&type=all
677
+ http://[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:8080/index.html
678
+ http://[1080:0:0:0:8:800:200C:417A]/index.html
679
+ http://[3ffe:2a00:100:7031::1]
680
+ http://[1080::8:800:200C:417A]/foo
681
+ http://[::192.9.5.5]/ipng
682
+ http://[::FFFF:129.144.52.38]:3474/index.html
683
+ http://[2010:836B:4179::836B:4179]
684
+
685
+ https://mail.google.com/
686
+ https://127.0.0.1/
687
+ https://r4.com:8080/
688
+
689
+ ftp://ftp.ruby-lang.org/pub/ruby/1.0/ruby-0.49.tar.gz
690
+ ftp://crashoverride:god@gibson.ellingsonmineral.com/root/.workspace/.garbage.
691
+
692
+ ldap:/o=University%20of%20Michigan,c=US
693
+ ldap://ldap.itd.umich.edu/o=University%20of%20Michigan,c=US
694
+ ldap://ldap.itd.umich.edu/o=University%20of%20Michigan,c=US?postalAddress
695
+ ldap://host.com:6666/o=University%20of%20Michigan,c=US??sub?(cn=Babs%20Jensen)
696
+ ldap://ldap.itd.umich.edu/c=GB?objectClass?one
697
+ ldap://ldap.question.com/o=Question%3f,c=US?mail
698
+ ldap://ldap.netscape.com/o=Babsco,c=US??(int=%5c00%5c00%5c00%5c04)
699
+ ldap:/??sub??bindname=cn=Manager%2co=Foo
700
+ ldap:/??sub??!bindname=cn=Manager%2co=Foo
701
+ }
716
702
 
717
- @validator.should be_okay()
718
- @validator.should_not have_errors()
703
+ INVALID_URIS = %W{
704
+ glark:
705
+
706
+ http:
707
+ http://
708
+ http://_com/vlog/rb_08_feb_01
709
+ http://del.icio.us/search/\x20\x14\x18
710
+ http://FEDC:BA98:7654:3210:FEDC:BA98:7654:3210/index.html
711
+ http://1080:0:0:0:8:800:200C:417A/index.html
712
+ http://3ffe:2a00:100:7031::1
713
+ http://1080::8:800:200C:417A/foo
714
+ http://::192.9.5.5/ipng
715
+ http://::FFFF:129.144.52.38:80/index.html
716
+ http://2010:836B:4179::836B:4179
717
+
718
+ https:
719
+ https://user:pass@/
720
+ https://r4.com:nonnumericport/
721
+
722
+ ftp:
723
+ ftp:ruby-0.49.tar.gz
724
+ ftp://crashoverride:god@/root/.workspace/.garbage.
725
+
726
+ ldap:
727
+ ldap:/o=University\x20of\x20Michigan,c=US
728
+ ldap://ldap.itd.umich.edu/o=University+\x00of+Michigan
729
+ }
719
730
 
720
- @validator[:email].should == 'jrandom@hacker.ie'
721
- end
731
+ before( :each ) do
732
+ @validator.add( :homepage, :uri )
733
+ end
722
734
 
723
- it "accepts hyphenated domains in RFC822 addresses for fields with email constraints" do
724
- @validator.add( :email )
725
- @validator.validate( 'email' => 'jrandom@just-another-hacquer.fr' )
735
+ VALID_URIS.each do |uri_string|
736
+ it "accepts #{uri_string} for fields with URI constraints" do
737
+ @validator.validate( 'homepage' => uri_string )
726
738
 
727
- @validator.should be_okay()
728
- @validator.should_not have_errors()
739
+ @validator.should be_okay()
740
+ @validator.should_not have_errors()
729
741
 
730
- @validator[:email].should == 'jrandom@just-another-hacquer.fr'
731
- end
742
+ @validator[:homepage].should be_a_kind_of( URI::Generic )
743
+ @validator[:homepage].to_s.should == uri_string
744
+ end
745
+ end
732
746
 
733
- COMPLEX_ADDRESSES = [
734
- 'ruby+hacker@random-example.org',
735
- '"ruby hacker"@ph8675309.org',
736
- 'jrandom@[ruby hacquer].com',
737
- 'abcdefghijklmnopqrstuvwxyz@abcdefghijklmnopqrstuvwxyz',
738
- ]
739
- COMPLEX_ADDRESSES.each do |addy|
740
- it "accepts #{addy} for fields with email constraints" do
741
- @validator.add( :mail, :email )
742
- @validator.validate( 'mail' => addy )
747
+ INVALID_URIS.each do |uri_string|
748
+ it "rejects #{uri_string} for fields with URI constraints" do
749
+ @validator.validate( 'homepage' => uri_string )
743
750
 
744
- @validator.should be_okay()
745
- @validator.should_not have_errors()
751
+ @validator.should_not be_okay()
752
+ @validator.should have_errors()
753
+
754
+ @validator[:homepage].should be_nil()
755
+ end
756
+ end
746
757
 
747
- @validator[:mail].should == addy
748
758
  end
749
- end
750
759
 
760
+ describe ":email constraints" do
751
761
 
752
- BOGUS_ADDRESSES = [
753
- 'jrandom@hacquer com',
754
- 'jrandom@ruby hacquer.com',
755
- 'j random@rubyhacquer.com',
756
- 'j random@ruby|hacquer.com',
757
- 'j:random@rubyhacquer.com',
758
- ]
759
- BOGUS_ADDRESSES.each do |addy|
760
- it "rejects #{addy} for fields with email constraints" do
761
- @validator.add( :mail, :email )
762
- @validator.validate( 'mail' => addy )
762
+ COMPLEX_ADDRESSES = [
763
+ 'ruby+hacker@random-example.org',
764
+ '"ruby hacker"@ph8675309.org',
765
+ 'jrandom@[ruby hacquer].com',
766
+ 'abcdefghijklmnopqrstuvwxyz@abcdefghijklmnopqrstuvwxyz',
767
+ ]
768
+ BOGUS_ADDRESSES = [
769
+ 'jrandom@hacquer com',
770
+ 'jrandom@ruby hacquer.com',
771
+ 'j random@rubyhacquer.com',
772
+ 'j random@ruby|hacquer.com',
773
+ 'j:random@rubyhacquer.com',
774
+ ]
763
775
 
764
- @validator.should_not be_okay()
765
- @validator.should have_errors()
776
+ it "accepts simple RFC822 addresses for fields with email constraints" do
777
+ @validator.add( :email )
778
+ @validator.validate( 'email' => 'jrandom@hacker.ie' )
779
+
780
+ @validator.should be_okay()
781
+ @validator.should_not have_errors()
782
+
783
+ @validator[:email].should == 'jrandom@hacker.ie'
784
+ end
785
+
786
+ it "accepts hyphenated domains in RFC822 addresses for fields with email constraints" do
787
+ @validator.add( :email )
788
+ @validator.validate( 'email' => 'jrandom@just-another-hacquer.fr' )
789
+
790
+ @validator.should be_okay()
791
+ @validator.should_not have_errors()
792
+
793
+ @validator[:email].should == 'jrandom@just-another-hacquer.fr'
794
+ end
795
+
796
+ COMPLEX_ADDRESSES.each do |addy|
797
+ it "accepts #{addy} for fields with email constraints" do
798
+ @validator.add( :mail, :email )
799
+ @validator.validate( 'mail' => addy )
800
+
801
+ @validator.should be_okay()
802
+ @validator.should_not have_errors()
803
+
804
+ @validator[:mail].should == addy
805
+ end
806
+ end
807
+
808
+ BOGUS_ADDRESSES.each do |addy|
809
+ it "rejects #{addy} for fields with email constraints" do
810
+ @validator.add( :mail, :email )
811
+ @validator.validate( 'mail' => addy )
812
+
813
+ @validator.should_not be_okay()
814
+ @validator.should have_errors()
815
+
816
+ @validator[:mail].should be_nil()
817
+ end
818
+ end
766
819
 
767
- @validator[:mail].should be_nil()
768
820
  end
769
- end
770
821
 
771
- it "accepts simple hosts for fields with host constraints" do
772
- @validator.add( :host, :hostname )
773
- @validator.validate( 'host' => 'deveiate.org' )
822
+ describe ":hostname constraints" do
774
823
 
775
- @validator.should be_okay()
776
- @validator.should_not have_errors()
824
+ BOGUS_HOSTS = [
825
+ '.',
826
+ 'glah ',
827
+ 'glah[lock]',
828
+ 'glah.be$',
829
+ 'indus«tree».com',
830
+ ]
777
831
 
778
- @validator[:host].should == 'deveiate.org'
779
- end
832
+ it "accepts simple hostnames for fields with hostname constraints" do
833
+ @validator.add( :host, :hostname )
834
+ @validator.validate( 'host' => 'deveiate.org' )
780
835
 
781
- it "accepts hyphenated hosts for fields with host constraints" do
782
- @validator.add( :hostname )
783
- @validator.validate( 'hostname' => 'your-characters-can-fly.kr' )
836
+ @validator.should be_okay()
837
+ @validator.should_not have_errors()
784
838
 
785
- @validator.should be_okay()
786
- @validator.should_not have_errors()
839
+ @validator[:host].should == 'deveiate.org'
840
+ end
787
841
 
788
- @validator[:hostname].should == 'your-characters-can-fly.kr'
789
- end
842
+ it "accepts hyphenated hostnames for fields with hostname constraints" do
843
+ @validator.add( :hostname )
844
+ @validator.validate( 'hostname' => 'your-characters-can-fly.kr' )
790
845
 
791
- BOGUS_HOSTS = [
792
- '.',
793
- 'glah ',
794
- 'glah[lock]',
795
- 'glah.be$',
796
- 'indus«tree».com',
797
- ]
846
+ @validator.should be_okay()
847
+ @validator.should_not have_errors()
798
848
 
799
- BOGUS_HOSTS.each do |hostname|
800
- it "rejects #{hostname} for fields with host constraints" do
801
- @validator.add( :hostname )
802
- @validator.validate( 'hostname' => hostname )
849
+ @validator[:hostname].should == 'your-characters-can-fly.kr'
850
+ end
803
851
 
804
- @validator.should_not be_okay()
805
- @validator.should have_errors()
852
+ BOGUS_HOSTS.each do |hostname|
853
+ it "rejects #{hostname} for fields with :hostname constraints" do
854
+ @validator.add( :hostname )
855
+ @validator.validate( 'hostname' => hostname )
856
+
857
+ @validator.should_not be_okay()
858
+ @validator.should have_errors()
859
+
860
+ @validator[:hostname].should be_nil()
861
+ end
862
+ end
806
863
 
807
- @validator[:hostname].should be_nil()
808
864
  end
809
- end
810
865
 
811
- it "accepts alpha characters for fields with alpha constraints" do
812
- @validator.add( :alpha )
813
- @validator.validate( 'alpha' => 'abelincoln' )
866
+ describe ":alpha constraints" do
814
867
 
815
- @validator.should be_okay()
816
- @validator.should_not have_errors()
868
+ it "accepts alpha characters for fields with alpha constraints" do
869
+ @validator.add( :alpha )
870
+ @validator.validate( 'alpha' => 'abelincoln' )
817
871
 
818
- @validator[:alpha].should == 'abelincoln'
819
- end
872
+ @validator.should be_okay()
873
+ @validator.should_not have_errors()
820
874
 
821
- it "rejects non-alpha characters for fields with alpha constraints" do
822
- @validator.add( :alpha )
823
- @validator.validate( 'alpha' => 'duck45' )
875
+ @validator[:alpha].should == 'abelincoln'
876
+ end
824
877
 
825
- @validator.should_not be_okay()
826
- @validator.should have_errors()
878
+ it "rejects non-alpha characters for fields with alpha constraints" do
879
+ @validator.add( :alpha )
880
+ @validator.validate( 'alpha' => 'duck45' )
827
881
 
828
- @validator[:alpha].should be_nil()
829
- end
882
+ @validator.should_not be_okay()
883
+ @validator.should have_errors()
830
884
 
831
- ### 'alphanumeric'
832
- it "accepts alphanumeric characters for fields with alphanumeric constraints" do
833
- @validator.add( :username, :alphanumeric )
834
- @validator.validate( 'username' => 'zombieabe11' )
885
+ @validator[:alpha].should be_nil()
886
+ end
835
887
 
836
- @validator.should be_okay()
837
- @validator.should_not have_errors()
888
+ end
838
889
 
839
- @validator[:username].should == 'zombieabe11'
840
- end
890
+ describe ":alphanumeric constraints" do
841
891
 
842
- it "rejects non-alphanumeric characters for fields with alphanumeric constraints" do
843
- @validator.add( :username, :alphanumeric )
844
- @validator.validate( 'username' => 'duck!ling' )
892
+ it "accepts alphanumeric characters for fields with alphanumeric constraints" do
893
+ @validator.add( :username, :alphanumeric )
894
+ @validator.validate( 'username' => 'zombieabe11' )
845
895
 
846
- @validator.should_not be_okay()
847
- @validator.should have_errors()
896
+ @validator.should be_okay()
897
+ @validator.should_not have_errors()
848
898
 
849
- @validator[:username].should be_nil()
850
- end
899
+ @validator[:username].should == 'zombieabe11'
900
+ end
851
901
 
852
- ### 'printable'
853
- it "accepts printable characters for fields with 'printable' constraints" do
854
- test_content = <<-EOF
855
- I saw you with some kind of medical apparatus strapped to your
856
- spine. It was all glass and metal, a great crystaline hypodermic
857
- spider, carrying you into the aether with a humming, crackling sound.
858
- EOF
902
+ it "rejects non-alphanumeric characters for fields with alphanumeric constraints" do
903
+ @validator.add( :username, :alphanumeric )
904
+ @validator.validate( 'username' => 'duck!ling' )
859
905
 
860
- @validator.add( :prologue, :printable )
861
- @validator.validate( 'prologue' => test_content )
906
+ @validator.should_not be_okay()
907
+ @validator.should have_errors()
862
908
 
863
- @validator.should be_okay()
864
- @validator[:prologue].should == test_content
865
- end
909
+ @validator[:username].should be_nil()
910
+ end
866
911
 
867
- it "rejects non-printable characters for fields with 'printable' constraints" do
868
- @validator.add( :prologue, :printable )
869
- @validator.validate( 'prologue' => %{\0Something cold\0} )
912
+ end
870
913
 
871
- @validator.should_not be_okay()
872
- @validator.should have_errors()
914
+ describe ":printable constraints" do
873
915
 
874
- @validator[:prologue].should be_nil()
875
- end
916
+ it "accepts printable characters for fields with 'printable' constraints" do
917
+ test_content = <<-EOF
918
+ I saw you with some kind of medical apparatus strapped to your
919
+ spine. It was all glass and metal, a great crystaline hypodermic
920
+ spider, carrying you into the aether with a humming, crackling sound.
921
+ EOF
876
922
 
923
+ @validator.add( :prologue, :printable )
924
+ @validator.validate( 'prologue' => test_content )
877
925
 
878
- it "accepts any word characters for fields with 'word' constraints" do
879
- @validator.add( :vocab_word, :word )
880
- @validator.validate( 'vocab_word' => "Собака" )
926
+ @validator.should be_okay()
927
+ @validator[:prologue].should == test_content
928
+ end
881
929
 
882
- @validator.should_not have_errors()
883
- @validator.should be_okay()
930
+ it "rejects non-printable characters for fields with 'printable' constraints" do
931
+ @validator.add( :prologue, :printable )
932
+ @validator.validate( 'prologue' => %{\0Something cold\0} )
884
933
 
885
- @validator[:vocab_word].should == "Собака"
886
- end
934
+ @validator.should_not be_okay()
935
+ @validator.should have_errors()
887
936
 
888
- it "accepts parameters for fields with Proc constraints if the Proc returns a true value" do
889
- test_date = '2007-07-17'
937
+ @validator[:prologue].should be_nil()
938
+ end
890
939
 
891
- @validator.add( :creation_date ) do |input|
892
- Date.parse( input )
893
940
  end
894
- @validator.validate( 'creation_date' => test_date )
895
941
 
896
- @validator.should be_okay()
897
- @validator.should_not have_errors()
942
+ describe ":word constraints" do
898
943
 
899
- @validator[:creation_date].should == Date.parse( test_date )
900
- end
944
+ it "accepts any word characters for fields with 'word' constraints" do
945
+ @validator.add( :vocab_word, :word )
946
+ @validator.validate( 'vocab_word' => "Собака" )
947
+
948
+ @validator.should_not have_errors()
949
+ @validator.should be_okay()
950
+
951
+ @validator[:vocab_word].should == "Собака"
952
+ end
953
+
954
+ it "rejects non-word characters for fields with 'word' constraints" do
955
+ @validator.add( :vocab_word, :word )
956
+ @validator.validate( 'vocab_word' => "Собака!" )
957
+
958
+ @validator.should have_errors()
959
+ @validator.should_not be_okay()
960
+
961
+ @validator[:vocab_word].should be_nil()
962
+ end
901
963
 
902
- it "rejects parameters for fields with Proc constraints if the Proc returns a false value" do
903
- @validator.add( :creation_date ) do |input|
904
- Date.parse( input )
905
964
  end
906
- @validator.validate( 'creation_date' => '::::' )
907
965
 
908
- @validator.should_not be_okay()
909
- @validator.should have_errors()
966
+ describe "Proc constraints" do
910
967
 
911
- @validator[:creation_date].should be_nil()
912
- end
968
+ it "accepts parameters for fields with Proc constraints if the Proc returns a true value" do
969
+ test_date = '2007-07-17'
913
970
 
914
- it "can be merged with another set of parameters" do
915
- @validator.add( :foo, :integer, :required )
916
- @validator.validate( {} )
917
- newval = @validator.merge( 'foo' => '1' )
971
+ @validator.add( :creation_date ) do |input|
972
+ Date.parse( input )
973
+ end
974
+ @validator.validate( 'creation_date' => test_date )
918
975
 
919
- newval.should_not equal( @validator )
976
+ @validator.should be_okay()
977
+ @validator.should_not have_errors()
920
978
 
921
- @validator.should_not be_okay()
922
- @validator.should have_errors()
923
- newval.should be_okay()
924
- newval.should_not have_errors()
979
+ @validator[:creation_date].should == Date.parse( test_date )
980
+ end
925
981
 
926
- @validator[:foo].should == nil
927
- newval[:foo].should == 1
928
- end
982
+ it "rejects parameters for fields with Proc constraints if the Proc returns a false value" do
983
+ @validator.add( :creation_date ) do |input|
984
+ Date.parse( input )
985
+ end
986
+ @validator.validate( 'creation_date' => '::::' )
929
987
 
930
- it "can have required parameters merged into it after the initial validation" do
931
- @validator.add( :foo, :integer, :required )
932
- @validator.validate( {} )
933
- @validator.merge!( 'foo' => '1' )
988
+ @validator.should_not be_okay()
989
+ @validator.should have_errors()
934
990
 
935
- @validator.should be_okay()
936
- @validator.should_not have_errors()
991
+ @validator[:creation_date].should be_nil()
992
+ end
937
993
 
938
- @validator[:foo].should == 1
939
- end
994
+ end
940
995
 
941
- it "can have optional parameters merged into it after the initial validation" do
942
- @validator.add( :foom, /^\d+$/ )
943
- @validator.validate( {} )
944
- @validator.merge!( 'foom' => '5' )
996
+ describe "merging new parameters" do
945
997
 
946
- @validator.should be_okay()
947
- @validator.should_not have_errors()
998
+ it "can be merged with another set of parameters" do
999
+ @validator.add( :foo, :integer, :required )
1000
+ @validator.validate( {} )
1001
+ newval = @validator.merge( 'foo' => '1' )
948
1002
 
949
- @validator[:foom].should == '5'
950
- end
1003
+ newval.should_not equal( @validator )
1004
+
1005
+ @validator.should_not be_okay()
1006
+ @validator.should have_errors()
1007
+ newval.should be_okay()
1008
+ newval.should_not have_errors()
1009
+
1010
+ @validator[:foo].should == nil
1011
+ newval[:foo].should == 1
1012
+ end
1013
+
1014
+ it "can have required parameters merged into it after the initial validation" do
1015
+ @validator.add( :foo, :integer, :required )
1016
+ @validator.validate( {} )
1017
+ @validator.merge!( 'foo' => '1' )
1018
+
1019
+ @validator.should be_okay()
1020
+ @validator.should_not have_errors()
1021
+
1022
+ @validator[:foo].should == 1
1023
+ end
1024
+
1025
+ it "can have optional parameters merged into it after the initial validation" do
1026
+ @validator.add( :foom, /^\d+$/ )
1027
+ @validator.validate( {} )
1028
+ @validator.merge!( 'foom' => '5' )
1029
+
1030
+ @validator.should be_okay()
1031
+ @validator.should_not have_errors()
1032
+
1033
+ @validator[:foom].should == '5'
1034
+ end
1035
+
1036
+ it "rejects invalid parameters when they're merged after initial validation" do
1037
+ @validator.add( :foom, /^\d+$/ )
1038
+ @validator.add( :bewm, /^\d+$/ )
1039
+ @validator.validate( 'foom' => "1" )
1040
+
1041
+ @validator.merge!( 'bewm' => 'buckwheat noodles' )
1042
+
1043
+ @validator.should_not be_okay()
1044
+ @validator.should have_errors()
1045
+ @validator[:bewm].should == nil
1046
+ end
1047
+
1048
+ end
951
1049
 
952
- it "rejects invalid parameters when they're merged after initial validation" do
953
- @validator.add( :foom, /^\d+$/ )
954
- @validator.add( :bewm, /^\d+$/ )
955
- @validator.validate( 'foom' => "1" )
956
-
957
- @validator.merge!( 'bewm' => 'buckwheat noodles' )
958
-
959
- @validator.should_not be_okay()
960
- @validator.should have_errors()
961
- @validator[:bewm].should == nil
962
- end
963
-
964
- it "allows valid parameters to be fetched en masse" do
965
- @validator.add( :foom, /^\d+$/ )
966
- @validator.add( :bewm, /^\d+$/ )
967
- @validator.validate( 'foom' => "1", "bewm" => "2" )
968
- @validator.values_at( :foom, :bewm ).should == [ '1', '2' ]
969
- end
970
-
971
- it "treats ArgumentErrors in builtin constraints as validation failures" do
972
- @validator.add( :integer )
973
- @validator.validate( 'integer' => 'jalopy' )
974
- @validator.should_not be_okay()
975
- @validator.should have_errors()
976
- @validator[:integer].should be_nil()
977
- end
1050
+ end # describe "constraints"
978
1051
 
979
1052
  end
980
1053