simple_form 2.0.0.rc → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of simple_form might be problematic. Click here for more details.

Files changed (45) hide show
  1. data/CHANGELOG.md +16 -6
  2. data/README.md +18 -19
  3. data/lib/generators/simple_form/install_generator.rb +1 -1
  4. data/lib/generators/simple_form/templates/_form.html.erb +2 -2
  5. data/lib/generators/simple_form/templates/_form.html.haml +2 -2
  6. data/lib/generators/simple_form/templates/_form.html.slim +4 -4
  7. data/lib/generators/simple_form/templates/config/initializers/simple_form.rb.tt +23 -20
  8. data/lib/simple_form.rb +13 -9
  9. data/lib/simple_form/action_view_extensions/builder.rb +64 -22
  10. data/lib/simple_form/action_view_extensions/form_helper.rb +1 -1
  11. data/lib/simple_form/components/errors.rb +1 -1
  12. data/lib/simple_form/components/labels.rb +8 -2
  13. data/lib/simple_form/error_notification.rb +1 -2
  14. data/lib/simple_form/form_builder.rb +19 -6
  15. data/lib/simple_form/helpers/required.rb +5 -3
  16. data/lib/simple_form/inputs/base.rb +4 -1
  17. data/lib/simple_form/inputs/boolean_input.rb +4 -1
  18. data/lib/simple_form/inputs/collection_check_boxes_input.rb +2 -2
  19. data/lib/simple_form/inputs/collection_radio_buttons_input.rb +3 -5
  20. data/lib/simple_form/inputs/date_time_input.rb +8 -4
  21. data/lib/simple_form/inputs/grouped_collection_select_input.rb +1 -1
  22. data/lib/simple_form/version.rb +1 -1
  23. data/lib/simple_form/wrappers/builder.rb +46 -18
  24. data/lib/simple_form/wrappers/many.rb +1 -0
  25. data/lib/simple_form/wrappers/root.rb +1 -1
  26. data/test/action_view_extensions/builder_test.rb +100 -12
  27. data/test/action_view_extensions/form_helper_test.rb +13 -13
  28. data/test/components/label_test.rb +24 -0
  29. data/test/form_builder/association_test.rb +10 -0
  30. data/test/form_builder/button_test.rb +19 -0
  31. data/test/form_builder/error_notification_test.rb +16 -0
  32. data/test/form_builder/error_test.rb +21 -1
  33. data/test/form_builder/general_test.rb +8 -0
  34. data/test/form_builder/hint_test.rb +10 -2
  35. data/test/form_builder/input_field_test.rb +13 -1
  36. data/test/form_builder/label_test.rb +14 -0
  37. data/test/form_builder/wrapper_test.rb +10 -1
  38. data/test/inputs/boolean_input_test.rb +10 -0
  39. data/test/inputs/datetime_input_test.rb +20 -6
  40. data/test/inputs/grouped_collection_select_input_test.rb +9 -0
  41. data/test/inputs/priority_input_test.rb +1 -1
  42. data/test/inputs/string_input_test.rb +1 -1
  43. data/test/support/misc_helpers.rb +11 -12
  44. data/test/test_helper.rb +6 -4
  45. metadata +13 -10
@@ -2,23 +2,23 @@ require 'test_helper'
2
2
 
3
3
  class FormHelperTest < ActionView::TestCase
4
4
 
5
- test 'simple form for yields an instance of FormBuilder' do
5
+ test 'SimpleForm for yields an instance of FormBuilder' do
6
6
  simple_form_for :user do |f|
7
7
  assert f.instance_of?(SimpleForm::FormBuilder)
8
8
  end
9
9
  end
10
10
 
11
- test 'simple form should add default class to form' do
11
+ test 'SimpleForm should add default class to form' do
12
12
  concat(simple_form_for(:user) do |f| end)
13
13
  assert_select 'form.simple_form'
14
14
  end
15
15
 
16
- test 'simple form should use default browser validations by default' do
16
+ test 'SimpleForm should use default browser validations by default' do
17
17
  concat(simple_form_for(:user) do |f| end)
18
18
  assert_no_select 'form[novalidate]'
19
19
  end
20
20
 
21
- test 'simple form should not use default browser validations if specified in the configuration options' do
21
+ test 'SimpleForm should not use default browser validations if specified in the configuration options' do
22
22
  swap SimpleForm, :browser_validations => false do
23
23
  concat(simple_form_for(:user) do |f| end)
24
24
  assert_select 'form[novalidate="novalidate"]'
@@ -37,49 +37,49 @@ class FormHelperTest < ActionView::TestCase
37
37
  end
38
38
  end
39
39
 
40
- test 'simple form should add object name as css class to form when object is not present' do
40
+ test 'SimpleForm should add object name as css class to form when object is not present' do
41
41
  concat(simple_form_for(:user) do |f| end)
42
42
  assert_select 'form.simple_form.user'
43
43
  end
44
44
 
45
- test 'simple form should add :as option as css class to form when object is not present' do
45
+ test 'SimpleForm should add :as option as css class to form when object is not present' do
46
46
  concat(simple_form_for(:user, :as => 'superuser') do |f| end)
47
47
  assert_select 'form.simple_form.superuser'
48
48
  end
49
49
 
50
- test 'simple form should add object class name with new prefix as css class to form if record is not persisted' do
50
+ test 'SimpleForm should add object class name with new prefix as css class to form if record is not persisted' do
51
51
  @user.new_record!
52
52
  concat(simple_form_for(@user) do |f| end)
53
53
  assert_select 'form.simple_form.new_user'
54
54
  end
55
55
 
56
- test 'simple form should add :as option with new prefix as css class to form if record is not persisted' do
56
+ test 'SimpleForm should add :as option with new prefix as css class to form if record is not persisted' do
57
57
  @user.new_record!
58
58
  concat(simple_form_for(@user, :as => 'superuser') do |f| end)
59
59
  assert_select 'form.simple_form.new_superuser'
60
60
  end
61
61
 
62
- test 'simple form should add edit class prefix as css class to form if record is persisted' do
62
+ test 'SimpleForm should add edit class prefix as css class to form if record is persisted' do
63
63
  concat(simple_form_for(@user) do |f| end)
64
64
  assert_select 'form.simple_form.edit_user'
65
65
  end
66
66
 
67
- test 'simple form should add :as options with edit prefix as css class to form if record is persisted' do
67
+ test 'SimpleForm should add :as options with edit prefix as css class to form if record is persisted' do
68
68
  concat(simple_form_for(@user, :as => 'superuser') do |f| end)
69
69
  assert_select 'form.simple_form.edit_superuser'
70
70
  end
71
71
 
72
- test 'simple form should not add object class to form if css_class is specified' do
72
+ test 'SimpleForm should not add object class to form if css_class is specified' do
73
73
  concat(simple_form_for(:user, :html => {:class => nil}) do |f| end)
74
74
  assert_no_select 'form.user'
75
75
  end
76
76
 
77
- test 'simple form should add custom class to form if css_class is specified' do
77
+ test 'SimpleForm should add custom class to form if css_class is specified' do
78
78
  concat(simple_form_for(:user, :html => {:class => 'my_class'}) do |f| end)
79
79
  assert_select 'form.my_class'
80
80
  end
81
81
 
82
- test 'pass options to simple form' do
82
+ test 'pass options to SimpleForm' do
83
83
  concat(simple_form_for(:user, :url => '/account', :html => { :id => 'my_form' }) do |f| end)
84
84
  assert_select 'form#my_form'
85
85
  assert_select 'form[action=/account]'
@@ -166,6 +166,21 @@ class IsolatedLabelTest < ActionView::TestCase
166
166
  assert_select 'label.datetime'
167
167
  end
168
168
 
169
+ test 'label should not have css class from type when generate_additional_classes_for does not include :label' do
170
+ swap SimpleForm, :generate_additional_classes_for => [:wrapper, :input] do
171
+ with_label_for @user, :name, :string
172
+ assert_no_select 'label.string'
173
+ with_label_for @user, :description, :text
174
+ assert_no_select 'label.text'
175
+ with_label_for @user, :age, :integer
176
+ assert_no_select 'label.integer'
177
+ with_label_for @user, :born_at, :date
178
+ assert_no_select 'label.date'
179
+ with_label_for @user, :created_at, :datetime
180
+ assert_no_select 'label.datetime'
181
+ end
182
+ end
183
+
169
184
  test 'label should obtain required from ActiveModel::Validations when it is included' do
170
185
  with_label_for @validating_user, :name, :string
171
186
  assert_select 'label.required'
@@ -173,6 +188,15 @@ class IsolatedLabelTest < ActionView::TestCase
173
188
  assert_select 'label.optional'
174
189
  end
175
190
 
191
+ test 'label should not obtain required from ActiveModel::Validations when generate_additional_classes_for does not include :label' do
192
+ swap SimpleForm, :generate_additional_classes_for => [:wrapper, :input] do
193
+ with_label_for @validating_user, :name, :string
194
+ assert_no_select 'label.required'
195
+ with_label_for @validating_user, :status, :string
196
+ assert_no_select 'label.optional'
197
+ end
198
+ end
199
+
176
200
  test 'label should allow overriding required when ActiveModel::Validations is included' do
177
201
  with_label_for @validating_user, :name, :string, :required => false
178
202
  assert_select 'label.optional'
@@ -164,4 +164,14 @@ class AssociationTest < ActionView::TestCase
164
164
  assert_select 'form ul', :count => 1
165
165
  assert_select 'form ul li', :count => 3
166
166
  end
167
+
168
+ test 'builder with collection support should not change the options hash' do
169
+ options = { :as => :check_boxes, :collection_wrapper_tag => :ul, :item_wrapper_tag => :li}
170
+ with_association_for @user, :tags, options
171
+
172
+ assert_select 'form ul', :count => 1
173
+ assert_select 'form ul li', :count => 3
174
+ assert_equal({ :as => :check_boxes, :collection_wrapper_tag => :ul, :item_wrapper_tag => :li},
175
+ options)
176
+ end
167
177
  end
@@ -13,6 +13,18 @@ class ButtonTest < ActionView::TestCase
13
13
  assert_select 'form input.button[type=submit][value=Save Post]'
14
14
  end
15
15
 
16
+ test 'builder should create buttons with options' do
17
+ with_button_for :post, :submit, :class => 'my_button'
18
+ assert_select 'form input.button.my_button[type=submit][value=Save Post]'
19
+ end
20
+
21
+ test 'builder should not modify the options hash' do
22
+ options = { :class => 'my_button' }
23
+ with_button_for :post, :submit, options
24
+ assert_select 'form input.button.my_button[type=submit][value=Save Post]'
25
+ assert_equal({ :class => 'my_button' }, options)
26
+ end
27
+
16
28
  test 'builder should create buttons for records' do
17
29
  @user.new_record!
18
30
  with_button_for @user, :submit
@@ -25,4 +37,11 @@ class ButtonTest < ActionView::TestCase
25
37
  assert_select 'form input.btn[type=submit][value=Save Post]'
26
38
  end
27
39
  end
40
+
41
+ if ActionView::Helpers::FormBuilder.method_defined?(:button)
42
+ test "allows to use Rails button helper when available" do
43
+ with_button_for :post, :button, 'Save!'
44
+ assert_select 'form button.button[type=submit]', 'Save!'
45
+ end
46
+ end
28
47
  end
@@ -60,4 +60,20 @@ class ErrorNotificationTest < ActionView::TestCase
60
60
  assert_select 'div.error_notification'
61
61
  end
62
62
  end
63
+
64
+ test 'error notification can contain HTML tags' do
65
+ with_error_notification_for @user, :message => 'Erro encontrado ao criar <b>usuário</b>'
66
+ assert_select 'p.error_notification', 'Erro encontrado ao criar usuário'
67
+ assert_select 'p.error_notification b', 'usuário'
68
+ end
69
+
70
+ test 'error notification uses I18n based on model to generate the notification message and accepts HTML' do
71
+ store_translations(:en, :simple_form => { :error_notification => { :user =>
72
+ 'Alguns erros foram encontrados para o <b>usuário</b>:'
73
+ } }) do
74
+ with_error_notification_for @user
75
+ assert_select 'p.error_notification', 'Alguns erros foram encontrados para o usuário:'
76
+ assert_select 'p.error_notification b', 'usuário'
77
+ end
78
+ end
63
79
  end
@@ -54,6 +54,13 @@ class ErrorTest < ActionView::TestCase
54
54
  assert_select 'span#error.error.yay'
55
55
  end
56
56
 
57
+ test 'error should not modify the options hash' do
58
+ options = { :id => 'error', :class => 'yay' }
59
+ with_error_for @user, :name, options
60
+ assert_select 'span#error.error.yay'
61
+ assert_equal({ :id => 'error', :class => 'yay' }, options)
62
+ end
63
+
57
64
  test 'error should find errors on attribute and association' do
58
65
  with_error_for @user, :company_id, :as => :select,
59
66
  :error_method => :to_sentence, :reflection => Association.new(Company, :company, {})
@@ -73,6 +80,12 @@ class ErrorTest < ActionView::TestCase
73
80
  assert_no_select 'p.error[error_method]'
74
81
  end
75
82
 
83
+ test 'error should generate an error message with raw HTML tags' do
84
+ with_error_for @user, :name, :error_prefix => '<b>Name</b>'
85
+ assert_select 'span.error', "Name can't be blank"
86
+ assert_select 'span.error b', "Name"
87
+ end
88
+
76
89
  # FULL ERRORS
77
90
 
78
91
  test 'full error should generate an full error tag for the attribute' do
@@ -80,7 +93,7 @@ class ErrorTest < ActionView::TestCase
80
93
  assert_select 'span.error', "Super User Name! can't be blank"
81
94
  end
82
95
 
83
- test 'full error should generate an full error tag with a clean HTML' do
96
+ test 'full error should generate an full error tag with a clean HTML' do
84
97
  with_full_error_for @user, :name
85
98
  assert_no_select 'span.error[error_html]'
86
99
  end
@@ -90,6 +103,13 @@ class ErrorTest < ActionView::TestCase
90
103
  assert_select 'span.error#name_error', "Your name can't be blank"
91
104
  end
92
105
 
106
+ test 'full error should not modify the options hash' do
107
+ options = { :id => 'name_error' }
108
+ with_full_error_for @user, :name, options
109
+ assert_select 'span.error#name_error', "Super User Name! can't be blank"
110
+ assert_equal({ :id => 'name_error' }, options)
111
+ end
112
+
93
113
  # CUSTOM WRAPPERS
94
114
 
95
115
  test 'error with custom wrappers works' do
@@ -38,6 +38,14 @@ class FormBuilderTest < ActionView::TestCase
38
38
  end
39
39
  end
40
40
 
41
+ test 'builder should allow to skip input_type class' do
42
+ swap SimpleForm, :generate_additional_classes_for => [:label, :wrapper] do
43
+ with_form_for @user, :post_count
44
+ assert_no_select "form input#user_post_count.integer"
45
+ assert_select "form input#user_post_count"
46
+ end
47
+ end
48
+
41
49
  test 'builder should allow adding custom input mappings for integer input types' do
42
50
  swap SimpleForm, :input_mappings => { /lock_version/ => :hidden } do
43
51
  with_form_for @user, :lock_version
@@ -18,9 +18,17 @@ class HintTest < ActionView::TestCase
18
18
  assert_select 'span.hint', 'Use with care...'
19
19
  end
20
20
 
21
+ test 'hint should not modify the options hash' do
22
+ options = { :hint => 'Use with care...' }
23
+ with_hint_for @user, :name, options
24
+ assert_select 'span.hint', 'Use with care...'
25
+ assert_equal({ :hint => 'Use with care...' }, options)
26
+ end
27
+
21
28
  test 'hint should be generated cleanly with optional text' do
22
- with_hint_for @user, :name, :hint => 'Use with care...'
29
+ with_hint_for @user, :name, :hint => 'Use with care...', :hint_tag => :span
23
30
  assert_no_select 'span.hint[hint]'
31
+ assert_no_select 'span.hint[hint_tag]'
24
32
  assert_no_select 'span.hint[hint_html]'
25
33
  end
26
34
 
@@ -109,7 +117,7 @@ class HintTest < ActionView::TestCase
109
117
  test 'hint with custom wrappers works' do
110
118
  swap_wrapper do
111
119
  with_hint_for @user, :name, :hint => "can't be blank"
112
- assert_select 'span.omg_hint', "can't be blank"
120
+ assert_select 'div.omg_hint', "can't be blank"
113
121
  end
114
122
  end
115
123
  end
@@ -29,6 +29,18 @@ class InputFieldTest < ActionView::TestCase
29
29
  assert_select 'input.string.name#name_input'
30
30
  end
31
31
 
32
+ test 'builder input_field should not modify the options hash' do
33
+ options = { :id => 'name_input', :class => 'name' }
34
+
35
+ with_concat_form_for(@user) do |f|
36
+ f.input_field :name, options
37
+ end
38
+
39
+ assert_select 'input.string.name#name_input'
40
+ assert_equal({ :id => 'name_input', :class => 'name' }, options)
41
+ end
42
+
43
+
32
44
  test 'builder input_field should generate an input tag with a clean HTML' do
33
45
  with_concat_form_for(@user) do |f|
34
46
  f.input_field :name, :as => :integer, :class => 'name'
@@ -48,4 +60,4 @@ class InputFieldTest < ActionView::TestCase
48
60
  assert_no_select 'select.status[label_method]'
49
61
  assert_no_select 'select.status[value_method]'
50
62
  end
51
- end
63
+ end
@@ -28,6 +28,20 @@ class LabelTest < ActionView::TestCase
28
28
  assert_select 'label.string#name_label', /My label/
29
29
  end
30
30
 
31
+ test 'builder label should generate label tag with clean HTML' do
32
+ with_label_for @user, :name, :label => 'My label', :required => true, :id => 'name_label'
33
+ assert_select 'label.string#name_label', /My label/
34
+ assert_no_select 'label[label]'
35
+ assert_no_select 'label[required]'
36
+ end
37
+
38
+ test 'builder should not modify the options hash' do
39
+ options = { :label => 'My label', :id => 'name_label' }
40
+ with_label_for @user, :name, options
41
+ assert_select 'label.string#name_label', /My label/
42
+ assert_equal({ :label => 'My label', :id => 'name_label' }, options)
43
+ end
44
+
31
45
  test 'builder should fallback to default label when string is given' do
32
46
  with_label_for @user, :name, 'Nome do usuário'
33
47
  assert_select 'label', 'Nome do usuário'
@@ -66,6 +66,15 @@ class WrapperTest < ActionView::TestCase
66
66
  assert_select 'form div.wrapper.required.string'
67
67
  end
68
68
 
69
+ test 'wrapper should skip additional classes when configured' do
70
+ swap SimpleForm, :generate_additional_classes_for => [:input, :label] do
71
+ with_form_for @user, :name, :wrapper_class => :wrapper
72
+ assert_select 'form div.wrapper'
73
+ assert_no_select 'div.required'
74
+ assert_no_select 'div.string'
75
+ end
76
+ end
77
+
69
78
  # Custom wrapper test
70
79
 
71
80
  test 'custom wrappers works' do
@@ -75,7 +84,7 @@ class WrapperTest < ActionView::TestCase
75
84
  assert_select "section.custom_wrapper div.another_wrapper input.string"
76
85
  assert_no_select "section.custom_wrapper div.another_wrapper span.omg_error"
77
86
  assert_select "section.custom_wrapper div.error_wrapper span.omg_error"
78
- assert_select "section.custom_wrapper > span.omg_hint", "cool"
87
+ assert_select "section.custom_wrapper > div.omg_hint", "cool"
79
88
  end
80
89
  end
81
90
 
@@ -88,4 +88,14 @@ class BooleanInputTest < ActionView::TestCase
88
88
  end
89
89
  end
90
90
  end
91
+
92
+ test 'input boolean with nested style works using :label_input in wrapper config, adding "checkbox" class to label' do
93
+ swap_wrapper :default, self.custom_wrapper_without_top_level do
94
+ swap SimpleForm, :boolean_style => :nested do
95
+ with_input_for @user, :active, :boolean
96
+
97
+ assert_select 'input[type=hidden] + label.boolean.checkbox > input.boolean'
98
+ end
99
+ end
100
+ end
91
101
  end
@@ -62,14 +62,28 @@ class DateTimeInputTest < ActionView::TestCase
62
62
  assert_select 'select.time option', 'minuto'
63
63
  end
64
64
 
65
- test 'label should point to first option when date input type' do
66
- with_input_for :project, :created_at, :date
67
- assert_select 'label[for=project_created_at_1i]'
65
+ test 'label should use i18n to get target for date input type' do
66
+ store_translations(:en, :date => { :order => [:month, :day, :year] }) do
67
+ with_input_for :project, :created_at, :date
68
+ assert_select 'label[for=project_created_at_2i]'
69
+ end
70
+ end
71
+
72
+ test 'label should use i18n to get target for datetime input type' do
73
+ store_translations(:en, :date => { :order => [:month, :day, :year] }) do
74
+ with_input_for :project, :created_at, :datetime
75
+ assert_select 'label[for=project_created_at_2i]'
76
+ end
77
+ end
78
+
79
+ test 'label should use order to get target when date input type' do
80
+ with_input_for :project, :created_at, :date, :order => [:month, :year, :day]
81
+ assert_select 'label[for=project_created_at_2i]'
68
82
  end
69
83
 
70
- test 'label should point to first option when datetime input type' do
71
- with_input_for :project, :created_at, :datetime
72
- assert_select 'label[for=project_created_at_1i]'
84
+ test 'label should use order to get target when datetime input type' do
85
+ with_input_for :project, :created_at, :datetime, :order => [:month, :year, :day]
86
+ assert_select 'label[for=project_created_at_2i]'
73
87
  end
74
88
 
75
89
  test 'label should point to first option when time input type' do
@@ -20,6 +20,15 @@ class GroupedCollectionSelectInputTest < ActionView::TestCase
20
20
  end
21
21
  end
22
22
 
23
+ test 'grouped collection accepts empty array collection form' do
24
+ with_input_for @user, :tag_ids, :grouped_select,
25
+ :collection => [],
26
+ :group_method => :last
27
+
28
+ assert_select 'select.grouped_select#user_tag_ids'
29
+ end
30
+
31
+
23
32
  test 'grouped collection accepts proc as collection' do
24
33
  with_input_for @user, :tag_ids, :grouped_select,
25
34
  :collection => Proc.new { [['Authors', ['Jose', 'Carlos']], ['General', ['Bob', 'John']]] },
@@ -9,7 +9,7 @@ class PriorityInputTest < ActionView::TestCase
9
9
  assert_no_select 'select option[value=][disabled=disabled]'
10
10
  end
11
11
 
12
- test 'input should generate a country select with simple form default' do
12
+ test 'input should generate a country select with SimpleForm default' do
13
13
  swap SimpleForm, :country_priority => [ 'Brazil' ] do
14
14
  with_input_for @user, :country, :country
15
15
  assert_select 'select option[value=][disabled=disabled]'
@@ -4,7 +4,7 @@ require 'test_helper'
4
4
  class StringInputTest < ActionView::TestCase
5
5
  test 'input should map text field to string attribute' do
6
6
  with_input_for @user, :name, :string
7
- assert_select "input#user_name[type=text][name='user[name]'][value=New in Simple Form!]"
7
+ assert_select "input#user_name[type=text][name='user[name]'][value=New in SimpleForm!]"
8
8
  end
9
9
 
10
10
  test 'input should generate a password field for password attributes' do