simple_form 1.5.2 → 2.0.0.rc

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 (105) hide show
  1. data/CHANGELOG.md +224 -0
  2. data/MIT-LICENSE +1 -1
  3. data/README.md +817 -0
  4. data/lib/generators/simple_form/install_generator.rb +15 -1
  5. data/lib/generators/simple_form/templates/README +12 -0
  6. data/lib/generators/simple_form/templates/config/initializers/simple_form.rb.tt +173 -0
  7. data/lib/simple_form.rb +109 -43
  8. data/lib/simple_form/action_view_extensions/builder.rb +158 -53
  9. data/lib/simple_form/action_view_extensions/form_helper.rb +29 -22
  10. data/lib/simple_form/components.rb +11 -1
  11. data/lib/simple_form/components/errors.rb +6 -24
  12. data/lib/simple_form/components/hints.rb +7 -21
  13. data/lib/simple_form/components/html5.rb +26 -0
  14. data/lib/simple_form/components/labels.rb +15 -13
  15. data/lib/simple_form/components/maxlength.rb +41 -0
  16. data/lib/simple_form/components/min_max.rb +49 -0
  17. data/lib/simple_form/components/pattern.rb +34 -0
  18. data/lib/simple_form/components/placeholders.rb +5 -17
  19. data/lib/simple_form/components/readonly.rb +22 -0
  20. data/lib/simple_form/core_ext/hash.rb +16 -0
  21. data/lib/simple_form/error_notification.rb +8 -1
  22. data/lib/simple_form/form_builder.rb +86 -22
  23. data/lib/simple_form/helpers.rb +7 -4
  24. data/lib/simple_form/helpers/autofocus.rb +11 -0
  25. data/lib/simple_form/helpers/disabled.rb +15 -0
  26. data/lib/simple_form/helpers/readonly.rb +15 -0
  27. data/lib/simple_form/helpers/required.rb +7 -10
  28. data/lib/simple_form/helpers/validators.rb +4 -4
  29. data/lib/simple_form/inputs.rb +17 -13
  30. data/lib/simple_form/inputs/base.rb +50 -81
  31. data/lib/simple_form/inputs/boolean_input.rb +43 -4
  32. data/lib/simple_form/inputs/collection_check_boxes_input.rb +21 -0
  33. data/lib/simple_form/inputs/collection_input.rb +27 -13
  34. data/lib/simple_form/inputs/collection_radio_buttons_input.rb +69 -0
  35. data/lib/simple_form/inputs/collection_select_input.rb +14 -0
  36. data/lib/simple_form/inputs/date_time_input.rb +2 -2
  37. data/lib/simple_form/inputs/grouped_collection_select_input.rb +41 -0
  38. data/lib/simple_form/inputs/hidden_input.rb +3 -6
  39. data/lib/simple_form/inputs/numeric_input.rb +3 -51
  40. data/lib/simple_form/inputs/password_input.rb +1 -2
  41. data/lib/simple_form/inputs/priority_input.rb +2 -2
  42. data/lib/simple_form/inputs/range_input.rb +1 -3
  43. data/lib/simple_form/inputs/string_input.rb +6 -8
  44. data/lib/simple_form/inputs/text_input.rb +1 -2
  45. data/lib/simple_form/version.rb +1 -1
  46. data/lib/simple_form/wrappers.rb +8 -0
  47. data/lib/simple_form/wrappers/builder.rb +75 -0
  48. data/lib/simple_form/wrappers/many.rb +68 -0
  49. data/lib/simple_form/wrappers/root.rb +34 -0
  50. data/lib/simple_form/wrappers/single.rb +18 -0
  51. data/test/action_view_extensions/builder_test.rb +195 -100
  52. data/test/action_view_extensions/form_helper_test.rb +24 -2
  53. data/test/components/label_test.rb +20 -5
  54. data/test/form_builder/association_test.rb +167 -0
  55. data/test/form_builder/button_test.rb +28 -0
  56. data/test/{error_notification_test.rb → form_builder/error_notification_test.rb} +2 -1
  57. data/test/form_builder/error_test.rb +101 -0
  58. data/test/form_builder/general_test.rb +348 -0
  59. data/test/form_builder/hint_test.rb +115 -0
  60. data/test/form_builder/input_field_test.rb +51 -0
  61. data/test/form_builder/label_test.rb +51 -0
  62. data/test/form_builder/wrapper_test.rb +140 -0
  63. data/test/generators/simple_form_generator_test.rb +32 -0
  64. data/test/inputs/boolean_input_test.rb +91 -0
  65. data/test/inputs/collection_check_boxes_input_test.rb +224 -0
  66. data/test/inputs/collection_radio_buttons_input_test.rb +326 -0
  67. data/test/inputs/collection_select_input_test.rb +241 -0
  68. data/test/inputs/datetime_input_test.rb +85 -0
  69. data/test/inputs/disabled_test.rb +38 -0
  70. data/test/inputs/discovery_test.rb +61 -0
  71. data/test/inputs/file_input_test.rb +16 -0
  72. data/test/inputs/general_test.rb +69 -0
  73. data/test/inputs/grouped_collection_select_input_test.rb +109 -0
  74. data/test/inputs/hidden_input_test.rb +30 -0
  75. data/test/inputs/numeric_input_test.rb +167 -0
  76. data/test/inputs/priority_input_test.rb +43 -0
  77. data/test/inputs/readonly_test.rb +61 -0
  78. data/test/inputs/required_test.rb +113 -0
  79. data/test/inputs/string_input_test.rb +140 -0
  80. data/test/inputs/text_input_test.rb +24 -0
  81. data/test/{discovery_inputs.rb → support/discovery_inputs.rb} +0 -0
  82. data/test/support/misc_helpers.rb +48 -6
  83. data/test/support/mock_controller.rb +2 -2
  84. data/test/support/models.rb +20 -5
  85. data/test/test_helper.rb +5 -8
  86. metadata +123 -98
  87. data/.gitignore +0 -3
  88. data/.gitmodules +0 -3
  89. data/.travis.yml +0 -15
  90. data/CHANGELOG.rdoc +0 -159
  91. data/Gemfile +0 -9
  92. data/README.rdoc +0 -466
  93. data/Rakefile +0 -27
  94. data/lib/generators/simple_form/templates/config/initializers/simple_form.rb +0 -93
  95. data/lib/simple_form/components/wrapper.rb +0 -38
  96. data/lib/simple_form/helpers/has_errors.rb +0 -15
  97. data/lib/simple_form/helpers/maxlength.rb +0 -24
  98. data/lib/simple_form/helpers/pattern.rb +0 -28
  99. data/simple_form.gemspec +0 -25
  100. data/test/components/error_test.rb +0 -56
  101. data/test/components/hint_test.rb +0 -74
  102. data/test/components/wrapper_test.rb +0 -63
  103. data/test/custom_components.rb +0 -7
  104. data/test/form_builder_test.rb +0 -930
  105. data/test/inputs_test.rb +0 -995
@@ -42,9 +42,31 @@ class FormHelperTest < ActionView::TestCase
42
42
  assert_select 'form.simple_form.user'
43
43
  end
44
44
 
45
- test 'simple form should add object class name as css class to form' do
45
+ test 'simple form should add :as option as css class to form when object is not present' do
46
+ concat(simple_form_for(:user, :as => 'superuser') do |f| end)
47
+ assert_select 'form.simple_form.superuser'
48
+ end
49
+
50
+ test 'simple form should add object class name with new prefix as css class to form if record is not persisted' do
51
+ @user.new_record!
46
52
  concat(simple_form_for(@user) do |f| end)
47
- assert_select 'form.simple_form.user'
53
+ assert_select 'form.simple_form.new_user'
54
+ end
55
+
56
+ test 'simple form should add :as option with new prefix as css class to form if record is not persisted' do
57
+ @user.new_record!
58
+ concat(simple_form_for(@user, :as => 'superuser') do |f| end)
59
+ assert_select 'form.simple_form.new_superuser'
60
+ end
61
+
62
+ test 'simple form should add edit class prefix as css class to form if record is persisted' do
63
+ concat(simple_form_for(@user) do |f| end)
64
+ assert_select 'form.simple_form.edit_user'
65
+ end
66
+
67
+ test 'simple form should add :as options with edit prefix as css class to form if record is persisted' do
68
+ concat(simple_form_for(@user, :as => 'superuser') do |f| end)
69
+ assert_select 'form.simple_form.edit_superuser'
48
70
  end
49
71
 
50
72
  test 'simple form should not add object class to form if css_class is specified' do
@@ -1,7 +1,8 @@
1
1
  # encoding: UTF-8
2
2
  require 'test_helper'
3
3
 
4
- class LabelTest < ActionView::TestCase
4
+ # Isolated tests for label without triggering f.label.
5
+ class IsolatedLabelTest < ActionView::TestCase
5
6
  setup do
6
7
  SimpleForm::Inputs::Base.reset_i18n_cache :translate_required_html
7
8
  end
@@ -71,16 +72,16 @@ class LabelTest < ActionView::TestCase
71
72
  end
72
73
  end
73
74
 
74
- test 'input should use i18n based only on attribute to lookup translation' do
75
- store_translations(:en, :simple_form => { :labels => { :age => 'Idade' } } ) do
75
+ test 'input should use i18n under defaults to lookup translation' do
76
+ store_translations(:en, :simple_form => { :labels => { :defaults => {:age => 'Idade'} } } ) do
76
77
  with_label_for @user, :age, :integer
77
78
  assert_select 'label[for=user_age]', /Idade/
78
79
  end
79
80
  end
80
81
 
81
82
  test 'input should not use i18n label if translate is false' do
82
- swap SimpleForm, :translate => false do
83
- store_translations(:en, :simple_form => { :labels => { :age => 'Idade' } } ) do
83
+ swap SimpleForm, :translate_labels => false do
84
+ store_translations(:en, :simple_form => { :labels => { :defaults => {:age => 'Idade'} } } ) do
84
85
  with_label_for @user, :age, :integer
85
86
  assert_select 'label[for=user_age]', /Age/
86
87
  end
@@ -246,6 +247,11 @@ class LabelTest < ActionView::TestCase
246
247
  assert_select 'label[for=project_name]', /Name/
247
248
  end
248
249
 
250
+ test 'label should include for attribute for select collection' do
251
+ with_label_for @user, :sex, :select, :collection => [:male, :female]
252
+ assert_select 'label[for=user_sex]'
253
+ end
254
+
249
255
  test 'label should use i18n properly when object is not present' do
250
256
  store_translations(:en, :simple_form => { :labels => {
251
257
  :project => { :name => 'Nome' }
@@ -268,4 +274,13 @@ class LabelTest < ActionView::TestCase
268
274
  assert_select 'label.my_custom_class'
269
275
  end
270
276
  end
277
+
278
+ test 'label strips extra classes even when label_class is nil' do
279
+ swap SimpleForm, :label_class => nil do
280
+ with_label_for @user, :name, :string
281
+ assert_select "label[class='string required']"
282
+ assert_no_select "label[class='string required ']"
283
+ assert_no_select "label[class=' string required']"
284
+ end
285
+ end
271
286
  end
@@ -0,0 +1,167 @@
1
+ # encoding: UTF-8
2
+ require 'test_helper'
3
+
4
+ class AssociationTest < ActionView::TestCase
5
+ def with_association_for(object, *args)
6
+ with_concat_form_for(object) do |f|
7
+ f.association(*args)
8
+ end
9
+ end
10
+
11
+ test 'builder should not allow creating an association input when no object exists' do
12
+ assert_raise ArgumentError do
13
+ with_association_for :post, :author
14
+ end
15
+ end
16
+
17
+ test 'builder association with a block calls simple_fields_for' do
18
+ simple_form_for @user do |f|
19
+ f.association :posts do |posts_form|
20
+ assert posts_form.instance_of?(SimpleForm::FormBuilder)
21
+ end
22
+ end
23
+ end
24
+
25
+ test 'builder association forwards collection to simple_fields_for' do
26
+ calls = 0
27
+ simple_form_for @user do |f|
28
+ f.association :company, :collection => Company.all do |c|
29
+ calls += 1
30
+ end
31
+ end
32
+
33
+ assert_equal 3, calls
34
+ end
35
+
36
+ test 'builder association marks input as required based on both association and attribute' do
37
+ swap SimpleForm, :required_by_default => false do
38
+ with_association_for @validating_user, :company, :collection => []
39
+ assert_select 'label.required'
40
+ end
41
+ end
42
+
43
+ test 'builder preloads collection association' do
44
+ value = @user.tags
45
+ value.expects(:to_a).returns(value)
46
+ with_association_for @user, :tags
47
+ assert_select 'form select.select#user_tag_ids'
48
+ assert_select 'form select option[value=1]', 'Tag 1'
49
+ assert_select 'form select option[value=2]', 'Tag 2'
50
+ assert_select 'form select option[value=3]', 'Tag 3'
51
+ end
52
+
53
+ test 'builder does not preload collection association if preload is false' do
54
+ value = @user.company
55
+ value.expects(:to_a).never
56
+ with_association_for @user, :company, :preload => false
57
+ assert_select 'form select.select#user_company_id'
58
+ assert_select 'form select option[value=1]', 'Company 1'
59
+ assert_select 'form select option[value=2]', 'Company 2'
60
+ assert_select 'form select option[value=3]', 'Company 3'
61
+ end
62
+
63
+ test 'builder does not preload non-collection association' do
64
+ value = @user.company
65
+ value.expects(:to_a).never
66
+ with_association_for @user, :company, :preload => false
67
+ assert_select 'form select.select#user_company_id'
68
+ assert_select 'form select option[value=1]', 'Company 1'
69
+ assert_select 'form select option[value=2]', 'Company 2'
70
+ assert_select 'form select option[value=3]', 'Company 3'
71
+ end
72
+
73
+ # ASSOCIATIONS - BELONGS TO
74
+ test 'builder creates a select for belongs_to associations' do
75
+ with_association_for @user, :company
76
+ assert_select 'form select.select#user_company_id'
77
+ assert_select 'form select option[value=1]', 'Company 1'
78
+ assert_select 'form select option[value=2]', 'Company 2'
79
+ assert_select 'form select option[value=3]', 'Company 3'
80
+ end
81
+
82
+ test 'builder allows collection radio for belongs_to associations' do
83
+ with_association_for @user, :company, :as => :radio_buttons
84
+ assert_select 'form input.radio_buttons#user_company_id_1'
85
+ assert_select 'form input.radio_buttons#user_company_id_2'
86
+ assert_select 'form input.radio_buttons#user_company_id_3'
87
+ end
88
+
89
+ test 'builder marks the record which already belongs to the user' do
90
+ @user.company_id = 2
91
+ with_association_for @user, :company, :as => :radio_buttons
92
+ assert_no_select 'form input.radio_buttons#user_company_id_1[checked=checked]'
93
+ assert_select 'form input.radio_buttons#user_company_id_2[checked=checked]'
94
+ assert_no_select 'form input.radio_buttons#user_company_id_3[checked=checked]'
95
+ end
96
+
97
+ # ASSOCIATIONS - FINDERS
98
+ test 'builder should use reflection conditions to find collection' do
99
+ with_association_for @user, :special_company
100
+ assert_select 'form select.select#user_special_company_id'
101
+ assert_select 'form select option[value=1]'
102
+ assert_no_select 'form select option[value=2]'
103
+ assert_no_select 'form select option[value=3]'
104
+ end
105
+
106
+ test 'builder should allow overriding collection to association input' do
107
+ with_association_for @user, :company, :include_blank => false,
108
+ :collection => [Company.new(999, 'Teste')]
109
+ assert_select 'form select.select#user_company_id'
110
+ assert_no_select 'form select option[value=1]'
111
+ assert_select 'form select option[value=999]', 'Teste'
112
+ assert_select 'form select option', :count => 1
113
+ end
114
+
115
+ # ASSOCIATIONS - has_*
116
+ test 'builder does not allow has_one associations' do
117
+ assert_raise RuntimeError do
118
+ with_association_for @user, :first_company, :as => :radio_buttons
119
+ end
120
+ end
121
+
122
+ test 'builder creates a select with multiple options for collection associations' do
123
+ with_association_for @user, :tags
124
+ assert_select 'form select.select#user_tag_ids'
125
+ assert_select 'form select[multiple=multiple][size=5]'
126
+ assert_select 'form select option[value=1]', 'Tag 1'
127
+ assert_select 'form select option[value=2]', 'Tag 2'
128
+ assert_select 'form select option[value=3]', 'Tag 3'
129
+ end
130
+
131
+ test 'builder allows size to be overwritten for collection associations' do
132
+ with_association_for @user, :tags, :input_html => { :size => 10 }
133
+ assert_select 'form select[multiple=multiple][size=10]'
134
+ end
135
+
136
+ test 'builder marks all selected records which already belongs to user' do
137
+ @user.tag_ids = [1, 2]
138
+ with_association_for @user, :tags
139
+ assert_select 'form select option[value=1][selected=selected]'
140
+ assert_select 'form select option[value=2][selected=selected]'
141
+ assert_no_select 'form select option[value=3][selected=selected]'
142
+ end
143
+
144
+ test 'builder allows a collection of check boxes for collection associations' do
145
+ @user.tag_ids = [1, 2]
146
+ with_association_for @user, :tags, :as => :check_boxes
147
+ assert_select 'form input#user_tag_ids_1[type=checkbox]'
148
+ assert_select 'form input#user_tag_ids_2[type=checkbox]'
149
+ assert_select 'form input#user_tag_ids_3[type=checkbox]'
150
+ end
151
+
152
+ test 'builder marks all selected records for collection boxes' do
153
+ @user.tag_ids = [1, 2]
154
+ with_association_for @user, :tags, :as => :check_boxes
155
+ assert_select 'form input[type=checkbox][value=1][checked=checked]'
156
+ assert_select 'form input[type=checkbox][value=2][checked=checked]'
157
+ assert_no_select 'form input[type=checkbox][value=3][checked=checked]'
158
+ end
159
+
160
+ test 'builder with collection support giving collection and item wrapper tags' do
161
+ with_association_for @user, :tags, :as => :check_boxes,
162
+ :collection_wrapper_tag => :ul, :item_wrapper_tag => :li
163
+
164
+ assert_select 'form ul', :count => 1
165
+ assert_select 'form ul li', :count => 3
166
+ end
167
+ end
@@ -0,0 +1,28 @@
1
+ # encoding: UTF-8
2
+ require 'test_helper'
3
+
4
+ class ButtonTest < ActionView::TestCase
5
+ def with_button_for(object, *args)
6
+ with_concat_form_for(object) do |f|
7
+ f.button(*args)
8
+ end
9
+ end
10
+
11
+ test 'builder should create buttons' do
12
+ with_button_for :post, :submit
13
+ assert_select 'form input.button[type=submit][value=Save Post]'
14
+ end
15
+
16
+ test 'builder should create buttons for records' do
17
+ @user.new_record!
18
+ with_button_for @user, :submit
19
+ assert_select 'form input.button[type=submit][value=Create User]'
20
+ end
21
+
22
+ test "builder should use the default class from the configuration" do
23
+ swap SimpleForm, :button_class => 'btn' do
24
+ with_button_for :post, :submit
25
+ assert_select 'form input.btn[type=submit][value=Save Post]'
26
+ end
27
+ end
28
+ end
@@ -1,8 +1,8 @@
1
1
  # encoding: UTF-8
2
2
  require 'test_helper'
3
3
 
4
+ # Tests for f.error_notification
4
5
  class ErrorNotificationTest < ActionView::TestCase
5
-
6
6
  def with_error_notification_for(object, options={}, &block)
7
7
  with_concat_form_for(object) do |f|
8
8
  f.error_notification(options)
@@ -11,6 +11,7 @@ class ErrorNotificationTest < ActionView::TestCase
11
11
 
12
12
  test 'error notification is not generated when the object has no error' do
13
13
  assert @validating_user.valid?
14
+
14
15
  with_error_notification_for @validating_user
15
16
  assert_no_select 'p.error_notification'
16
17
  end
@@ -0,0 +1,101 @@
1
+ require 'test_helper'
2
+
3
+ # Tests for f.error and f.full_error
4
+ class ErrorTest < ActionView::TestCase
5
+ def with_error_for(object, *args)
6
+ with_concat_form_for(object) do |f|
7
+ f.error(*args)
8
+ end
9
+ end
10
+
11
+ def with_full_error_for(object, *args)
12
+ with_concat_form_for(object) do |f|
13
+ f.full_error(*args)
14
+ end
15
+ end
16
+
17
+ test 'error should not generate content for attribute without errors' do
18
+ with_error_for @user, :active
19
+ assert_no_select 'span.error'
20
+ end
21
+
22
+ test 'error should not generate messages when object is not present' do
23
+ with_error_for :project, :name
24
+ assert_no_select 'span.error'
25
+ end
26
+
27
+ test "error should not generate messages when object doesn't respond to errors method" do
28
+ @user.instance_eval { undef errors }
29
+ with_error_for @user, :name
30
+ assert_no_select 'span.error'
31
+ end
32
+
33
+ test 'error should generate messages for attribute with single error' do
34
+ with_error_for @user, :name
35
+ assert_select 'span.error', "can't be blank"
36
+ end
37
+
38
+ test 'error should generate messages for attribute with one error when using first' do
39
+ swap SimpleForm, :error_method => :first do
40
+ with_error_for @user, :age
41
+ assert_select 'span.error', 'is not a number'
42
+ end
43
+ end
44
+
45
+ test 'error should generate messages for attribute with several errors when using to_sentence' do
46
+ swap SimpleForm, :error_method => :to_sentence do
47
+ with_error_for @user, :age
48
+ assert_select 'span.error', 'is not a number and must be greater than 18'
49
+ end
50
+ end
51
+
52
+ test 'error should be able to pass html options' do
53
+ with_error_for @user, :name, :id => 'error', :class => 'yay'
54
+ assert_select 'span#error.error.yay'
55
+ end
56
+
57
+ test 'error should find errors on attribute and association' do
58
+ with_error_for @user, :company_id, :as => :select,
59
+ :error_method => :to_sentence, :reflection => Association.new(Company, :company, {})
60
+ assert_select 'span.error', 'must be valid and company must be present'
61
+ end
62
+
63
+ test 'error should generate an error tag with a clean HTML' do
64
+ with_error_for @user, :name
65
+ assert_no_select 'span.error[error_html]'
66
+ end
67
+
68
+ test 'error should generate an error tag with a clean HTML when errors options are present' do
69
+ with_error_for @user, :name, :error_tag => :p, :error_prefix => 'Name', :error_method => :first
70
+ assert_no_select 'p.error[error_html]'
71
+ assert_no_select 'p.error[error_tag]'
72
+ assert_no_select 'p.error[error_prefix]'
73
+ assert_no_select 'p.error[error_method]'
74
+ end
75
+
76
+ # FULL ERRORS
77
+
78
+ test 'full error should generate an full error tag for the attribute' do
79
+ with_full_error_for @user, :name
80
+ assert_select 'span.error', "Super User Name! can't be blank"
81
+ end
82
+
83
+ test 'full error should generate an full error tag with a clean HTML' do
84
+ with_full_error_for @user, :name
85
+ assert_no_select 'span.error[error_html]'
86
+ end
87
+
88
+ test 'full error should allow passing options to full error tag' do
89
+ with_full_error_for @user, :name, :id => 'name_error', :error_prefix => "Your name"
90
+ assert_select 'span.error#name_error', "Your name can't be blank"
91
+ end
92
+
93
+ # CUSTOM WRAPPERS
94
+
95
+ test 'error with custom wrappers works' do
96
+ swap_wrapper do
97
+ with_error_for @user, :name
98
+ assert_select 'span.omg_error', "can't be blank"
99
+ end
100
+ end
101
+ end
@@ -0,0 +1,348 @@
1
+ # encoding: UTF-8
2
+ require 'test_helper'
3
+
4
+ class FormBuilderTest < ActionView::TestCase
5
+ def with_custom_form_for(object, *args, &block)
6
+ with_concat_custom_form_for(object) do |f|
7
+ f.input(*args, &block)
8
+ end
9
+ end
10
+
11
+ test 'nested simple fields should yield an instance of FormBuilder' do
12
+ simple_form_for :user do |f|
13
+ f.simple_fields_for :posts do |posts_form|
14
+ assert posts_form.instance_of?(SimpleForm::FormBuilder)
15
+ end
16
+ end
17
+ end
18
+
19
+ test 'builder input is html safe' do
20
+ simple_form_for @user do |f|
21
+ assert f.input(:name).html_safe?
22
+ end
23
+ end
24
+
25
+ test 'builder input should allow a block to configure input' do
26
+ with_form_for @user, :name do
27
+ text_field_tag :foo, :bar, :id => :cool
28
+ end
29
+ assert_no_select 'input.string'
30
+ assert_select 'input#cool'
31
+ end
32
+
33
+ test 'builder should allow adding custom input mappings for default input types' do
34
+ swap SimpleForm, :input_mappings => { /count$/ => :integer } do
35
+ with_form_for @user, :post_count
36
+ assert_no_select 'form input#user_post_count.string'
37
+ assert_select 'form input#user_post_count.numeric.integer'
38
+ end
39
+ end
40
+
41
+ test 'builder should allow adding custom input mappings for integer input types' do
42
+ swap SimpleForm, :input_mappings => { /lock_version/ => :hidden } do
43
+ with_form_for @user, :lock_version
44
+ assert_no_select 'form input#user_lock_version.integer'
45
+ assert_select 'form input#user_lock_version.hidden'
46
+ end
47
+ end
48
+
49
+ test 'builder uses the first matching custom input map when more than one matches' do
50
+ swap SimpleForm, :input_mappings => { /count$/ => :integer, /^post_/ => :password } do
51
+ with_form_for @user, :post_count
52
+ assert_no_select 'form input#user_post_count.password'
53
+ assert_select 'form input#user_post_count.numeric.integer'
54
+ end
55
+ end
56
+
57
+ test 'builder uses the custom map only for matched attributes' do
58
+ swap SimpleForm, :input_mappings => { /lock_version/ => :hidden } do
59
+ with_form_for @user, :post_count
60
+ assert_no_select 'form input#user_post_count.hidden'
61
+ assert_select 'form input#user_post_count.string'
62
+ end
63
+ end
64
+
65
+ # INPUT TYPES
66
+ test 'builder should generate text fields for string columns' do
67
+ with_form_for @user, :name
68
+ assert_select 'form input#user_name.string'
69
+ end
70
+
71
+ test 'builder should generate text areas for text columns' do
72
+ with_form_for @user, :description
73
+ assert_select 'form textarea#user_description.text'
74
+ end
75
+
76
+ test 'builder should generate a checkbox for boolean columns' do
77
+ with_form_for @user, :active
78
+ assert_select 'form input[type=checkbox]#user_active.boolean'
79
+ end
80
+
81
+ test 'builder should use integer text field for integer columns' do
82
+ with_form_for @user, :age
83
+ assert_select 'form input#user_age.numeric.integer'
84
+ end
85
+
86
+ test 'builder should generate decimal text field for decimal columns' do
87
+ with_form_for @user, :credit_limit
88
+ assert_select 'form input#user_credit_limit.numeric.decimal'
89
+ end
90
+
91
+ test 'builder should generate password fields for columns that matches password' do
92
+ with_form_for @user, :password
93
+ assert_select 'form input#user_password.password'
94
+ end
95
+
96
+ test 'builder should generate country fields for columns that matches country' do
97
+ with_form_for @user, :residence_country
98
+ assert_select 'form select#user_residence_country.country'
99
+ end
100
+
101
+ test 'builder should generate time_zone fields for columns that matches time_zone' do
102
+ with_form_for @user, :time_zone
103
+ assert_select 'form select#user_time_zone.time_zone'
104
+ end
105
+
106
+ test 'builder should generate email fields for columns that matches email' do
107
+ with_form_for @user, :email
108
+ assert_select 'form input#user_email.string.email'
109
+ end
110
+
111
+ test 'builder should generate tel fields for columns that matches phone' do
112
+ with_form_for @user, :phone_number
113
+ assert_select 'form input#user_phone_number.string.tel'
114
+ end
115
+
116
+ test 'builder should generate url fields for columns that matches url' do
117
+ with_form_for @user, :url
118
+ assert_select 'form input#user_url.string.url'
119
+ end
120
+
121
+ test 'builder should generate date select for date columns' do
122
+ with_form_for @user, :born_at
123
+ assert_select 'form select#user_born_at_1i.date'
124
+ end
125
+
126
+ test 'builder should generate time select for time columns' do
127
+ with_form_for @user, :delivery_time
128
+ assert_select 'form select#user_delivery_time_4i.time'
129
+ end
130
+
131
+ test 'builder should generate datetime select for datetime columns' do
132
+ with_form_for @user, :created_at
133
+ assert_select 'form select#user_created_at_1i.datetime'
134
+ end
135
+
136
+ test 'builder should generate datetime select for timestamp columns' do
137
+ with_form_for @user, :updated_at
138
+ assert_select 'form select#user_updated_at_1i.datetime'
139
+ end
140
+
141
+ test 'builder should generate file for file columns' do
142
+ @user.avatar = mock("file")
143
+ @user.avatar.expects(:respond_to?).with(:mounted_as).returns(false)
144
+ @user.avatar.expects(:respond_to?).with(:file?).returns(false)
145
+ @user.avatar.expects(:respond_to?).with(:public_filename).returns(true)
146
+
147
+ with_form_for @user, :avatar
148
+ assert_select 'form input#user_avatar.file'
149
+ end
150
+
151
+ test 'builder should generate file for attributes that are real db columns but have file methods' do
152
+ @user.home_picture = mock("file")
153
+ @user.home_picture.expects(:respond_to?).with(:mounted_as).returns(true)
154
+
155
+ with_form_for @user, :home_picture
156
+ assert_select 'form input#user_home_picture.file'
157
+ end
158
+
159
+ test 'build should generate select if a collection is given' do
160
+ with_form_for @user, :age, :collection => 1..60
161
+ assert_select 'form select#user_age.select'
162
+ end
163
+
164
+ test 'builder should allow overriding default input type for text' do
165
+ with_form_for @user, :name, :as => :text
166
+ assert_no_select 'form input#user_name'
167
+ assert_select 'form textarea#user_name.text'
168
+
169
+ with_form_for @user, :active, :as => :radio_buttons
170
+ assert_no_select 'form input[type=checkbox]'
171
+ assert_select 'form input.radio_buttons[type=radio]', :count => 2
172
+
173
+ with_form_for @user, :born_at, :as => :string
174
+ assert_no_select 'form select'
175
+ assert_select 'form input#user_born_at.string'
176
+ end
177
+
178
+ # COMMON OPTIONS
179
+ test 'builder should add chosen form class' do
180
+ swap SimpleForm, :form_class => :my_custom_class do
181
+ with_form_for @user, :name
182
+ assert_select 'form.my_custom_class'
183
+ end
184
+ end
185
+
186
+ test 'builder should allow passing options to input' do
187
+ with_form_for @user, :name, :input_html => { :class => 'my_input', :id => 'my_input' }
188
+ assert_select 'form input#my_input.my_input.string'
189
+ end
190
+
191
+ test 'builder should not propagate input options to wrapper' do
192
+ with_form_for @user, :name, :input_html => { :class => 'my_input', :id => 'my_input' }
193
+ assert_no_select 'form div.input.my_input.string'
194
+ assert_select 'form input#my_input.my_input.string'
195
+ end
196
+
197
+ test 'builder should generate a input with label' do
198
+ with_form_for @user, :name
199
+ assert_select 'form label.string[for=user_name]', /Name/
200
+ end
201
+
202
+ test 'builder should be able to disable the label for a input' do
203
+ with_form_for @user, :name, :label => false
204
+ assert_no_select 'form label'
205
+ end
206
+
207
+ test 'builder should use custom label' do
208
+ with_form_for @user, :name, :label => 'Yay!'
209
+ assert_select 'form label', /Yay!/
210
+ end
211
+
212
+ test 'builder should pass options to label' do
213
+ with_form_for @user, :name, :label_html => { :id => "cool" }
214
+ assert_select 'form label#cool', /Name/
215
+ end
216
+
217
+ test 'builder should not generate hints for a input' do
218
+ with_form_for @user, :name
219
+ assert_no_select 'span.hint'
220
+ end
221
+
222
+ test 'builder should be able to add a hint for a input' do
223
+ with_form_for @user, :name, :hint => 'test'
224
+ assert_select 'span.hint', 'test'
225
+ end
226
+
227
+ test 'builder should be able to disable a hint even if it exists in i18n' do
228
+ store_translations(:en, :simple_form => { :hints => { :name => 'Hint test' } }) do
229
+ with_form_for @user, :name, :hint => false
230
+ assert_no_select 'span.hint'
231
+ end
232
+ end
233
+
234
+ test 'builder should pass options to hint' do
235
+ with_form_for @user, :name, :hint => 'test', :hint_html => { :id => "cool" }
236
+ assert_select 'span.hint#cool', 'test'
237
+ end
238
+
239
+ test 'builder should generate errors for attribute without errors' do
240
+ with_form_for @user, :credit_limit
241
+ assert_no_select 'span.errors'
242
+ end
243
+
244
+ test 'builder should generate errors for attribute with errors' do
245
+ with_form_for @user, :name
246
+ assert_select 'span.error', "can't be blank"
247
+ end
248
+
249
+ test 'builder should be able to disable showing errors for a input' do
250
+ with_form_for @user, :name, :error => false
251
+ assert_no_select 'span.error'
252
+ end
253
+
254
+ test 'builder should pass options to errors' do
255
+ with_form_for @user, :name, :error_html => { :id => "cool" }
256
+ assert_select 'span.error#cool', "can't be blank"
257
+ end
258
+
259
+ test 'placeholder should not be generated when set to false' do
260
+ store_translations(:en, :simple_form => { :placeholders => { :user => {
261
+ :name => 'Name goes here'
262
+ } } }) do
263
+ with_form_for @user, :name, :placeholder => false
264
+ assert_no_select 'input[placeholder]'
265
+ end
266
+ end
267
+
268
+ # DEFAULT OPTIONS
269
+ test 'builder should receive a default argument and pass it to the inputs' do
270
+ with_concat_form_for @user, :defaults => { :input_html => { :class => 'default_class' } } do |f|
271
+ f.input :name
272
+ end
273
+ assert_select 'input.default_class'
274
+ end
275
+
276
+ test 'builder should receive a default argument and pass it to the inputs, respecting the specific options' do
277
+ with_concat_form_for @user, :defaults => { :input_html => { :class => 'default_class' } } do |f|
278
+ f.input :name, :input_html => { :id => 'specific_id' }
279
+ end
280
+ assert_select 'input.default_class#specific_id'
281
+ end
282
+
283
+ test 'builder should receive a default argument and pass it to the inputs, overwriting the defaults with specific options' do
284
+ with_concat_form_for @user, :defaults => { :input_html => { :class => 'default_class', :id => 'default_id' } } do |f|
285
+ f.input :name, :input_html => { :id => 'specific_id' }
286
+ end
287
+ assert_select 'input.default_class#specific_id'
288
+ end
289
+
290
+ test 'builder should receive a default argument and pass it to the inputs without changing the defaults' do
291
+ with_concat_form_for @user, :defaults => { :input_html => { :class => 'default_class', :id => 'default_id' } } do |f|
292
+ concat(f.input :name)
293
+ concat(f.input :credit_limit)
294
+ end
295
+
296
+ assert_select "input.string.default_class[name='user[name]']"
297
+ assert_no_select "input.string[name='user[credit_limit]']"
298
+ end
299
+
300
+ # WITHOUT OBJECT
301
+ test 'builder should generate properly when object is not present' do
302
+ with_form_for :project, :name
303
+ assert_select 'form input.string#project_name'
304
+ end
305
+
306
+ test 'builder should generate password fields based on attribute name when object is not present' do
307
+ with_form_for :project, :password_confirmation
308
+ assert_select 'form input[type=password].password#project_password_confirmation'
309
+ end
310
+
311
+ test 'builder should generate text fields by default for all attributes when object is not present' do
312
+ with_form_for :project, :created_at
313
+ assert_select 'form input.string#project_created_at'
314
+ with_form_for :project, :budget
315
+ assert_select 'form input.string#project_budget'
316
+ end
317
+
318
+ test 'builder should allow overriding input type when object is not present' do
319
+ with_form_for :project, :created_at, :as => :datetime
320
+ assert_select 'form select.datetime#project_created_at_1i'
321
+ with_form_for :project, :budget, :as => :decimal
322
+ assert_select 'form input.decimal#project_budget'
323
+ end
324
+
325
+ # CUSTOM FORM BUILDER
326
+ test 'custom builder should inherit mappings' do
327
+ with_custom_form_for @user, :email
328
+ assert_select 'form input[type=email]#user_email.custom'
329
+ end
330
+
331
+ test 'form with CustomMapTypeFormBuilder should use custom map type builder' do
332
+ with_concat_custom_mapping_form_for(:user) do |user|
333
+ assert user.instance_of?(CustomMapTypeFormBuilder)
334
+ end
335
+ end
336
+
337
+ test 'form with CustomMapTypeFormBuilder should use custom mapping' do
338
+ with_concat_custom_mapping_form_for(:user) do |user|
339
+ assert_equal SimpleForm::Inputs::StringInput, user.class.mappings[:custom_type]
340
+ end
341
+ end
342
+
343
+ test 'form without CustomMapTypeFormBuilder should not use custom mapping' do
344
+ with_concat_form_for(:user) do |user|
345
+ assert_nil user.class.mappings[:custom_type]
346
+ end
347
+ end
348
+ end