formtastic 3.0.0 → 5.0.0

Sign up to get free protection for your applications and to get access to all the features.
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