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,36 @@
1
+ require_relative 'helpers/nested_form'
2
+
3
+ module BootstrapForm
4
+ module Helper
5
+ include ::BootstrapForm::Helpers::NestedForm
6
+
7
+ def bootstrap_form_for(object, options = {}, &block)
8
+ options.reverse_merge!({builder: BootstrapForm::FormBuilder})
9
+
10
+ options[:html] ||= {}
11
+ options[:html][:role] ||= 'form'
12
+
13
+ if options[:layout] == :inline
14
+ options[:html][:class] = [options[:html][:class], "form-inline"].compact.join(" ")
15
+ end
16
+
17
+ temporarily_disable_field_error_proc do
18
+ form_for(object, options, &block)
19
+ end
20
+ end
21
+
22
+ def bootstrap_form_tag(options = {}, &block)
23
+ options[:acts_like_form_tag] = true
24
+
25
+ bootstrap_form_for("", options, &block)
26
+ end
27
+
28
+ def temporarily_disable_field_error_proc
29
+ original_proc = ActionView::Base.field_error_proc
30
+ ActionView::Base.field_error_proc = proc { |input, instance| input }
31
+ yield
32
+ ensure
33
+ ActionView::Base.field_error_proc = original_proc
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,94 @@
1
+ module BootstrapForm
2
+ module Helpers
3
+ module Bootstrap
4
+ def submit(name = nil, options = {})
5
+ options.reverse_merge! class: 'btn btn-secondary'
6
+ super(name, options)
7
+ end
8
+
9
+ def primary(name = nil, options = {})
10
+ options.reverse_merge! class: 'btn btn-primary'
11
+ submit(name, options)
12
+ end
13
+
14
+ def alert_message(title, options = {})
15
+ css = options[:class] || 'alert alert-danger'
16
+
17
+ if object.respond_to?(:errors) && object.errors.full_messages.any?
18
+ content_tag :div, class: css do
19
+ concat content_tag :p, title
20
+ concat error_summary unless options[:error_summary] == false
21
+ end
22
+ end
23
+ end
24
+
25
+ def error_summary
26
+ content_tag :ul, class: 'rails-bootstrap-forms-error-summary' do
27
+ object.errors.full_messages.each do |error|
28
+ concat content_tag(:li, error)
29
+ end
30
+ end
31
+ end
32
+
33
+ def errors_on(name, options = {})
34
+ if has_error?(name)
35
+ hide_attribute_name = options[:hide_attribute_name] || false
36
+
37
+ content_tag :div, class: "alert alert-danger" do
38
+ if hide_attribute_name
39
+ object.errors[name].join(", ")
40
+ else
41
+ object.errors.full_messages_for(name).join(", ")
42
+ end
43
+ end
44
+ end
45
+ end
46
+
47
+ def static_control(*args, &block)
48
+ options = args.extract_options!
49
+ name = args.first
50
+
51
+ html = if block_given?
52
+ capture(&block)
53
+ else
54
+ object.send(name)
55
+ end
56
+
57
+ form_group_builder(name, options) do
58
+ content_tag(:p, html, class: static_class)
59
+ end
60
+ end
61
+
62
+ def custom_control(*args, &block)
63
+ options = args.extract_options!
64
+ name = args.first
65
+
66
+ form_group_builder(name, options, &block)
67
+ end
68
+
69
+ def prepend_and_append_input(options, &block)
70
+ options = options.extract!(:prepend, :append, :input_group_class)
71
+ input_group_class = ["input-group", options[:input_group_class]].compact.join(' ')
72
+
73
+ input = capture(&block)
74
+
75
+ input = content_tag(:span, options[:prepend], class: input_group_class(options[:prepend])) + input if options[:prepend]
76
+ input << content_tag(:span, options[:append], class: input_group_class(options[:append])) if options[:append]
77
+ input = content_tag(:div, input, class: input_group_class) unless options.empty?
78
+ input
79
+ end
80
+
81
+ def input_group_class(add_on_content)
82
+ if add_on_content.match(/btn/)
83
+ 'input-group-btn'
84
+ else
85
+ 'input-group-addon'
86
+ end
87
+ end
88
+
89
+ def static_class
90
+ "form-control-static"
91
+ end
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,33 @@
1
+ begin
2
+ require 'nested_form/builder_mixin'
3
+
4
+ module BootstrapForm
5
+ class NestedFormBuilder < ::BootstrapForm::FormBuilder
6
+ include ::NestedForm::BuilderMixin
7
+ end
8
+ end
9
+
10
+ module BootstrapForm
11
+ module Helpers
12
+ module NestedForm
13
+ def bootstrap_nested_form_for(object, options = {}, &block)
14
+ options.reverse_merge!({builder: BootstrapForm::NestedFormBuilder})
15
+ bootstrap_form_for(object, options) do |f|
16
+ capture(f, &block).to_s << after_nested_form_callbacks
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+
23
+ rescue LoadError
24
+ module BootstrapForm
25
+ module Helpers
26
+ module NestedForm
27
+ def bootstrap_nested_form_for(object, options = {}, &block)
28
+ raise 'nested_forms was not found. Is it in your Gemfile?'
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,3 @@
1
+ module BootstrapForm
2
+ VERSION = "4.0.0.beta1".freeze
3
+ end
@@ -0,0 +1 @@
1
+ require_relative "./bootstrap_form"
@@ -0,0 +1,144 @@
1
+ require 'test_helper'
2
+
3
+ class BootstrapCheckboxTest < ActionView::TestCase
4
+ include BootstrapForm::Helper
5
+
6
+ def setup
7
+ setup_test_fixture
8
+ end
9
+
10
+ test "check_box is wrapped correctly" do
11
+ expected = %{<div class="form-check"><label class="form-check-label" for="user_terms"><input name="user[terms]" type="hidden" value="0" /><input class="form-check-input" id="user_terms" name="user[terms]" type="checkbox" value="1" /> I agree to the terms</label></div>}
12
+ assert_equivalent_xml expected, @builder.check_box(:terms, label: 'I agree to the terms')
13
+ end
14
+
15
+ test "disabled check_box has proper wrapper classes" do
16
+ expected = %{<div class="form-check disabled"><label class="form-check-label" for="user_terms"><input disabled="disabled" name="user[terms]" type="hidden" value="0" /><input class="form-check-input" disabled="disabled" id="user_terms" name="user[terms]" type="checkbox" value="1" /> I agree to the terms</label></div>}
17
+ assert_equivalent_xml expected, @builder.check_box(:terms, label: 'I agree to the terms', disabled: true)
18
+ end
19
+
20
+ test "check_box label allows html" do
21
+ expected = %{<div class="form-check"><label class="form-check-label" for="user_terms"><input name="user[terms]" type="hidden" value="0" /><input class="form-check-input" id="user_terms" name="user[terms]" type="checkbox" value="1" /> I agree to the <a href="#">terms</a></label></div>}
22
+ assert_equivalent_xml expected, @builder.check_box(:terms, label: %{I agree to the <a href="#">terms</a>}.html_safe)
23
+ end
24
+
25
+ test "check_box accepts a block to define the label" do
26
+ expected = %{<div class="form-check"><label class="form-check-label" for="user_terms"><input name="user[terms]" type="hidden" value="0" /><input class="form-check-input" id="user_terms" name="user[terms]" type="checkbox" value="1" /> I agree to the terms</label></div>}
27
+ assert_equivalent_xml expected, @builder.check_box(:terms) { "I agree to the terms" }
28
+ end
29
+
30
+ test "check_box accepts a custom label class" do
31
+ expected = %{<div class="form-check"><label class="form-check-label btn" for="user_terms"><input name="user[terms]" type="hidden" value="0" /><input class="form-check-input" id="user_terms" name="user[terms]" type="checkbox" value="1" /> Terms</label></div>}
32
+ assert_equivalent_xml expected, @builder.check_box(:terms, label_class: 'btn')
33
+ end
34
+
35
+ test "check_box responds to checked_value and unchecked_value arguments" do
36
+ expected = %{<div class="form-check"><label class="form-check-label" for="user_terms"><input name="user[terms]" type="hidden" value="no" /><input class="form-check-input" id="user_terms" name="user[terms]" type="checkbox" value="yes" /> I agree to the terms</label></div>}
37
+ assert_equivalent_xml expected, @builder.check_box(:terms, {label: 'I agree to the terms'}, 'yes', 'no')
38
+ end
39
+
40
+ test "inline checkboxes" do
41
+ expected = %{<label class="form-check-inline" for="user_terms"><input name="user[terms]" type="hidden" value="0" /><input class="form-check-input" id="user_terms" name="user[terms]" type="checkbox" value="1" /> I agree to the terms</label>}
42
+ assert_equivalent_xml expected, @builder.check_box(:terms, label: 'I agree to the terms', inline: true)
43
+ end
44
+
45
+ test "disabled inline check_box" do
46
+ expected = %{<label class="form-check-inline disabled" for="user_terms"><input disabled="disabled" name="user[terms]" type="hidden" value="0" /><input class="form-check-input" disabled="disabled" id="user_terms" name="user[terms]" type="checkbox" value="1" /> I agree to the terms</label>}
47
+ assert_equivalent_xml expected, @builder.check_box(:terms, label: 'I agree to the terms', inline: true, disabled: true)
48
+ end
49
+
50
+ test "inline checkboxes with custom label class" do
51
+ expected = %{<label class="form-check-inline btn" for="user_terms"><input name="user[terms]" type="hidden" value="0" /><input class="form-check-input" id="user_terms" name="user[terms]" type="checkbox" value="1" /> Terms</label>}
52
+ assert_equivalent_xml expected, @builder.check_box(:terms, inline: true, label_class: 'btn')
53
+ end
54
+
55
+ test 'collection_check_boxes renders the form_group correctly' do
56
+ collection = [Address.new(id: 1, street: 'Foobar')]
57
+ expected = %{<input id="user_misc" multiple="multiple" name="user[misc][]" type="hidden" value="" /><div class="form-group"><label class="form-control-label" for="user_misc">This is a checkbox collection</label><div class="form-check"><label class="form-check-label" for="user_misc_1"><input class="form-check-input" id="user_misc_1" name="user[misc][]" type="checkbox" value="1" /> Foobar</label></div><span class="form-text text-muted">With a help!</span></div>}
58
+
59
+ assert_equivalent_xml expected, @builder.collection_check_boxes(:misc, collection, :id, :street, label: 'This is a checkbox collection', help: 'With a help!')
60
+ end
61
+
62
+ test 'collection_check_boxes renders multiple checkboxes correctly' do
63
+ collection = [Address.new(id: 1, street: 'Foo'), Address.new(id: 2, street: 'Bar')]
64
+ expected = %{<input id="user_misc" multiple="multiple" name="user[misc][]" type="hidden" value="" /><div class="form-group"><label class="form-control-label" for="user_misc">Misc</label><div class="form-check"><label class="form-check-label" for="user_misc_1"><input class="form-check-input" id="user_misc_1" name="user[misc][]" type="checkbox" value="1" /> Foo</label></div><div class="form-check"><label class="form-check-label" for="user_misc_2"><input class="form-check-input" id="user_misc_2" name="user[misc][]" type="checkbox" value="2" /> Bar</label></div></div>}
65
+
66
+ assert_equivalent_xml expected, @builder.collection_check_boxes(:misc, collection, :id, :street)
67
+ end
68
+
69
+ test 'collection_check_boxes renders inline checkboxes correctly' do
70
+ collection = [Address.new(id: 1, street: 'Foo'), Address.new(id: 2, street: 'Bar')]
71
+ expected = %{<input id="user_misc" multiple="multiple" name="user[misc][]" type="hidden" value="" /><div class="form-group"><label class="form-control-label" for="user_misc">Misc</label><label class="form-check-inline" for="user_misc_1"><input class="form-check-input" id="user_misc_1" name="user[misc][]" type="checkbox" value="1" /> Foo</label><label class="form-check-inline" for="user_misc_2"><input class="form-check-input" id="user_misc_2" name="user[misc][]" type="checkbox" value="2" /> Bar</label></div>}
72
+
73
+ assert_equivalent_xml expected, @builder.collection_check_boxes(:misc, collection, :id, :street, inline: true)
74
+ end
75
+
76
+ test 'collection_check_boxes renders with checked option correctly' do
77
+ collection = [Address.new(id: 1, street: 'Foo'), Address.new(id: 2, street: 'Bar')]
78
+ expected = %{<input id="user_misc" multiple="multiple" name="user[misc][]" type="hidden" value="" /><div class="form-group"><label class="form-control-label" for="user_misc">Misc</label><div class="form-check"><label class="form-check-label" for="user_misc_1"><input checked="checked" class="form-check-input" id="user_misc_1" name="user[misc][]" type="checkbox" value="1" /> Foo</label></div><div class="form-check"><label class="form-check-label" for="user_misc_2"><input class="form-check-input" id="user_misc_2" name="user[misc][]" type="checkbox" value="2" /> Bar</label></div></div>}
79
+
80
+ assert_equivalent_xml expected, @builder.collection_check_boxes(:misc, collection, :id, :street, checked: 1)
81
+ assert_equivalent_xml expected, @builder.collection_check_boxes(:misc, collection, :id, :street, checked: collection.first)
82
+ end
83
+
84
+ test 'collection_check_boxes renders with multiple checked options correctly' do
85
+ collection = [Address.new(id: 1, street: 'Foo'), Address.new(id: 2, street: 'Bar')]
86
+ expected = %{<input id="user_misc" multiple="multiple" name="user[misc][]" type="hidden" value="" /><div class="form-group"><label class="form-control-label" for="user_misc">Misc</label><div class="form-check"><label class="form-check-label" for="user_misc_1"><input checked="checked" class="form-check-input" id="user_misc_1" name="user[misc][]" type="checkbox" value="1" /> Foo</label></div><div class="form-check"><label class="form-check-label" for="user_misc_2"><input checked="checked" class="form-check-input" id="user_misc_2" name="user[misc][]" type="checkbox" value="2" /> Bar</label></div></div>}
87
+
88
+ assert_equivalent_xml expected, @builder.collection_check_boxes(:misc, collection, :id, :street, checked: [1, 2])
89
+ assert_equivalent_xml expected, @builder.collection_check_boxes(:misc, collection, :id, :street, checked: collection)
90
+ end
91
+
92
+ test 'collection_check_boxes sanitizes values when generating label `for`' do
93
+ collection = [Address.new(id: 1, street: 'Foo St')]
94
+ expected = %{<input id="user_misc" multiple="multiple" name="user[misc][]" type="hidden" value="" /><div class="form-group"><label class="form-control-label" for="user_misc">Misc</label><div class="form-check"><label class="form-check-label" for="user_misc_foo_st"><input class="form-check-input" id="user_misc_foo_st" name="user[misc][]" type="checkbox" value="Foo St" /> Foo St</label></div></div>}
95
+
96
+ assert_equivalent_xml expected, @builder.collection_check_boxes(:misc, collection, :street, :street)
97
+ end
98
+
99
+ test 'collection_check_boxes renders multiple checkboxes with labels defined by Proc :text_method correctly' do
100
+ collection = [Address.new(id: 1, street: 'Foo'), Address.new(id: 2, street: 'Bar')]
101
+ expected = %{<input id="user_misc" multiple="multiple" name="user[misc][]" type="hidden" value="" /><div class="form-group"><label class="form-control-label" for="user_misc">Misc</label><div class="form-check"><label class="form-check-label" for="user_misc_1"><input class="form-check-input" id="user_misc_1" name="user[misc][]" type="checkbox" value="1" /> ooF</label></div><div class="form-check"><label class="form-check-label" for="user_misc_2"><input class="form-check-input" id="user_misc_2" name="user[misc][]" type="checkbox" value="2" /> raB</label></div></div>}
102
+
103
+ assert_equivalent_xml expected, @builder.collection_check_boxes(:misc, collection, :id, Proc.new { |a| a.street.reverse })
104
+ end
105
+
106
+ test 'collection_check_boxes renders multiple checkboxes with values defined by Proc :value_method correctly' do
107
+ collection = [Address.new(id: 1, street: 'Foo'), Address.new(id: 2, street: 'Bar')]
108
+ expected = %{<input id="user_misc" multiple="multiple" name="user[misc][]" type="hidden" value="" /><div class="form-group"><label class="form-control-label" for="user_misc">Misc</label><div class="form-check"><label class="form-check-label" for="user_misc_address_1"><input class="form-check-input" id="user_misc_address_1" name="user[misc][]" type="checkbox" value="address_1" /> Foo</label></div><div class="form-check"><label class="form-check-label" for="user_misc_address_2"><input class="form-check-input" id="user_misc_address_2" name="user[misc][]" type="checkbox" value="address_2" /> Bar</label></div></div>}
109
+
110
+ assert_equivalent_xml expected, @builder.collection_check_boxes(:misc, collection, Proc.new { |a| "address_#{a.id}" }, :street)
111
+ end
112
+
113
+ test 'collection_check_boxes renders multiple checkboxes with labels defined by lambda :text_method correctly' do
114
+ collection = [Address.new(id: 1, street: 'Foo'), Address.new(id: 2, street: 'Bar')]
115
+ expected = %{<input id="user_misc" multiple="multiple" name="user[misc][]" type="hidden" value="" /><div class="form-group"><label class="form-control-label" for="user_misc">Misc</label><div class="form-check"><label class="form-check-label" for="user_misc_1"><input class="form-check-input" id="user_misc_1" name="user[misc][]" type="checkbox" value="1" /> ooF</label></div><div class="form-check"><label class="form-check-label" for="user_misc_2"><input class="form-check-input" id="user_misc_2" name="user[misc][]" type="checkbox" value="2" /> raB</label></div></div>}
116
+
117
+ assert_equivalent_xml expected, @builder.collection_check_boxes(:misc, collection, :id, lambda { |a| a.street.reverse })
118
+ end
119
+
120
+ test 'collection_check_boxes renders multiple checkboxes with values defined by lambda :value_method correctly' do
121
+ collection = [Address.new(id: 1, street: 'Foo'), Address.new(id: 2, street: 'Bar')]
122
+ expected = %{<input id="user_misc" multiple="multiple" name="user[misc][]" type="hidden" value="" /><div class="form-group"><label class="form-control-label" for="user_misc">Misc</label><div class="form-check"><label class="form-check-label" for="user_misc_address_1"><input class="form-check-input" id="user_misc_address_1" name="user[misc][]" type="checkbox" value="address_1" /> Foo</label></div><div class="form-check"><label class="form-check-label" for="user_misc_address_2"><input class="form-check-input" id="user_misc_address_2" name="user[misc][]" type="checkbox" value="address_2" /> Bar</label></div></div>}
123
+
124
+ assert_equivalent_xml expected, @builder.collection_check_boxes(:misc, collection, lambda { |a| "address_#{a.id}" }, :street)
125
+ end
126
+
127
+ test 'collection_check_boxes renders with checked option correctly with Proc :value_method' do
128
+ collection = [Address.new(id: 1, street: 'Foo'), Address.new(id: 2, street: 'Bar')]
129
+ expected = %{<input id="user_misc" multiple="multiple" name="user[misc][]" type="hidden" value="" /><div class="form-group"><label class="form-control-label" for="user_misc">Misc</label><div class="form-check"><label class="form-check-label" for="user_misc_address_1"><input checked="checked" class="form-check-input" id="user_misc_address_1" name="user[misc][]" type="checkbox" value="address_1" /> Foo</label></div><div class="form-check"><label class="form-check-label" for="user_misc_address_2"><input class="form-check-input" id="user_misc_address_2" name="user[misc][]" type="checkbox" value="address_2" /> Bar</label></div></div>}
130
+
131
+ assert_equivalent_xml expected, @builder.collection_check_boxes(:misc, collection, Proc.new { |a| "address_#{a.id}" }, :street, checked: "address_1")
132
+ assert_equivalent_xml expected, @builder.collection_check_boxes(:misc, collection, Proc.new { |a| "address_#{a.id}" }, :street, checked: collection.first)
133
+ end
134
+
135
+ test 'collection_check_boxes renders with multiple checked options correctly with lambda :value_method' do
136
+ collection = [Address.new(id: 1, street: 'Foo'), Address.new(id: 2, street: 'Bar')]
137
+ expected = %{<input id="user_misc" multiple="multiple" name="user[misc][]" type="hidden" value="" /><div class="form-group"><label class="form-control-label" for="user_misc">Misc</label><div class="form-check"><label class="form-check-label" for="user_misc_address_1"><input checked="checked" class="form-check-input" id="user_misc_address_1" name="user[misc][]" type="checkbox" value="address_1" /> Foo</label></div><div class="form-check"><label class="form-check-label" for="user_misc_address_2"><input checked="checked" class="form-check-input" id="user_misc_address_2" name="user[misc][]" type="checkbox" value="address_2" /> Bar</label></div></div>}
138
+
139
+ assert_equivalent_xml expected, @builder.collection_check_boxes(:misc, collection, lambda { |a| "address_#{a.id}" }, :street, checked: ["address_1", "address_2"])
140
+ assert_equivalent_xml expected, @builder.collection_check_boxes(:misc, collection, lambda { |a| "address_#{a.id}" }, :street, checked: collection)
141
+ end
142
+
143
+
144
+ end
@@ -0,0 +1,152 @@
1
+ require 'test_helper'
2
+
3
+ class BootstrapFieldsTest < ActionView::TestCase
4
+ include BootstrapForm::Helper
5
+
6
+ def setup
7
+ setup_test_fixture
8
+ end
9
+
10
+ test "color fields are wrapped correctly" do
11
+ expected = %{<div class="form-group"><label class="form-control-label" for="user_misc">Misc</label><input class="form-control" id="user_misc" name="user[misc]" type="color" value="#000000" /></div>}
12
+ assert_equivalent_xml expected, @builder.color_field(:misc)
13
+ end
14
+
15
+ test "date fields are wrapped correctly" do
16
+ expected = %{<div class="form-group"><label class="form-control-label" for="user_misc">Misc</label><input class="form-control" id="user_misc" name="user[misc]" type="date" /></div>}
17
+ assert_equivalent_xml expected, @builder.date_field(:misc)
18
+ end
19
+
20
+ test "date time fields are wrapped correctly" do
21
+ expected = %{<div class="form-group"><label class="form-control-label" for="user_misc">Misc</label><input class="form-control" id="user_misc" name="user[misc]" type="datetime" /></div>}
22
+ assert_equivalent_xml expected, @builder.datetime_field(:misc)
23
+ end
24
+
25
+ test "date time local fields are wrapped correctly" do
26
+ expected = %{<div class="form-group"><label class="form-control-label" for="user_misc">Misc</label><input class="form-control" id="user_misc" name="user[misc]" type="datetime-local" /></div>}
27
+ assert_equivalent_xml expected, @builder.datetime_local_field(:misc)
28
+ end
29
+
30
+ test "email fields are wrapped correctly" do
31
+ expected = %{<div class="form-group"><label class="form-control-label" for="user_misc">Misc</label><input class="form-control" id="user_misc" name="user[misc]" type="email" /></div>}
32
+ assert_equivalent_xml expected, @builder.email_field(:misc)
33
+ end
34
+
35
+ test "file fields are wrapped correctly" do
36
+ expected = %{<div class="form-group"><label class="form-control-label" for="user_misc">Misc</label><input id="user_misc" name="user[misc]" type="file" /></div>}
37
+ assert_equivalent_xml expected, @builder.file_field(:misc)
38
+ end
39
+
40
+ test "hidden fields are supported" do
41
+ expected = %{<input id="user_misc" name="user[misc]" type="hidden" />}
42
+ assert_equivalent_xml expected, @builder.hidden_field(:misc)
43
+ end
44
+
45
+ test "month local fields are wrapped correctly" do
46
+ expected = %{<div class="form-group"><label class="form-control-label" for="user_misc">Misc</label><input class="form-control" id="user_misc" name="user[misc]" type="month" /></div>}
47
+ assert_equivalent_xml expected, @builder.month_field(:misc)
48
+ end
49
+
50
+ test "number fields are wrapped correctly" do
51
+ expected = %{<div class="form-group"><label class="form-control-label" for="user_misc">Misc</label><input class="form-control" id="user_misc" name="user[misc]" type="number" /></div>}
52
+ assert_equivalent_xml expected, @builder.number_field(:misc)
53
+ end
54
+
55
+ test "password fields are wrapped correctly" do
56
+ 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="password" /><span class="form-text text-muted">A good password should be at least six characters long</span></div>}
57
+ assert_equivalent_xml expected, @builder.password_field(:password)
58
+ end
59
+
60
+ test "phone/telephone fields are wrapped correctly" do
61
+ expected = %{<div class="form-group"><label class="form-control-label" for="user_misc">Misc</label><input class="form-control" id="user_misc" name="user[misc]" type="tel" /></div>}
62
+ assert_equivalent_xml expected, @builder.phone_field(:misc)
63
+ assert_equivalent_xml expected, @builder.telephone_field(:misc)
64
+ end
65
+
66
+ test "range fields are wrapped correctly" do
67
+ expected = %{<div class="form-group"><label class="form-control-label" for="user_misc">Misc</label><input class="form-control" id="user_misc" name="user[misc]" type="range" /></div>}
68
+ assert_equivalent_xml expected, @builder.range_field(:misc)
69
+ end
70
+
71
+ test "search fields are wrapped correctly" do
72
+ expected = %{<div class="form-group"><label class="form-control-label" for="user_misc">Misc</label><input class="form-control" id="user_misc" name="user[misc]" type="search" /></div>}
73
+ assert_equivalent_xml expected, @builder.search_field(:misc)
74
+ end
75
+
76
+ test "text areas are wrapped correctly" do
77
+ expected = %{<div class="form-group"><label class="form-control-label" for="user_comments">Comments</label><textarea class="form-control" id="user_comments" name="user[comments]">\nmy comment</textarea></div>}
78
+ assert_equivalent_xml expected, @builder.text_area(:comments)
79
+ end
80
+
81
+ test "text fields are wrapped correctly" do
82
+ 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" /></div>}
83
+ assert_equivalent_xml expected, @builder.text_field(:email)
84
+ end
85
+
86
+ test "time fields are wrapped correctly" do
87
+ expected = %{<div class="form-group"><label class="form-control-label" for="user_misc">Misc</label><input class="form-control" id="user_misc" name="user[misc]" type="time" /></div>}
88
+ assert_equivalent_xml expected, @builder.time_field(:misc)
89
+ end
90
+
91
+ test "url fields are wrapped correctly" do
92
+ expected = %{<div class="form-group"><label class="form-control-label" for="user_misc">Misc</label><input class="form-control" id="user_misc" name="user[misc]" type="url" /></div>}
93
+ assert_equivalent_xml expected, @builder.url_field(:misc)
94
+ end
95
+
96
+ test "week fields are wrapped correctly" do
97
+ expected = %{<div class="form-group"><label class="form-control-label" for="user_misc">Misc</label><input class="form-control" id="user_misc" name="user[misc]" type="week" /></div>}
98
+ assert_equivalent_xml expected, @builder.week_field(:misc)
99
+ end
100
+
101
+ test "bootstrap_form_for helper works for associations" do
102
+ @user.address = Address.new(street: '123 Main Street')
103
+
104
+ output = bootstrap_form_for(@user) do |f|
105
+ f.fields_for :address do |af|
106
+ af.text_field(:street)
107
+ end
108
+ end
109
+
110
+ 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" for="user_address_attributes_street">Street</label><input class="form-control" id="user_address_attributes_street" name="user[address_attributes][street]" type="text" value="123 Main Street" /></div></form>}
111
+ assert_equivalent_xml expected, output
112
+ end
113
+
114
+ test "bootstrap_form_for helper works for serialized hash attributes" do
115
+ @user.preferences = { favorite_color: "cerulean" }
116
+
117
+ output = bootstrap_form_for(@user) do |f|
118
+ f.fields_for :preferences do |builder|
119
+ builder.text_field :favorite_color, value: @user.preferences[:favorite_color]
120
+ end
121
+ end
122
+
123
+ 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" for="user_preferences_favorite_color">Favorite color</label><input class="form-control" id="user_preferences_favorite_color" name="user[preferences][favorite_color]" type="text" value="cerulean" /></div></form>}
124
+ assert_equivalent_xml expected, output
125
+ end
126
+
127
+ test "fields_for correctly passes horizontal style from parent builder" do
128
+ @user.address = Address.new(street: '123 Main Street')
129
+
130
+ output = bootstrap_form_for(@user, layout: :horizontal, label_col: 'col-sm-2', control_col: 'col-sm-10') do |f|
131
+ f.fields_for :address do |af|
132
+ af.text_field(:street)
133
+ end
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="form-group row"><label class="form-control-label col-sm-2" for="user_address_attributes_street">Street</label><div class="col-sm-10"><input class="form-control" id="user_address_attributes_street" name="user[address_attributes][street]" type="text" value="123 Main Street" /></div></div></form>}
137
+ assert_equivalent_xml expected, output
138
+ end
139
+
140
+ test "fields_for correctly passes inline style from parent builder" do
141
+ @user.address = Address.new(street: '123 Main Street')
142
+
143
+ output = bootstrap_form_for(@user, layout: :inline) do |f|
144
+ f.fields_for :address do |af|
145
+ af.text_field(:street)
146
+ end
147
+ end
148
+
149
+ 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><div class="form-group"><label class="form-control-label" for="user_address_attributes_street">Street</label><input class="form-control" id="user_address_attributes_street" name="user[address_attributes][street]" type="text" value="123 Main Street" /></div></form>}
150
+ assert_equivalent_xml expected, output
151
+ end
152
+ end