simple_form 2.0.0.rc → 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.

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