formeze 1.9.1 → 2.0.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.
- data/README.md +87 -6
- data/Rakefile.rb +1 -0
- data/formeze.gemspec +1 -1
- data/lib/formeze.rb +96 -52
- data/spec/formeze_spec.rb +171 -36
- metadata +3 -3
data/README.md
CHANGED
@@ -1,5 +1,8 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
formeze
|
2
|
+
=======
|
3
|
+
|
4
|
+
|
5
|
+
A little library for handling form data/input.
|
3
6
|
|
4
7
|
|
5
8
|
Motivation
|
@@ -207,14 +210,93 @@ Custom scrub methods can be defined by adding a symbol/proc entry to the
|
|
207
210
|
`Formeze.scrub_methods` hash.
|
208
211
|
|
209
212
|
|
213
|
+
Custom validation
|
214
|
+
-----------------
|
215
|
+
|
216
|
+
You may need additional validation logic beyond what the field options
|
217
|
+
described above provide, such as validating the format of a field without
|
218
|
+
using a regular expression, validating that two fields are equal etc.
|
219
|
+
This can be accomplished using the `validates` class method. Pass the
|
220
|
+
name of the field to be validated, and a block/proc that encapsulates
|
221
|
+
the validation logic. For example:
|
222
|
+
|
223
|
+
```ruby
|
224
|
+
class ExampleForm < Formeze::Form
|
225
|
+
field :email
|
226
|
+
|
227
|
+
validates :email, &EmailAddress.method(:valid?)
|
228
|
+
end
|
229
|
+
```
|
230
|
+
|
231
|
+
If the block/proc takes no arguments then it will be evaluated in the
|
232
|
+
scope of the form instance, which gives you access to the values of other
|
233
|
+
fields (and methods defined on the form). For example:
|
234
|
+
|
235
|
+
```ruby
|
236
|
+
class ExampleForm < Formeze::Form
|
237
|
+
field :password
|
238
|
+
field :password_confirmation
|
239
|
+
|
240
|
+
validates :password_confirmation do
|
241
|
+
password_confirmation == password
|
242
|
+
end
|
243
|
+
end
|
244
|
+
```
|
245
|
+
|
246
|
+
Specify the `when` option with a proc to peform the validation conditionally.
|
247
|
+
Similar to the `defined_if` and `defined_unless` field options, the proc is
|
248
|
+
evaluated in the scope of the form instance. For example:
|
249
|
+
|
250
|
+
```ruby
|
251
|
+
class ExampleForm < Formeze::Form
|
252
|
+
field :business_name, :defined_if => :business_account?
|
253
|
+
field :vat_number, :defined_if => :business_account?
|
254
|
+
|
255
|
+
validates :vat_number, :when => :business_account? do
|
256
|
+
# ...
|
257
|
+
end
|
258
|
+
|
259
|
+
def initialize(account)
|
260
|
+
@account = account
|
261
|
+
end
|
262
|
+
|
263
|
+
def business_account?
|
264
|
+
@account.business?
|
265
|
+
end
|
266
|
+
end
|
267
|
+
```
|
268
|
+
|
269
|
+
Specify the `error` option with a symbol to control which error the validation
|
270
|
+
generates. The I18n integration described below can be used to specify the
|
271
|
+
error message used, both for errors that are explicitly specified using this
|
272
|
+
option, and the default "invalid" error. For example:
|
273
|
+
|
274
|
+
```ruby
|
275
|
+
class ExampleForm < Formeze::Form
|
276
|
+
field :email
|
277
|
+
field :password
|
278
|
+
field :password_confirmation
|
279
|
+
|
280
|
+
validates :email, &EmailAddress.method(:valid?)
|
281
|
+
|
282
|
+
validates :password_confirmation, :error => :does_not_match do
|
283
|
+
password_confirmation == password
|
284
|
+
end
|
285
|
+
end
|
286
|
+
```
|
287
|
+
|
288
|
+
The error for the email validation would use the `formeze.errors.invalid`
|
289
|
+
I18n key, defaulting to "is invalid". The error message for the password
|
290
|
+
confirmation validation would use the `formeze.errors.does_not_match` key.
|
291
|
+
|
292
|
+
|
210
293
|
Rails usage
|
211
294
|
-----------
|
212
295
|
|
213
296
|
This is the basic pattern for using a formeze form in a Rails controller:
|
214
297
|
|
215
298
|
```ruby
|
216
|
-
form = SomeForm.
|
217
|
-
form.parse(request.raw_post)
|
299
|
+
form = SomeForm.parse(request.raw_post)
|
218
300
|
|
219
301
|
if form.valid?
|
220
302
|
# do something with form data
|
@@ -234,8 +316,7 @@ Using formeze with sinatra is similar, the only difference is that there is
|
|
234
316
|
no raw_post method on the request object so the body has to be read directly:
|
235
317
|
|
236
318
|
```ruby
|
237
|
-
form = SomeForm.
|
238
|
-
form.parse(request.body.read)
|
319
|
+
form = SomeForm.parse(request.body.read)
|
239
320
|
|
240
321
|
if form.valid?
|
241
322
|
# do something with form data
|
data/Rakefile.rb
CHANGED
data/formeze.gemspec
CHANGED
data/lib/formeze.rb
CHANGED
@@ -16,32 +16,36 @@ module Formeze
|
|
16
16
|
|
17
17
|
def initialize(name, options = {})
|
18
18
|
@name, @options = name, options
|
19
|
+
|
20
|
+
if options.has_key?(:word_limit)
|
21
|
+
Kernel.warn '[formeze] :word_limit option is deprecated, please use custom validation instead'
|
22
|
+
end
|
19
23
|
end
|
20
24
|
|
21
25
|
def validate(value, form)
|
22
26
|
value = Formeze.scrub(value, @options[:scrub])
|
23
27
|
|
24
28
|
if value !~ /\S/
|
25
|
-
|
29
|
+
form.add_error(self, error(:required, 'is required')) if required?
|
26
30
|
|
27
31
|
form.send(:"#{name}=", blank_value? ? blank_value : value)
|
28
32
|
else
|
29
|
-
|
33
|
+
form.add_error(self, error(:not_multiline, 'cannot contain newlines')) if !multiline? && value.lines.count > 1
|
30
34
|
|
31
|
-
|
35
|
+
form.add_error(self, error(:too_long, 'is too long')) if too_long?(value)
|
32
36
|
|
33
|
-
|
37
|
+
form.add_error(self, error(:too_short, 'is too short')) if too_short?(value)
|
34
38
|
|
35
|
-
|
39
|
+
form.add_error(self, error(:no_match, 'is invalid')) if no_match?(value)
|
36
40
|
|
37
|
-
|
41
|
+
form.add_error(self, error(:bad_value, 'is invalid')) if values? && !values.include?(value)
|
38
42
|
|
39
43
|
form.send(:"#{name}=", value)
|
40
44
|
end
|
41
45
|
end
|
42
46
|
|
43
|
-
def error(
|
44
|
-
translate(
|
47
|
+
def error(key, default)
|
48
|
+
Formeze.translate(key, :scope => [:formeze, :errors], :default => default)
|
45
49
|
end
|
46
50
|
|
47
51
|
def key
|
@@ -53,7 +57,7 @@ module Formeze
|
|
53
57
|
end
|
54
58
|
|
55
59
|
def label
|
56
|
-
@options.fetch(:label) { translate(name, :scope => [:formeze, :labels], :default => Label.new(name)) }
|
60
|
+
@options.fetch(:label) { Formeze.translate(name, :scope => [:formeze, :labels], :default => Label.new(name)) }
|
57
61
|
end
|
58
62
|
|
59
63
|
def required?
|
@@ -77,15 +81,7 @@ module Formeze
|
|
77
81
|
end
|
78
82
|
|
79
83
|
def too_many_characters?(value)
|
80
|
-
|
81
|
-
value.chars.count > @options.fetch(:maxlength)
|
82
|
-
elsif @options.has_key?(:char_limit)
|
83
|
-
Kernel.warn '[formeze] :char_limit option is deprecated, please use :maxlength instead'
|
84
|
-
|
85
|
-
value.chars.count > @options.fetch(:char_limit)
|
86
|
-
else
|
87
|
-
value.chars.count > 64
|
88
|
-
end
|
84
|
+
value.chars.count > @options.fetch(:maxlength) { 64 }
|
89
85
|
end
|
90
86
|
|
91
87
|
def too_many_words?(value)
|
@@ -127,12 +123,60 @@ module Formeze
|
|
127
123
|
def defined_unless
|
128
124
|
@options.fetch(:defined_unless)
|
129
125
|
end
|
126
|
+
end
|
130
127
|
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
128
|
+
class FieldSet
|
129
|
+
include Enumerable
|
130
|
+
|
131
|
+
def initialize
|
132
|
+
@fields, @index = [], {}
|
133
|
+
end
|
134
|
+
|
135
|
+
def each(&block)
|
136
|
+
@fields.each(&block)
|
137
|
+
end
|
138
|
+
|
139
|
+
def <<(field)
|
140
|
+
@fields << field
|
141
|
+
|
142
|
+
@index[field.name] = field
|
143
|
+
end
|
144
|
+
|
145
|
+
def [](field_name)
|
146
|
+
@index.fetch(field_name)
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
class Validation
|
151
|
+
def initialize(field, options, &block)
|
152
|
+
@field, @options, @block = field, options, block
|
153
|
+
end
|
154
|
+
|
155
|
+
def error_key
|
156
|
+
@options.fetch(:error) { :invalid }
|
157
|
+
end
|
158
|
+
|
159
|
+
def error_message
|
160
|
+
Formeze.translate(error_key, :scope => [:formeze, :errors], :default => 'is invalid')
|
161
|
+
end
|
162
|
+
|
163
|
+
def validates?(form)
|
164
|
+
@options.has_key?(:when) ? form.instance_eval(&@options[:when]) : true
|
165
|
+
end
|
166
|
+
|
167
|
+
def value?(form)
|
168
|
+
form.send(@field.name) =~ /\S/
|
169
|
+
end
|
170
|
+
|
171
|
+
def validate(form)
|
172
|
+
if validates?(form) && value?(form)
|
173
|
+
return_value = if @block.arity == 1
|
174
|
+
@block.call(form.send(@field.name))
|
175
|
+
else
|
176
|
+
form.instance_eval(&@block)
|
177
|
+
end
|
178
|
+
|
179
|
+
form.add_error(@field, error_message) unless return_value
|
136
180
|
end
|
137
181
|
end
|
138
182
|
end
|
@@ -164,7 +208,7 @@ module Formeze
|
|
164
208
|
include ArrayAttrAccessor
|
165
209
|
|
166
210
|
def fields
|
167
|
-
@fields ||=
|
211
|
+
@fields ||= FieldSet.new
|
168
212
|
end
|
169
213
|
|
170
214
|
def field(*args)
|
@@ -179,20 +223,12 @@ module Formeze
|
|
179
223
|
end
|
180
224
|
end
|
181
225
|
|
182
|
-
def
|
183
|
-
@
|
226
|
+
def validations
|
227
|
+
@validations ||= []
|
184
228
|
end
|
185
229
|
|
186
|
-
def
|
187
|
-
|
188
|
-
end
|
189
|
-
|
190
|
-
def errors
|
191
|
-
@errors ||= []
|
192
|
-
end
|
193
|
-
|
194
|
-
def error(message)
|
195
|
-
errors << message
|
230
|
+
def validates(field_name, options = {}, &block)
|
231
|
+
validations << Validation.new(fields[field_name], options, &block)
|
196
232
|
end
|
197
233
|
|
198
234
|
def parse(encoded_form_data)
|
@@ -236,23 +272,33 @@ module Formeze
|
|
236
272
|
end
|
237
273
|
|
238
274
|
values.each do |value|
|
239
|
-
field.validate(value, self)
|
240
|
-
error!("#{field.label} #{error}", field.name)
|
241
|
-
end
|
275
|
+
field.validate(value, self)
|
242
276
|
end
|
243
277
|
end
|
244
278
|
|
245
279
|
if defined?(Rails)
|
246
|
-
%w(utf8 authenticity_token).each
|
280
|
+
%w(utf8 authenticity_token).each do |key|
|
281
|
+
form_data.delete(key)
|
282
|
+
end
|
247
283
|
end
|
248
284
|
|
249
|
-
|
285
|
+
unless form_data.empty?
|
286
|
+
raise KeyError, "unexpected form keys: #{form_data.keys.sort.join(', ')}"
|
287
|
+
end
|
250
288
|
|
251
|
-
self.class.
|
252
|
-
|
289
|
+
self.class.validations.each do |validation|
|
290
|
+
validation.validate(self)
|
253
291
|
end
|
254
292
|
end
|
255
293
|
|
294
|
+
def add_error(field, message)
|
295
|
+
error = ValidationError.new("#{field.label} #{message}")
|
296
|
+
|
297
|
+
errors << error
|
298
|
+
|
299
|
+
field_errors[field.name] << error
|
300
|
+
end
|
301
|
+
|
256
302
|
def valid?
|
257
303
|
errors.empty?
|
258
304
|
end
|
@@ -273,13 +319,15 @@ module Formeze
|
|
273
319
|
field_errors[field_name]
|
274
320
|
end
|
275
321
|
|
276
|
-
def
|
322
|
+
def to_h
|
277
323
|
self.class.fields.inject({}) do |hash, field|
|
278
324
|
hash[field.name] = send(field.name)
|
279
325
|
hash
|
280
326
|
end
|
281
327
|
end
|
282
328
|
|
329
|
+
alias_method :to_hash, :to_h
|
330
|
+
|
283
331
|
private
|
284
332
|
|
285
333
|
def field_defined?(field)
|
@@ -295,14 +343,6 @@ module Formeze
|
|
295
343
|
def field_errors
|
296
344
|
@field_errors ||= Hash.new { |h, k| h[k] = [] }
|
297
345
|
end
|
298
|
-
|
299
|
-
def error!(message, field_name = nil)
|
300
|
-
error = ValidationError.new(message)
|
301
|
-
|
302
|
-
errors << error
|
303
|
-
|
304
|
-
field_errors[field_name] << error unless field_name.nil?
|
305
|
-
end
|
306
346
|
end
|
307
347
|
|
308
348
|
def self.scrub_methods
|
@@ -321,6 +361,10 @@ module Formeze
|
|
321
361
|
end
|
322
362
|
end
|
323
363
|
|
364
|
+
def self.translate(key, options)
|
365
|
+
defined?(I18n) ? I18n.translate(key, options) : options.fetch(:default)
|
366
|
+
end
|
367
|
+
|
324
368
|
def self.setup(form)
|
325
369
|
form.send :include, InstanceMethods
|
326
370
|
|
data/spec/formeze_spec.rb
CHANGED
@@ -38,8 +38,10 @@ describe 'FormWithField' do
|
|
38
38
|
proc { @form.parse('title=foo&title=bar') }.must_raise(Formeze::ValueError)
|
39
39
|
end
|
40
40
|
|
41
|
-
it 'raises an exception when
|
42
|
-
proc { @form.parse('title=Untitled&foo=bar') }.must_raise(Formeze::KeyError)
|
41
|
+
it 'raises an exception when the data contains unexpected keys' do
|
42
|
+
exception = proc { @form.parse('title=Untitled&foo=bar&baz=') }.must_raise(Formeze::KeyError)
|
43
|
+
|
44
|
+
exception.message.must_equal('unexpected form keys: baz, foo')
|
43
45
|
end
|
44
46
|
end
|
45
47
|
|
@@ -105,6 +107,12 @@ describe 'FormWithField after parsing valid input' do
|
|
105
107
|
end
|
106
108
|
end
|
107
109
|
|
110
|
+
describe 'to_h method' do
|
111
|
+
it 'returns a hash containing the field name and its value' do
|
112
|
+
@form.to_h.must_equal({:title => 'Untitled'})
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
108
116
|
describe 'to_hash method' do
|
109
117
|
it 'returns a hash containing the field name and its value' do
|
110
118
|
@form.to_hash.must_equal({:title => 'Untitled'})
|
@@ -227,23 +235,6 @@ describe 'FormWithFieldThatCanHaveMultipleLines after parsing input containing n
|
|
227
235
|
end
|
228
236
|
end
|
229
237
|
|
230
|
-
class FormWithCharacterLimitedField < Formeze::Form
|
231
|
-
field :title, :char_limit => 16
|
232
|
-
end
|
233
|
-
|
234
|
-
describe 'FormWithCharacterLimitedField after parsing input with too many characters' do
|
235
|
-
before do
|
236
|
-
@form = FormWithCharacterLimitedField.new
|
237
|
-
@form.parse('title=This+Title+Will+Be+Too+Long')
|
238
|
-
end
|
239
|
-
|
240
|
-
describe 'valid query method' do
|
241
|
-
it 'returns false' do
|
242
|
-
@form.valid?.must_equal(false)
|
243
|
-
end
|
244
|
-
end
|
245
|
-
end
|
246
|
-
|
247
238
|
class FormWithMaxLengthField < Formeze::Form
|
248
239
|
field :title, :maxlength => 16
|
249
240
|
end
|
@@ -509,16 +500,55 @@ describe 'FormWithHaltingCondition after parsing input with same_address set and
|
|
509
500
|
end
|
510
501
|
end
|
511
502
|
|
512
|
-
class
|
503
|
+
class FormWithOptionalKey < Formeze::Form
|
504
|
+
field :accept_terms, :values => %w(true), :key_required => false
|
505
|
+
end
|
506
|
+
|
507
|
+
describe 'FormWithOptionalKey after parsing input without the key' do
|
508
|
+
before do
|
509
|
+
@form = FormWithOptionalKey.new
|
510
|
+
@form.parse('')
|
511
|
+
end
|
512
|
+
|
513
|
+
describe 'valid query method' do
|
514
|
+
it 'returns true' do
|
515
|
+
@form.valid?.must_equal(true)
|
516
|
+
end
|
517
|
+
end
|
518
|
+
end
|
519
|
+
|
520
|
+
class FormWithOptionalFieldThatCanOnlyHaveSpecifiedValues < Formeze::Form
|
521
|
+
field :size, :required => false, :values => %w(S M L XL)
|
522
|
+
end
|
523
|
+
|
524
|
+
describe 'FormWithOptionalFieldThatCanOnlyHaveSpecifiedValues after parsing blank input' do
|
525
|
+
before do
|
526
|
+
@form = FormWithOptionalFieldThatCanOnlyHaveSpecifiedValues.new
|
527
|
+
@form.parse('size=')
|
528
|
+
end
|
529
|
+
|
530
|
+
describe 'valid query method' do
|
531
|
+
it 'returns true' do
|
532
|
+
@form.valid?.must_equal(true)
|
533
|
+
end
|
534
|
+
end
|
535
|
+
end
|
536
|
+
|
537
|
+
module EmailAddress
|
538
|
+
def self.valid?(address)
|
539
|
+
address.include?('@')
|
540
|
+
end
|
541
|
+
end
|
542
|
+
|
543
|
+
class FormWithCustomEmailValidation < Formeze::Form
|
513
544
|
field :email
|
514
545
|
|
515
|
-
|
516
|
-
error 'Email is invalid'
|
546
|
+
validates :email, &EmailAddress.method(:valid?)
|
517
547
|
end
|
518
548
|
|
519
|
-
describe '
|
549
|
+
describe 'FormWithCustomEmailValidation after parsing invalid input' do
|
520
550
|
before do
|
521
|
-
@form =
|
551
|
+
@form = FormWithCustomEmailValidation.new
|
522
552
|
@form.parse('email=alice')
|
523
553
|
end
|
524
554
|
|
@@ -527,33 +557,85 @@ describe 'FormWithCustomValidation after parsing invalid input' do
|
|
527
557
|
@form.valid?.must_equal(false)
|
528
558
|
end
|
529
559
|
end
|
560
|
+
|
561
|
+
describe 'errors method' do
|
562
|
+
it 'includes a generic error message for the named field' do
|
563
|
+
@form.errors.map(&:to_s).must_include('Email is invalid')
|
564
|
+
end
|
565
|
+
end
|
566
|
+
|
567
|
+
describe 'errors_on query method' do
|
568
|
+
it 'returns true when given the field name' do
|
569
|
+
@form.errors_on?(:email).must_equal(true)
|
570
|
+
end
|
571
|
+
end
|
530
572
|
end
|
531
573
|
|
532
|
-
|
533
|
-
|
574
|
+
describe 'FormWithCustomEmailValidation after parsing blank input' do
|
575
|
+
before do
|
576
|
+
@form = FormWithCustomEmailValidation.new
|
577
|
+
@form.parse('email=')
|
578
|
+
end
|
579
|
+
|
580
|
+
describe 'errors method' do
|
581
|
+
it 'will not include the custom validation error message' do
|
582
|
+
@form.errors.map(&:to_s).wont_include('Email is invalid')
|
583
|
+
end
|
584
|
+
end
|
534
585
|
end
|
535
586
|
|
536
|
-
|
587
|
+
class FormWithCustomPasswordConfirmationCheck < Formeze::Form
|
588
|
+
field :password
|
589
|
+
field :password_confirmation
|
590
|
+
|
591
|
+
validates :password_confirmation, :error => :does_not_match do
|
592
|
+
password_confirmation == password
|
593
|
+
end
|
594
|
+
end
|
595
|
+
|
596
|
+
describe 'FormWithCustomPasswordConfirmationCheck after parsing invalid input' do
|
537
597
|
before do
|
538
|
-
@form =
|
539
|
-
@form.parse('')
|
598
|
+
@form = FormWithCustomPasswordConfirmationCheck.new
|
599
|
+
@form.parse('password=foo&password_confirmation=bar')
|
540
600
|
end
|
541
601
|
|
542
602
|
describe 'valid query method' do
|
543
|
-
it 'returns
|
544
|
-
@form.valid?.must_equal(
|
603
|
+
it 'returns false' do
|
604
|
+
@form.valid?.must_equal(false)
|
605
|
+
end
|
606
|
+
end
|
607
|
+
|
608
|
+
describe 'errors method' do
|
609
|
+
it 'includes a generic error message for the named field' do
|
610
|
+
@form.errors.map(&:to_s).must_include('Password confirmation is invalid')
|
611
|
+
end
|
612
|
+
end
|
613
|
+
|
614
|
+
describe 'errors_on query method' do
|
615
|
+
it 'returns true when given the field name' do
|
616
|
+
@form.errors_on?(:password_confirmation).must_equal(true)
|
545
617
|
end
|
546
618
|
end
|
547
619
|
end
|
548
620
|
|
549
|
-
class
|
550
|
-
field :
|
621
|
+
class FormWithCustomMinimumSpendValidation < Formeze::Form
|
622
|
+
field :minimum_spend
|
623
|
+
|
624
|
+
field :fixed_discount, :required => false, :blank => nil
|
625
|
+
|
626
|
+
validates :minimum_spend, :when => :fixed_discount? do
|
627
|
+
minimum_spend.to_f > 0
|
628
|
+
end
|
629
|
+
|
630
|
+
def fixed_discount?
|
631
|
+
!fixed_discount.nil?
|
632
|
+
end
|
551
633
|
end
|
552
634
|
|
553
|
-
describe '
|
635
|
+
describe 'FormWithCustomMinimumSpendValidation after parsing valid input' do
|
554
636
|
before do
|
555
|
-
@form =
|
556
|
-
@form.parse('
|
637
|
+
@form = FormWithCustomMinimumSpendValidation.new
|
638
|
+
@form.parse('minimum_spend=0.00&fixed_discount=')
|
557
639
|
end
|
558
640
|
|
559
641
|
describe 'valid query method' do
|
@@ -561,6 +643,43 @@ describe 'FormWithOptionalFieldThatCanOnlyHaveSpecifiedValues after parsing blan
|
|
561
643
|
@form.valid?.must_equal(true)
|
562
644
|
end
|
563
645
|
end
|
646
|
+
|
647
|
+
describe 'errors method' do
|
648
|
+
it 'returns an empty array' do
|
649
|
+
@form.errors.must_be_empty
|
650
|
+
end
|
651
|
+
end
|
652
|
+
|
653
|
+
describe 'errors_on query method' do
|
654
|
+
it 'returns false when given the field name' do
|
655
|
+
@form.errors_on?(:minimum_spend).must_equal(false)
|
656
|
+
end
|
657
|
+
end
|
658
|
+
end
|
659
|
+
|
660
|
+
describe 'FormWithCustomMinimumSpendValidation after parsing invalid input' do
|
661
|
+
before do
|
662
|
+
@form = FormWithCustomMinimumSpendValidation.new
|
663
|
+
@form.parse('minimum_spend=0.00&fixed_discount=10%')
|
664
|
+
end
|
665
|
+
|
666
|
+
describe 'valid query method' do
|
667
|
+
it 'returns false' do
|
668
|
+
@form.valid?.must_equal(false)
|
669
|
+
end
|
670
|
+
end
|
671
|
+
|
672
|
+
describe 'errors method' do
|
673
|
+
it 'includes a generic error message for the named field' do
|
674
|
+
@form.errors.map(&:to_s).must_include('Minimum spend is invalid')
|
675
|
+
end
|
676
|
+
end
|
677
|
+
|
678
|
+
describe 'errors_on query method' do
|
679
|
+
it 'returns true when given the field name' do
|
680
|
+
@form.errors_on?(:minimum_spend).must_equal(true)
|
681
|
+
end
|
682
|
+
end
|
564
683
|
end
|
565
684
|
|
566
685
|
describe 'FormWithField on Rails' do
|
@@ -601,6 +720,22 @@ describe 'I18n integration' do
|
|
601
720
|
form.errors.first.to_s.must_equal('Title cannot be blank')
|
602
721
|
end
|
603
722
|
|
723
|
+
it 'provides i18n support for overriding the default custom validation error message' do
|
724
|
+
I18n.backend.store_translations :en, {:formeze => {:errors => {:invalid => 'is not valid'}}}
|
725
|
+
|
726
|
+
form = FormWithCustomEmailValidation.new
|
727
|
+
form.parse('email=alice')
|
728
|
+
form.errors.first.to_s.must_equal('Email is not valid')
|
729
|
+
end
|
730
|
+
|
731
|
+
it 'provides i18n support for specifying custom validation error messages' do
|
732
|
+
I18n.backend.store_translations :en, {:formeze => {:errors => {:does_not_match => 'does not match'}}}
|
733
|
+
|
734
|
+
form = FormWithCustomPasswordConfirmationCheck.new
|
735
|
+
form.parse('password=foo&password_confirmation=bar')
|
736
|
+
form.errors.first.to_s.must_equal('Password confirmation does not match')
|
737
|
+
end
|
738
|
+
|
604
739
|
it 'provides i18n support for specifying field labels globally' do
|
605
740
|
I18n.backend.store_translations :en, {:formeze => {:labels => {:title => 'TITLE'}}}
|
606
741
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: formeze
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-06-10 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake
|
@@ -75,7 +75,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
75
75
|
version: '0'
|
76
76
|
requirements: []
|
77
77
|
rubyforge_project:
|
78
|
-
rubygems_version: 1.8.
|
78
|
+
rubygems_version: 1.8.25
|
79
79
|
signing_key:
|
80
80
|
specification_version: 3
|
81
81
|
summary: See description
|