comfy_bootstrap_form 4.0.0.beta1

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 (76) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +621 -0
  4. data/Rakefile +37 -0
  5. data/app/assets/stylesheets/rails_bootstrap_forms.css +10 -0
  6. data/lib/bootstrap_form.rb +13 -0
  7. data/lib/bootstrap_form/aliasing.rb +35 -0
  8. data/lib/bootstrap_form/form_builder.rb +460 -0
  9. data/lib/bootstrap_form/helper.rb +36 -0
  10. data/lib/bootstrap_form/helpers/bootstrap.rb +94 -0
  11. data/lib/bootstrap_form/helpers/nested_form.rb +33 -0
  12. data/lib/bootstrap_form/version.rb +3 -0
  13. data/lib/comfy_bootstrap_form.rb +1 -0
  14. data/test/bootstrap_checkbox_test.rb +144 -0
  15. data/test/bootstrap_fields_test.rb +152 -0
  16. data/test/bootstrap_form_group_test.rb +313 -0
  17. data/test/bootstrap_form_test.rb +276 -0
  18. data/test/bootstrap_other_components_test.rb +86 -0
  19. data/test/bootstrap_radio_button_test.rb +124 -0
  20. data/test/bootstrap_selects_test.rb +160 -0
  21. data/test/dummy/Gemfile +45 -0
  22. data/test/dummy/Gemfile.lock +120 -0
  23. data/test/dummy/README.rdoc +28 -0
  24. data/test/dummy/Rakefile +10 -0
  25. data/test/dummy/app/assets/javascripts/application.js +16 -0
  26. data/test/dummy/app/assets/stylesheets/application.css +13 -0
  27. data/test/dummy/app/controllers/application_controller.rb +5 -0
  28. data/test/dummy/app/helpers/application_helper.rb +2 -0
  29. data/test/dummy/app/models/address.rb +3 -0
  30. data/test/dummy/app/models/faux_user.rb +9 -0
  31. data/test/dummy/app/models/super_user.rb +2 -0
  32. data/test/dummy/app/models/user.rb +9 -0
  33. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  34. data/test/dummy/bin/bundle +3 -0
  35. data/test/dummy/bin/rails +4 -0
  36. data/test/dummy/bin/rake +4 -0
  37. data/test/dummy/config.ru +4 -0
  38. data/test/dummy/config/application.rb +23 -0
  39. data/test/dummy/config/boot.rb +4 -0
  40. data/test/dummy/config/database.yml +25 -0
  41. data/test/dummy/config/environment.rb +5 -0
  42. data/test/dummy/config/environments/development.rb +29 -0
  43. data/test/dummy/config/environments/production.rb +80 -0
  44. data/test/dummy/config/environments/test.rb +53 -0
  45. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  46. data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  47. data/test/dummy/config/initializers/generic_migration.rb +6 -0
  48. data/test/dummy/config/initializers/inflections.rb +16 -0
  49. data/test/dummy/config/initializers/mime_types.rb +5 -0
  50. data/test/dummy/config/initializers/secret_token.rb +12 -0
  51. data/test/dummy/config/initializers/session_store.rb +3 -0
  52. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  53. data/test/dummy/config/locales/en.yml +23 -0
  54. data/test/dummy/config/routes.rb +3 -0
  55. data/test/dummy/db/migrate/20130703191909_create_users.rb +13 -0
  56. data/test/dummy/db/migrate/20130703191937_create_addresses.rb +13 -0
  57. data/test/dummy/db/migrate/20130912171202_add_preferences_to_user.rb +5 -0
  58. data/test/dummy/db/migrate/20140327190145_add_terms_to_user.rb +5 -0
  59. data/test/dummy/db/migrate/20140922133133_add_type_to_users.rb +5 -0
  60. data/test/dummy/db/schema.rb +38 -0
  61. data/test/dummy/db/seeds.rb +7 -0
  62. data/test/dummy/db/test.sqlite3 +0 -0
  63. data/test/dummy/log/test.log +18394 -0
  64. data/test/dummy/public/404.html +58 -0
  65. data/test/dummy/public/422.html +58 -0
  66. data/test/dummy/public/500.html +57 -0
  67. data/test/dummy/public/favicon.ico +0 -0
  68. data/test/dummy/public/robots.txt +5 -0
  69. data/test/dummy/test/fixtures/addresses.yml +15 -0
  70. data/test/dummy/test/fixtures/users.yml +15 -0
  71. data/test/dummy/test/models/address_test.rb +7 -0
  72. data/test/dummy/test/models/user_test.rb +7 -0
  73. data/test/dummy/test/test_helper.rb +15 -0
  74. data/test/special_form_class_models_test.rb +43 -0
  75. data/test/test_helper.rb +86 -0
  76. metadata +309 -0
@@ -0,0 +1,313 @@
1
+ require 'test_helper'
2
+
3
+ class BootstrapFormGroupTest < ActionView::TestCase
4
+ include BootstrapForm::Helper
5
+
6
+ def setup
7
+ setup_test_fixture
8
+ end
9
+
10
+ test "changing the label text via the label option parameter" do
11
+ expected = %{<div class="form-group"><label class="form-control-label required" for="user_email">Email Address</label><input class="form-control" id="user_email" name="user[email]" type="text" value="steve@example.com" /></div>}
12
+ assert_equivalent_xml expected, @builder.text_field(:email, label: 'Email Address')
13
+ end
14
+
15
+ test "changing the label text via the html_options label hash" do
16
+ expected = %{<div class="form-group"><label class="form-control-label required" for="user_email">Email Address</label><input class="form-control" id="user_email" name="user[email]" type="text" value="steve@example.com" /></div>}
17
+ assert_equivalent_xml expected, @builder.text_field(:email, label: {text: 'Email Address'})
18
+ end
19
+
20
+ test "hiding a label" do
21
+ expected = %{<div class="form-group"><label class="sr-only form-control-label required" for="user_email">Email</label><input class="form-control" id="user_email" name="user[email]" type="text" value="steve@example.com" /></div>}
22
+ assert_equivalent_xml expected, @builder.text_field(:email, hide_label: true)
23
+ end
24
+
25
+ test "adding a custom label class via the label_class parameter" do
26
+ expected = %{<div class="form-group"><label class="btn form-control-label required" for="user_email">Email</label><input class="form-control" id="user_email" name="user[email]" type="text" value="steve@example.com" /></div>}
27
+ assert_equivalent_xml expected, @builder.text_field(:email, label_class: 'btn')
28
+ end
29
+
30
+ test "adding a custom label class via the html_options label hash" do
31
+ expected = %{<div class="form-group"><label class="btn form-control-label required" for="user_email">Email</label><input class="form-control" id="user_email" name="user[email]" type="text" value="steve@example.com" /></div>}
32
+ assert_equivalent_xml expected, @builder.text_field(:email, label: {class: 'btn'})
33
+ end
34
+
35
+ test "adding a custom label and changing the label text via the html_options label hash" do
36
+ expected = %{<div class="form-group"><label class="btn form-control-label required" for="user_email">Email Address</label><input class="form-control" id="user_email" name="user[email]" type="text" value="steve@example.com" /></div>}
37
+ assert_equivalent_xml expected, @builder.text_field(:email, label: {class: 'btn', text: "Email Address"})
38
+ end
39
+
40
+ test "skipping a label" do
41
+ expected = %{<div class="form-group"><input class="form-control" id="user_email" name="user[email]" type="text" value="steve@example.com" /></div>}
42
+ assert_equivalent_xml expected, @builder.text_field(:email, skip_label: true)
43
+ end
44
+
45
+ test "preventing a label from having the required class" do
46
+ expected = %{<div class="form-group"><label class="form-control-label" for="user_email">Email</label><input class="form-control" id="user_email" name="user[email]" type="text" value="steve@example.com" /></div>}
47
+ assert_equivalent_xml expected, @builder.text_field(:email, skip_required: true)
48
+ end
49
+
50
+ test "adding prepend text" do
51
+ expected = %{<div class="form-group"><label class="form-control-label required" for="user_email">Email</label><div class="input-group"><span class="input-group-addon">@</span><input class="form-control" id="user_email" name="user[email]" type="text" value="steve@example.com" /></div></div>}
52
+ assert_equivalent_xml expected, @builder.text_field(:email, prepend: '@')
53
+ end
54
+
55
+ test "adding append text" do
56
+ expected = %{<div class="form-group"><label class="form-control-label required" for="user_email">Email</label><div class="input-group"><input class="form-control" id="user_email" name="user[email]" type="text" value="steve@example.com" /><span class="input-group-addon">.00</span></div></div>}
57
+ assert_equivalent_xml expected, @builder.text_field(:email, append: '.00')
58
+ end
59
+
60
+ test "append and prepend button" do
61
+ prefix = %{<div class="form-group"><label class="form-control-label required" for="user_email">Email</label><div class="input-group">}
62
+ field = %{<input class="form-control" id="user_email" name="user[email]" type="text" value="steve@example.com" />}
63
+ button = %{<span class="input-group-btn"><a class="btn btn-secondary" href="#">Click</a></span>}
64
+ suffix = %{</div></div>}
65
+ after_button = prefix + field + button + suffix
66
+ before_button = prefix + button + field + suffix
67
+ both_button = prefix + button + field + button + suffix
68
+ button_src = link_to("Click", "#", class: "btn btn-secondary")
69
+ assert_equivalent_xml after_button, @builder.text_field(:email, append: button_src)
70
+ assert_equivalent_xml before_button, @builder.text_field(:email, prepend: button_src)
71
+ assert_equivalent_xml both_button, @builder.text_field(:email, append: button_src, prepend: button_src)
72
+ end
73
+
74
+ test "adding both prepend and append text" do
75
+ expected = %{<div class="form-group"><label class="form-control-label required" for="user_email">Email</label><div class="input-group"><span class="input-group-addon">$</span><input class="form-control" id="user_email" name="user[email]" type="text" value="steve@example.com" /><span class="input-group-addon">.00</span></div></div>}
76
+ assert_equivalent_xml expected, @builder.text_field(:email, prepend: '$', append: '.00')
77
+ end
78
+
79
+ test "help messages for default forms" do
80
+ expected = %{<div class="form-group"><label class="form-control-label required" for="user_email">Email</label><input class="form-control" id="user_email" name="user[email]" type="text" value="steve@example.com" /><span class="form-text text-muted">This is required</span></div>}
81
+ assert_equivalent_xml expected, @builder.text_field(:email, help: 'This is required')
82
+ end
83
+
84
+ test "help messages for horizontal forms" do
85
+ expected = %{<div class="form-group row"><label class="form-control-label col-sm-2 required" for="user_email">Email</label><div class="col-sm-10"><input class="form-control" id="user_email" name="user[email]" type="text" value="steve@example.com" /><span class="form-text text-muted">This is required</span></div></div>}
86
+ assert_equivalent_xml expected, @horizontal_builder.text_field(:email, help: "This is required")
87
+ end
88
+
89
+ test "help messages to look up I18n automatically" do
90
+ expected = %{<div class="form-group"><label class="form-control-label" for="user_password">Password</label><input class="form-control" id="user_password" name="user[password]" type="text" value="secret" /><span class="form-text text-muted">A good password should be at least six characters long</span></div>}
91
+ assert_equivalent_xml expected, @builder.text_field(:password)
92
+ end
93
+
94
+ test "help messages to warn about deprecated I18n key" do
95
+ super_user = SuperUser.new(@user.attributes)
96
+ builder = BootstrapForm::FormBuilder.new(:super_user, super_user, self, {})
97
+
98
+ I18n.backend.store_translations(:en, activerecord: {
99
+ help: {
100
+ superuser: {
101
+ password: 'A good password should be at least six characters long'
102
+ }
103
+ }
104
+ })
105
+
106
+ builder.stubs(:warn).returns(true)
107
+ builder.expects(:warn).at_least_once
108
+
109
+ builder.password_field(:password)
110
+ end
111
+
112
+ test "help messages to ignore translation when user disables help" do
113
+ expected = %{<div class="form-group"><label class="form-control-label" for="user_password">Password</label><input class="form-control" id="user_password" name="user[password]" type="text" value="secret" /></div>}
114
+ assert_equivalent_xml expected, @builder.text_field(:password, help: false)
115
+ end
116
+
117
+ test "form_group creates a valid structure and allows arbitrary html to be added via a block" do
118
+ output = @horizontal_builder.form_group :nil, label: { text: 'Foo' } do
119
+ %{<p class="form-control-static">Bar</p>}.html_safe
120
+ end
121
+
122
+ expected = %{<div class="form-group row"><label class="form-control-label col-sm-2" for="user_nil">Foo</label><div class="col-sm-10"><p class="form-control-static">Bar</p></div></div>}
123
+ assert_equivalent_xml expected, output
124
+ end
125
+
126
+ test "form_group adds a spacer when no label exists for a horizontal form" do
127
+ output = @horizontal_builder.form_group do
128
+ %{<p class="form-control-static">Bar</p>}.html_safe
129
+ end
130
+
131
+ expected = %{<div class="form-group row"><div class="col-sm-10 col-sm-offset-2"><p class="form-control-static">Bar</p></div></div>}
132
+ assert_equivalent_xml expected, output
133
+ end
134
+
135
+ test "form_group renders the label correctly" do
136
+ output = @horizontal_builder.form_group :email, label: { text: 'Custom Control' } do
137
+ %{<p class="form-control-static">Bar</p>}.html_safe
138
+ end
139
+
140
+ expected = %{<div class="form-group row"><label class="form-control-label col-sm-2 required" for="user_email">Custom Control</label><div class="col-sm-10"><p class="form-control-static">Bar</p></div></div>}
141
+ assert_equivalent_xml expected, output
142
+ end
143
+
144
+ test "form_group accepts class thorugh options hash" do
145
+ output = @horizontal_builder.form_group :email, class: "foo" do
146
+ %{<p class="form-control-static">Bar</p>}.html_safe
147
+ end
148
+
149
+ expected = %{<div class="form-group foo row"><div class="col-sm-10 col-sm-offset-2"><p class="form-control-static">Bar</p></div></div>}
150
+ assert_equivalent_xml expected, output
151
+ end
152
+
153
+ test "form_group accepts class thorugh options hash without needing a name" do
154
+ output = @horizontal_builder.form_group class: "foo" do
155
+ %{<p class="form-control-static">Bar</p>}.html_safe
156
+ end
157
+
158
+ expected = %{<div class="form-group foo row"><div class="col-sm-10 col-sm-offset-2"><p class="form-control-static">Bar</p></div></div>}
159
+ assert_equivalent_xml expected, output
160
+ end
161
+
162
+ test "form_group overrides the label's 'class' and 'for' attributes if others are passed" do
163
+ output = @horizontal_builder.form_group nil, label: { text: 'Custom Control', class: 'foo', for: 'bar' } do
164
+ %{<p class="form-control-static">Bar</p>}.html_safe
165
+ end
166
+
167
+ expected = %{<div class="form-group row"><label class="foo form-control-label col-sm-2" for="bar">Custom Control</label><div class="col-sm-10"><p class="form-control-static">Bar</p></div></div>}
168
+ assert_equivalent_xml expected, output
169
+ end
170
+
171
+ test 'form_group renders the "error" class and message corrrectly when object is invalid' do
172
+ @user.email = nil
173
+ @user.valid?
174
+
175
+ output = @builder.form_group :email do
176
+ %{<p class="form-control-static">Bar</p>}.html_safe
177
+ end
178
+
179
+ expected = <<-HTML.strip_heredoc
180
+ <div class="form-group has-danger">
181
+ <p class="form-control-static">Bar</p>
182
+ <span class="invalid-feedback">can&#39;t be blank, is too short (minimum is 5 characters)</span>
183
+ </div>
184
+ HTML
185
+ assert_equivalent_xml expected, output
186
+ end
187
+
188
+ test "adds class to wrapped form_group by a field" do
189
+ expected = %{<div class="form-group none-margin"><label class="form-control-label" for="user_misc">Misc</label><input class="form-control" id="user_misc" name="user[misc]" type="search" /></div>}
190
+ assert_equivalent_xml expected, @builder.search_field(:misc, wrapper_class: 'none-margin')
191
+ end
192
+
193
+ test "adds class to wrapped form_group by a field with errors" do
194
+ @user.email = nil
195
+ @user.valid?
196
+
197
+ expected = <<-HTML.strip_heredoc
198
+ <div class="form-group none-margin has-danger">
199
+ <div class="field_with_errors">
200
+ <label class="form-control-label required" for="user_email">Email</label>
201
+ </div>
202
+ <div class="field_with_errors">
203
+ <input class="form-control is-invalid" id="user_email" name="user[email]" type="email" />
204
+ </div>
205
+ <span class="invalid-feedback">can&#39;t be blank, is too short (minimum is 5 characters)</span>
206
+ </div>
207
+ HTML
208
+ assert_equivalent_xml expected, @builder.email_field(:email, wrapper_class: 'none-margin')
209
+ end
210
+
211
+ test "adds class to wrapped form_group by a field with errors when bootstrap_form_for is used" do
212
+ @user.email = nil
213
+ @user.valid?
214
+
215
+ output = bootstrap_form_for(@user) do |f|
216
+ f.text_field(:email, help: 'This is required', wrapper_class: 'none-margin')
217
+ end
218
+
219
+ expected = <<-HTML.strip_heredoc
220
+ <form accept-charset="UTF-8" action="/users" class="new_user" id="new_user" method="post" role="form">
221
+ <input name="utf8" type="hidden" value="&#x2713;" />
222
+ <div class="form-group none-margin has-danger">
223
+ <label class="form-control-label required" for="user_email">Email</label>
224
+ <input class="form-control is-invalid" id="user_email" name="user[email]" type="text" />
225
+ <span class="invalid-feedback">can&#39;t be blank, is too short (minimum is 5 characters)</span>
226
+ </div>
227
+ </form>
228
+ HTML
229
+ assert_equivalent_xml expected, output
230
+ end
231
+
232
+ test "adds offset for form_group without label" do
233
+ output = @horizontal_builder.form_group do
234
+ @horizontal_builder.submit
235
+ end
236
+
237
+ expected = %{<div class="form-group row"><div class="col-sm-10 col-sm-offset-2"><input class="btn btn-secondary" name="commit" type="submit" value="Create User" /></div></div>}
238
+ assert_equivalent_xml expected, output
239
+ end
240
+
241
+ test "adds offset for form_group without label but specific label_col" do
242
+ output = @horizontal_builder.form_group label_col: 'col-sm-5', control_col: 'col-sm-8' do
243
+ @horizontal_builder.submit
244
+ end
245
+
246
+ expected = %{<div class="form-group row"><div class="col-sm-8 col-sm-offset-5"><input class="btn btn-secondary" name="commit" type="submit" value="Create User" /></div></div>}
247
+ assert_equivalent_xml expected, output
248
+ end
249
+
250
+ test "adding an icon to a field" do
251
+ expected = %{<div class="form-group has-feedback"><label class="form-control-label" for="user_misc">Misc</label><input class="form-control" id="user_misc" name="user[misc]" type="email" /><span class="glyphicon glyphicon-ok form-control-feedback"></span></div>}
252
+ assert_equivalent_xml expected, @builder.email_field(:misc, icon: 'ok')
253
+ end
254
+
255
+ test "single form_group call in horizontal form should not be smash design" do
256
+ output = ''
257
+ output = @horizontal_builder.form_group do
258
+ "Hallo"
259
+ end
260
+
261
+ output = output + @horizontal_builder.text_field(:email)
262
+
263
+ expected = %{<div class="form-group row"><div class="col-sm-10 col-sm-offset-2">Hallo</div></div><div class="form-group row"><label class="form-control-label col-sm-2 required" for="user_email">Email</label><div class="col-sm-10"><input class="form-control" id="user_email" name="user[email]" type="text" value="steve@example.com" /></div></div>}
264
+ assert_equivalent_xml expected, output
265
+ end
266
+
267
+ test "adds data-attributes (or any other options) to wrapper" do
268
+ expected = %{<div class="form-group" data-foo="bar"><label class="form-control-label" for="user_misc">Misc</label><input class="form-control" id="user_misc" name="user[misc]" type="search" /></div>}
269
+ assert_equivalent_xml expected, @builder.search_field(:misc, wrapper: { data: { foo: 'bar' } })
270
+ end
271
+
272
+ test "passing options to a form control get passed through" do
273
+ expected = %{<div class="form-group"><label class="form-control-label required" for="user_email">Email</label><input autofocus="autofocus" class="form-control" id="user_email" name="user[email]" type="text" value="steve@example.com" /></div>}
274
+ assert_equivalent_xml expected, @builder.text_field(:email, autofocus: true)
275
+ end
276
+
277
+ test "doesn't throw undefined method error when the content block returns nil" do
278
+ output = @builder.form_group :nil, label: { text: 'Foo' } do
279
+ nil
280
+ end
281
+
282
+ expected = %{<div class="form-group"><label class="form-control-label" for="user_nil">Foo</label></div>}
283
+ assert_equivalent_xml expected, output
284
+ end
285
+
286
+ test "custom form group layout option" do
287
+ expected = %{<form accept-charset="UTF-8" action="/users" class="new_user" id="new_user" method="post" role="form"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="&#x2713;" /></div><div class="form-group"><label class="form-control-label required" for="user_email">Email</label><input class="form-control" id="user_email" name="user[email]" type="email" value="steve@example.com" /></div></form>}
288
+ assert_equivalent_xml expected, bootstrap_form_for(@user, layout: :horizontal) { |f| f.email_field :email, layout: :inline }
289
+ end
290
+
291
+ test "non-default column span on form is reflected in form_group" do
292
+ non_default_horizontal_builder = BootstrapForm::FormBuilder.new(:user, @user, self, { layout: :horizontal, label_col: "col-sm-3", control_col: "col-sm-9" })
293
+ output = non_default_horizontal_builder.form_group do
294
+ %{<p class="form-control-static">Bar</p>}.html_safe
295
+ end
296
+
297
+ expected = %{<div class="form-group row"><div class="col-sm-9 col-sm-offset-3"><p class="form-control-static">Bar</p></div></div>}
298
+ assert_equivalent_xml expected, output
299
+ end
300
+
301
+ test "non-default column span on form isn't mutated" do
302
+ frozen_horizontal_builder = BootstrapForm::FormBuilder.new(:user, @user, self, { layout: :horizontal, label_col: "col-sm-3".freeze, control_col: "col-sm-9".freeze })
303
+ output = frozen_horizontal_builder.form_group { 'test' }
304
+
305
+ expected = %{<div class="form-group row"><div class="col-sm-9 col-sm-offset-3">test</div></div>}
306
+ assert_equivalent_xml expected, output
307
+ end
308
+
309
+ test ":input_group_class should apply to input-group" do
310
+ expected = %{<div class="form-group"><label class="form-control-label required" for="user_email">Email</label><div class="input-group input-group-lg"><input class="form-control" id="user_email" name="user[email]" type="email" value="steve@example.com" /><span class="input-group-btn"><input class="btn btn-primary" name="commit" type="submit" value="Subscribe" /></span></div></div>}
311
+ assert_equivalent_xml expected, @builder.email_field(:email, append: @builder.primary('Subscribe'), input_group_class: 'input-group-lg')
312
+ end
313
+ end
@@ -0,0 +1,276 @@
1
+ require 'test_helper'
2
+
3
+ class BootstrapFormTest < ActionView::TestCase
4
+ include BootstrapForm::Helper
5
+
6
+ def setup
7
+ setup_test_fixture
8
+ end
9
+
10
+ test "default-style forms" do
11
+ expected = %{<form accept-charset="UTF-8" action="/users" class="new_user" id="new_user" method="post" role="form"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="&#x2713;" /></div></form>}
12
+ assert_equivalent_xml expected, bootstrap_form_for(@user) { |f| nil }
13
+ end
14
+
15
+ test "inline-style forms" do
16
+ expected = %{<form accept-charset="UTF-8" action="/users" class="form-inline" id="new_user" method="post" role="form"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="&#x2713;" /></div></form>}
17
+ assert_equivalent_xml expected, bootstrap_form_for(@user, layout: :inline) { |f| nil }
18
+ end
19
+
20
+ test "horizontal-style forms" do
21
+ expected = %{<form accept-charset="UTF-8" action="/users" class="new_user" id="new_user" method="post" role="form"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="&#x2713;" /></div><div class="form-group row"><label class="form-control-label col-sm-2 required" for="user_email">Email</label><div class="col-sm-10"><input class="form-control" id="user_email" name="user[email]" type="email" value="steve@example.com" /></div></div></form>}
22
+ assert_equivalent_xml expected, bootstrap_form_for(@user, layout: :horizontal) { |f| f.email_field :email }
23
+ end
24
+
25
+ test "existing styles aren't clobbered when specifying a form style" do
26
+ expected = %{<form accept-charset="UTF-8" action="/users" class="my-style" id="new_user" method="post" role="form"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="&#x2713;" /></div><div class="form-group row"><label class="form-control-label col-sm-2 required" for="user_email">Email</label><div class="col-sm-10"><input class="form-control" id="user_email" name="user[email]" type="email" value="steve@example.com" /></div></div></form>}
27
+ assert_equivalent_xml expected, bootstrap_form_for(@user, layout: :horizontal, html: { class: "my-style" }) { |f| f.email_field :email }
28
+ end
29
+
30
+ test "given role attribute should not be covered by default role attribute" do
31
+ expected = %{<form accept-charset="UTF-8" action="/users" class="new_user" id="new_user" method="post" role="not-a-form"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="&#x2713;" /></div></form>}
32
+ assert_equivalent_xml expected, bootstrap_form_for(@user, html: { role: 'not-a-form'}) {|f| nil}
33
+ end
34
+
35
+ test "bootstrap_form_tag acts like a form tag" do
36
+ expected = %{<form accept-charset="UTF-8" action="/users" method="post" role="form"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="&#x2713;" /></div><div class="form-group"><label class="form-control-label" for="email">Your Email</label><input class="form-control" id="email" name="email" type="text" /></div></form>}
37
+ assert_equivalent_xml expected, bootstrap_form_tag(url: '/users') { |f| f.text_field :email, label: "Your Email" }
38
+ end
39
+
40
+ test "bootstrap_form_tag does not clobber custom options" do
41
+ expected = %{<form accept-charset="UTF-8" action="/users" method="post" role="form"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="&#x2713;" /></div><div class="form-group"><label class="form-control-label" for="ID">Email</label><input class="form-control" id="ID" name="NAME" type="text" /></div></form>}
42
+ assert_equivalent_xml expected, bootstrap_form_tag(url: '/users') { |f| f.text_field :email, name: 'NAME', id: "ID" }
43
+ end
44
+
45
+ test "bootstrap_form_tag allows an empty name for checkboxes" do
46
+ checkbox = if ::Rails::VERSION::STRING >= '5.1'
47
+ %{<div class="form-check"><label class="form-check-label" for="misc"><input name="misc" type="hidden" value="0" /><input class="form-check-input" id="misc" name="misc" type="checkbox" value="1" /> Misc</label></div>}
48
+ else
49
+ %{<div class="form-check"><label class="form-check-label" for="_misc"><input name="[misc]" type="hidden" value="0" /><input class="form-check-input" id="_misc" name="[misc]" type="checkbox" value="1" /> Misc</label></div>}
50
+ end
51
+ hidden = if ::Rails::VERSION::STRING >= '4.2'
52
+ %{<input name="utf8" type="hidden" value="&#x2713;" />}
53
+ else
54
+ %{<div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="&#x2713;" /></div>}
55
+ end
56
+ expected = %{<form accept-charset="UTF-8" action="/users" method="post" role="form">#{hidden}#{checkbox}</form>}
57
+ assert_equivalent_xml expected, bootstrap_form_tag(url: '/users') { |f| f.check_box :misc }
58
+ end
59
+
60
+ test "errors display correctly and inline_errors are turned off by default when label_errors is true" do
61
+ @user.email = nil
62
+ @user.valid?
63
+
64
+ expected = <<-HTML.strip_heredoc
65
+ <form accept-charset="UTF-8" action="/users" class="new_user" id="new_user" method="post" role="form">
66
+ <input name="utf8" type="hidden" value="&#x2713;" />
67
+ <div class="form-group has-danger">
68
+ <label class="form-control-label required" for="user_email">Email can&#39;t be blank, is too short (minimum is 5 characters)</label>
69
+ <input class="form-control is-invalid" id="user_email" name="user[email]" type="text" />
70
+ </div>
71
+ </form>
72
+ HTML
73
+ assert_equivalent_xml expected, bootstrap_form_for(@user, label_errors: true) { |f| f.text_field :email }
74
+ end
75
+
76
+ test "errors display correctly and inline_errors can also be on when label_errors is true" do
77
+ @user.email = nil
78
+ @user.valid?
79
+
80
+ expected = <<-HTML.strip_heredoc
81
+ <form accept-charset="UTF-8" action="/users" class="new_user" id="new_user" method="post" role="form">
82
+ <input name="utf8" type="hidden" value="&#x2713;" />
83
+ <div class="form-group has-danger">
84
+ <label class="form-control-label required" for="user_email">Email can&#39;t be blank, is too short (minimum is 5 characters)</label>
85
+ <input class="form-control is-invalid" id="user_email" name="user[email]" type="text" />
86
+ <span class="invalid-feedback">can't be blank, is too short (minimum is 5 characters)</span>
87
+ </div>
88
+ </form>
89
+ HTML
90
+ assert_equivalent_xml expected, bootstrap_form_for(@user, label_errors: true, inline_errors: true) { |f| f.text_field :email }
91
+ end
92
+
93
+ test "label error messages use humanized attribute names" do
94
+ I18n.backend.store_translations(:en, {activerecord: {attributes: {user: {email: 'Your e-mail address'}}}})
95
+
96
+ @user.email = nil
97
+ @user.valid?
98
+
99
+ expected = <<-HTML.strip_heredoc
100
+ <form accept-charset="UTF-8" action="/users" class="new_user" id="new_user" method="post" role="form">
101
+ <input name="utf8" type="hidden" value="&#x2713;" />
102
+ <div class="form-group has-danger">
103
+ <label class="form-control-label required" for="user_email">Your e-mail address can&#39;t be blank, is too short (minimum is 5 characters)</label>
104
+ <input class="form-control is-invalid" id="user_email" name="user[email]" type="text" />
105
+ <span class="invalid-feedback">can&#39;t be blank, is too short (minimum is 5 characters)</span>
106
+ </div>
107
+ </form>
108
+ HTML
109
+ assert_equivalent_xml expected, bootstrap_form_for(@user, label_errors: true, inline_errors: true) { |f| f.text_field :email }
110
+
111
+ I18n.backend.store_translations(:en, {activerecord: {attributes: {user: {email: nil}}}})
112
+ end
113
+
114
+ test "alert message is wrapped correctly" do
115
+ @user.email = nil
116
+ @user.valid?
117
+ expected = %{<div class="alert alert-danger"><p>Please fix the following errors:</p><ul class="rails-bootstrap-forms-error-summary"><li>Email can&#39;t be blank</li><li>Email is too short (minimum is 5 characters)</li><li>Terms must be accepted</li></ul></div>}
118
+ assert_equivalent_xml expected, @builder.alert_message('Please fix the following errors:')
119
+ end
120
+
121
+ test "changing the class name for the alert message" do
122
+ @user.email = nil
123
+ @user.valid?
124
+ expected = %{<div class="my-css-class"><p>Please fix the following errors:</p><ul class="rails-bootstrap-forms-error-summary"><li>Email can&#39;t be blank</li><li>Email is too short (minimum is 5 characters)</li><li>Terms must be accepted</li></ul></div>}
125
+ assert_equivalent_xml expected, @builder.alert_message('Please fix the following errors:', class: 'my-css-class')
126
+ end
127
+
128
+ test "alert_message contains the error summary when inline_errors are turned off" do
129
+ @user.email = nil
130
+ @user.valid?
131
+
132
+ output = bootstrap_form_for(@user, inline_errors: false) do |f|
133
+ f.alert_message('Please fix the following errors:')
134
+ end
135
+
136
+ expected = %{<form accept-charset="UTF-8" action="/users" class="new_user" id="new_user" method="post" role="form"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="&#x2713;" /></div><div class="alert alert-danger"><p>Please fix the following errors:</p><ul class="rails-bootstrap-forms-error-summary"><li>Email can&#39;t be blank</li><li>Email is too short (minimum is 5 characters)</li><li>Terms must be accepted</li></ul></div></form>}
137
+ assert_equivalent_xml expected, output
138
+ end
139
+
140
+ test "alert_message allows the error_summary to be turned off" do
141
+ @user.email = nil
142
+ @user.valid?
143
+
144
+ output = bootstrap_form_for(@user, inline_errors: false) do |f|
145
+ f.alert_message('Please fix the following errors:', error_summary: false)
146
+ end
147
+
148
+ expected = %{<form accept-charset="UTF-8" action="/users" class="new_user" id="new_user" method="post" role="form"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="&#x2713;" /></div><div class="alert alert-danger"><p>Please fix the following errors:</p></div></form>}
149
+ assert_equivalent_xml expected, output
150
+ end
151
+
152
+ test "alert_message allows the error_summary to be turned on with inline_errors also turned on" do
153
+ @user.email = nil
154
+ @user.valid?
155
+
156
+ output = bootstrap_form_for(@user, inline_errors: true) do |f|
157
+ f.alert_message('Please fix the following errors:', error_summary: true)
158
+ end
159
+
160
+ expected = %{<form accept-charset="UTF-8" action="/users" class="new_user" id="new_user" method="post" role="form"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="&#x2713;" /></div><div class="alert alert-danger"><p>Please fix the following errors:</p><ul class="rails-bootstrap-forms-error-summary"><li>Email can&#39;t be blank</li><li>Email is too short (minimum is 5 characters)</li><li>Terms must be accepted</li></ul></div></form>}
161
+ assert_equivalent_xml expected, output
162
+ end
163
+
164
+ test "error_summary returns an unordered list of errors" do
165
+ @user.email = nil
166
+ @user.valid?
167
+
168
+ expected = %{<ul class="rails-bootstrap-forms-error-summary"><li>Email can&#39;t be blank</li><li>Email is too short (minimum is 5 characters)</li><li>Terms must be accepted</li></ul>}
169
+ assert_equivalent_xml expected, @builder.error_summary
170
+ end
171
+
172
+ test 'errors_on renders the errors for a specific attribute when invalid' do
173
+ @user.email = nil
174
+ @user.valid?
175
+
176
+ expected = %{<div class="alert alert-danger">Email can&#39;t be blank, Email is too short (minimum is 5 characters)</div>}
177
+ assert_equivalent_xml expected, @builder.errors_on(:email)
178
+ end
179
+
180
+ test "custom label width for horizontal forms" do
181
+ expected = %{<form accept-charset="UTF-8" action="/users" class="new_user" id="new_user" method="post" role="form"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="&#x2713;" /></div><div class="form-group row"><label class="form-control-label col-sm-1 required" for="user_email">Email</label><div class="col-sm-10"><input class="form-control" id="user_email" name="user[email]" type="email" value="steve@example.com" /></div></div></form>}
182
+ assert_equivalent_xml expected, bootstrap_form_for(@user, layout: :horizontal) { |f| f.email_field :email, label_col: 'col-sm-1' }
183
+ end
184
+
185
+ test "offset for form group without label respects label width for horizontal forms" do
186
+ expected = %{<form accept-charset="UTF-8" action="/users" class="new_user" id="new_user" method="post" role="form"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="&#x2713;" /></div><div class="form-group row"><div class="col-md-10 col-md-offset-2"><input class="btn btn-secondary" name="commit" type="submit" value="Create User" /></div></div></form>}
187
+ assert_equivalent_xml expected, bootstrap_form_for(@user, layout: :horizontal, label_col: 'col-md-2', control_col: 'col-md-10') { |f| f.form_group { f.submit } }
188
+ end
189
+
190
+ test "custom input width for horizontal forms" do
191
+ expected = %{<form accept-charset="UTF-8" action="/users" class="new_user" id="new_user" method="post" role="form"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="&#x2713;" /></div><div class="form-group row"><label class="form-control-label col-sm-2 required" for="user_email">Email</label><div class="col-sm-5"><input class="form-control" id="user_email" name="user[email]" type="email" value="steve@example.com" /></div></div></form>}
192
+ assert_equivalent_xml expected, bootstrap_form_for(@user, layout: :horizontal) { |f| f.email_field :email, control_col: 'col-sm-5' }
193
+ end
194
+
195
+ test "the field contains the error and is not wrapped in div.field_with_errors when bootstrap_form_for is used" do
196
+ @user.email = nil
197
+ @user.valid?
198
+
199
+ output = bootstrap_form_for(@user) do |f|
200
+ f.text_field(:email, help: 'This is required')
201
+ end
202
+
203
+ expected = <<-HTML.strip_heredoc
204
+ <form accept-charset="UTF-8" action="/users" class="new_user" id="new_user" method="post" role="form">
205
+ <input name="utf8" type="hidden" value="&#x2713;" />
206
+ <div class="form-group has-danger">
207
+ <label class="form-control-label required" for="user_email">Email</label>
208
+ <input class="form-control is-invalid" id="user_email" name="user[email]" type="text" />
209
+ <span class="invalid-feedback">can't be blank, is too short (minimum is 5 characters)</span>
210
+ </div>
211
+ </form>
212
+ HTML
213
+ assert_equivalent_xml expected, output
214
+ end
215
+
216
+ test "the field is wrapped with div.field_with_errors when form_for is used" do
217
+ @user.email = nil
218
+ @user.valid?
219
+
220
+ output = form_for(@user, builder: BootstrapForm::FormBuilder) do |f|
221
+ f.text_field(:email, help: 'This is required')
222
+ end
223
+
224
+ expected = <<-HTML.strip_heredoc
225
+ <form accept-charset="UTF-8" action="/users" class="new_user" id="new_user" method="post">
226
+ <input name="utf8" type="hidden" value="&#x2713;" />
227
+ <div class="form-group has-danger">
228
+ <div class="field_with_errors">
229
+ <label class="form-control-label required" for="user_email">Email</label>
230
+ </div>
231
+ <div class="field_with_errors">
232
+ <input class="form-control is-invalid" id="user_email" name="user[email]" type="text" />
233
+ </div>
234
+ <span class="invalid-feedback">can&#39;t be blank, is too short (minimum is 5 characters)</span>
235
+ </div>
236
+ </form>
237
+ HTML
238
+ assert_equivalent_xml expected, output
239
+ end
240
+
241
+ test "help is preserved when inline_errors: false is passed to bootstrap_form_for" do
242
+ @user.email = nil
243
+ @user.valid?
244
+
245
+ output = bootstrap_form_for(@user, inline_errors: false) do |f|
246
+ f.text_field(:email, help: 'This is required')
247
+ end
248
+
249
+ expected = <<-HTML.strip_heredoc
250
+ <form accept-charset="UTF-8" action="/users" class="new_user" id="new_user" method="post" role="form">
251
+ <input name="utf8" type="hidden" value="&#x2713;" />
252
+ <div class="form-group has-danger">
253
+ <label class="form-control-label required" for="user_email">Email</label>
254
+ <input class="form-control is-invalid" id="user_email" name="user[email]" type="text" />
255
+ <span class="form-text text-muted">This is required</span>
256
+ </div>
257
+ </form>
258
+ HTML
259
+ assert_equivalent_xml expected, output
260
+ end
261
+
262
+ test "allows the form object to be nil" do
263
+ builder = BootstrapForm::FormBuilder.new :other_model, nil, self, {}
264
+ expected = %{<div class="form-group"><label class="form-control-label" for="other_model_email">Email</label><input class="form-control" id="other_model_email" name="other_model[email]" type="text" /></div>}
265
+ assert_equivalent_xml expected, builder.text_field(:email)
266
+ end
267
+
268
+ test 'errors_on hide attribute name in message' do
269
+ @user.email = nil
270
+ @user.valid?
271
+
272
+ expected = %{<div class="alert alert-danger">can&#39;t be blank, is too short (minimum is 5 characters)</div>}
273
+
274
+ assert_equivalent_xml expected, @builder.errors_on(:email, hide_attribute_name: true)
275
+ end
276
+ end