formtastic 3.0.0 → 5.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.
Files changed (175) hide show
  1. checksums.yaml +5 -13
  2. data/.gitattributes +1 -0
  3. data/.github/workflows/test.yml +61 -0
  4. data/.gitignore +3 -2
  5. data/CHANGELOG.md +61 -0
  6. data/Gemfile.lock +140 -0
  7. data/MIT-LICENSE +1 -1
  8. data/{README.textile → README.md} +191 -168
  9. data/RELEASE_PROCESS +3 -1
  10. data/Rakefile +24 -8
  11. data/app/assets/stylesheets/formtastic.css +1 -1
  12. data/bin/appraisal +8 -0
  13. data/formtastic.gemspec +13 -17
  14. data/gemfiles/rails_6.0/Gemfile +5 -0
  15. data/gemfiles/rails_6.1/Gemfile +5 -0
  16. data/gemfiles/rails_7.0/Gemfile +5 -0
  17. data/gemfiles/rails_7.1/Gemfile +5 -0
  18. data/gemfiles/rails_edge/Gemfile +13 -0
  19. data/lib/formtastic/action_class_finder.rb +19 -0
  20. data/lib/formtastic/actions/base.rb +1 -0
  21. data/lib/formtastic/actions/button_action.rb +56 -53
  22. data/lib/formtastic/actions/buttonish.rb +1 -0
  23. data/lib/formtastic/actions/input_action.rb +60 -57
  24. data/lib/formtastic/actions/link_action.rb +69 -67
  25. data/lib/formtastic/actions.rb +7 -3
  26. data/lib/formtastic/deprecation.rb +6 -0
  27. data/lib/formtastic/engine.rb +4 -1
  28. data/lib/formtastic/form_builder.rb +32 -25
  29. data/lib/formtastic/helpers/action_helper.rb +22 -31
  30. data/lib/formtastic/helpers/actions_helper.rb +1 -0
  31. data/lib/formtastic/helpers/enum.rb +14 -0
  32. data/lib/formtastic/helpers/errors_helper.rb +3 -2
  33. data/lib/formtastic/helpers/fieldset_wrapper.rb +16 -11
  34. data/lib/formtastic/helpers/file_column_detection.rb +1 -0
  35. data/lib/formtastic/helpers/form_helper.rb +4 -3
  36. data/lib/formtastic/helpers/input_helper.rb +59 -80
  37. data/lib/formtastic/helpers/inputs_helper.rb +33 -27
  38. data/lib/formtastic/helpers/reflection.rb +5 -4
  39. data/lib/formtastic/helpers.rb +2 -2
  40. data/lib/formtastic/html_attributes.rb +13 -1
  41. data/lib/formtastic/i18n.rb +2 -1
  42. data/lib/formtastic/input_class_finder.rb +19 -0
  43. data/lib/formtastic/inputs/base/associations.rb +1 -0
  44. data/lib/formtastic/inputs/base/choices.rb +4 -3
  45. data/lib/formtastic/inputs/base/collections.rb +47 -11
  46. data/lib/formtastic/inputs/base/database.rb +8 -5
  47. data/lib/formtastic/inputs/base/datetime_pickerish.rb +1 -0
  48. data/lib/formtastic/inputs/base/errors.rb +7 -6
  49. data/lib/formtastic/inputs/base/fileish.rb +1 -0
  50. data/lib/formtastic/inputs/base/hints.rb +2 -1
  51. data/lib/formtastic/inputs/base/html.rb +12 -10
  52. data/lib/formtastic/inputs/base/labelling.rb +3 -2
  53. data/lib/formtastic/inputs/base/naming.rb +5 -4
  54. data/lib/formtastic/inputs/base/numeric.rb +1 -0
  55. data/lib/formtastic/inputs/base/options.rb +3 -3
  56. data/lib/formtastic/inputs/base/placeholder.rb +1 -0
  57. data/lib/formtastic/inputs/base/stringish.rb +1 -0
  58. data/lib/formtastic/inputs/base/timeish.rb +9 -4
  59. data/lib/formtastic/inputs/base/validations.rb +39 -12
  60. data/lib/formtastic/inputs/base/wrapping.rb +2 -3
  61. data/lib/formtastic/inputs/base.rb +17 -12
  62. data/lib/formtastic/inputs/boolean_input.rb +2 -1
  63. data/lib/formtastic/inputs/check_boxes_input.rb +16 -24
  64. data/lib/formtastic/inputs/color_input.rb +1 -1
  65. data/lib/formtastic/inputs/country_input.rb +4 -1
  66. data/lib/formtastic/inputs/datalist_input.rb +42 -0
  67. data/lib/formtastic/inputs/date_picker_input.rb +1 -0
  68. data/lib/formtastic/inputs/date_select_input.rb +1 -0
  69. data/lib/formtastic/inputs/datetime_picker_input.rb +1 -0
  70. data/lib/formtastic/inputs/datetime_select_input.rb +1 -0
  71. data/lib/formtastic/inputs/email_input.rb +1 -0
  72. data/lib/formtastic/inputs/file_input.rb +3 -2
  73. data/lib/formtastic/inputs/hidden_input.rb +3 -2
  74. data/lib/formtastic/inputs/number_input.rb +1 -0
  75. data/lib/formtastic/inputs/password_input.rb +1 -0
  76. data/lib/formtastic/inputs/phone_input.rb +1 -0
  77. data/lib/formtastic/inputs/radio_input.rb +26 -21
  78. data/lib/formtastic/inputs/range_input.rb +1 -0
  79. data/lib/formtastic/inputs/search_input.rb +1 -0
  80. data/lib/formtastic/inputs/select_input.rb +32 -10
  81. data/lib/formtastic/inputs/string_input.rb +1 -0
  82. data/lib/formtastic/inputs/text_input.rb +1 -0
  83. data/lib/formtastic/inputs/time_picker_input.rb +1 -0
  84. data/lib/formtastic/inputs/time_select_input.rb +1 -0
  85. data/lib/formtastic/inputs/time_zone_input.rb +17 -6
  86. data/lib/formtastic/inputs/url_input.rb +1 -0
  87. data/lib/formtastic/inputs.rb +33 -28
  88. data/lib/formtastic/localized_string.rb +2 -1
  89. data/lib/formtastic/localizer.rb +23 -24
  90. data/lib/formtastic/namespaced_class_finder.rb +98 -0
  91. data/lib/formtastic/version.rb +2 -1
  92. data/lib/formtastic.rb +19 -14
  93. data/lib/generators/formtastic/form/form_generator.rb +8 -2
  94. data/lib/generators/formtastic/input/input_generator.rb +47 -0
  95. data/lib/generators/formtastic/install/install_generator.rb +2 -0
  96. data/lib/generators/templates/formtastic.rb +29 -7
  97. data/lib/generators/templates/input.rb +19 -0
  98. data/sample/basic_inputs.html +1 -1
  99. data/script/integration-template.rb +73 -0
  100. data/script/integration.sh +19 -0
  101. data/spec/action_class_finder_spec.rb +13 -0
  102. data/spec/actions/button_action_spec.rb +21 -20
  103. data/spec/actions/generic_action_spec.rb +134 -133
  104. data/spec/actions/input_action_spec.rb +20 -19
  105. data/spec/actions/link_action_spec.rb +30 -29
  106. data/spec/builder/custom_builder_spec.rb +39 -22
  107. data/spec/builder/error_proc_spec.rb +6 -5
  108. data/spec/builder/semantic_fields_for_spec.rb +46 -45
  109. data/spec/fast_spec_helper.rb +13 -0
  110. data/spec/generators/formtastic/form/form_generator_spec.rb +33 -32
  111. data/spec/generators/formtastic/input/input_generator_spec.rb +125 -0
  112. data/spec/generators/formtastic/install/install_generator_spec.rb +10 -9
  113. data/spec/helpers/action_helper_spec.rb +70 -97
  114. data/spec/helpers/actions_helper_spec.rb +43 -42
  115. data/spec/helpers/form_helper_spec.rb +56 -39
  116. data/spec/helpers/input_helper_spec.rb +314 -255
  117. data/spec/helpers/inputs_helper_spec.rb +217 -202
  118. data/spec/helpers/reflection_helper_spec.rb +7 -6
  119. data/spec/helpers/semantic_errors_helper_spec.rb +26 -25
  120. data/spec/i18n_spec.rb +30 -29
  121. data/spec/input_class_finder_spec.rb +11 -0
  122. data/spec/inputs/base/collections_spec.rb +78 -0
  123. data/spec/inputs/base/validations_spec.rb +481 -0
  124. data/spec/inputs/boolean_input_spec.rb +73 -72
  125. data/spec/inputs/check_boxes_input_spec.rb +174 -123
  126. data/spec/inputs/color_input_spec.rb +53 -64
  127. data/spec/inputs/country_input_spec.rb +23 -22
  128. data/spec/inputs/custom_input_spec.rb +3 -6
  129. data/spec/inputs/datalist_input_spec.rb +62 -0
  130. data/spec/inputs/date_picker_input_spec.rb +114 -113
  131. data/spec/inputs/date_select_input_spec.rb +76 -61
  132. data/spec/inputs/datetime_picker_input_spec.rb +123 -122
  133. data/spec/inputs/datetime_select_input_spec.rb +85 -68
  134. data/spec/inputs/email_input_spec.rb +17 -16
  135. data/spec/inputs/file_input_spec.rb +18 -17
  136. data/spec/inputs/hidden_input_spec.rb +32 -31
  137. data/spec/inputs/include_blank_spec.rb +10 -9
  138. data/spec/inputs/label_spec.rb +36 -31
  139. data/spec/inputs/number_input_spec.rb +212 -211
  140. data/spec/inputs/password_input_spec.rb +17 -16
  141. data/spec/inputs/phone_input_spec.rb +17 -16
  142. data/spec/inputs/placeholder_spec.rb +18 -17
  143. data/spec/inputs/radio_input_spec.rb +92 -65
  144. data/spec/inputs/range_input_spec.rb +136 -135
  145. data/spec/inputs/readonly_spec.rb +51 -0
  146. data/spec/inputs/search_input_spec.rb +16 -15
  147. data/spec/inputs/select_input_spec.rb +209 -102
  148. data/spec/inputs/string_input_spec.rb +51 -50
  149. data/spec/inputs/text_input_spec.rb +34 -33
  150. data/spec/inputs/time_picker_input_spec.rb +115 -114
  151. data/spec/inputs/time_select_input_spec.rb +84 -70
  152. data/spec/inputs/time_zone_input_spec.rb +58 -31
  153. data/spec/inputs/url_input_spec.rb +17 -16
  154. data/spec/inputs/with_options_spec.rb +9 -8
  155. data/spec/localizer_spec.rb +18 -17
  156. data/spec/namespaced_class_finder_spec.rb +91 -0
  157. data/spec/schema.rb +22 -0
  158. data/spec/spec_helper.rb +180 -249
  159. data/spec/support/custom_macros.rb +128 -98
  160. data/spec/support/deprecation.rb +2 -1
  161. data/spec/support/shared_examples.rb +13 -0
  162. data/spec/support/specialized_class_finder_shared_example.rb +28 -0
  163. data/spec/support/test_environment.rb +25 -10
  164. metadata +95 -136
  165. data/.travis.yml +0 -28
  166. data/Appraisals +0 -25
  167. data/CHANGELOG +0 -27
  168. data/gemfiles/rails_3.2.gemfile +0 -7
  169. data/gemfiles/rails_4.0.4.gemfile +0 -7
  170. data/gemfiles/rails_4.1.gemfile +0 -7
  171. data/gemfiles/rails_4.gemfile +0 -7
  172. data/gemfiles/rails_edge.gemfile +0 -10
  173. data/lib/formtastic/util.rb +0 -53
  174. data/spec/support/deferred_garbage_collection.rb +0 -21
  175. data/spec/util_spec.rb +0 -52
@@ -1,12 +1,13 @@
1
1
  # encoding: utf-8
2
+ # frozen_string_literal: true
2
3
  require 'spec_helper'
3
4
 
4
- describe 'FormHelper' do
5
+ RSpec.describe 'FormHelper' do
5
6
 
6
7
  include FormtasticSpecHelper
7
8
 
8
9
  before do
9
- @output_buffer = ''
10
+ @output_buffer = ActionView::OutputBuffer.new ''
10
11
  mock_everything
11
12
  end
12
13
 
@@ -14,45 +15,45 @@ describe 'FormHelper' do
14
15
 
15
16
  it 'yields an instance of Formtastic::FormBuilder' do
16
17
  semantic_form_for(@new_post, :url => '/hello') do |builder|
17
- builder.class.should == Formtastic::FormBuilder
18
+ expect(builder.class).to eq(Formtastic::FormBuilder)
18
19
  end
19
20
  end
20
21
 
21
22
  it 'adds a class of "formtastic" to the generated form' do
22
23
  concat(semantic_form_for(@new_post, :url => '/hello') do |builder|
23
24
  end)
24
- output_buffer.should have_tag("form.formtastic")
25
+ expect(output_buffer.to_str).to have_tag("form.formtastic")
25
26
  end
26
27
 
27
- it 'adds a "novalidate" attribute to the generated form when configured to do so' do
28
+ it 'does not add "novalidate" attribute to the generated form when configured to do so' do
28
29
  with_config :perform_browser_validations, true do
29
30
  concat(semantic_form_for(@new_post, :url => '/hello') do |builder|
30
31
  end)
31
- output_buffer.should_not have_tag("form[@novalidate]")
32
+ expect(output_buffer.to_str).not_to have_tag("form[@novalidate]")
32
33
  end
33
34
  end
34
35
 
35
- it 'omits a "novalidate" attribute to the generated form when configured to do so' do
36
+ it 'adds "novalidate" attribute to the generated form when configured to do so' do
36
37
  with_config :perform_browser_validations, false do
37
38
  concat(semantic_form_for(@new_post, :url => '/hello') do |builder|
38
39
  end)
39
- output_buffer.should have_tag("form[@novalidate]")
40
+ expect(output_buffer.to_str).to have_tag("form[@novalidate]")
40
41
  end
41
42
  end
42
43
 
43
- it 'allows form HTML to override "novalidate" attribute when configure to not show' do
44
+ it 'allows form HTML to override "novalidate" attribute when configured to validate' do
44
45
  with_config :perform_browser_validations, false do
45
46
  concat(semantic_form_for(@new_post, :url => '/hello', :html => { :novalidate => true }) do |builder|
46
47
  end)
47
- output_buffer.should have_tag("form[@novalidate]")
48
+ expect(output_buffer.to_str).to have_tag("form[@novalidate]")
48
49
  end
49
50
  end
50
51
 
51
- it 'allows form HTML to override "novalidate" attribute when configure to show' do
52
+ it 'allows form HTML to override "novalidate" attribute when configured to not validate' do
52
53
  with_config :perform_browser_validations, true do
53
54
  concat(semantic_form_for(@new_post, :url => '/hello', :html => { :novalidate => false }) do |builder|
54
55
  end)
55
- output_buffer.should_not have_tag("form[@novalidate]")
56
+ expect(output_buffer.to_str).not_to have_tag("form[@novalidate]")
56
57
  end
57
58
  end
58
59
 
@@ -60,103 +61,109 @@ describe 'FormHelper' do
60
61
  Formtastic::Helpers::FormHelper.default_form_class = 'xyz'
61
62
  concat(semantic_form_for(::Post.new, :as => :post, :url => '/hello') do |builder|
62
63
  end)
63
- output_buffer.should have_tag("form.xyz")
64
+ expect(output_buffer.to_str).to have_tag("form.xyz")
64
65
  end
65
66
 
66
67
  it 'omits the leading spaces from the classes in the generated form when the default class is nil' do
67
68
  Formtastic::Helpers::FormHelper.default_form_class = nil
68
69
  concat(semantic_form_for(::Post.new, :as => :post, :url => '/hello') do |builder|
69
70
  end)
70
- output_buffer.should have_tag("form[class='post']")
71
+ expect(output_buffer.to_str).to have_tag("form[class='post']")
71
72
  end
72
73
 
73
74
  it 'adds class matching the object name to the generated form when a symbol is provided' do
74
75
  concat(semantic_form_for(@new_post, :url => '/hello') do |builder|
75
76
  end)
76
- output_buffer.should have_tag("form.post")
77
+ expect(output_buffer.to_str).to have_tag("form.post")
77
78
 
78
79
  concat(semantic_form_for(:project, :url => '/hello') do |builder|
79
80
  end)
80
- output_buffer.should have_tag("form.project")
81
+ expect(output_buffer.to_str).to have_tag("form.project")
81
82
  end
82
83
 
83
84
  it 'adds class matching the :as option when provided' do
84
85
  concat(semantic_form_for(@new_post, :as => :message, :url => '/hello') do |builder|
85
86
  end)
86
- output_buffer.should have_tag("form.message")
87
+ expect(output_buffer.to_str).to have_tag("form.message")
87
88
 
88
89
  concat(semantic_form_for([:admins, @new_post], :as => :message, :url => '/hello') do |builder|
89
90
  end)
90
- output_buffer.should have_tag("form.message")
91
+ expect(output_buffer.to_str).to have_tag("form.message")
91
92
  end
92
93
 
93
94
  it 'adds class matching the object\'s class to the generated form when an object is provided' do
94
95
  concat(semantic_form_for(@new_post) do |builder|
95
96
  end)
96
- output_buffer.should have_tag("form.post")
97
+ expect(output_buffer.to_str).to have_tag("form.post")
97
98
  end
98
99
 
99
100
  it 'adds a namespaced class to the generated form' do
100
101
  concat(semantic_form_for(::Namespaced::Post.new, :url => '/hello') do |builder|
101
102
  end)
102
- output_buffer.should have_tag("form.namespaced_post")
103
+ expect(output_buffer.to_str).to have_tag("form.namespaced_post")
103
104
  end
104
105
 
105
106
  it 'adds a customized class to the generated form' do
106
107
  Formtastic::Helpers::FormHelper.default_form_model_class_proc = lambda { |model_class_name| "#{model_class_name}_form" }
107
108
  concat(semantic_form_for(@new_post, :url => '/hello') do |builder|
108
109
  end)
109
- output_buffer.should have_tag("form.post_form")
110
+ expect(output_buffer.to_str).to have_tag("form.post_form")
110
111
 
111
112
  concat(semantic_form_for(:project, :url => '/hello') do |builder|
112
113
  end)
113
- output_buffer.should have_tag("form.project_form")
114
+ expect(output_buffer.to_str).to have_tag("form.project_form")
114
115
  end
115
116
 
116
117
  describe 'allows :html options' do
117
- before(:each) do
118
+ before(:example) do
118
119
  concat(semantic_form_for(@new_post, :url => '/hello', :html => { :id => "something-special", :class => "something-extra", :multipart => true }) do |builder|
119
120
  end)
120
121
  end
121
122
 
122
123
  it 'to add a id of "something-special" to generated form' do
123
- output_buffer.should have_tag("form#something-special")
124
+ expect(output_buffer.to_str).to have_tag("form#something-special")
124
125
  end
125
126
 
126
127
  it 'to add a class of "something-extra" to generated form' do
127
- output_buffer.should have_tag("form.something-extra")
128
+ expect(output_buffer.to_str).to have_tag("form.something-extra")
128
129
  end
129
130
 
130
131
  it 'to add enctype="multipart/form-data"' do
131
- output_buffer.should have_tag('form[@enctype="multipart/form-data"]')
132
+ expect(output_buffer.to_str).to have_tag('form[@enctype="multipart/form-data"]')
132
133
  end
133
134
  end
134
135
 
135
136
  it 'can be called with a resource-oriented style' do
136
137
  semantic_form_for(@new_post) do |builder|
137
- builder.object.class.should == ::Post
138
- builder.object_name.should == "post"
138
+ expect(builder.object.class).to eq(::Post)
139
+ expect(builder.object_name).to eq("post")
139
140
  end
140
141
  end
141
142
 
142
143
  it 'can be called with a generic style and instance variable' do
143
144
  semantic_form_for(@new_post, :as => :post, :url => new_post_path) do |builder|
144
- builder.object.class.should == ::Post
145
- builder.object_name.to_s.should == "post" # TODO: is this forced .to_s a bad assumption somewhere?
145
+ expect(builder.object.class).to eq(::Post)
146
+ expect(builder.object_name.to_s).to eq("post") # TODO: is this forced .to_s a bad assumption somewhere?
146
147
  end
147
148
  end
148
149
 
149
150
  it 'can be called with a generic style and inline object' do
150
151
  semantic_form_for(@new_post, :url => new_post_path) do |builder|
151
- builder.object.class.should == ::Post
152
- builder.object_name.to_s.should == "post" # TODO: is this forced .to_s a bad assumption somewhere?
152
+ expect(builder.object.class).to eq(::Post)
153
+ expect(builder.object_name.to_s).to eq("post") # TODO: is this forced .to_s a bad assumption somewhere?
153
154
  end
154
155
  end
155
156
 
156
157
  describe 'ActionView::Base.field_error_proc' do
158
+ around do |ex|
159
+ error_proc = Formtastic::Helpers::FormHelper.formtastic_field_error_proc
160
+ ex.run
161
+ Formtastic::Helpers::FormHelper.formtastic_field_error_proc = error_proc
162
+ end
163
+
157
164
  it 'is set to no-op wrapper by default' do
158
165
  semantic_form_for(@new_post, :url => '/hello') do |builder|
159
- ::ActionView::Base.field_error_proc.call("html", nil).should == "html"
166
+ expect(::ActionView::Base.field_error_proc.call("html", nil)).to eq("html")
160
167
  end
161
168
  end
162
169
 
@@ -164,15 +171,15 @@ describe 'FormHelper' do
164
171
  field_error_proc = double()
165
172
  Formtastic::Helpers::FormHelper.formtastic_field_error_proc = field_error_proc
166
173
  semantic_form_for(@new_post, :url => '/hello') do |builder|
167
- ::ActionView::Base.field_error_proc.should == field_error_proc
174
+ expect(::ActionView::Base.field_error_proc).to eq(field_error_proc)
168
175
  end
169
176
  end
170
177
 
171
178
  it 'is restored to its original value after the form is rendered' do
172
- lambda do
179
+ expect do
173
180
  Formtastic::Helpers::FormHelper.formtastic_field_error_proc = proc {""}
174
181
  semantic_form_for(@new_post, :url => '/hello') { |builder| }
175
- end.should_not change(::ActionView::Base, :field_error_proc)
182
+ end.not_to change(::ActionView::Base, :field_error_proc)
176
183
  end
177
184
  end
178
185
 
@@ -181,7 +188,7 @@ describe 'FormHelper' do
181
188
  class MyAwesomeCustomBuilder < Formtastic::FormBuilder
182
189
  end
183
190
  semantic_form_for(@new_post, :url => '/hello', :builder => MyAwesomeCustomBuilder) do |builder|
184
- builder.class.should == MyAwesomeCustomBuilder
191
+ expect(builder.class).to eq(MyAwesomeCustomBuilder)
185
192
  end
186
193
  end
187
194
  end
@@ -189,7 +196,17 @@ describe 'FormHelper' do
189
196
  describe 'with :namespace option' do
190
197
  it "should set the custom_namespace" do
191
198
  semantic_form_for(@new_post, :namespace => 'context2') do |builder|
192
- builder.custom_namespace == 'context2'
199
+ expect(builder.dom_id_namespace).to eq('context2')
200
+ end
201
+ end
202
+ end
203
+
204
+ describe 'without :namespace option' do
205
+ it 'defaults to class settings' do
206
+ expect(Formtastic::FormBuilder).to receive(:custom_namespace).and_return('context2')
207
+
208
+ semantic_form_for(@new_post) do |builder|
209
+ expect(builder.dom_id_namespace).to eq('context2')
193
210
  end
194
211
  end
195
212
  end
@@ -199,7 +216,7 @@ describe 'FormHelper' do
199
216
  describe '#semantic_fields_for' do
200
217
  it 'yields an instance of Formtastic::FormBuilder' do
201
218
  semantic_fields_for(@new_post) do |builder|
202
- builder.class.should.kind_of?(Formtastic::FormBuilder)
219
+ expect(builder.class).to be(Formtastic::FormBuilder)
203
220
  end
204
221
  end
205
222
  end