formtastic 2.1.0 → 4.0.0

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