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,4 +1,5 @@
1
1
  # encoding: utf-8
2
+ # frozen_string_literal: true
2
3
 
3
4
  module CustomMacros
4
5
 
@@ -10,104 +11,122 @@ module CustomMacros
10
11
 
11
12
  def it_should_have_input_wrapper_with_class(class_name)
12
13
  it "should have input wrapper with class '#{class_name}'" do
13
- output_buffer.should have_tag("form li.#{class_name}")
14
+ expect(output_buffer.to_str).to have_tag("form li.#{class_name}")
14
15
  end
15
16
  end
16
17
 
17
18
  def it_should_have_input_wrapper_with_id(id_string)
18
19
  it "should have input wrapper with id '#{id_string}'" do
19
- output_buffer.should have_tag("form li##{id_string}")
20
+ expect(output_buffer.to_str).to have_tag("form li##{id_string}")
20
21
  end
21
22
  end
22
23
 
23
24
  def it_should_not_have_a_label
24
25
  it "should not have a label" do
25
- output_buffer.should_not have_tag("form li label")
26
+ expect(output_buffer.to_str).not_to have_tag("form li label")
26
27
  end
27
28
  end
28
29
 
29
30
  def it_should_have_a_nested_fieldset
30
31
  it "should have a nested_fieldset" do
31
- output_buffer.should have_tag("form li fieldset")
32
+ expect(output_buffer.to_str).to have_tag("form li fieldset")
32
33
  end
33
34
  end
34
-
35
+
35
36
  def it_should_have_a_nested_fieldset_with_class(klass)
36
37
  it "should have a nested_fieldset with class #{klass}" do
37
- output_buffer.should have_tag("form li fieldset.#{klass}")
38
+ expect(output_buffer.to_str).to have_tag("form li fieldset.#{klass}")
38
39
  end
39
40
  end
40
-
41
+
41
42
  def it_should_have_a_nested_ordered_list_with_class(klass)
42
43
  it "should have a nested fieldset with class #{klass}" do
43
- output_buffer.should have_tag("form li ol.#{klass}")
44
+ expect(output_buffer.to_str).to have_tag("form li ol.#{klass}")
44
45
  end
45
46
  end
46
47
 
47
48
  def it_should_have_label_with_text(string_or_regex)
48
49
  it "should have a label with text '#{string_or_regex}'" do
49
- output_buffer.should have_tag("form li label", string_or_regex)
50
+ expect(output_buffer.to_str).to have_tag("form li label", :text => string_or_regex)
50
51
  end
51
52
  end
52
53
 
53
54
  def it_should_have_label_for(element_id)
54
55
  it "should have a label for ##{element_id}" do
55
- output_buffer.should have_tag("form li label.label[@for='#{element_id}']")
56
+ expect(output_buffer.to_str).to have_tag("form li label.label[@for='#{element_id}']")
56
57
  end
57
58
  end
58
-
59
+
59
60
  def it_should_have_an_inline_label_for(element_id)
60
61
  it "should have a label for ##{element_id}" do
61
- output_buffer.should have_tag("form li label[@for='#{element_id}']")
62
+ expect(output_buffer.to_str).to have_tag("form li label[@for='#{element_id}']")
62
63
  end
63
64
  end
64
65
 
65
66
  def it_should_have_input_with_id(element_id)
66
67
  it "should have an input with id '#{element_id}'" do
67
- output_buffer.should have_tag("form li input##{element_id}")
68
+ expect(output_buffer.to_str).to have_tag("form li input##{element_id}")
68
69
  end
69
70
  end
70
71
 
71
72
  def it_should_have_select_with_id(element_id)
72
73
  it "should have a select box with id '#{element_id}'" do
73
- output_buffer.should have_tag("form li select##{element_id}")
74
+ expect(output_buffer.to_str).to have_tag("form li select##{element_id}")
75
+ end
76
+ end
77
+
78
+ # TODO use for many of the other macros
79
+ def it_should_have_tag_with(type, attribute_value_hash)
80
+ attribute_value_hash.each do |attribute, value|
81
+ it "should have a #{type} box with #{attribute} '#{value}'" do
82
+ expect(output_buffer.to_str).to have_tag("form li #{type}[@#{attribute}=\"#{value}\"]")
83
+ end
84
+ end
85
+ end
86
+ def it_should_have_input_with(attribute_value_hash)
87
+ it_should_have_tag_with(:input, attribute_value_hash)
88
+ end
89
+
90
+ def it_should_have_many_tags(type, count)
91
+ it "should have #{count} #{type} tags" do
92
+ expect(output_buffer.to_str).to have_tag("form li #{type}", count: count)
74
93
  end
75
94
  end
76
95
 
77
96
  def it_should_have_input_with_type(input_type)
78
97
  it "should have a #{input_type} input" do
79
- output_buffer.should have_tag("form li input[@type=\"#{input_type}\"]")
98
+ expect(output_buffer.to_str).to have_tag("form li input[@type=\"#{input_type}\"]")
80
99
  end
81
100
  end
82
101
 
83
102
  def it_should_have_input_with_name(name)
84
103
  it "should have an input named #{name}" do
85
- output_buffer.should have_tag("form li input[@name=\"#{name}\"]")
104
+ expect(output_buffer.to_str).to have_tag("form li input[@name=\"#{name}\"]")
86
105
  end
87
106
  end
88
107
 
89
108
  def it_should_have_select_with_name(name)
90
109
  it "should have an input named #{name}" do
91
- output_buffer.should have_tag("form li select[@name=\"#{name}\"]")
110
+ expect(output_buffer.to_str).to have_tag("form li select[@name=\"#{name}\"]")
92
111
  end
93
112
  end
94
113
 
95
114
  def it_should_have_textarea_with_name(name)
96
115
  it "should have an input named #{name}" do
97
- output_buffer.should have_tag("form li textarea[@name=\"#{name}\"]")
116
+ expect(output_buffer.to_str).to have_tag("form li textarea[@name=\"#{name}\"]")
98
117
  end
99
118
  end
100
119
 
101
120
  def it_should_have_textarea_with_id(element_id)
102
121
  it "should have an input with id '#{element_id}'" do
103
- output_buffer.should have_tag("form li textarea##{element_id}")
122
+ expect(output_buffer.to_str).to have_tag("form li textarea##{element_id}")
104
123
  end
105
124
  end
106
125
 
107
126
  def it_should_have_label_and_input_with_id(element_id)
108
127
  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}']")
128
+ expect(output_buffer.to_str).to have_tag("form li input##{element_id}")
129
+ expect(output_buffer.to_str).to have_tag("form li label[@for='#{element_id}']")
111
130
  end
112
131
  end
113
132
 
@@ -117,7 +136,7 @@ module CustomMacros
117
136
  concat(semantic_form_for(@new_post) do |builder|
118
137
  concat(builder.input(:title, :as => as))
119
138
  end)
120
- output_buffer.should have_tag("form li input[@size='#{Formtastic::FormBuilder.default_text_field_size}']")
139
+ expect(output_buffer.to_str).to have_tag("form li input[@size='#{Formtastic::FormBuilder.default_text_field_size}']")
121
140
  end
122
141
  end
123
142
  end
@@ -128,8 +147,8 @@ module CustomMacros
128
147
  concat(semantic_form_for(@new_post) do |builder|
129
148
  concat(builder.input(:title, :as => as))
130
149
  end)
131
- output_buffer.should have_tag("form li input")
132
- output_buffer.should_not have_tag("form li input[@size]")
150
+ expect(output_buffer.to_str).to have_tag("form li input")
151
+ expect(output_buffer.to_str).not_to have_tag("form li input[@size]")
133
152
  end
134
153
  end
135
154
  end
@@ -139,7 +158,7 @@ module CustomMacros
139
158
  concat(semantic_form_for(@new_post) do |builder|
140
159
  concat(builder.input(:title, :as => as, :input_html => { :class => 'myclass' }))
141
160
  end)
142
- output_buffer.should have_tag("form li input.myclass")
161
+ expect(output_buffer.to_str).to have_tag("form li input.myclass")
143
162
  end
144
163
  end
145
164
 
@@ -148,27 +167,28 @@ module CustomMacros
148
167
  concat(semantic_form_for(@new_post) do |builder|
149
168
  concat(builder.input(:title, :as => as, :input_html => { :id => 'myid' }))
150
169
  end)
151
- output_buffer.should have_tag('form li label[@for="myid"]')
170
+ expect(output_buffer.to_str).to have_tag('form li label[@for="myid"]')
152
171
  end
153
172
  end
154
173
 
155
174
  def it_should_have_maxlength_matching_column_limit
156
175
  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']")
176
+ expect(@new_post.column_for_attribute(:title).limit).to eq(50)
177
+ expect(output_buffer.to_str).to have_tag("form li input[@maxlength='50']")
159
178
  end
160
179
  end
161
180
 
162
181
  def it_should_use_column_size_for_columns_shorter_than_default_text_field_size(as)
163
182
  it 'should use the column size for columns shorter than default_text_field_size' do
164
183
  column_limit_shorted_than_default = 1
165
- @new_post.stub(:column_for_attribute).and_return(double('column', :type => as, :limit => column_limit_shorted_than_default))
184
+ allow(@new_post).to receive(:column_for_attribute)
185
+ .and_return(double('column', :type => as, :limit => column_limit_shorted_than_default))
166
186
 
167
187
  concat(semantic_form_for(@new_post) do |builder|
168
188
  concat(builder.input(:title, :as => as))
169
189
  end)
170
190
 
171
- output_buffer.should have_tag("form li input[@size='#{column_limit_shorted_than_default}']")
191
+ expect(output_buffer.to_str).to have_tag("form li input[@size='#{column_limit_shorted_than_default}']")
172
192
  end
173
193
  end
174
194
 
@@ -177,25 +197,25 @@ module CustomMacros
177
197
  before do
178
198
  @title_errors = ['must not be blank', 'must be longer than 10 characters', 'must be awesome']
179
199
  @errors = double('errors')
180
- @errors.stub(:[]).with(errors_matcher(:title)).and_return(@title_errors)
200
+ allow(@errors).to receive(:[]).with(errors_matcher(:title)).and_return(@title_errors)
181
201
  Formtastic::FormBuilder.file_metadata_suffixes.each do |suffix|
182
- @errors.stub(:[]).with(errors_matcher("title_#{suffix}".to_sym)).and_return(nil)
202
+ allow(@errors).to receive(:[]).with(errors_matcher("title_#{suffix}".to_sym)).and_return(nil)
183
203
  end
184
- @new_post.stub(:errors).and_return(@errors)
204
+ allow(@new_post).to receive(:errors).and_return(@errors)
185
205
  end
186
206
 
187
207
  it 'should apply an errors class to the list item' do
188
208
  concat(semantic_form_for(@new_post) do |builder|
189
209
  concat(builder.input(:title, :as => type))
190
210
  end)
191
- output_buffer.should have_tag('form li.error')
211
+ expect(output_buffer.to_str).to have_tag('form li.error')
192
212
  end
193
213
 
194
214
  it 'should not wrap the input with the Rails default error wrapping' do
195
215
  concat(semantic_form_for(@new_post) do |builder|
196
216
  concat(builder.input(:title, :as => type))
197
217
  end)
198
- output_buffer.should_not have_tag('div.fieldWithErrors')
218
+ expect(output_buffer.to_str).not_to have_tag('div.fieldWithErrors')
199
219
  end
200
220
 
201
221
  it 'should render a paragraph for the errors' do
@@ -203,7 +223,7 @@ module CustomMacros
203
223
  concat(semantic_form_for(@new_post) do |builder|
204
224
  concat(builder.input(:title, :as => type))
205
225
  end)
206
- output_buffer.should have_tag('form li.error p.inline-errors')
226
+ expect(output_buffer.to_str).to have_tag('form li.error p.inline-errors')
207
227
  end
208
228
 
209
229
  it 'should not display an error list' do
@@ -211,7 +231,7 @@ module CustomMacros
211
231
  concat(semantic_form_for(@new_post) do |builder|
212
232
  concat(builder.input(:title, :as => type))
213
233
  end)
214
- output_buffer.should have_tag('form li.error ul.errors')
234
+ expect(output_buffer.to_str).to have_tag('form li.error ul.errors')
215
235
  end
216
236
  end
217
237
 
@@ -223,15 +243,15 @@ module CustomMacros
223
243
  end
224
244
 
225
245
  it 'should not apply an errors class to the list item' do
226
- output_buffer.should_not have_tag('form li.error')
246
+ expect(output_buffer.to_str).not_to have_tag('form li.error')
227
247
  end
228
248
 
229
249
  it 'should not render a paragraph for the errors' do
230
- output_buffer.should_not have_tag('form li.error p.inline-errors')
250
+ expect(output_buffer.to_str).not_to have_tag('form li.error p.inline-errors')
231
251
  end
232
252
 
233
253
  it 'should not display an error list' do
234
- output_buffer.should_not have_tag('form li.error ul.errors')
254
+ expect(output_buffer.to_str).not_to have_tag('form li.error ul.errors')
235
255
  end
236
256
  end
237
257
 
@@ -243,26 +263,22 @@ module CustomMacros
243
263
  end
244
264
 
245
265
  it 'should not apply an errors class to the list item' do
246
- output_buffer.should_not have_tag('form li.error')
266
+ expect(output_buffer.to_str).not_to have_tag('form li.error')
247
267
  end
248
268
 
249
269
  it 'should not render a paragraph for the errors' do
250
- output_buffer.should_not have_tag('form li.error p.inline-errors')
270
+ expect(output_buffer.to_str).not_to have_tag('form li.error p.inline-errors')
251
271
  end
252
272
 
253
273
  it 'should not display an error list' do
254
- output_buffer.should_not have_tag('form li.error ul.errors')
274
+ expect(output_buffer.to_str).not_to have_tag('form li.error ul.errors')
255
275
  end
256
276
  end
257
277
  end
258
278
 
259
279
  def it_should_call_find_on_association_class_when_no_collection_is_provided(as)
260
280
  it "should call find on the association class when no collection is provided" do
261
- if Formtastic::Util.rails3?
262
- ::Author.should_receive(:scoped)
263
- else
264
- ::Author.should_receive(:where)
265
- end
281
+ expect(::Author).to receive(:where)
266
282
  concat(semantic_form_for(@new_post) do |builder|
267
283
  concat(builder.input(:author, :as => as))
268
284
  end)
@@ -274,14 +290,14 @@ module CustomMacros
274
290
 
275
291
  before do
276
292
  @authors = ([::Author.all] * 2).flatten
277
- output_buffer.replace ''
293
+ @output_buffer = ActionView::OutputBuffer.new ''
278
294
  end
279
295
 
280
296
  it 'should use the provided collection' do
281
297
  concat(semantic_form_for(@new_post) do |builder|
282
298
  concat(builder.input(:author, :as => as, :collection => @authors))
283
299
  end)
284
- output_buffer.should have_tag("form li.#{as} #{countable}", :count => @authors.size + (as == :select ? 1 : 0))
300
+ expect(output_buffer.to_str).to have_tag("form li.#{as} #{countable}", :count => @authors.size + (as == :select ? 1 : 0))
285
301
  end
286
302
 
287
303
  describe 'and the :collection is an array of strings' do
@@ -295,24 +311,24 @@ module CustomMacros
295
311
  end)
296
312
 
297
313
  @categories.each do |value|
298
- output_buffer.should have_tag("form li.#{as}", /#{value}/)
299
- output_buffer.should have_tag("form li.#{as} #{countable}[@value='#{value}']")
314
+ expect(output_buffer.to_str).to have_tag("form li.#{as}", :text => /#{value}/)
315
+ expect(output_buffer.to_str).to have_tag("form li.#{as} #{countable}[@value='#{value}']")
300
316
  end
301
317
  end
302
318
 
303
319
  if as == :radio
304
320
  it 'should generate a sanitized label for attribute' do
305
- @bob.stub(:category_name).and_return(@categories)
321
+ allow(@bob).to receive(:category_name).and_return(@categories)
306
322
  concat(semantic_form_for(@new_post) do |builder|
307
323
  fields = builder.semantic_fields_for(@bob) do |bob_builder|
308
324
  concat(bob_builder.input(:category_name, :as => as, :collection => @categories))
309
325
  end
310
326
  concat(fields)
311
327
  end)
312
- output_buffer.should have_tag("form li fieldset ol li label[@for='post_author_category_name_general']")
313
- output_buffer.should have_tag("form li fieldset ol li label[@for='post_author_category_name_design']")
314
- output_buffer.should have_tag("form li fieldset ol li label[@for='post_author_category_name_development']")
315
- output_buffer.should have_tag("form li fieldset ol li label[@for='post_author_category_name_quasi-serious_inventions']")
328
+ expect(output_buffer.to_str).to have_tag("form li fieldset ol li label[@for='post_author_category_name_general']")
329
+ expect(output_buffer.to_str).to have_tag("form li fieldset ol li label[@for='post_author_category_name_design']")
330
+ expect(output_buffer.to_str).to have_tag("form li fieldset ol li label[@for='post_author_category_name_development']")
331
+ expect(output_buffer.to_str).to have_tag("form li fieldset ol li label[@for='post_author_category_name_quasi-serious_inventions']")
316
332
  end
317
333
  end
318
334
  end
@@ -328,8 +344,8 @@ module CustomMacros
328
344
  end)
329
345
 
330
346
  @categories.each do |label, value|
331
- output_buffer.should have_tag("form li.#{as}", /#{label}/)
332
- output_buffer.should have_tag("form li.#{as} #{countable}[@value='#{value}']")
347
+ expect(output_buffer.to_str).to have_tag("form li.#{as}", :text => /#{label}/)
348
+ expect(output_buffer.to_str).to have_tag("form li.#{as} #{countable}[@value='#{value}']")
333
349
  end
334
350
  end
335
351
  end
@@ -346,9 +362,9 @@ module CustomMacros
346
362
 
347
363
  @categories.each do |text, value|
348
364
  label = as == :select ? :option : :label
349
- output_buffer.should have_tag("form li.#{as} #{label}", /#{text}/i)
350
- output_buffer.should have_tag("form li.#{as} #{countable}[@value='#{value.to_s}']")
351
- output_buffer.should have_tag("form li.#{as} #{countable}#post_category_name_#{value.to_s}") if as == :radio
365
+ expect(output_buffer.to_str).to have_tag("form li.#{as} #{label}", :text => /#{text}/i)
366
+ expect(output_buffer.to_str).to have_tag("form li.#{as} #{countable}[@value='#{value.to_s}']")
367
+ expect(output_buffer.to_str).to have_tag("form li.#{as} #{countable}#post_category_name_#{value.to_s}") if as == :radio
352
368
  end
353
369
  end
354
370
  end
@@ -364,8 +380,8 @@ module CustomMacros
364
380
  concat(builder.input(:category_name, :as => as, :collection => @choices))
365
381
  end)
366
382
 
367
- output_buffer.should have_tag("form li.#{as} #{countable}#post_category_name_true")
368
- output_buffer.should have_tag("form li.#{as} #{countable}#post_category_name_false")
383
+ expect(output_buffer.to_str).to have_tag("form li.#{as} #{countable}#post_category_name_true")
384
+ expect(output_buffer.to_str).to have_tag("form li.#{as} #{countable}#post_category_name_false")
369
385
  end
370
386
  end
371
387
  end
@@ -382,8 +398,8 @@ module CustomMacros
382
398
 
383
399
  @categories.each do |value|
384
400
  label = as == :select ? :option : :label
385
- output_buffer.should have_tag("form li.#{as} #{label}", /#{value}/i)
386
- output_buffer.should have_tag("form li.#{as} #{countable}[@value='#{value.to_s}']")
401
+ expect(output_buffer.to_str).to have_tag("form li.#{as} #{label}", :text => /#{value}/i)
402
+ expect(output_buffer.to_str).to have_tag("form li.#{as} #{countable}[@value='#{value.to_s}']")
387
403
  end
388
404
  end
389
405
  end
@@ -399,8 +415,8 @@ module CustomMacros
399
415
  end)
400
416
 
401
417
  @categories.each do |label, value|
402
- output_buffer.should have_tag("form li.#{as}", /#{label}/)
403
- output_buffer.should have_tag("form li.#{as} #{countable}[@value='#{value}']")
418
+ expect(output_buffer.to_str).to have_tag("form li.#{as}", :text => /#{label}/)
419
+ expect(output_buffer.to_str).to have_tag("form li.#{as} #{countable}[@value='#{value}']")
404
420
  end
405
421
  end
406
422
 
@@ -410,28 +426,32 @@ module CustomMacros
410
426
 
411
427
  describe 'as a symbol' do
412
428
  before do
413
- concat(semantic_form_for(@new_post) do |builder|
414
- concat(builder.input(:author, :as => as, :member_label => :login))
415
- end)
429
+ with_deprecation_silenced do
430
+ concat(semantic_form_for(@new_post) do |builder|
431
+ concat(builder.input(:author, :as => as, :member_label => :login))
432
+ end)
433
+ end
416
434
  end
417
435
 
418
436
  it 'should have options with text content from the specified method' do
419
437
  ::Author.all.each do |author|
420
- output_buffer.should have_tag("form li.#{as}", /#{author.login}/)
438
+ expect(output_buffer.to_str).to have_tag("form li.#{as}", :text => /#{author.login}/)
421
439
  end
422
440
  end
423
441
  end
424
442
 
425
443
  describe 'as a proc' do
426
444
  before do
427
- concat(semantic_form_for(@new_post) do |builder|
428
- concat(builder.input(:author, :as => as, :member_label => Proc.new {|a| a.login.reverse }))
429
- end)
445
+ with_deprecation_silenced do
446
+ concat(semantic_form_for(@new_post) do |builder|
447
+ concat(builder.input(:author, :as => as, :member_label => Proc.new {|a| a.login.reverse }))
448
+ end)
449
+ end
430
450
  end
431
451
 
432
452
  it 'should have options with the proc applied to each' do
433
453
  ::Author.all.each do |author|
434
- output_buffer.should have_tag("form li.#{as}", /#{author.login.reverse}/)
454
+ expect(output_buffer.to_str).to have_tag("form li.#{as}", :text => /#{author.login.reverse}/)
435
455
  end
436
456
  end
437
457
  end
@@ -441,14 +461,16 @@ module CustomMacros
441
461
  def reverse_login(a)
442
462
  a.login.reverse
443
463
  end
444
- concat(semantic_form_for(@new_post) do |builder|
445
- concat(builder.input(:author, :as => as, :member_label => method(:reverse_login)))
446
- end)
464
+ with_deprecation_silenced do
465
+ concat(semantic_form_for(@new_post) do |builder|
466
+ concat(builder.input(:author, :as => as, :member_label => method(:reverse_login)))
467
+ end)
468
+ end
447
469
  end
448
470
 
449
471
  it 'should have options with the proc applied to each' do
450
472
  ::Author.all.each do |author|
451
- output_buffer.should have_tag("form li.#{as}", /#{author.login.reverse}/)
473
+ expect(output_buffer.to_str).to have_tag("form li.#{as}", :text => /#{author.login.reverse}/)
452
474
  end
453
475
  end
454
476
  end
@@ -459,17 +481,19 @@ module CustomMacros
459
481
 
460
482
  describe "when the collection objects respond to #{label_method}" do
461
483
  before do
462
- @fred.stub(:respond_to?).and_return { |m| m.to_s == label_method || m.to_s == 'id' }
463
- [@fred, @bob].each { |a| a.stub(label_method).and_return('The Label Text') }
484
+ allow(@fred).to receive(:respond_to?) { |m| m.to_s == label_method || m.to_s == 'id' }
485
+ [@fred, @bob].each { |a| allow(a).to receive(label_method).and_return('The Label Text') }
464
486
 
465
- concat(semantic_form_for(@new_post) do |builder|
466
- concat(builder.input(:author, :as => as))
467
- end)
487
+ with_deprecation_silenced do
488
+ concat(semantic_form_for(@new_post) do |builder|
489
+ concat(builder.input(:author, :as => as))
490
+ end)
491
+ end
468
492
  end
469
493
 
470
494
  it "should render the options with #{label_method} as the label" do
471
495
  ::Author.all.each do |author|
472
- output_buffer.should have_tag("form li.#{as}", /The Label Text/)
496
+ expect(output_buffer.to_str).to have_tag("form li.#{as}", :text => /The Label Text/)
473
497
  end
474
498
  end
475
499
  end
@@ -481,28 +505,32 @@ module CustomMacros
481
505
 
482
506
  describe 'as a symbol' do
483
507
  before do
484
- concat(semantic_form_for(@new_post) do |builder|
485
- concat(builder.input(:author, :as => as, :member_value => :login))
486
- end)
508
+ with_deprecation_silenced do
509
+ concat(semantic_form_for(@new_post) do |builder|
510
+ concat(builder.input(:author, :as => as, :member_value => :login))
511
+ end)
512
+ end
487
513
  end
488
514
 
489
515
  it 'should have options with values from specified method' do
490
516
  ::Author.all.each do |author|
491
- output_buffer.should have_tag("form li.#{as} #{countable}[@value='#{author.login}']")
517
+ expect(output_buffer.to_str).to have_tag("form li.#{as} #{countable}[@value='#{author.login}']")
492
518
  end
493
519
  end
494
520
  end
495
521
 
496
522
  describe 'as a proc' do
497
523
  before do
498
- concat(semantic_form_for(@new_post) do |builder|
499
- concat(builder.input(:author, :as => as, :member_value => Proc.new {|a| a.login.reverse }))
500
- end)
524
+ with_deprecation_silenced do
525
+ concat(semantic_form_for(@new_post) do |builder|
526
+ concat(builder.input(:author, :as => as, :member_value => Proc.new {|a| a.login.reverse }))
527
+ end)
528
+ end
501
529
  end
502
530
 
503
531
  it 'should have options with the proc applied to each value' do
504
532
  ::Author.all.each do |author|
505
- output_buffer.should have_tag("form li.#{as} #{countable}[@value='#{author.login.reverse}']")
533
+ expect(output_buffer.to_str).to have_tag("form li.#{as} #{countable}[@value='#{author.login.reverse}']")
506
534
  end
507
535
  end
508
536
  end
@@ -512,14 +540,16 @@ module CustomMacros
512
540
  def reverse_login(a)
513
541
  a.login.reverse
514
542
  end
515
- concat(semantic_form_for(@new_post) do |builder|
516
- concat(builder.input(:author, :as => as, :member_value => method(:reverse_login)))
517
- end)
543
+ with_deprecation_silenced do
544
+ concat(semantic_form_for(@new_post) do |builder|
545
+ concat(builder.input(:author, :as => as, :member_value => method(:reverse_login)))
546
+ end)
547
+ end
518
548
  end
519
549
 
520
550
  it 'should have options with the proc applied to each value' do
521
551
  ::Author.all.each do |author|
522
- output_buffer.should have_tag("form li.#{as} #{countable}[@value='#{author.login.reverse}']")
552
+ expect(output_buffer.to_str).to have_tag("form li.#{as} #{countable}[@value='#{author.login.reverse}']")
523
553
  end
524
554
  end
525
555
  end
@@ -1,5 +1,6 @@
1
+ # frozen_string_literal: true
1
2
  def with_deprecation_silenced(&block)
2
- ::ActiveSupport::Deprecation.silence do
3
+ ::Formtastic::Deprecation.silence do
3
4
  yield
4
5
  end
5
6
  end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+ RSpec.shared_context 'form builder' do
3
+ include FormtasticSpecHelper
4
+
5
+ before do
6
+ @output_buffer = ActionView::OutputBuffer.new ''
7
+ mock_everything
8
+ end
9
+
10
+ after do
11
+ ::I18n.backend.reload!
12
+ end
13
+ end
@@ -0,0 +1,28 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+ #
4
+ RSpec.shared_examples 'Specialized Class Finder' do
5
+ let(:builder) { Formtastic::FormBuilder.allocate }
6
+ subject(:finder) { described_class.new(builder) }
7
+
8
+ context 'by default' do
9
+ it 'includes Object and the default namespaces' do
10
+ expect(finder.namespaces).to eq([Object, default])
11
+ end
12
+ end
13
+
14
+ context 'with namespace configuration set to a custom list of modules' do
15
+ before do
16
+ stub_const('CustomModule', Module.new)
17
+ stub_const('AnotherModule', Module.new)
18
+
19
+ allow(Formtastic::FormBuilder).to receive(namespaces_setting)
20
+ .and_return([ CustomModule, AnotherModule ])
21
+ end
22
+
23
+ it 'includes just the custom namespaces' do
24
+ expect(finder.namespaces).to eq([CustomModule, AnotherModule])
25
+ end
26
+ end
27
+
28
+ end