formtastic 2.1.0 → 4.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 (164) hide show
  1. checksums.yaml +7 -0
  2. data/.gitattributes +1 -0
  3. data/.github/workflows/test.yml +61 -0
  4. data/.gitignore +4 -2
  5. data/CHANGELOG.md +52 -0
  6. data/Gemfile +1 -1
  7. data/Gemfile.lock +105 -0
  8. data/MIT-LICENSE +1 -1
  9. data/{README.textile → README.md} +204 -219
  10. data/RELEASE_PROCESS +3 -1
  11. data/Rakefile +27 -29
  12. data/app/assets/stylesheets/formtastic.css +3 -2
  13. data/bin/appraisal +8 -0
  14. data/formtastic.gemspec +11 -14
  15. data/gemfiles/rails_5.2/Gemfile +5 -0
  16. data/gemfiles/rails_6.0/Gemfile +5 -0
  17. data/gemfiles/rails_6.1/Gemfile +5 -0
  18. data/gemfiles/rails_edge/Gemfile +13 -0
  19. data/lib/formtastic/action_class_finder.rb +18 -0
  20. data/lib/formtastic/actions/button_action.rb +55 -60
  21. data/lib/formtastic/actions/input_action.rb +59 -57
  22. data/lib/formtastic/actions/link_action.rb +68 -67
  23. data/lib/formtastic/actions.rb +6 -3
  24. data/lib/formtastic/deprecation.rb +5 -0
  25. data/lib/formtastic/engine.rb +3 -1
  26. data/lib/formtastic/form_builder.rb +35 -16
  27. data/lib/formtastic/helpers/action_helper.rb +34 -28
  28. data/lib/formtastic/helpers/enum.rb +13 -0
  29. data/lib/formtastic/helpers/errors_helper.rb +2 -2
  30. data/lib/formtastic/helpers/fieldset_wrapper.rb +16 -12
  31. data/lib/formtastic/helpers/form_helper.rb +19 -16
  32. data/lib/formtastic/helpers/input_helper.rb +69 -97
  33. data/lib/formtastic/helpers/inputs_helper.rb +35 -25
  34. data/lib/formtastic/helpers/reflection.rb +4 -4
  35. data/lib/formtastic/helpers.rb +1 -2
  36. data/lib/formtastic/html_attributes.rb +12 -1
  37. data/lib/formtastic/i18n.rb +1 -1
  38. data/lib/formtastic/input_class_finder.rb +18 -0
  39. data/lib/formtastic/inputs/base/choices.rb +2 -2
  40. data/lib/formtastic/inputs/base/collections.rb +46 -14
  41. data/lib/formtastic/inputs/base/database.rb +7 -2
  42. data/lib/formtastic/inputs/base/datetime_pickerish.rb +85 -0
  43. data/lib/formtastic/inputs/base/errors.rb +7 -7
  44. data/lib/formtastic/inputs/base/hints.rb +2 -2
  45. data/lib/formtastic/inputs/base/html.rb +10 -9
  46. data/lib/formtastic/inputs/base/labelling.rb +5 -8
  47. data/lib/formtastic/inputs/base/naming.rb +4 -4
  48. data/lib/formtastic/inputs/base/numeric.rb +1 -1
  49. data/lib/formtastic/inputs/base/options.rb +3 -4
  50. data/lib/formtastic/inputs/base/stringish.rb +10 -2
  51. data/lib/formtastic/inputs/base/timeish.rb +34 -22
  52. data/lib/formtastic/inputs/base/validations.rb +41 -13
  53. data/lib/formtastic/inputs/base/wrapping.rb +29 -26
  54. data/lib/formtastic/inputs/base.rb +22 -15
  55. data/lib/formtastic/inputs/boolean_input.rb +26 -12
  56. data/lib/formtastic/inputs/check_boxes_input.rb +39 -31
  57. data/lib/formtastic/inputs/color_input.rb +41 -0
  58. data/lib/formtastic/inputs/country_input.rb +24 -5
  59. data/lib/formtastic/inputs/datalist_input.rb +41 -0
  60. data/lib/formtastic/inputs/date_picker_input.rb +93 -0
  61. data/lib/formtastic/inputs/{date_input.rb → date_select_input.rb} +1 -1
  62. data/lib/formtastic/inputs/datetime_picker_input.rb +103 -0
  63. data/lib/formtastic/inputs/{datetime_input.rb → datetime_select_input.rb} +1 -1
  64. data/lib/formtastic/inputs/file_input.rb +2 -2
  65. data/lib/formtastic/inputs/hidden_input.rb +2 -6
  66. data/lib/formtastic/inputs/radio_input.rb +28 -22
  67. data/lib/formtastic/inputs/select_input.rb +36 -39
  68. data/lib/formtastic/inputs/time_picker_input.rb +99 -0
  69. data/lib/formtastic/inputs/{time_input.rb → time_select_input.rb} +6 -2
  70. data/lib/formtastic/inputs/time_zone_input.rb +16 -6
  71. data/lib/formtastic/inputs.rb +32 -21
  72. data/lib/formtastic/localized_string.rb +1 -1
  73. data/lib/formtastic/localizer.rb +24 -24
  74. data/lib/formtastic/namespaced_class_finder.rb +99 -0
  75. data/lib/formtastic/version.rb +1 -1
  76. data/lib/formtastic.rb +20 -10
  77. data/lib/generators/formtastic/form/form_generator.rb +10 -4
  78. data/lib/generators/formtastic/input/input_generator.rb +46 -0
  79. data/lib/generators/formtastic/install/install_generator.rb +5 -19
  80. data/lib/generators/templates/_form.html.slim +2 -2
  81. data/lib/generators/templates/formtastic.rb +46 -25
  82. data/lib/generators/templates/input.rb +19 -0
  83. data/sample/basic_inputs.html +23 -3
  84. data/script/integration-template.rb +74 -0
  85. data/script/integration.sh +19 -0
  86. data/spec/action_class_finder_spec.rb +12 -0
  87. data/spec/actions/button_action_spec.rb +8 -8
  88. data/spec/actions/generic_action_spec.rb +92 -56
  89. data/spec/actions/input_action_spec.rb +7 -7
  90. data/spec/actions/link_action_spec.rb +10 -10
  91. data/spec/builder/custom_builder_spec.rb +36 -20
  92. data/spec/builder/error_proc_spec.rb +4 -4
  93. data/spec/builder/semantic_fields_for_spec.rb +28 -29
  94. data/spec/fast_spec_helper.rb +12 -0
  95. data/spec/generators/formtastic/form/form_generator_spec.rb +45 -32
  96. data/spec/generators/formtastic/input/input_generator_spec.rb +124 -0
  97. data/spec/generators/formtastic/install/install_generator_spec.rb +9 -9
  98. data/spec/helpers/action_helper_spec.rb +75 -103
  99. data/spec/helpers/actions_helper_spec.rb +17 -17
  100. data/spec/helpers/form_helper_spec.rb +84 -33
  101. data/spec/helpers/input_helper_spec.rb +333 -285
  102. data/spec/helpers/inputs_helper_spec.rb +167 -121
  103. data/spec/helpers/reflection_helper_spec.rb +3 -3
  104. data/spec/helpers/semantic_errors_helper_spec.rb +23 -23
  105. data/spec/i18n_spec.rb +26 -26
  106. data/spec/input_class_finder_spec.rb +10 -0
  107. data/spec/inputs/base/collections_spec.rb +76 -0
  108. data/spec/inputs/base/validations_spec.rb +480 -0
  109. data/spec/inputs/boolean_input_spec.rb +100 -65
  110. data/spec/inputs/check_boxes_input_spec.rb +200 -101
  111. data/spec/inputs/color_input_spec.rb +85 -0
  112. data/spec/inputs/country_input_spec.rb +20 -20
  113. data/spec/inputs/custom_input_spec.rb +3 -4
  114. data/spec/inputs/datalist_input_spec.rb +61 -0
  115. data/spec/inputs/date_picker_input_spec.rb +449 -0
  116. data/spec/inputs/date_select_input_spec.rb +249 -0
  117. data/spec/inputs/datetime_picker_input_spec.rb +490 -0
  118. data/spec/inputs/datetime_select_input_spec.rb +209 -0
  119. data/spec/inputs/email_input_spec.rb +5 -5
  120. data/spec/inputs/file_input_spec.rb +6 -6
  121. data/spec/inputs/hidden_input_spec.rb +22 -35
  122. data/spec/inputs/include_blank_spec.rb +11 -11
  123. data/spec/inputs/label_spec.rb +62 -25
  124. data/spec/inputs/number_input_spec.rb +112 -112
  125. data/spec/inputs/password_input_spec.rb +5 -5
  126. data/spec/inputs/phone_input_spec.rb +5 -5
  127. data/spec/inputs/placeholder_spec.rb +6 -6
  128. data/spec/inputs/radio_input_spec.rb +99 -55
  129. data/spec/inputs/range_input_spec.rb +66 -66
  130. data/spec/inputs/readonly_spec.rb +50 -0
  131. data/spec/inputs/search_input_spec.rb +5 -5
  132. data/spec/inputs/select_input_spec.rb +170 -170
  133. data/spec/inputs/string_input_spec.rb +68 -16
  134. data/spec/inputs/text_input_spec.rb +16 -16
  135. data/spec/inputs/time_picker_input_spec.rb +455 -0
  136. data/spec/inputs/time_select_input_spec.rb +261 -0
  137. data/spec/inputs/time_zone_input_spec.rb +54 -28
  138. data/spec/inputs/url_input_spec.rb +5 -5
  139. data/spec/inputs/with_options_spec.rb +7 -7
  140. data/spec/localizer_spec.rb +39 -17
  141. data/spec/namespaced_class_finder_spec.rb +79 -0
  142. data/spec/schema.rb +21 -0
  143. data/spec/spec_helper.rb +254 -221
  144. data/spec/support/custom_macros.rb +128 -95
  145. data/spec/support/shared_examples.rb +12 -0
  146. data/spec/support/specialized_class_finder_shared_example.rb +27 -0
  147. data/spec/support/test_environment.rb +26 -10
  148. metadata +177 -238
  149. data/.travis.yml +0 -8
  150. data/Appraisals +0 -11
  151. data/CHANGELOG +0 -371
  152. data/gemfiles/rails-3.0.gemfile +0 -7
  153. data/gemfiles/rails-3.1.gemfile +0 -7
  154. data/gemfiles/rails-3.2.gemfile +0 -7
  155. data/lib/formtastic/helpers/buttons_helper.rb +0 -310
  156. data/lib/formtastic/inputs/base/grouped_collections.rb +0 -77
  157. data/lib/formtastic/util.rb +0 -25
  158. data/lib/tasks/verify_rcov.rb +0 -44
  159. data/spec/helpers/buttons_helper_spec.rb +0 -166
  160. data/spec/helpers/commit_button_helper_spec.rb +0 -530
  161. data/spec/inputs/date_input_spec.rb +0 -227
  162. data/spec/inputs/datetime_input_spec.rb +0 -185
  163. data/spec/inputs/time_input_spec.rb +0 -267
  164. data/spec/support/deferred_garbage_collection.rb +0 -21
@@ -10,104 +10,122 @@ module CustomMacros
10
10
 
11
11
  def it_should_have_input_wrapper_with_class(class_name)
12
12
  it "should have input wrapper with class '#{class_name}'" do
13
- output_buffer.should have_tag("form li.#{class_name}")
13
+ expect(output_buffer).to have_tag("form li.#{class_name}")
14
14
  end
15
15
  end
16
16
 
17
17
  def it_should_have_input_wrapper_with_id(id_string)
18
18
  it "should have input wrapper with id '#{id_string}'" do
19
- output_buffer.should have_tag("form li##{id_string}")
19
+ expect(output_buffer).to have_tag("form li##{id_string}")
20
20
  end
21
21
  end
22
22
 
23
23
  def it_should_not_have_a_label
24
24
  it "should not have a label" do
25
- output_buffer.should_not have_tag("form li label")
25
+ expect(output_buffer).not_to have_tag("form li label")
26
26
  end
27
27
  end
28
28
 
29
29
  def it_should_have_a_nested_fieldset
30
30
  it "should have a nested_fieldset" do
31
- output_buffer.should have_tag("form li fieldset")
31
+ expect(output_buffer).to have_tag("form li fieldset")
32
32
  end
33
33
  end
34
-
34
+
35
35
  def it_should_have_a_nested_fieldset_with_class(klass)
36
36
  it "should have a nested_fieldset with class #{klass}" do
37
- output_buffer.should have_tag("form li fieldset.#{klass}")
37
+ expect(output_buffer).to have_tag("form li fieldset.#{klass}")
38
38
  end
39
39
  end
40
-
40
+
41
41
  def it_should_have_a_nested_ordered_list_with_class(klass)
42
42
  it "should have a nested fieldset with class #{klass}" do
43
- output_buffer.should have_tag("form li ol.#{klass}")
43
+ expect(output_buffer).to have_tag("form li ol.#{klass}")
44
44
  end
45
45
  end
46
46
 
47
47
  def it_should_have_label_with_text(string_or_regex)
48
48
  it "should have a label with text '#{string_or_regex}'" do
49
- output_buffer.should have_tag("form li label", string_or_regex)
49
+ expect(output_buffer).to have_tag("form li label", :text => string_or_regex)
50
50
  end
51
51
  end
52
52
 
53
53
  def it_should_have_label_for(element_id)
54
54
  it "should have a label for ##{element_id}" do
55
- output_buffer.should have_tag("form li label.label[@for='#{element_id}']")
55
+ expect(output_buffer).to have_tag("form li label.label[@for='#{element_id}']")
56
56
  end
57
57
  end
58
-
58
+
59
59
  def it_should_have_an_inline_label_for(element_id)
60
60
  it "should have a label for ##{element_id}" do
61
- output_buffer.should have_tag("form li label[@for='#{element_id}']")
61
+ expect(output_buffer).to have_tag("form li label[@for='#{element_id}']")
62
62
  end
63
63
  end
64
64
 
65
65
  def it_should_have_input_with_id(element_id)
66
66
  it "should have an input with id '#{element_id}'" do
67
- output_buffer.should have_tag("form li input##{element_id}")
67
+ expect(output_buffer).to have_tag("form li input##{element_id}")
68
68
  end
69
69
  end
70
70
 
71
71
  def it_should_have_select_with_id(element_id)
72
72
  it "should have a select box with id '#{element_id}'" do
73
- output_buffer.should have_tag("form li select##{element_id}")
73
+ expect(output_buffer).to have_tag("form li select##{element_id}")
74
+ end
75
+ end
76
+
77
+ # TODO use for many of the other macros
78
+ def it_should_have_tag_with(type, attribute_value_hash)
79
+ attribute_value_hash.each do |attribute, value|
80
+ it "should have a #{type} box with #{attribute} '#{value}'" do
81
+ expect(output_buffer).to have_tag("form li #{type}[@#{attribute}=\"#{value}\"]")
82
+ end
83
+ end
84
+ end
85
+ def it_should_have_input_with(attribute_value_hash)
86
+ it_should_have_tag_with(:input, attribute_value_hash)
87
+ end
88
+
89
+ def it_should_have_many_tags(type, count)
90
+ it "should have #{count} #{type} tags" do
91
+ expect(output_buffer).to have_tag("form li #{type}", count: count)
74
92
  end
75
93
  end
76
94
 
77
95
  def it_should_have_input_with_type(input_type)
78
96
  it "should have a #{input_type} input" do
79
- output_buffer.should have_tag("form li input[@type=\"#{input_type}\"]")
97
+ expect(output_buffer).to have_tag("form li input[@type=\"#{input_type}\"]")
80
98
  end
81
99
  end
82
100
 
83
101
  def it_should_have_input_with_name(name)
84
102
  it "should have an input named #{name}" do
85
- output_buffer.should have_tag("form li input[@name=\"#{name}\"]")
103
+ expect(output_buffer).to have_tag("form li input[@name=\"#{name}\"]")
86
104
  end
87
105
  end
88
106
 
89
107
  def it_should_have_select_with_name(name)
90
108
  it "should have an input named #{name}" do
91
- output_buffer.should have_tag("form li select[@name=\"#{name}\"]")
109
+ expect(output_buffer).to have_tag("form li select[@name=\"#{name}\"]")
92
110
  end
93
111
  end
94
112
 
95
113
  def it_should_have_textarea_with_name(name)
96
114
  it "should have an input named #{name}" do
97
- output_buffer.should have_tag("form li textarea[@name=\"#{name}\"]")
115
+ expect(output_buffer).to have_tag("form li textarea[@name=\"#{name}\"]")
98
116
  end
99
117
  end
100
118
 
101
119
  def it_should_have_textarea_with_id(element_id)
102
120
  it "should have an input with id '#{element_id}'" do
103
- output_buffer.should have_tag("form li textarea##{element_id}")
121
+ expect(output_buffer).to have_tag("form li textarea##{element_id}")
104
122
  end
105
123
  end
106
124
 
107
125
  def it_should_have_label_and_input_with_id(element_id)
108
126
  it "should have an input with id '#{element_id}'" do
109
- output_buffer.should have_tag("form li input##{element_id}")
110
- output_buffer.should have_tag("form li label[@for='#{element_id}']")
127
+ expect(output_buffer).to have_tag("form li input##{element_id}")
128
+ expect(output_buffer).to have_tag("form li label[@for='#{element_id}']")
111
129
  end
112
130
  end
113
131
 
@@ -117,7 +135,7 @@ module CustomMacros
117
135
  concat(semantic_form_for(@new_post) do |builder|
118
136
  concat(builder.input(:title, :as => as))
119
137
  end)
120
- output_buffer.should have_tag("form li input[@size='#{Formtastic::FormBuilder.default_text_field_size}']")
138
+ expect(output_buffer).to have_tag("form li input[@size='#{Formtastic::FormBuilder.default_text_field_size}']")
121
139
  end
122
140
  end
123
141
  end
@@ -128,8 +146,8 @@ module CustomMacros
128
146
  concat(semantic_form_for(@new_post) do |builder|
129
147
  concat(builder.input(:title, :as => as))
130
148
  end)
131
- output_buffer.should have_tag("form li input")
132
- output_buffer.should_not have_tag("form li input[@size]")
149
+ expect(output_buffer).to have_tag("form li input")
150
+ expect(output_buffer).not_to have_tag("form li input[@size]")
133
151
  end
134
152
  end
135
153
  end
@@ -139,7 +157,7 @@ module CustomMacros
139
157
  concat(semantic_form_for(@new_post) do |builder|
140
158
  concat(builder.input(:title, :as => as, :input_html => { :class => 'myclass' }))
141
159
  end)
142
- output_buffer.should have_tag("form li input.myclass")
160
+ expect(output_buffer).to have_tag("form li input.myclass")
143
161
  end
144
162
  end
145
163
 
@@ -148,27 +166,28 @@ module CustomMacros
148
166
  concat(semantic_form_for(@new_post) do |builder|
149
167
  concat(builder.input(:title, :as => as, :input_html => { :id => 'myid' }))
150
168
  end)
151
- output_buffer.should have_tag('form li label[@for="myid"]')
169
+ expect(output_buffer).to have_tag('form li label[@for="myid"]')
152
170
  end
153
171
  end
154
172
 
155
173
  def it_should_have_maxlength_matching_column_limit
156
174
  it 'should have a maxlength matching column limit' do
157
- @new_post.column_for_attribute(:title).limit.should == 50
158
- output_buffer.should have_tag("form li input[@maxlength='50']")
175
+ expect(@new_post.column_for_attribute(:title).limit).to eq(50)
176
+ expect(output_buffer).to have_tag("form li input[@maxlength='50']")
159
177
  end
160
178
  end
161
179
 
162
180
  def it_should_use_column_size_for_columns_shorter_than_default_text_field_size(as)
163
181
  it 'should use the column size for columns shorter than default_text_field_size' do
164
182
  column_limit_shorted_than_default = 1
165
- @new_post.stub!(:column_for_attribute).and_return(mock('column', :type => as, :limit => column_limit_shorted_than_default))
183
+ allow(@new_post).to receive(:column_for_attribute)
184
+ .and_return(double('column', :type => as, :limit => column_limit_shorted_than_default))
166
185
 
167
186
  concat(semantic_form_for(@new_post) do |builder|
168
187
  concat(builder.input(:title, :as => as))
169
188
  end)
170
189
 
171
- output_buffer.should have_tag("form li input[@size='#{column_limit_shorted_than_default}']")
190
+ expect(output_buffer).to have_tag("form li input[@size='#{column_limit_shorted_than_default}']")
172
191
  end
173
192
  end
174
193
 
@@ -176,26 +195,26 @@ module CustomMacros
176
195
  describe 'when there are errors on the object for this method' do
177
196
  before do
178
197
  @title_errors = ['must not be blank', 'must be longer than 10 characters', 'must be awesome']
179
- @errors = mock('errors')
180
- @errors.stub!(:[]).with(:title).and_return(@title_errors)
198
+ @errors = double('errors')
199
+ allow(@errors).to receive(:[]).with(errors_matcher(:title)).and_return(@title_errors)
181
200
  Formtastic::FormBuilder.file_metadata_suffixes.each do |suffix|
182
- @errors.stub!(:[]).with("title_#{suffix}".to_sym).and_return(nil)
201
+ allow(@errors).to receive(:[]).with(errors_matcher("title_#{suffix}".to_sym)).and_return(nil)
183
202
  end
184
- @new_post.stub!(:errors).and_return(@errors)
203
+ allow(@new_post).to receive(:errors).and_return(@errors)
185
204
  end
186
205
 
187
206
  it 'should apply an errors class to the list item' do
188
207
  concat(semantic_form_for(@new_post) do |builder|
189
208
  concat(builder.input(:title, :as => type))
190
209
  end)
191
- output_buffer.should have_tag('form li.error')
210
+ expect(output_buffer).to have_tag('form li.error')
192
211
  end
193
212
 
194
213
  it 'should not wrap the input with the Rails default error wrapping' do
195
214
  concat(semantic_form_for(@new_post) do |builder|
196
215
  concat(builder.input(:title, :as => type))
197
216
  end)
198
- output_buffer.should_not have_tag('div.fieldWithErrors')
217
+ expect(output_buffer).not_to have_tag('div.fieldWithErrors')
199
218
  end
200
219
 
201
220
  it 'should render a paragraph for the errors' do
@@ -203,7 +222,7 @@ module CustomMacros
203
222
  concat(semantic_form_for(@new_post) do |builder|
204
223
  concat(builder.input(:title, :as => type))
205
224
  end)
206
- output_buffer.should have_tag('form li.error p.inline-errors')
225
+ expect(output_buffer).to have_tag('form li.error p.inline-errors')
207
226
  end
208
227
 
209
228
  it 'should not display an error list' do
@@ -211,7 +230,7 @@ module CustomMacros
211
230
  concat(semantic_form_for(@new_post) do |builder|
212
231
  concat(builder.input(:title, :as => type))
213
232
  end)
214
- output_buffer.should have_tag('form li.error ul.errors')
233
+ expect(output_buffer).to have_tag('form li.error ul.errors')
215
234
  end
216
235
  end
217
236
 
@@ -223,15 +242,15 @@ module CustomMacros
223
242
  end
224
243
 
225
244
  it 'should not apply an errors class to the list item' do
226
- output_buffer.should_not have_tag('form li.error')
245
+ expect(output_buffer).not_to have_tag('form li.error')
227
246
  end
228
247
 
229
248
  it 'should not render a paragraph for the errors' do
230
- output_buffer.should_not have_tag('form li.error p.inline-errors')
249
+ expect(output_buffer).not_to have_tag('form li.error p.inline-errors')
231
250
  end
232
251
 
233
252
  it 'should not display an error list' do
234
- output_buffer.should_not have_tag('form li.error ul.errors')
253
+ expect(output_buffer).not_to have_tag('form li.error ul.errors')
235
254
  end
236
255
  end
237
256
 
@@ -243,22 +262,22 @@ module CustomMacros
243
262
  end
244
263
 
245
264
  it 'should not apply an errors class to the list item' do
246
- output_buffer.should_not have_tag('form li.error')
265
+ expect(output_buffer).not_to have_tag('form li.error')
247
266
  end
248
267
 
249
268
  it 'should not render a paragraph for the errors' do
250
- output_buffer.should_not have_tag('form li.error p.inline-errors')
269
+ expect(output_buffer).not_to have_tag('form li.error p.inline-errors')
251
270
  end
252
271
 
253
272
  it 'should not display an error list' do
254
- output_buffer.should_not have_tag('form li.error ul.errors')
273
+ expect(output_buffer).not_to have_tag('form li.error ul.errors')
255
274
  end
256
275
  end
257
276
  end
258
277
 
259
278
  def it_should_call_find_on_association_class_when_no_collection_is_provided(as)
260
279
  it "should call find on the association class when no collection is provided" do
261
- ::Author.should_receive(:where)
280
+ expect(::Author).to receive(:where)
262
281
  concat(semantic_form_for(@new_post) do |builder|
263
282
  concat(builder.input(:author, :as => as))
264
283
  end)
@@ -269,7 +288,7 @@ module CustomMacros
269
288
  describe 'when the :collection option is provided' do
270
289
 
271
290
  before do
272
- @authors = ::Author.all * 2
291
+ @authors = ([::Author.all] * 2).flatten
273
292
  output_buffer.replace ''
274
293
  end
275
294
 
@@ -277,7 +296,7 @@ module CustomMacros
277
296
  concat(semantic_form_for(@new_post) do |builder|
278
297
  concat(builder.input(:author, :as => as, :collection => @authors))
279
298
  end)
280
- output_buffer.should have_tag("form li.#{as} #{countable}", :count => @authors.size + (as == :select ? 1 : 0))
299
+ expect(output_buffer).to have_tag("form li.#{as} #{countable}", :count => @authors.size + (as == :select ? 1 : 0))
281
300
  end
282
301
 
283
302
  describe 'and the :collection is an array of strings' do
@@ -291,24 +310,24 @@ module CustomMacros
291
310
  end)
292
311
 
293
312
  @categories.each do |value|
294
- output_buffer.should have_tag("form li.#{as}", /#{value}/)
295
- output_buffer.should have_tag("form li.#{as} #{countable}[@value='#{value}']")
313
+ expect(output_buffer).to have_tag("form li.#{as}", :text => /#{value}/)
314
+ expect(output_buffer).to have_tag("form li.#{as} #{countable}[@value='#{value}']")
296
315
  end
297
316
  end
298
317
 
299
318
  if as == :radio
300
319
  it 'should generate a sanitized label for attribute' do
301
- @bob.stub!(:category_name).and_return(@categories)
320
+ allow(@bob).to receive(:category_name).and_return(@categories)
302
321
  concat(semantic_form_for(@new_post) do |builder|
303
322
  fields = builder.semantic_fields_for(@bob) do |bob_builder|
304
323
  concat(bob_builder.input(:category_name, :as => as, :collection => @categories))
305
324
  end
306
325
  concat(fields)
307
326
  end)
308
- output_buffer.should have_tag("form li fieldset ol li label[@for='post_author_category_name_general']")
309
- output_buffer.should have_tag("form li fieldset ol li label[@for='post_author_category_name_design']")
310
- output_buffer.should have_tag("form li fieldset ol li label[@for='post_author_category_name_development']")
311
- output_buffer.should have_tag("form li fieldset ol li label[@for='post_author_category_name_quasi-serious_inventions']")
327
+ expect(output_buffer).to have_tag("form li fieldset ol li label[@for='post_author_category_name_general']")
328
+ expect(output_buffer).to have_tag("form li fieldset ol li label[@for='post_author_category_name_design']")
329
+ expect(output_buffer).to have_tag("form li fieldset ol li label[@for='post_author_category_name_development']")
330
+ expect(output_buffer).to have_tag("form li fieldset ol li label[@for='post_author_category_name_quasi-serious_inventions']")
312
331
  end
313
332
  end
314
333
  end
@@ -324,8 +343,8 @@ module CustomMacros
324
343
  end)
325
344
 
326
345
  @categories.each do |label, value|
327
- output_buffer.should have_tag("form li.#{as}", /#{label}/)
328
- output_buffer.should have_tag("form li.#{as} #{countable}[@value='#{value}']")
346
+ expect(output_buffer).to have_tag("form li.#{as}", :text => /#{label}/)
347
+ expect(output_buffer).to have_tag("form li.#{as} #{countable}[@value='#{value}']")
329
348
  end
330
349
  end
331
350
  end
@@ -342,9 +361,9 @@ module CustomMacros
342
361
 
343
362
  @categories.each do |text, value|
344
363
  label = as == :select ? :option : :label
345
- output_buffer.should have_tag("form li.#{as} #{label}", /#{text}/i)
346
- output_buffer.should have_tag("form li.#{as} #{countable}[@value='#{value.to_s}']")
347
- output_buffer.should have_tag("form li.#{as} #{countable}#post_category_name_#{value.to_s}") if as == :radio
364
+ expect(output_buffer).to have_tag("form li.#{as} #{label}", :text => /#{text}/i)
365
+ expect(output_buffer).to have_tag("form li.#{as} #{countable}[@value='#{value.to_s}']")
366
+ expect(output_buffer).to have_tag("form li.#{as} #{countable}#post_category_name_#{value.to_s}") if as == :radio
348
367
  end
349
368
  end
350
369
  end
@@ -360,8 +379,8 @@ module CustomMacros
360
379
  concat(builder.input(:category_name, :as => as, :collection => @choices))
361
380
  end)
362
381
 
363
- output_buffer.should have_tag("form li.#{as} #{countable}#post_category_name_true")
364
- output_buffer.should have_tag("form li.#{as} #{countable}#post_category_name_false")
382
+ expect(output_buffer).to have_tag("form li.#{as} #{countable}#post_category_name_true")
383
+ expect(output_buffer).to have_tag("form li.#{as} #{countable}#post_category_name_false")
365
384
  end
366
385
  end
367
386
  end
@@ -378,8 +397,8 @@ module CustomMacros
378
397
 
379
398
  @categories.each do |value|
380
399
  label = as == :select ? :option : :label
381
- output_buffer.should have_tag("form li.#{as} #{label}", /#{value}/i)
382
- output_buffer.should have_tag("form li.#{as} #{countable}[@value='#{value.to_s}']")
400
+ expect(output_buffer).to have_tag("form li.#{as} #{label}", :text => /#{value}/i)
401
+ expect(output_buffer).to have_tag("form li.#{as} #{countable}[@value='#{value.to_s}']")
383
402
  end
384
403
  end
385
404
  end
@@ -395,8 +414,8 @@ module CustomMacros
395
414
  end)
396
415
 
397
416
  @categories.each do |label, value|
398
- output_buffer.should have_tag("form li.#{as}", /#{label}/)
399
- output_buffer.should have_tag("form li.#{as} #{countable}[@value='#{value}']")
417
+ expect(output_buffer).to have_tag("form li.#{as}", :text => /#{label}/)
418
+ expect(output_buffer).to have_tag("form li.#{as} #{countable}[@value='#{value}']")
400
419
  end
401
420
  end
402
421
 
@@ -406,28 +425,32 @@ module CustomMacros
406
425
 
407
426
  describe 'as a symbol' do
408
427
  before do
409
- concat(semantic_form_for(@new_post) do |builder|
410
- concat(builder.input(:author, :as => as, :member_label => :login))
411
- end)
428
+ with_deprecation_silenced do
429
+ concat(semantic_form_for(@new_post) do |builder|
430
+ concat(builder.input(:author, :as => as, :member_label => :login))
431
+ end)
432
+ end
412
433
  end
413
434
 
414
435
  it 'should have options with text content from the specified method' do
415
436
  ::Author.all.each do |author|
416
- output_buffer.should have_tag("form li.#{as}", /#{author.login}/)
437
+ expect(output_buffer).to have_tag("form li.#{as}", :text => /#{author.login}/)
417
438
  end
418
439
  end
419
440
  end
420
441
 
421
442
  describe 'as a proc' do
422
443
  before do
423
- concat(semantic_form_for(@new_post) do |builder|
424
- concat(builder.input(:author, :as => as, :member_label => Proc.new {|a| a.login.reverse }))
425
- end)
444
+ with_deprecation_silenced do
445
+ concat(semantic_form_for(@new_post) do |builder|
446
+ concat(builder.input(:author, :as => as, :member_label => Proc.new {|a| a.login.reverse }))
447
+ end)
448
+ end
426
449
  end
427
450
 
428
451
  it 'should have options with the proc applied to each' do
429
452
  ::Author.all.each do |author|
430
- output_buffer.should have_tag("form li.#{as}", /#{author.login.reverse}/)
453
+ expect(output_buffer).to have_tag("form li.#{as}", :text => /#{author.login.reverse}/)
431
454
  end
432
455
  end
433
456
  end
@@ -437,14 +460,16 @@ module CustomMacros
437
460
  def reverse_login(a)
438
461
  a.login.reverse
439
462
  end
440
- concat(semantic_form_for(@new_post) do |builder|
441
- concat(builder.input(:author, :as => as, :member_label => method(:reverse_login)))
442
- end)
463
+ with_deprecation_silenced do
464
+ concat(semantic_form_for(@new_post) do |builder|
465
+ concat(builder.input(:author, :as => as, :member_label => method(:reverse_login)))
466
+ end)
467
+ end
443
468
  end
444
469
 
445
470
  it 'should have options with the proc applied to each' do
446
471
  ::Author.all.each do |author|
447
- output_buffer.should have_tag("form li.#{as}", /#{author.login.reverse}/)
472
+ expect(output_buffer).to have_tag("form li.#{as}", :text => /#{author.login.reverse}/)
448
473
  end
449
474
  end
450
475
  end
@@ -455,17 +480,19 @@ module CustomMacros
455
480
 
456
481
  describe "when the collection objects respond to #{label_method}" do
457
482
  before do
458
- @fred.stub!(:respond_to?).and_return { |m| m.to_s == label_method || m.to_s == 'id' }
459
- ::Author.all.each { |a| a.stub!(label_method).and_return('The Label Text') }
483
+ allow(@fred).to receive(:respond_to?) { |m| m.to_s == label_method || m.to_s == 'id' }
484
+ [@fred, @bob].each { |a| allow(a).to receive(label_method).and_return('The Label Text') }
460
485
 
461
- concat(semantic_form_for(@new_post) do |builder|
462
- concat(builder.input(:author, :as => as))
463
- end)
486
+ with_deprecation_silenced do
487
+ concat(semantic_form_for(@new_post) do |builder|
488
+ concat(builder.input(:author, :as => as))
489
+ end)
490
+ end
464
491
  end
465
492
 
466
493
  it "should render the options with #{label_method} as the label" do
467
494
  ::Author.all.each do |author|
468
- output_buffer.should have_tag("form li.#{as}", /The Label Text/)
495
+ expect(output_buffer).to have_tag("form li.#{as}", :text => /The Label Text/)
469
496
  end
470
497
  end
471
498
  end
@@ -477,28 +504,32 @@ module CustomMacros
477
504
 
478
505
  describe 'as a symbol' do
479
506
  before do
480
- concat(semantic_form_for(@new_post) do |builder|
481
- concat(builder.input(:author, :as => as, :member_value => :login))
482
- end)
507
+ with_deprecation_silenced do
508
+ concat(semantic_form_for(@new_post) do |builder|
509
+ concat(builder.input(:author, :as => as, :member_value => :login))
510
+ end)
511
+ end
483
512
  end
484
513
 
485
514
  it 'should have options with values from specified method' do
486
515
  ::Author.all.each do |author|
487
- output_buffer.should have_tag("form li.#{as} #{countable}[@value='#{author.login}']")
516
+ expect(output_buffer).to have_tag("form li.#{as} #{countable}[@value='#{author.login}']")
488
517
  end
489
518
  end
490
519
  end
491
520
 
492
521
  describe 'as a proc' do
493
522
  before do
494
- concat(semantic_form_for(@new_post) do |builder|
495
- concat(builder.input(:author, :as => as, :member_value => Proc.new {|a| a.login.reverse }))
496
- end)
523
+ with_deprecation_silenced do
524
+ concat(semantic_form_for(@new_post) do |builder|
525
+ concat(builder.input(:author, :as => as, :member_value => Proc.new {|a| a.login.reverse }))
526
+ end)
527
+ end
497
528
  end
498
529
 
499
530
  it 'should have options with the proc applied to each value' do
500
531
  ::Author.all.each do |author|
501
- output_buffer.should have_tag("form li.#{as} #{countable}[@value='#{author.login.reverse}']")
532
+ expect(output_buffer).to have_tag("form li.#{as} #{countable}[@value='#{author.login.reverse}']")
502
533
  end
503
534
  end
504
535
  end
@@ -508,14 +539,16 @@ module CustomMacros
508
539
  def reverse_login(a)
509
540
  a.login.reverse
510
541
  end
511
- concat(semantic_form_for(@new_post) do |builder|
512
- concat(builder.input(:author, :as => as, :member_value => method(:reverse_login)))
513
- end)
542
+ with_deprecation_silenced do
543
+ concat(semantic_form_for(@new_post) do |builder|
544
+ concat(builder.input(:author, :as => as, :member_value => method(:reverse_login)))
545
+ end)
546
+ end
514
547
  end
515
548
 
516
549
  it 'should have options with the proc applied to each value' do
517
550
  ::Author.all.each do |author|
518
- output_buffer.should have_tag("form li.#{as} #{countable}[@value='#{author.login.reverse}']")
551
+ expect(output_buffer).to have_tag("form li.#{as} #{countable}[@value='#{author.login.reverse}']")
519
552
  end
520
553
  end
521
554
  end
@@ -0,0 +1,12 @@
1
+ RSpec.shared_context 'form builder' do
2
+ include FormtasticSpecHelper
3
+
4
+ before do
5
+ @output_buffer = ''
6
+ mock_everything
7
+ end
8
+
9
+ after do
10
+ ::I18n.backend.reload!
11
+ end
12
+ end
@@ -0,0 +1,27 @@
1
+ # encoding: utf-8
2
+ #
3
+ RSpec.shared_examples 'Specialized Class Finder' do
4
+ let(:builder) { Formtastic::FormBuilder.allocate }
5
+ subject(:finder) { described_class.new(builder) }
6
+
7
+ context 'by default' do
8
+ it 'includes Object and the default namespaces' do
9
+ expect(finder.namespaces).to eq([Object, default])
10
+ end
11
+ end
12
+
13
+ context 'with namespace configuration set to a custom list of modules' do
14
+ before do
15
+ stub_const('CustomModule', Module.new)
16
+ stub_const('AnotherModule', Module.new)
17
+
18
+ allow(Formtastic::FormBuilder).to receive(namespaces_setting)
19
+ .and_return([ CustomModule, AnotherModule ])
20
+ end
21
+
22
+ it 'includes just the custom namespaces' do
23
+ expect(finder.namespaces).to eq([CustomModule, AnotherModule])
24
+ end
25
+ end
26
+
27
+ end
@@ -1,11 +1,32 @@
1
1
  # encoding: utf-8
2
- require 'rspec'
3
- require 'rspec_tag_matchers'
2
+ require 'rspec/core'
3
+
4
+ require 'rspec-dom-testing'
4
5
 
5
6
  RSpec.configure do |config|
6
- config.include RspecTagMatchers
7
7
  config.include CustomMacros
8
+ config.include RSpec::Dom::Testing::Matchers
8
9
  config.mock_with :rspec
10
+
11
+ # rspec-rails 3 will no longer automatically infer an example group's spec type
12
+ # from the file location. You can explicitly opt-in to the feature using this
13
+ # config option.
14
+ # To explicitly tag specs without using automatic inference, set the `:type`
15
+ # metadata manually:
16
+ #
17
+ # describe ThingsController, :type => :controller do
18
+ # # Equivalent to being in spec/controllers
19
+ # end
20
+ config.infer_spec_type_from_file_location!
21
+
22
+ # Setting this config option `false` removes rspec-core's monkey patching of the
23
+ # top level methods like `describe`, `shared_examples_for` and `shared_context`
24
+ # on `main` and `Module`. The methods are always available through the `RSpec`
25
+ # module like `RSpec.describe` regardless of this setting.
26
+ # For backwards compatibility this defaults to `true`.
27
+ #
28
+ # https://relishapp.com/rspec/rspec-core/v/3-0/docs/configuration/global-namespace-dsl
29
+ config.expose_dsl_globally = false
9
30
  end
10
31
 
11
32
  require "action_controller/railtie"
@@ -14,16 +35,11 @@ require 'active_model'
14
35
  # Create a simple rails application for use in testing the viewhelper
15
36
  module FormtasticTest
16
37
  class Application < Rails::Application
17
- # Configure the default encoding used in templates for Ruby 1.9.
18
- config.encoding = "utf-8"
19
38
  config.active_support.deprecation = :stderr
39
+ config.secret_key_base = "secret"
40
+ config.eager_load = false
20
41
  end
21
42
  end
22
43
  FormtasticTest::Application.initialize!
23
44
 
24
45
  require 'rspec/rails'
25
-
26
- # Quick hack to avoid the 'Spec' deprecation warnings from rspec_tag_matchers
27
- module Spec
28
- include RSpec
29
- end