client_side_validations 3.0.2 → 3.1.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.
Files changed (73) hide show
  1. data/client_side_validations.gemspec +4 -7
  2. data/lib/client_side_validations/action_view/form_builder.rb +97 -9
  3. data/lib/client_side_validations/action_view/form_helper.rb +24 -7
  4. data/lib/client_side_validations/action_view.rb +4 -3
  5. data/lib/client_side_validations/active_model/length.rb +12 -10
  6. data/lib/client_side_validations/active_model/numericality.rb +14 -9
  7. data/lib/client_side_validations/active_model.rb +21 -13
  8. data/lib/client_side_validations/active_record/middleware.rb +10 -2
  9. data/lib/client_side_validations/active_record/uniqueness.rb +10 -8
  10. data/lib/client_side_validations/engine.rb +6 -0
  11. data/lib/client_side_validations/files.rb +8 -0
  12. data/lib/client_side_validations/formtastic.rb +3 -3
  13. data/lib/client_side_validations/middleware.rb +5 -7
  14. data/lib/client_side_validations/mongo_mapper/middleware.rb +20 -0
  15. data/lib/client_side_validations/mongo_mapper/uniqueness.rb +28 -0
  16. data/lib/client_side_validations/mongo_mapper.rb +9 -0
  17. data/lib/client_side_validations/mongoid/uniqueness.rb +10 -8
  18. data/lib/client_side_validations/version.rb +1 -1
  19. data/lib/client_side_validations.rb +8 -3
  20. data/lib/generators/client_side_validations/copy_asset_generator.rb +23 -0
  21. data/lib/generators/client_side_validations/install_generator.rb +18 -6
  22. data/lib/generators/templates/client_side_validations/README.rails.3.0 +6 -0
  23. data/lib/generators/templates/client_side_validations/README.rails.3.1 +7 -0
  24. data/lib/generators/templates/{client_side_validations.rb → client_side_validations/initializer.rb} +1 -1
  25. data/test/action_view/cases/helper.rb +37 -13
  26. data/test/action_view/cases/test_helpers.rb +364 -1
  27. data/test/action_view/cases/test_legacy_helpers.rb +68 -1
  28. data/test/active_model/cases/test_validations.rb +27 -3
  29. data/test/active_record/cases/test_middleware.rb +41 -16
  30. data/test/active_record/cases/test_uniqueness_validator.rb +5 -0
  31. data/test/active_record/models/user.rb +4 -0
  32. data/test/base_helper.rb +2 -0
  33. data/test/core_ext/cases/test_core_ext.rb +1 -0
  34. data/test/formtastic/cases/helper.rb +5 -0
  35. data/test/formtastic/cases/test_form_builder.rb +3 -3
  36. data/test/formtastic/cases/test_form_helper.rb +3 -4
  37. data/test/generators/cases/test_generators.rb +31 -0
  38. data/test/javascript/public/test/callbacks/elementAfter.js +1 -1
  39. data/test/javascript/public/test/callbacks/elementBefore.js +1 -1
  40. data/test/javascript/public/test/callbacks/elementFail.js +1 -1
  41. data/test/javascript/public/test/callbacks/elementPass.js +1 -1
  42. data/test/javascript/public/test/callbacks/formAfter.js +1 -1
  43. data/test/javascript/public/test/callbacks/formBefore.js +1 -1
  44. data/test/javascript/public/test/callbacks/formFail.js +1 -1
  45. data/test/javascript/public/test/callbacks/formPass.js +1 -1
  46. data/test/javascript/public/test/form_builders/validateForm.js +1 -1
  47. data/test/javascript/public/test/form_builders/validateFormtastic.js +2 -2
  48. data/test/javascript/public/test/form_builders/validateNestedForm.js +66 -0
  49. data/test/javascript/public/test/form_builders/validateSimpleForm.js +1 -1
  50. data/test/javascript/public/test/validateElement.js +36 -1
  51. data/test/javascript/public/test/validators/length.js +7 -1
  52. data/test/javascript/public/test/validators/numericality.js +7 -0
  53. data/test/javascript/public/test/validators/presence.js +6 -0
  54. data/test/javascript/public/test/validators/uniqueness.js +8 -1
  55. data/test/javascript/server.rb +9 -3
  56. data/test/javascript/views/index.erb +1 -1
  57. data/test/javascript/views/layout.erb +1 -1
  58. data/test/middleware/cases/helper.rb +3 -0
  59. data/test/mongo_mapper/cases/helper.rb +9 -0
  60. data/test/mongo_mapper/cases/test_base.rb +15 -0
  61. data/test/mongo_mapper/cases/test_middleware.rb +77 -0
  62. data/test/mongo_mapper/cases/test_uniqueness_validator.rb +50 -0
  63. data/test/mongo_mapper/models/magazine.rb +11 -0
  64. data/test/mongoid/cases/test_middleware.rb +15 -6
  65. data/test/mongoid/cases/test_uniqueness_validator.rb +5 -0
  66. data/test/mongoid/models/book.rb +4 -0
  67. data/test/simple_form/cases/helper.rb +3 -0
  68. data/test/simple_form/cases/test_form_helper.rb +3 -1
  69. data/test/test_loader.rb +6 -0
  70. data/{javascript → vendor/assets/javascripts}/rails.validations.js +32 -17
  71. metadata +44 -23
  72. data/lib/generators/templates/README +0 -7
  73. data/test/generators/cases/test_install_generator.rb +0 -15
@@ -1,20 +1,32 @@
1
1
  module ClientSideValidations
2
2
  module Generators
3
3
  class InstallGenerator < Rails::Generators::Base
4
- source_root File.expand_path('../../templates', __FILE__)
4
+ source_root File.expand_path('../../templates/client_side_validations', __FILE__)
5
5
 
6
- desc 'Creates a ClientSideValidations initializer and copies client-side-validations.js to public/javascripts.'
6
+ if Rails.version >= '3.1'
7
+ desc 'Creates a ClientSideValidations initializer.'
8
+ else
9
+ desc 'Creates a ClientSideValidations initializer and copies rails.validations.js to public/javascripts.'
10
+ end
7
11
 
8
12
  def copy_initializer
9
- copy_file 'client_side_validations.rb', 'config/initializers/client_side_validations.rb'
13
+ copy_file 'initializer.rb', 'config/initializers/client_side_validations.rb'
10
14
  end
11
15
 
12
- def copy_locale
13
- copy_file '../../../javascript/rails.validations.js', 'public/javascripts/rails.validations.js'
16
+ def copy_javascript_asset
17
+ if Rails.version >= '3.0'
18
+ if Rails.version < '3.1'
19
+ copy_file '../../../../vendor/assets/javascripts/rails.validations.js', 'public/javascripts/rails.validations.js'
20
+ end
21
+ end
14
22
  end
15
23
 
16
24
  def show_readme
17
- readme 'README' if behavior == :invoke
25
+ if Rails.version >= '3.1'
26
+ readme 'README.rails.3.1' if behavior == :invoke
27
+ else
28
+ readme 'README.rails.3.0' if behavior == :invoke
29
+ end
18
30
  end
19
31
  end
20
32
  end
@@ -0,0 +1,6 @@
1
+ *********************
2
+ ClientSideValidations
3
+ *********************
4
+
5
+ Client Side Validations only works with jQuery.
6
+ You'll need to include jQuery in your layout file before you include 'rails.validations.js'
@@ -0,0 +1,7 @@
1
+ *********************
2
+ ClientSideValidations
3
+ *********************
4
+
5
+ In your app/assets/javascripts/application.js file add the following:
6
+
7
+ //= require rails.validations
@@ -1,7 +1,7 @@
1
1
  # ClientSideValidations Initializer
2
2
 
3
3
  require 'client_side_validations/simple_form' if defined?(::SimpleForm)
4
- require 'client_side_validations/formtastic' if defined?(::Formtastic)
4
+ require 'client_side_validations/formtastic' if defined?(::Formtastic)
5
5
 
6
6
  # Uncomment the following block if you want each input field to have the validation messages attached.
7
7
  # ActionView::Base.field_error_proc = Proc.new do |html_tag, instance|
@@ -1,8 +1,14 @@
1
1
  require 'base_helper'
2
2
  require 'action_view'
3
- require 'client_side_validations/action_view'
4
- require 'action_view/template/handlers/erb'
3
+ require 'action_view/template'
5
4
  require 'action_view/models'
5
+ require 'client_side_validations/action_view'
6
+
7
+ module ActionController
8
+ class Base
9
+ include ActionDispatch::Routing::RouteSet.new.url_helpers
10
+ end
11
+ end
6
12
 
7
13
  module ActionViewTestSetup
8
14
  include ::ClientSideValidations::ActionView::Helpers::FormHelper
@@ -12,6 +18,19 @@ module ActionViewTestSetup
12
18
  @output_buffer = super
13
19
  end
14
20
 
21
+ Routes = ActionDispatch::Routing::RouteSet.new
22
+ Routes.draw do
23
+ resources :posts do
24
+ resources :comments
25
+ end
26
+ end
27
+
28
+ def _routes
29
+ Routes
30
+ end
31
+
32
+ include Routes.url_helpers
33
+
15
34
  def setup
16
35
  super
17
36
 
@@ -67,14 +86,11 @@ module ActionViewTestSetup
67
86
  @post.body = "Back to the hill and over it again!"
68
87
  @post.secret = 1
69
88
  @post.written_on = Date.new(2004, 6, 15)
70
- end
71
89
 
72
- def url_for(object)
73
- @url_for_options = object
74
- if object.is_a?(Hash)
75
- "http://www.example.com"
90
+ if defined?(ActionView::OutputFlow)
91
+ @view_flow = ActionView::OutputFlow.new
76
92
  else
77
- super
93
+ @_content_for = Hash.new { |h,k| h[k] = ActiveSupport::SafeBuffer.new }
78
94
  end
79
95
  end
80
96
 
@@ -85,33 +101,40 @@ module ActionViewTestSetup
85
101
  txt << %{</div>}
86
102
  end
87
103
 
88
- def form_text(action = "http://www.example.com", id = nil, html_class = nil, remote = nil, validators = nil)
104
+ def form_text(action = "http://www.example.com", id = nil, html_class = nil, remote = nil, validators = nil, file = nil)
89
105
  txt = %{<form accept-charset="UTF-8" action="#{action}"}
90
106
  txt << %{ data-remote="true"} if remote
91
107
  txt << %{ class="#{html_class}"} if html_class
92
108
  txt << %{ data-validate="true"} if validators
109
+ txt << %{ enctype="multipart/form-data"} if file
93
110
  txt << %{ id="#{id}"} if id
94
- txt << %{ method="post">}
111
+ txt << %{ method="post"}
112
+ txt << %{ novalidate="novalidate"} if validators
113
+ txt << %{>}
95
114
  end
96
115
 
97
116
  def whole_form(action = "http://www.example.com", id = nil, html_class = nil, options = nil)
98
117
  contents = block_given? ? yield : ""
99
118
 
100
119
  if options.is_a?(Hash)
101
- method, remote, validators = options.values_at(:method, :remote, :validators)
120
+ method, remote, validators, file = options.values_at(:method, :remote, :validators, :file)
102
121
  else
103
122
  method = options
104
123
  end
105
124
 
106
- html = form_text(action, id, html_class, remote, validators) + snowman(method) + (contents || "") + "</form>"
125
+ html = form_text(action, id, html_class, remote, validators, file) + snowman(method) + (contents || "") + "</form>"
107
126
 
108
127
  if options.is_a?(Hash) && options[:validators]
109
- html + %Q{<script>var #{id} = #{client_side_form_settings_helper.merge(:validators => validators).to_json};</script>}
128
+ build_script_tag(html, id, options[:validators])
110
129
  else
111
130
  html
112
131
  end
113
132
  end
114
133
 
134
+ def build_script_tag(html, id, validators)
135
+ (html || "") + %Q{<script>window['#{id}'] = #{client_side_form_settings_helper.merge(:validators => validators).to_json};</script>}
136
+ end
137
+
115
138
  protected
116
139
  def comments_path(post)
117
140
  "/posts/#{post.id}/comments"
@@ -150,3 +173,4 @@ module ActionViewTestSetup
150
173
  end
151
174
 
152
175
  end
176
+
@@ -44,7 +44,7 @@ class ClientSideValidations::ActionViewHelpersTest < ActionView::TestCase
44
44
  end
45
45
 
46
46
  validators = {'post[cost]' => {:presence => {:message => "can't be blank"}}}
47
- expected = whole_form("/posts/123", "edit_post_123", "edit_post", :method => "put", :validators => validators) do
47
+ expected = whole_form("/posts/123", "edit_post_123", "edit_post", :method => "put", :validators => validators, :file => true) do
48
48
  %{<input data-validate="true" id="post_cost" name="post[cost]" type="file" />}
49
49
  end
50
50
  assert_equal expected, output_buffer
@@ -233,5 +233,368 @@ class ClientSideValidations::ActionViewHelpersTest < ActionView::TestCase
233
233
  end
234
234
  assert_equal expected, output_buffer
235
235
  end
236
+
237
+ def test_ignore_an_individual_validator
238
+ hash = {
239
+ :cost => {
240
+ :presence => {
241
+ :message => "can't be blank"
242
+ },
243
+ :format => {
244
+ :with => /.+/,
245
+ :message => "is invalid"
246
+ }
247
+ }
248
+ }
249
+ @post.stubs(:client_side_validation_hash).returns(hash)
250
+ validators = {'post[cost]' => {:presence => {:message => "can't be blank"}}}
251
+ form_for(@post, :validate => true) do |f|
252
+ concat f.text_field(:cost, :validate => { :format => false })
253
+ end
254
+
255
+ validators = {'post[cost]' => {:presence => {:message => "can't be blank"}}}
256
+ expected = whole_form("/posts/123", "edit_post_123", "edit_post", :method => "put", :validators => validators) do
257
+ %{<input data-validate="true" id="post_cost" name="post[cost]" size="30" type="text" />}
258
+ end
259
+ assert_equal expected, output_buffer
260
+ end
261
+
262
+ def test_ignore_many_validators
263
+ hash = {
264
+ :cost => {
265
+ :presence => {
266
+ :message => "can't be blank"
267
+ },
268
+ :format => {
269
+ :with => /.+/,
270
+ :message => "is invalid"
271
+ }
272
+ }
273
+ }
274
+ @post.stubs(:client_side_validation_hash).returns(hash)
275
+ validators = {'post[cost]' => {:presence => {:message => "can't be blank"}}}
276
+ form_for(@post, :validate => true) do |f|
277
+ concat f.text_field(:cost, :validate => { :presence => false, :format => false })
278
+ end
279
+
280
+ validators = {}
281
+ expected = whole_form("/posts/123", "edit_post_123", "edit_post", :method => "put", :validators => validators) do
282
+ %{<input id="post_cost" name="post[cost]" size="30" type="text" />}
283
+ end
284
+ assert_equal expected, output_buffer
285
+ end
286
+
287
+ def test_select
288
+ form_for(@post, :validate => true) do |f|
289
+ concat f.select(:cost, [])
290
+ end
291
+
292
+ validators = {'post[cost]' => {:presence => {:message => "can't be blank"}}}
293
+ expected = whole_form("/posts/123", "edit_post_123", "edit_post", :method => "put", :validators => validators) do
294
+ %{<select data-validate="true" id="post_cost" name="post[cost]"></select>}
295
+ end
296
+ assert_equal expected, output_buffer
297
+ end
298
+
299
+ def test_select_multiple
300
+ form_for(@post, :validate => true) do |f|
301
+ concat f.select(:cost, [], {}, :multiple => true)
302
+ end
303
+
304
+ validators = {'post[cost][]' => {:presence => {:message => "can't be blank"}}}
305
+ expected = whole_form("/posts/123", "edit_post_123", "edit_post", :method => "put", :validators => validators) do
306
+ %{<select data-validate="true" id="post_cost" multiple="multiple" name="post[cost][]"></select>}
307
+ end
308
+ assert_equal expected, output_buffer
309
+ end
310
+
311
+ def test_collection_select
312
+ form_for(@post, :validate => true) do |f|
313
+ concat f.collection_select(:cost, [], :id, :name)
314
+ end
315
+
316
+ validators = {'post[cost]' => {:presence => {:message => "can't be blank"}}}
317
+ expected = whole_form("/posts/123", "edit_post_123", "edit_post", :method => "put", :validators => validators) do
318
+ %{<select data-validate="true" id="post_cost" name="post[cost]"></select>}
319
+ end
320
+ assert_equal expected, output_buffer
321
+ end
322
+
323
+ def test_grouped_collection_select
324
+ form_for(@post, :validate => true) do |f|
325
+ concat f.grouped_collection_select(:cost, [], :group_method, :group_label_method, :id, :name)
326
+ end
327
+
328
+ validators = {'post[cost]' => {:presence => {:message => "can't be blank"}}}
329
+ expected = whole_form("/posts/123", "edit_post_123", "edit_post", :method => "put", :validators => validators) do
330
+ %{<select data-validate="true" id="post_cost" name="post[cost]"></select>}
331
+ end
332
+ assert_equal expected, output_buffer
333
+ end
334
+
335
+ def test_time_zone_select
336
+ zones = mock('TimeZones')
337
+ zones.stubs(:all).returns([])
338
+ form_for(@post, :validate => true) do |f|
339
+ concat f.time_zone_select(:cost, nil, :model => zones)
340
+ end
341
+
342
+ validators = {'post[cost]' => {:presence => {:message => "can't be blank"}}}
343
+ expected = whole_form("/posts/123", "edit_post_123", "edit_post", :method => "put", :validators => validators) do
344
+ %{<select data-validate="true" id="post_cost" name="post[cost]"></select>}
345
+ end
346
+ assert_equal expected, output_buffer
347
+ end
348
+
349
+ def test_conditional_validator_filters
350
+ hash = {
351
+ :cost => {
352
+ :presence => {
353
+ :message => "can't be blank",
354
+ :unless => :cannot_validate?
355
+ }
356
+ },
357
+ :title => {
358
+ :presence => {
359
+ :message => "can't be blank",
360
+ :if => :can_validate?
361
+ }
362
+ }
363
+ }
364
+
365
+ @post.title = nil
366
+ @post.stubs(:cannot_validate?).returns(false)
367
+ @post.stubs(:can_validate?).returns(true)
368
+ @post.stubs(:client_side_validation_hash).returns(hash)
369
+ form_for(@post, :validate => true) do |f|
370
+ concat f.text_field(:cost)
371
+ concat f.text_field(:title)
372
+ end
373
+
374
+ validators = {}
375
+ expected = whole_form("/posts/123", "edit_post_123", "edit_post", :method => "put", :validators => validators) do
376
+ %{<input id="post_cost" name="post[cost]" size="30" type="text" />} +
377
+ %{<input id="post_title" name="post[title]" size="30" type="text" />}
378
+ end
379
+ assert_equal expected, output_buffer
380
+ end
381
+
382
+ def test_conditional_validators_should_be_filtered
383
+ hash = {
384
+ :cost => {
385
+ :presence => {
386
+ :message => "can't be blank",
387
+ :unless => :cannot_validate?
388
+ }
389
+ },
390
+ :title => {
391
+ :presence => {
392
+ :message => "can't be blank",
393
+ :if => :can_validate?
394
+ }
395
+ }
396
+ }
397
+
398
+ @post.title = nil
399
+ @post.stubs(:cannot_validate?).returns(false)
400
+ @post.stubs(:can_validate?).returns(true)
401
+ @post.stubs(:client_side_validation_hash).returns(hash)
402
+ form_for(@post, :validate => true) do |f|
403
+ concat f.text_field(:cost)
404
+ concat f.text_field(:title)
405
+ end
406
+
407
+ validators = {}
408
+ expected = whole_form("/posts/123", "edit_post_123", "edit_post", :method => "put", :validators => validators) do
409
+ %{<input id="post_cost" name="post[cost]" size="30" type="text" />} +
410
+ %{<input id="post_title" name="post[title]" size="30" type="text" />}
411
+ end
412
+ assert_equal expected, output_buffer
413
+ end
414
+
415
+ def test_conditional_validator_filters_being_forced
416
+ hash = {
417
+ :cost => {
418
+ :presence => {
419
+ :message => "can't be blank",
420
+ :unless => :cannot_validate?
421
+ }
422
+ },
423
+ :title => {
424
+ :presence => {
425
+ :message => "can't be blank",
426
+ :if => :can_validate?
427
+ }
428
+ }
429
+ }
430
+
431
+ @post.title = nil
432
+ @post.stubs(:cannot_validate?).returns(false)
433
+ @post.stubs(:can_validate?).returns(true)
434
+ @post.stubs(:client_side_validation_hash).returns(hash)
435
+ form_for(@post, :validate => true) do |f|
436
+ concat f.text_field(:cost, :validate => true)
437
+ concat f.text_field(:title, :validate => true)
438
+ end
439
+
440
+ validators = {
441
+ 'post[cost]' => {:presence => {:message => "can't be blank"}},
442
+ 'post[title]' => {:presence => {:message => "can't be blank"}}
443
+ }
444
+ expected = whole_form("/posts/123", "edit_post_123", "edit_post", :method => "put", :validators => validators) do
445
+ %{<input data-validate="true" id="post_cost" name="post[cost]" size="30" type="text" />} +
446
+ %{<input data-validate="true" id="post_title" name="post[title]" size="30" type="text" />}
447
+ end
448
+ assert_equal expected, output_buffer
449
+ end
450
+
451
+ def test_conditional_validator_filters_being_forced_and_not_meeting_condition
452
+ hash = {
453
+ :cost => {
454
+ :presence => {
455
+ :message => "can't be blank",
456
+ :unless => :cannot_validate?
457
+ }
458
+ },
459
+ :title => {
460
+ :presence => {
461
+ :message => "can't be blank",
462
+ :if => :can_validate?
463
+ }
464
+ }
465
+ }
466
+
467
+ @post.title = nil
468
+ @post.stubs(:cannot_validate?).returns(true)
469
+ @post.stubs(:can_validate?).returns(false)
470
+ @post.stubs(:client_side_validation_hash).returns(hash)
471
+ form_for(@post, :validate => true) do |f|
472
+ concat f.text_field(:cost, :validate => true)
473
+ concat f.text_field(:title, :validate => true)
474
+ end
475
+
476
+ validators = {}
477
+ expected = whole_form("/posts/123", "edit_post_123", "edit_post", :method => "put", :validators => validators) do
478
+ %{<input id="post_cost" name="post[cost]" size="30" type="text" />} +
479
+ %{<input id="post_title" name="post[title]" size="30" type="text" />}
480
+ end
481
+ assert_equal expected, output_buffer
482
+ end
483
+
484
+ def test_conditional_validator_filters_being_forced_individually
485
+ hash = {
486
+ :cost => {
487
+ :presence => {
488
+ :message => "can't be blank",
489
+ :unless => :cannot_validate?
490
+ }
491
+ },
492
+ :title => {
493
+ :presence => {
494
+ :message => "can't be blank",
495
+ :if => :can_validate?
496
+ }
497
+ }
498
+ }
499
+
500
+ @post.title = nil
501
+ @post.stubs(:cannot_validate?).returns(false)
502
+ @post.stubs(:can_validate?).returns(true)
503
+ @post.stubs(:client_side_validation_hash).returns(hash)
504
+ form_for(@post, :validate => true) do |f|
505
+ concat f.text_field(:cost, :validate => { :presence => true })
506
+ concat f.text_field(:title, :validate => { :presence => true })
507
+ end
508
+
509
+ validators = {
510
+ 'post[cost]' => {:presence => {:message => "can't be blank"}},
511
+ 'post[title]' => {:presence => {:message => "can't be blank"}}
512
+ }
513
+ expected = whole_form("/posts/123", "edit_post_123", "edit_post", :method => "put", :validators => validators) do
514
+ %{<input data-validate="true" id="post_cost" name="post[cost]" size="30" type="text" />} +
515
+ %{<input data-validate="true" id="post_title" name="post[title]" size="30" type="text" />}
516
+ end
517
+ assert_equal expected, output_buffer
518
+ end
519
+
520
+ def test_conditional_validator_filters_being_forced_and_not_meeting_condition_individually
521
+ hash = {
522
+ :cost => {
523
+ :presence => {
524
+ :message => "can't be blank",
525
+ :unless => :cannot_validate?
526
+ }
527
+ },
528
+ :title => {
529
+ :presence => {
530
+ :message => "can't be blank",
531
+ :if => :can_validate?
532
+ }
533
+ }
534
+ }
535
+
536
+ @post.title = nil
537
+ @post.stubs(:cannot_validate?).returns(true)
538
+ @post.stubs(:can_validate?).returns(false)
539
+ @post.stubs(:client_side_validation_hash).returns(hash)
540
+ form_for(@post, :validate => true) do |f|
541
+ concat f.text_field(:cost, :validate => { :presence => true })
542
+ concat f.text_field(:title, :validate => { :presence => true })
543
+ end
544
+
545
+ validators = {}
546
+ expected = whole_form("/posts/123", "edit_post_123", "edit_post", :method => "put", :validators => validators) do
547
+ %{<input id="post_cost" name="post[cost]" size="30" type="text" />} +
548
+ %{<input id="post_title" name="post[title]" size="30" type="text" />}
549
+ end
550
+ assert_equal expected, output_buffer
551
+ end
552
+
553
+ def test_conditional_validator_filters_being_forced_with_procs
554
+ hash = {
555
+ :cost => {
556
+ :presence => {
557
+ :message => "can't be blank",
558
+ :unless => Proc.new { |post| post.cannot_validate? }
559
+ }
560
+ },
561
+ :title => {
562
+ :presence => {
563
+ :message => "can't be blank",
564
+ :if => Proc.new { |post| post.can_validate? }
565
+ }
566
+ }
567
+ }
568
+
569
+ @post.title = nil
570
+ @post.stubs(:cannot_validate?).returns(false)
571
+ @post.stubs(:can_validate?).returns(true)
572
+ @post.stubs(:client_side_validation_hash).returns(hash)
573
+ form_for(@post, :validate => true) do |f|
574
+ concat f.text_field(:cost, :validate => true)
575
+ concat f.text_field(:title, :validate => true)
576
+ end
577
+
578
+ validators = {
579
+ 'post[cost]' => {:presence => {:message => "can't be blank"}},
580
+ 'post[title]' => {:presence => {:message => "can't be blank"}}
581
+ }
582
+ expected = whole_form("/posts/123", "edit_post_123", "edit_post", :method => "put", :validators => validators) do
583
+ %{<input data-validate="true" id="post_cost" name="post[cost]" size="30" type="text" />} +
584
+ %{<input data-validate="true" id="post_title" name="post[title]" size="30" type="text" />}
585
+ end
586
+ assert_equal expected, output_buffer
587
+ end
588
+
589
+ def test_pushing_script_to_content_for
590
+ form_for(@post, :validate => :post) do |f|
591
+ concat f.text_field(:cost)
592
+ end
593
+
594
+ validators = {'post[cost]' => {:presence => {:message => "can't be blank"}}}
595
+ expected = %{<form accept-charset="UTF-8" action="/posts/123" class="edit_post" data-validate="true" id="edit_post_123" method="post" novalidate="novalidate"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="&#x2713;" /><input name="_method" type="hidden" value="put" /></div><input data-validate="true" id="post_cost" name="post[cost]" size="30" type="text" /></form>}
596
+ assert_equal expected, output_buffer
597
+ assert_equal build_script_tag(nil, "edit_post_123", validators), content_for(:post)
598
+ end
236
599
  end
237
600
 
@@ -30,7 +30,7 @@ class ClientSideValidations::LegacyActionViewHelpersTest < ActionView::TestCase
30
30
  concat f.file_field(:cost)
31
31
  end
32
32
 
33
- expected = whole_form("/posts/123", "edit_post_123", "edit_post", "put") do
33
+ expected = whole_form("/posts/123", "edit_post_123", "edit_post", :method => :put, :file => true) do
34
34
  %{<input id="post_cost" name="post[cost]" type="file" />}
35
35
  end
36
36
  assert_equal expected, output_buffer
@@ -147,4 +147,71 @@ class ClientSideValidations::LegacyActionViewHelpersTest < ActionView::TestCase
147
147
  assert_equal expected, output_buffer
148
148
  end
149
149
 
150
+ def test_fields_for
151
+ result = fields_for(@comment) do |c|
152
+ c.text_field(:title)
153
+ end
154
+
155
+ expected = %{<input id="comment_title" name="comment[title]" size="30" type="text" />}
156
+
157
+ assert_equal expected, result
158
+ end
159
+
160
+ def test_select
161
+ form_for(@post) do |f|
162
+ concat f.select(:cost, [])
163
+ end
164
+
165
+ expected = whole_form("/posts/123", "edit_post_123", "edit_post", "put") do
166
+ %{<select id="post_cost" name="post[cost]"></select>}
167
+ end
168
+ assert_equal expected, output_buffer
169
+ end
170
+
171
+ def test_select_multiple
172
+ form_for(@post) do |f|
173
+ concat f.select(:cost, [], {}, :multiple => true)
174
+ end
175
+
176
+ expected = whole_form("/posts/123", "edit_post_123", "edit_post", "put") do
177
+ %{<select id="post_cost" multiple="multiple" name="post[cost][]"></select>}
178
+ end
179
+ assert_equal expected, output_buffer
180
+ end
181
+
182
+ def test_collection_select
183
+ form_for(@post) do |f|
184
+ concat f.collection_select(:cost, [], :id, :name)
185
+ end
186
+
187
+ expected = whole_form("/posts/123", "edit_post_123", "edit_post", "put") do
188
+ %{<select id="post_cost" name="post[cost]"></select>}
189
+ end
190
+ assert_equal expected, output_buffer
191
+ end
192
+
193
+ def test_grouped_collection_select
194
+ form_for(@post) do |f|
195
+ concat f.grouped_collection_select(:cost, [], :group_method, :group_label_method, :id, :name)
196
+ end
197
+
198
+ expected = whole_form("/posts/123", "edit_post_123", "edit_post", "put") do
199
+ %{<select id="post_cost" name="post[cost]"></select>}
200
+ end
201
+ assert_equal expected, output_buffer
202
+ end
203
+
204
+ def test_time_zone_select
205
+ zones = mock('TimeZones')
206
+ zones.stubs(:all).returns([])
207
+ form_for(@post) do |f|
208
+ concat f.time_zone_select(:cost, nil, :model => zones)
209
+ end
210
+
211
+ expected = whole_form("/posts/123", "edit_post_123", "edit_post", "put") do
212
+ %{<select id="post_cost" name="post[cost]"></select>}
213
+ end
214
+ assert_equal expected, output_buffer
215
+ end
150
216
  end
217
+
@@ -138,14 +138,38 @@ class ActiveModel::ValidationsTest < ClientSideValidations::ActiveModelTestBase
138
138
  assert_equal expected_hash, person.client_side_validation_hash
139
139
  end
140
140
 
141
- def test_validators_with_if_or_unless_are_ignored
141
+ def test_generic_block_validators_should_be_ignored
142
142
  person = new_person do |p|
143
- p.validates_presence_of :first_name, :if => Proc.new { |p| true }
144
- p.validates_presence_of :last_name, :unless => Proc.new { |p| true }
143
+ p.validates_each(:first_name) do |record, attr, value|
144
+ record.errors.add(:first_name, "failed")
145
+ end
145
146
  end
146
147
 
147
148
  expected_hash = {}
148
149
  assert_equal expected_hash, person.client_side_validation_hash
149
150
  end
151
+
152
+ def test_conditionals_persist_on_validator
153
+ person = new_person do |p|
154
+ p.validates :first_name, :presence => { :if => :can_validate? }
155
+ p.validates :last_name, :presence => { :unless => :cannot_validate? }
156
+ end
157
+
158
+ expected_hash = {
159
+ :first_name => {
160
+ :presence => {
161
+ :message => "can't be blank",
162
+ :if => :can_validate?
163
+ }
164
+ },
165
+ :last_name => {
166
+ :presence => {
167
+ :message => "can't be blank",
168
+ :unless => :cannot_validate?
169
+ }
170
+ }
171
+ }
172
+ assert_equal expected_hash, person.client_side_validation_hash
173
+ end
150
174
  end
151
175