formtastic 2.1.0 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (164) hide show
  1. checksums.yaml +7 -0
  2. data/.gitattributes +1 -0
  3. data/.github/workflows/test.yml +61 -0
  4. data/.gitignore +4 -2
  5. data/CHANGELOG.md +52 -0
  6. data/Gemfile +1 -1
  7. data/Gemfile.lock +105 -0
  8. data/MIT-LICENSE +1 -1
  9. data/{README.textile → README.md} +204 -219
  10. data/RELEASE_PROCESS +3 -1
  11. data/Rakefile +27 -29
  12. data/app/assets/stylesheets/formtastic.css +3 -2
  13. data/bin/appraisal +8 -0
  14. data/formtastic.gemspec +11 -14
  15. data/gemfiles/rails_5.2/Gemfile +5 -0
  16. data/gemfiles/rails_6.0/Gemfile +5 -0
  17. data/gemfiles/rails_6.1/Gemfile +5 -0
  18. data/gemfiles/rails_edge/Gemfile +13 -0
  19. data/lib/formtastic/action_class_finder.rb +18 -0
  20. data/lib/formtastic/actions/button_action.rb +55 -60
  21. data/lib/formtastic/actions/input_action.rb +59 -57
  22. data/lib/formtastic/actions/link_action.rb +68 -67
  23. data/lib/formtastic/actions.rb +6 -3
  24. data/lib/formtastic/deprecation.rb +5 -0
  25. data/lib/formtastic/engine.rb +3 -1
  26. data/lib/formtastic/form_builder.rb +35 -16
  27. data/lib/formtastic/helpers/action_helper.rb +34 -28
  28. data/lib/formtastic/helpers/enum.rb +13 -0
  29. data/lib/formtastic/helpers/errors_helper.rb +2 -2
  30. data/lib/formtastic/helpers/fieldset_wrapper.rb +16 -12
  31. data/lib/formtastic/helpers/form_helper.rb +19 -16
  32. data/lib/formtastic/helpers/input_helper.rb +69 -97
  33. data/lib/formtastic/helpers/inputs_helper.rb +35 -25
  34. data/lib/formtastic/helpers/reflection.rb +4 -4
  35. data/lib/formtastic/helpers.rb +1 -2
  36. data/lib/formtastic/html_attributes.rb +12 -1
  37. data/lib/formtastic/i18n.rb +1 -1
  38. data/lib/formtastic/input_class_finder.rb +18 -0
  39. data/lib/formtastic/inputs/base/choices.rb +2 -2
  40. data/lib/formtastic/inputs/base/collections.rb +46 -14
  41. data/lib/formtastic/inputs/base/database.rb +7 -2
  42. data/lib/formtastic/inputs/base/datetime_pickerish.rb +85 -0
  43. data/lib/formtastic/inputs/base/errors.rb +7 -7
  44. data/lib/formtastic/inputs/base/hints.rb +2 -2
  45. data/lib/formtastic/inputs/base/html.rb +10 -9
  46. data/lib/formtastic/inputs/base/labelling.rb +5 -8
  47. data/lib/formtastic/inputs/base/naming.rb +4 -4
  48. data/lib/formtastic/inputs/base/numeric.rb +1 -1
  49. data/lib/formtastic/inputs/base/options.rb +3 -4
  50. data/lib/formtastic/inputs/base/stringish.rb +10 -2
  51. data/lib/formtastic/inputs/base/timeish.rb +34 -22
  52. data/lib/formtastic/inputs/base/validations.rb +41 -13
  53. data/lib/formtastic/inputs/base/wrapping.rb +29 -26
  54. data/lib/formtastic/inputs/base.rb +22 -15
  55. data/lib/formtastic/inputs/boolean_input.rb +26 -12
  56. data/lib/formtastic/inputs/check_boxes_input.rb +39 -31
  57. data/lib/formtastic/inputs/color_input.rb +41 -0
  58. data/lib/formtastic/inputs/country_input.rb +24 -5
  59. data/lib/formtastic/inputs/datalist_input.rb +41 -0
  60. data/lib/formtastic/inputs/date_picker_input.rb +93 -0
  61. data/lib/formtastic/inputs/{date_input.rb → date_select_input.rb} +1 -1
  62. data/lib/formtastic/inputs/datetime_picker_input.rb +103 -0
  63. data/lib/formtastic/inputs/{datetime_input.rb → datetime_select_input.rb} +1 -1
  64. data/lib/formtastic/inputs/file_input.rb +2 -2
  65. data/lib/formtastic/inputs/hidden_input.rb +2 -6
  66. data/lib/formtastic/inputs/radio_input.rb +28 -22
  67. data/lib/formtastic/inputs/select_input.rb +36 -39
  68. data/lib/formtastic/inputs/time_picker_input.rb +99 -0
  69. data/lib/formtastic/inputs/{time_input.rb → time_select_input.rb} +6 -2
  70. data/lib/formtastic/inputs/time_zone_input.rb +16 -6
  71. data/lib/formtastic/inputs.rb +32 -21
  72. data/lib/formtastic/localized_string.rb +1 -1
  73. data/lib/formtastic/localizer.rb +24 -24
  74. data/lib/formtastic/namespaced_class_finder.rb +99 -0
  75. data/lib/formtastic/version.rb +1 -1
  76. data/lib/formtastic.rb +20 -10
  77. data/lib/generators/formtastic/form/form_generator.rb +10 -4
  78. data/lib/generators/formtastic/input/input_generator.rb +46 -0
  79. data/lib/generators/formtastic/install/install_generator.rb +5 -19
  80. data/lib/generators/templates/_form.html.slim +2 -2
  81. data/lib/generators/templates/formtastic.rb +46 -25
  82. data/lib/generators/templates/input.rb +19 -0
  83. data/sample/basic_inputs.html +23 -3
  84. data/script/integration-template.rb +74 -0
  85. data/script/integration.sh +19 -0
  86. data/spec/action_class_finder_spec.rb +12 -0
  87. data/spec/actions/button_action_spec.rb +8 -8
  88. data/spec/actions/generic_action_spec.rb +92 -56
  89. data/spec/actions/input_action_spec.rb +7 -7
  90. data/spec/actions/link_action_spec.rb +10 -10
  91. data/spec/builder/custom_builder_spec.rb +36 -20
  92. data/spec/builder/error_proc_spec.rb +4 -4
  93. data/spec/builder/semantic_fields_for_spec.rb +28 -29
  94. data/spec/fast_spec_helper.rb +12 -0
  95. data/spec/generators/formtastic/form/form_generator_spec.rb +45 -32
  96. data/spec/generators/formtastic/input/input_generator_spec.rb +124 -0
  97. data/spec/generators/formtastic/install/install_generator_spec.rb +9 -9
  98. data/spec/helpers/action_helper_spec.rb +75 -103
  99. data/spec/helpers/actions_helper_spec.rb +17 -17
  100. data/spec/helpers/form_helper_spec.rb +84 -33
  101. data/spec/helpers/input_helper_spec.rb +333 -285
  102. data/spec/helpers/inputs_helper_spec.rb +167 -121
  103. data/spec/helpers/reflection_helper_spec.rb +3 -3
  104. data/spec/helpers/semantic_errors_helper_spec.rb +23 -23
  105. data/spec/i18n_spec.rb +26 -26
  106. data/spec/input_class_finder_spec.rb +10 -0
  107. data/spec/inputs/base/collections_spec.rb +76 -0
  108. data/spec/inputs/base/validations_spec.rb +480 -0
  109. data/spec/inputs/boolean_input_spec.rb +100 -65
  110. data/spec/inputs/check_boxes_input_spec.rb +200 -101
  111. data/spec/inputs/color_input_spec.rb +85 -0
  112. data/spec/inputs/country_input_spec.rb +20 -20
  113. data/spec/inputs/custom_input_spec.rb +3 -4
  114. data/spec/inputs/datalist_input_spec.rb +61 -0
  115. data/spec/inputs/date_picker_input_spec.rb +449 -0
  116. data/spec/inputs/date_select_input_spec.rb +249 -0
  117. data/spec/inputs/datetime_picker_input_spec.rb +490 -0
  118. data/spec/inputs/datetime_select_input_spec.rb +209 -0
  119. data/spec/inputs/email_input_spec.rb +5 -5
  120. data/spec/inputs/file_input_spec.rb +6 -6
  121. data/spec/inputs/hidden_input_spec.rb +22 -35
  122. data/spec/inputs/include_blank_spec.rb +11 -11
  123. data/spec/inputs/label_spec.rb +62 -25
  124. data/spec/inputs/number_input_spec.rb +112 -112
  125. data/spec/inputs/password_input_spec.rb +5 -5
  126. data/spec/inputs/phone_input_spec.rb +5 -5
  127. data/spec/inputs/placeholder_spec.rb +6 -6
  128. data/spec/inputs/radio_input_spec.rb +99 -55
  129. data/spec/inputs/range_input_spec.rb +66 -66
  130. data/spec/inputs/readonly_spec.rb +50 -0
  131. data/spec/inputs/search_input_spec.rb +5 -5
  132. data/spec/inputs/select_input_spec.rb +170 -170
  133. data/spec/inputs/string_input_spec.rb +68 -16
  134. data/spec/inputs/text_input_spec.rb +16 -16
  135. data/spec/inputs/time_picker_input_spec.rb +455 -0
  136. data/spec/inputs/time_select_input_spec.rb +261 -0
  137. data/spec/inputs/time_zone_input_spec.rb +54 -28
  138. data/spec/inputs/url_input_spec.rb +5 -5
  139. data/spec/inputs/with_options_spec.rb +7 -7
  140. data/spec/localizer_spec.rb +39 -17
  141. data/spec/namespaced_class_finder_spec.rb +79 -0
  142. data/spec/schema.rb +21 -0
  143. data/spec/spec_helper.rb +254 -221
  144. data/spec/support/custom_macros.rb +128 -95
  145. data/spec/support/shared_examples.rb +12 -0
  146. data/spec/support/specialized_class_finder_shared_example.rb +27 -0
  147. data/spec/support/test_environment.rb +26 -10
  148. metadata +177 -238
  149. data/.travis.yml +0 -8
  150. data/Appraisals +0 -11
  151. data/CHANGELOG +0 -371
  152. data/gemfiles/rails-3.0.gemfile +0 -7
  153. data/gemfiles/rails-3.1.gemfile +0 -7
  154. data/gemfiles/rails-3.2.gemfile +0 -7
  155. data/lib/formtastic/helpers/buttons_helper.rb +0 -310
  156. data/lib/formtastic/inputs/base/grouped_collections.rb +0 -77
  157. data/lib/formtastic/util.rb +0 -25
  158. data/lib/tasks/verify_rcov.rb +0 -44
  159. data/spec/helpers/buttons_helper_spec.rb +0 -166
  160. data/spec/helpers/commit_button_helper_spec.rb +0 -530
  161. data/spec/inputs/date_input_spec.rb +0 -227
  162. data/spec/inputs/datetime_input_spec.rb +0 -185
  163. data/spec/inputs/time_input_spec.rb +0 -267
  164. data/spec/support/deferred_garbage_collection.rb +0 -21
@@ -1,7 +1,7 @@
1
1
  # encoding: utf-8
2
2
  require 'spec_helper'
3
3
 
4
- describe 'Formtastic::FormBuilder#inputs' do
4
+ RSpec.describe 'Formtastic::FormBuilder#inputs' do
5
5
 
6
6
  include FormtasticSpecHelper
7
7
 
@@ -23,24 +23,24 @@ describe 'Formtastic::FormBuilder#inputs' do
23
23
  end
24
24
 
25
25
  it 'should output just the content wrapped in inputs, not the whole template' do
26
- output_buffer.should =~ /before_builder/
27
- @inputs_output.should_not =~ /before_builder/
26
+ expect(output_buffer).to match(/before_builder/)
27
+ expect(@inputs_output).not_to match(/before_builder/)
28
28
  end
29
29
 
30
30
  it 'should render a fieldset inside the form, with a class of "inputs"' do
31
- output_buffer.should have_tag("form fieldset.inputs")
31
+ expect(output_buffer).to have_tag("form fieldset.inputs")
32
32
  end
33
33
 
34
34
  it 'should render an ol inside the fieldset' do
35
- output_buffer.should have_tag("form fieldset.inputs ol")
35
+ expect(output_buffer).to have_tag("form fieldset.inputs ol")
36
36
  end
37
37
 
38
38
  it 'should render the contents of the block inside the ol' do
39
- output_buffer.should have_tag("form fieldset.inputs ol", /hello/)
39
+ expect(output_buffer).to have_tag("form fieldset.inputs ol", :text => /hello/)
40
40
  end
41
41
 
42
42
  it 'should not render a legend inside the fieldset' do
43
- output_buffer.should_not have_tag("form fieldset.inputs legend")
43
+ expect(output_buffer).not_to have_tag("form fieldset.inputs legend")
44
44
  end
45
45
 
46
46
  it 'should render a fieldset even if no object is given' do
@@ -49,19 +49,20 @@ describe 'Formtastic::FormBuilder#inputs' do
49
49
  concat('bye')
50
50
  end
51
51
  end)
52
- output_buffer.should have_tag("form fieldset.inputs ol", /bye/)
52
+ expect(output_buffer).to have_tag("form fieldset.inputs ol", :text => /bye/)
53
53
  end
54
54
  end
55
55
 
56
56
  describe 'when a :for option is provided' do
57
57
 
58
58
  before do
59
- @new_post.stub!(:respond_to?).and_return(true, true)
60
- @new_post.stub!(:author).and_return(@bob)
59
+ allow(@new_post).to receive(:respond_to?).and_return(true, true)
60
+ allow(@new_post).to receive(:respond_to?).with(:empty?).and_return(false)
61
+ allow(@new_post).to receive(:author).and_return(@bob)
61
62
  end
62
63
 
63
64
  it 'should render nested inputs' do
64
- @bob.stub!(:column_for_attribute).and_return(mock('column', :type => :string, :limit => 255))
65
+ allow(@bob).to receive(:column_for_attribute).and_return(double('column', :type => :string, :limit => 255))
65
66
 
66
67
  concat(semantic_form_for(@new_post) do |builder|
67
68
  inputs = builder.inputs :for => [:author, @bob] do |bob_builder|
@@ -69,12 +70,12 @@ describe 'Formtastic::FormBuilder#inputs' do
69
70
  end
70
71
  concat(inputs)
71
72
  end)
72
- output_buffer.should have_tag("form fieldset.inputs #post_author_attributes_login")
73
- output_buffer.should_not have_tag("form fieldset.inputs #author_login")
73
+ expect(output_buffer).to have_tag("form fieldset.inputs #post_author_attributes_login")
74
+ expect(output_buffer).not_to have_tag("form fieldset.inputs #author_login")
74
75
  end
75
76
 
76
77
  it 'should concat rendered nested inputs to the template' do
77
- @bob.stub!(:column_for_attribute).and_return(mock('column', :type => :string, :limit => 255))
78
+ allow(@bob).to receive(:column_for_attribute).and_return(double('column', :type => :string, :limit => 255))
78
79
 
79
80
  concat(semantic_form_for(@new_post) do |builder|
80
81
  builder.inputs :for => [:author, @bob] do |bob_builder|
@@ -82,8 +83,8 @@ describe 'Formtastic::FormBuilder#inputs' do
82
83
  end
83
84
  end)
84
85
 
85
- output_buffer.should have_tag("form fieldset.inputs #post_author_attributes_login")
86
- output_buffer.should_not have_tag("form fieldset.inputs #author_login")
86
+ expect(output_buffer).to have_tag("form fieldset.inputs #post_author_attributes_login")
87
+ expect(output_buffer).not_to have_tag("form fieldset.inputs #author_login")
87
88
 
88
89
  end
89
90
 
@@ -96,15 +97,15 @@ describe 'Formtastic::FormBuilder#inputs' do
96
97
  end
97
98
  concat(inputs)
98
99
  end)
99
- output_buffer.should have_tag("form input[@name='post[author_attributes][login]']")
100
+ expect(output_buffer).to have_tag("form input[@name='post[author_attributes][login]']")
100
101
  end
101
102
 
102
103
  end
103
104
 
104
105
  describe "as a symbol representing a has_many association name" do
105
106
  before do
106
- @new_post.stub!(:authors).and_return([@bob, @fred])
107
- @new_post.stub!(:authors_attributes=)
107
+ allow(@new_post).to receive(:authors).and_return([@bob, @fred])
108
+ allow(@new_post).to receive(:authors_attributes=)
108
109
  end
109
110
 
110
111
  it 'should nest the inputs with a fieldset, legend and :name input for each item' do
@@ -114,13 +115,13 @@ describe 'Formtastic::FormBuilder#inputs' do
114
115
  end
115
116
  end)
116
117
 
117
- output_buffer.should have_tag("form fieldset.inputs", :count => 2)
118
- output_buffer.should have_tag("form fieldset.inputs legend", :count => 2)
119
- output_buffer.should have_tag("form fieldset.inputs legend", "1", :count => 1)
120
- output_buffer.should have_tag("form fieldset.inputs legend", "2")
121
- output_buffer.should have_tag("form input[@name='post[authors_attributes][0][login]']")
122
- output_buffer.should have_tag("form input[@name='post[authors_attributes][1][login]']")
123
- output_buffer.should_not have_tag('form fieldset[@name]')
118
+ expect(output_buffer).to have_tag("form fieldset.inputs", :count => 2)
119
+ expect(output_buffer).to have_tag("form fieldset.inputs legend", :count => 2)
120
+ expect(output_buffer).to have_tag("form fieldset.inputs legend", :text => "1", :count => 1)
121
+ expect(output_buffer).to have_tag("form fieldset.inputs legend", :text => "2")
122
+ expect(output_buffer).to have_tag("form input[@name='post[authors_attributes][0][login]']")
123
+ expect(output_buffer).to have_tag("form input[@name='post[authors_attributes][1][login]']")
124
+ expect(output_buffer).not_to have_tag('form fieldset[@name]')
124
125
  end
125
126
 
126
127
  it 'should include an indexed :label input for each item' do
@@ -130,9 +131,9 @@ describe 'Formtastic::FormBuilder#inputs' do
130
131
  end
131
132
  end)
132
133
 
133
- output_buffer.should have_tag("form fieldset.inputs label", "1", :count => 1)
134
- output_buffer.should have_tag("form fieldset.inputs label", "2", :count => 1)
135
- output_buffer.should_not have_tag('form fieldset legend')
134
+ expect(output_buffer).to have_tag("form fieldset.inputs label", :text => "1", :count => 1)
135
+ expect(output_buffer).to have_tag("form fieldset.inputs label", :text => "2", :count => 1)
136
+ expect(output_buffer).not_to have_tag('form fieldset legend')
136
137
  end
137
138
  end
138
139
 
@@ -145,7 +146,7 @@ describe 'Formtastic::FormBuilder#inputs' do
145
146
  end
146
147
  concat(inputs)
147
148
  end)
148
- output_buffer.should have_tag("form input[@name='post[author_attributes][login]']")
149
+ expect(output_buffer).to have_tag("form input[@name='post[author_attributes][login]']")
149
150
  end
150
151
 
151
152
  end
@@ -159,24 +160,24 @@ describe 'Formtastic::FormBuilder#inputs' do
159
160
  end
160
161
  concat(inputs)
161
162
  end)
162
- output_buffer.should have_tag("form input[@name='post[author][login]']")
163
+ expect(output_buffer).to have_tag("form input[@name='post[author][login]']")
163
164
  end
164
165
 
165
166
  end
166
167
 
167
168
  it 'should raise an error if :for and block with no argument is given' do
168
169
  semantic_form_for(@new_post) do |builder|
169
- proc {
170
+ expect {
170
171
  builder.inputs(:for => [:author, @bob]) do
171
172
  #
172
173
  end
173
- }.should raise_error(ArgumentError, 'You gave :for option with a block to inputs method, ' <<
174
+ }.to raise_error(ArgumentError, 'You gave :for option with a block to inputs method, ' <<
174
175
  'but the block does not accept any argument.')
175
176
  end
176
177
  end
177
178
 
178
179
  it 'should pass options down to semantic_fields_for' do
179
- @bob.stub!(:column_for_attribute).and_return(mock('column', :type => :string, :limit => 255))
180
+ allow(@bob).to receive(:column_for_attribute).and_return(double('column', :type => :string, :limit => 255))
180
181
 
181
182
  concat(semantic_form_for(@new_post) do |builder|
182
183
  inputs = builder.inputs :for => [:author, @bob], :for_options => { :index => 10 } do |bob_builder|
@@ -185,7 +186,7 @@ describe 'Formtastic::FormBuilder#inputs' do
185
186
  concat(inputs)
186
187
  end)
187
188
 
188
- output_buffer.should have_tag('form fieldset ol li #post_author_attributes_10_login')
189
+ expect(output_buffer).to have_tag('form fieldset ol li #post_author_attributes_10_login')
189
190
  end
190
191
 
191
192
  it 'should not add builder as a fieldset attribute tag' do
@@ -196,7 +197,7 @@ describe 'Formtastic::FormBuilder#inputs' do
196
197
  concat(inputs)
197
198
  end)
198
199
 
199
- output_buffer.should_not have_tag('fieldset[@builder="Formtastic::Helpers::FormHelper"]')
200
+ expect(output_buffer).not_to have_tag('fieldset[@builder="Formtastic::Helpers::FormHelper"]')
200
201
  end
201
202
 
202
203
  it 'should send parent_builder as an option to allow child index interpolation for legends' do
@@ -208,7 +209,7 @@ describe 'Formtastic::FormBuilder#inputs' do
208
209
  concat(inputs)
209
210
  end)
210
211
 
211
- output_buffer.should have_tag('fieldset legend', 'Author #1')
212
+ expect(output_buffer).to have_tag('fieldset legend', :text => 'Author #1')
212
213
  end
213
214
 
214
215
  it 'should also provide child index interpolation for legends when nested child index is a hash' do
@@ -220,7 +221,7 @@ describe 'Formtastic::FormBuilder#inputs' do
220
221
  concat(inputs)
221
222
  end)
222
223
 
223
- output_buffer.should have_tag('fieldset legend', 'Author #11')
224
+ expect(output_buffer).to have_tag('fieldset legend', :text => 'Author #11')
224
225
  end
225
226
 
226
227
  it 'should send parent_builder as an option to allow child index interpolation for labels' do
@@ -232,7 +233,7 @@ describe 'Formtastic::FormBuilder#inputs' do
232
233
  concat(inputs)
233
234
  end)
234
235
 
235
- output_buffer.should have_tag('fieldset label', 'Author #1')
236
+ expect(output_buffer).to have_tag('fieldset label', :text => 'Author #1')
236
237
  end
237
238
 
238
239
  it 'should also provide child index interpolation for labels when nested child index is a hash' do
@@ -244,7 +245,7 @@ describe 'Formtastic::FormBuilder#inputs' do
244
245
  concat(inputs)
245
246
  end)
246
247
 
247
- output_buffer.should have_tag('fieldset label', 'Author #11')
248
+ expect(output_buffer).to have_tag('fieldset label', :text => 'Author #11')
248
249
  end
249
250
  end
250
251
 
@@ -270,12 +271,13 @@ describe 'Formtastic::FormBuilder#inputs' do
270
271
  concat(inputs)
271
272
  end)
272
273
  end
273
-
274
+
275
+ # TODO: looks like the block isn't being called for the last assertion here
274
276
  it 'should render a fieldset with a legend inside the form' do
275
- output_buffer.should have_tag("form fieldset legend", /^#{@legend_text}$/)
276
- output_buffer.should have_tag("form fieldset legend", /^#{@legend_text_using_name}$/)
277
- output_buffer.should have_tag("form fieldset legend", /^#{@legend_text_using_title}$/)
278
- output_buffer.should have_tag("form fieldset legend", /^#{@nested_forms_legend_text}$/)
277
+ expect(output_buffer).to have_tag("form fieldset legend", :text => /^#{@legend_text}$/)
278
+ expect(output_buffer).to have_tag("form fieldset legend", :text => /^#{@legend_text_using_name}$/)
279
+ expect(output_buffer).to have_tag("form fieldset legend", :text => /^#{@legend_text_using_title}$/)
280
+ expect(output_buffer).to have_tag("form fieldset legend", :text => /^#{@nested_forms_legend_text}$/)
279
281
  end
280
282
  end
281
283
 
@@ -296,26 +298,23 @@ describe 'Formtastic::FormBuilder#inputs' do
296
298
  }
297
299
  }
298
300
  concat(semantic_form_for(@new_post) do |builder|
299
- inputs = builder.inputs :advanced_options do
300
- end
301
- concat(inputs)
302
- inputs =builder.inputs :name => :advanced_options_using_name do
303
- end
304
- concat(inputs)
305
- inputs = builder.inputs :title => :advanced_options_using_title do
306
- end
307
- concat(inputs)
308
- inputs = builder.inputs :nested_forms_title, :for => :authors do |nf|
309
- end
310
- concat(inputs)
301
+ concat(builder.inputs(:advanced_options) do
302
+ end)
303
+ concat(builder.inputs(:name => :advanced_options_using_name) do
304
+ end)
305
+ concat(builder.inputs(:title => :advanced_options_using_title) do
306
+ end)
307
+ concat(builder.inputs(:nested_forms_title, :for => :authors) do |nf|
308
+ end)
311
309
  end)
312
310
  end
313
-
311
+
312
+ # TODO: looks like the block isn't being called for the last assertion here
314
313
  it 'should render a fieldset with a localized legend inside the form' do
315
- output_buffer.should have_tag("form fieldset legend", /^#{@localized_legend_text}$/)
316
- output_buffer.should have_tag("form fieldset legend", /^#{@localized_legend_text_using_name}$/)
317
- output_buffer.should have_tag("form fieldset legend", /^#{@localized_legend_text_using_title}$/)
318
- output_buffer.should have_tag("form fieldset legend", /^#{@localized_nested_forms_legend_text}$/)
314
+ expect(output_buffer).to have_tag("form fieldset legend", :text => /^#{@localized_legend_text}$/)
315
+ expect(output_buffer).to have_tag("form fieldset legend", :text => /^#{@localized_legend_text_using_name}$/)
316
+ expect(output_buffer).to have_tag("form fieldset legend", :text => /^#{@localized_legend_text_using_title}$/)
317
+ expect(output_buffer).to have_tag("form fieldset legend", :text => /^#{@localized_nested_forms_legend_text}$/)
319
318
  end
320
319
  end
321
320
  end
@@ -332,8 +331,8 @@ describe 'Formtastic::FormBuilder#inputs' do
332
331
  end
333
332
 
334
333
  it 'should pass the options into the fieldset tag as attributes' do
335
- output_buffer.should have_tag("form fieldset##{@id_option}")
336
- output_buffer.should have_tag("form fieldset.#{@class_option}")
334
+ expect(output_buffer).to have_tag("form fieldset##{@id_option}")
335
+ expect(output_buffer).to have_tag("form fieldset.#{@class_option}")
337
336
  end
338
337
  end
339
338
 
@@ -342,18 +341,17 @@ describe 'Formtastic::FormBuilder#inputs' do
342
341
  describe 'without a block' do
343
342
 
344
343
  before do
345
- ::Post.stub!(:reflections).and_return({:author => mock('reflection', :options => {}, :macro => :belongs_to),
346
- :comments => mock('reflection', :options => {}, :macro => :has_many) })
347
- ::Author.stub!(:find).and_return([@fred, @bob])
348
-
349
- @new_post.stub!(:title)
350
- @new_post.stub!(:body)
351
- @new_post.stub!(:author_id)
352
-
353
- @new_post.stub!(:column_for_attribute).with(:title).and_return(mock('column', :type => :string, :limit => 255))
354
- @new_post.stub!(:column_for_attribute).with(:body).and_return(mock('column', :type => :text))
355
- @new_post.stub!(:column_for_attribute).with(:created_at).and_return(mock('column', :type => :datetime))
356
- @new_post.stub!(:column_for_attribute).with(:author).and_return(nil)
344
+ allow(::Post).to receive(:reflections).and_return({:author => double('reflection', :options => {}, :macro => :belongs_to),
345
+ :comments => double('reflection', :options => {}, :macro => :has_many) })
346
+
347
+ allow(@new_post).to receive(:title)
348
+ allow(@new_post).to receive(:body)
349
+ allow(@new_post).to receive(:author_id)
350
+
351
+ allow(@new_post).to receive(:column_for_attribute).with(:title).and_return(double('column', :type => :string, :limit => 255))
352
+ allow(@new_post).to receive(:column_for_attribute).with(:body).and_return(double('column', :type => :text))
353
+ allow(@new_post).to receive(:column_for_attribute).with(:created_at).and_return(double('column', :type => :datetime))
354
+ allow(@new_post).to receive(:column_for_attribute).with(:author).and_return(nil)
357
355
  end
358
356
 
359
357
  describe 'with no args (quick forms syntax)' do
@@ -364,52 +362,67 @@ describe 'Formtastic::FormBuilder#inputs' do
364
362
  end
365
363
 
366
364
  it 'should render a form' do
367
- output_buffer.should have_tag('form')
365
+ expect(output_buffer).to have_tag('form')
368
366
  end
369
367
 
370
368
  it 'should render a fieldset inside the form' do
371
- output_buffer.should have_tag('form > fieldset.inputs')
369
+ expect(output_buffer).to have_tag('form > fieldset.inputs')
372
370
  end
373
371
 
374
372
  it 'should not render a legend in the fieldset' do
375
- output_buffer.should_not have_tag('form > fieldset.inputs > legend')
373
+ expect(output_buffer).not_to have_tag('form > fieldset.inputs > legend')
376
374
  end
377
375
 
378
376
  it 'should render an ol in the fieldset' do
379
- output_buffer.should have_tag('form > fieldset.inputs > ol')
377
+ expect(output_buffer).to have_tag('form > fieldset.inputs > ol')
380
378
  end
381
379
 
382
380
  it 'should render a list item in the ol for each column and reflection' do
383
381
  # Remove the :has_many macro and :created_at column
384
382
  count = ::Post.content_columns.size + ::Post.reflections.size - 2
385
- output_buffer.should have_tag('form > fieldset.inputs > ol > li', :count => count)
383
+ expect(output_buffer).to have_tag('form > fieldset.inputs > ol > li', :count => count)
386
384
  end
387
385
 
388
386
  it 'should render a string list item for title' do
389
- output_buffer.should have_tag('form > fieldset.inputs > ol > li.string')
387
+ expect(output_buffer).to have_tag('form > fieldset.inputs > ol > li.string')
390
388
  end
391
389
 
392
390
  it 'should render a text list item for body' do
393
- output_buffer.should have_tag('form > fieldset.inputs > ol > li.text')
391
+ expect(output_buffer).to have_tag('form > fieldset.inputs > ol > li.text')
394
392
  end
395
393
 
396
394
  it 'should render a select list item for author_id' do
397
- output_buffer.should have_tag('form > fieldset.inputs > ol > li.select', :count => 1)
395
+ expect(output_buffer).to have_tag('form > fieldset.inputs > ol > li.select', :count => 1)
398
396
  end
399
397
 
400
398
  it 'should not render timestamps inputs by default' do
401
- output_buffer.should_not have_tag('form > fieldset.inputs > ol > li.datetime')
399
+ expect(output_buffer).not_to have_tag('form > fieldset.inputs > ol > li.datetime')
402
400
  end
403
-
401
+
402
+ context "with non-standard foregin keys" do
403
+ before do
404
+ @output_buffer = ''
405
+ end
406
+
407
+ it 'should respect foreign key while rendering select' do
408
+ concat(semantic_form_for(LegacyPost.new, {:url => '/'}) do |builder|
409
+ concat(builder.inputs)
410
+ end)
411
+ expect(output_buffer).to have_tag('form > fieldset.inputs > ol > li.select select#legacy_post_post_author', :count => 1)
412
+ expect(output_buffer).not_to have_tag('input#legacy_post_post_author')
413
+ end
414
+
415
+ end
416
+
404
417
  context "with a polymorphic association" do
405
418
 
406
419
  before do
407
- @new_post.stub!(:commentable)
408
- @new_post.class.stub!(:reflections).and_return({
409
- :commentable => mock('macro_reflection', :options => { :polymorphic => true }, :macro => :belongs_to)
420
+ allow(@new_post).to receive(:commentable)
421
+ allow(@new_post.class).to receive(:reflections).and_return({
422
+ :commentable => double('macro_reflection', :options => { :polymorphic => true }, :macro => :belongs_to)
410
423
  })
411
- @new_post.stub!(:column_for_attribute).with(:commentable).and_return(
412
- mock('column', :type => :integer)
424
+ allow(@new_post).to receive(:column_for_attribute).with(:commentable).and_return(
425
+ double('column', :type => :integer)
413
426
  )
414
427
  end
415
428
 
@@ -417,7 +430,7 @@ describe 'Formtastic::FormBuilder#inputs' do
417
430
  concat(semantic_form_for(@new_post) do |builder|
418
431
  concat(builder.inputs)
419
432
  end)
420
- output_buffer.should_not have_tag('li#post_commentable_input')
433
+ expect(output_buffer).not_to have_tag('li#post_commentable_input')
421
434
  end
422
435
 
423
436
  end
@@ -430,9 +443,9 @@ describe 'Formtastic::FormBuilder#inputs' do
430
443
  concat(builder.inputs(:title, :body))
431
444
  end)
432
445
 
433
- output_buffer.should have_tag('form > fieldset.inputs > ol > li', :count => 2)
434
- output_buffer.should have_tag('form > fieldset.inputs > ol > li.string')
435
- output_buffer.should have_tag('form > fieldset.inputs > ol > li.text')
446
+ expect(output_buffer).to have_tag('form > fieldset.inputs > ol > li', :count => 2)
447
+ expect(output_buffer).to have_tag('form > fieldset.inputs > ol > li.string')
448
+ expect(output_buffer).to have_tag('form > fieldset.inputs > ol > li.text')
436
449
  end
437
450
  end
438
451
 
@@ -442,22 +455,22 @@ describe 'Formtastic::FormBuilder#inputs' do
442
455
  concat(builder.inputs(:title, :body))
443
456
  end)
444
457
 
445
- output_buffer.should have_tag('form > fieldset.inputs > ol > li.string', :count => 2)
458
+ expect(output_buffer).to have_tag('form > fieldset.inputs > ol > li.string', :count => 2)
446
459
  end
447
460
  end
448
461
 
449
462
  context "with a polymorphic association" do
450
463
 
451
464
  it 'should raise an error for polymorphic associations (the collection class cannot be guessed)' do
452
- @new_post.stub!(:commentable)
453
- @new_post.class.stub!(:reflections).and_return({
454
- :commentable => mock('macro_reflection', :options => { :polymorphic => true }, :macro => :belongs_to)
465
+ allow(@new_post).to receive(:commentable)
466
+ allow(@new_post.class).to receive(:reflections).and_return({
467
+ :commentable => double('macro_reflection', :options => { :polymorphic => true }, :macro => :belongs_to)
455
468
  })
456
- @new_post.stub!(:column_for_attribute).with(:commentable).and_return(
457
- mock('column', :type => :integer)
469
+ allow(@new_post).to receive(:column_for_attribute).with(:commentable).and_return(
470
+ double('column', :type => :integer)
458
471
  )
459
- @new_post.class.stub!(:reflect_on_association).with(:commentable).and_return(
460
- mock('reflection', :macro => :belongs_to, :options => { :polymorphic => true })
472
+ allow(@new_post.class).to receive(:reflect_on_association).with(:commentable).and_return(
473
+ double('reflection', :macro => :belongs_to, :options => { :polymorphic => true })
461
474
  )
462
475
 
463
476
  expect {
@@ -474,13 +487,13 @@ describe 'Formtastic::FormBuilder#inputs' do
474
487
  describe 'when a :for option is provided' do
475
488
  describe 'and an object is given' do
476
489
  it 'should render nested inputs' do
477
- @bob.stub!(:column_for_attribute).and_return(mock('column', :type => :string, :limit => 255))
490
+ allow(@bob).to receive(:column_for_attribute).and_return(double('column', :type => :string, :limit => 255))
478
491
  concat(semantic_form_for(@new_post) do |builder|
479
492
  concat(builder.inputs(:login, :for => @bob))
480
493
  end)
481
494
 
482
- output_buffer.should have_tag("form fieldset.inputs #post_author_login")
483
- output_buffer.should_not have_tag("form fieldset.inputs #author_login")
495
+ expect(output_buffer).to have_tag("form fieldset.inputs #post_author_login")
496
+ expect(output_buffer).not_to have_tag("form fieldset.inputs #author_login")
484
497
  end
485
498
  end
486
499
 
@@ -489,8 +502,8 @@ describe 'Formtastic::FormBuilder#inputs' do
489
502
  concat(semantic_form_for(:project, :url => 'http://test.host/') do |builder|
490
503
  concat(builder.inputs(:login, :for => @bob))
491
504
  end)
492
- output_buffer.should have_tag("form fieldset.inputs #project_author_login")
493
- output_buffer.should_not have_tag("form fieldset.inputs #project_login")
505
+ expect(output_buffer).to have_tag("form fieldset.inputs #project_author_login")
506
+ expect(output_buffer).not_to have_tag("form fieldset.inputs #project_login")
494
507
  end
495
508
  end
496
509
  end
@@ -506,19 +519,52 @@ describe 'Formtastic::FormBuilder#inputs' do
506
519
  end
507
520
 
508
521
  it 'should render a form with a fieldset containing two list items' do
509
- output_buffer.should have_tag('form > fieldset.inputs > ol > li', :count => 4)
522
+ expect(output_buffer).to have_tag('form > fieldset.inputs > ol > li', :count => 4)
510
523
  end
511
524
 
512
525
  it 'should pass the options down to the fieldset' do
513
- output_buffer.should have_tag('form > fieldset#my-id.inputs')
526
+ expect(output_buffer).to have_tag('form > fieldset#my-id.inputs')
514
527
  end
515
528
 
516
529
  it 'should use the special :name option as a text for the legend tag' do
517
- output_buffer.should have_tag('form > fieldset#my-id.inputs > legend', /^#{@legend_text_using_option}$/)
518
- output_buffer.should have_tag('form > fieldset#my-id-2.inputs > legend', /^#{@legend_text_using_arg}$/)
530
+ expect(output_buffer).to have_tag('form > fieldset#my-id.inputs > legend', :text => /^#{@legend_text_using_option}$/)
531
+ expect(output_buffer).to have_tag('form > fieldset#my-id-2.inputs > legend', :text => /^#{@legend_text_using_arg}$/)
532
+ end
533
+ end
534
+
535
+ describe 'when a :except option is provided' do
536
+ describe 'and an object is given' do
537
+ it 'should render a form with a fieldset containing only string item' do
538
+ concat(semantic_form_for(@new_post) do |builder|
539
+ concat(builder.inputs :except => :body)
540
+ end)
541
+
542
+ expect(output_buffer).to have_tag('form > fieldset.inputs > ol > li', :count => 2)
543
+ expect(output_buffer).to have_tag('form > fieldset.inputs > ol > li.string')
544
+ expect(output_buffer).not_to have_tag('form > fieldset.inputs > ol > li.text')
545
+ end
546
+
547
+ it 'should render a form with a fieldset containing only text item' do
548
+ concat(semantic_form_for(@new_post) do |builder|
549
+ concat(builder.inputs :except => :title)
550
+ end)
551
+
552
+ expect(output_buffer).to have_tag('form > fieldset.inputs > ol > li', :count => 2)
553
+ expect(output_buffer).not_to have_tag('form > fieldset.inputs > ol > li.string')
554
+ expect(output_buffer).to have_tag('form > fieldset.inputs > ol > li.text')
555
+ end
556
+ end
557
+
558
+ describe 'and no object is given' do
559
+ it 'should render a form with a fieldset containing two list items' do
560
+ concat(semantic_form_for(:project, :url => 'http://test.host') do |builder|
561
+ concat(builder.inputs(:title, :body))
562
+ end)
563
+
564
+ expect(output_buffer).to have_tag('form > fieldset.inputs > ol > li.string', :count => 2)
565
+ end
519
566
  end
520
567
  end
521
-
522
568
  end
523
569
 
524
570
  describe 'nesting' do
@@ -529,7 +575,7 @@ describe 'Formtastic::FormBuilder#inputs' do
529
575
  concat(builder.inputs do
530
576
  end)
531
577
  end)
532
- output_buffer.should_not have_tag('form > li')
578
+ expect(output_buffer).not_to have_tag('form > li')
533
579
  end
534
580
  end
535
581
 
@@ -541,7 +587,7 @@ describe 'Formtastic::FormBuilder#inputs' do
541
587
  end)
542
588
  end)
543
589
  end)
544
- output_buffer.should have_tag('form > fieldset.inputs > ol > li > fieldset.inputs > ol')
590
+ expect(output_buffer).to have_tag('form > fieldset.inputs > ol > li > fieldset.inputs > ol')
545
591
  end
546
592
  end
547
593
 
@@ -553,7 +599,7 @@ describe 'Formtastic::FormBuilder#inputs' do
553
599
  end)
554
600
  end)
555
601
  end)
556
- output_buffer.should have_tag('form > fieldset.inputs > ol > li > fieldset.inputs > ol')
602
+ expect(output_buffer).to have_tag('form > fieldset.inputs > ol > li > fieldset.inputs > ol')
557
603
  end
558
604
  end
559
605
 
@@ -564,7 +610,7 @@ describe 'Formtastic::FormBuilder#inputs' do
564
610
  concat(builder.inputs(:title))
565
611
  end)
566
612
  end)
567
- output_buffer.should have_tag('form > fieldset.inputs > ol > li > fieldset.inputs > ol')
613
+ expect(output_buffer).to have_tag('form > fieldset.inputs > ol > li > fieldset.inputs > ol')
568
614
  end
569
615
  end
570
616
 
@@ -575,7 +621,7 @@ describe 'Formtastic::FormBuilder#inputs' do
575
621
  concat(builder.inputs(:name, :for => :author))
576
622
  end)
577
623
  end)
578
- output_buffer.should have_tag('form > fieldset.inputs > ol > li > fieldset.inputs > ol')
624
+ expect(output_buffer).to have_tag('form > fieldset.inputs > ol > li > fieldset.inputs > ol')
579
625
  end
580
626
  end
581
627
 
@@ -589,7 +635,7 @@ describe 'Formtastic::FormBuilder#inputs' do
589
635
  end)
590
636
  end)
591
637
  end)
592
- output_buffer.should have_tag('form > fieldset.inputs > ol > li > fieldset.inputs > ol > li > fieldset.inputs > ol')
638
+ expect(output_buffer).to have_tag('form > fieldset.inputs > ol > li > fieldset.inputs > ol > li > fieldset.inputs > ol')
593
639
  end
594
640
  end
595
641
 
@@ -603,7 +649,7 @@ describe 'Formtastic::FormBuilder#inputs' do
603
649
  end)
604
650
  end)
605
651
  end)
606
- output_buffer.should have_tag('form > fieldset.inputs > ol > li > fieldset.inputs > ol', :count => 2)
652
+ expect(output_buffer).to have_tag('form > fieldset.inputs > ol > li > fieldset.inputs > ol', :count => 2)
607
653
  end
608
654
  end
609
655
 
@@ -616,7 +662,7 @@ describe 'Formtastic::FormBuilder#inputs' do
616
662
  end
617
663
  end
618
664
  it "should throw PolymorphicInputWithoutCollectionError on sub_posts" do
619
- ::MongoPost.should_receive(:associations).at_least(3).times
665
+ expect(::MongoPost).to receive(:associations).at_least(3).times
620
666
  expect { generate_form }.to raise_error(Formtastic::PolymorphicInputWithoutCollectionError)
621
667
  end
622
668
  end
@@ -1,7 +1,7 @@
1
1
  # encoding: utf-8
2
2
  require 'spec_helper'
3
3
 
4
- describe 'Formtastic::Helpers::Reflection' do
4
+ RSpec.describe 'Formtastic::Helpers::Reflection' do
5
5
 
6
6
  include FormtasticSpecHelper
7
7
 
@@ -20,11 +20,11 @@ describe 'Formtastic::Helpers::Reflection' do
20
20
  context 'with an ActiveRecord object' do
21
21
  it "should return association details on an ActiveRecord association" do
22
22
  @reflection_tester = ReflectionTester.new(@new_post)
23
- @reflection_tester.reflection_for(:sub_posts).should_not be_nil
23
+ expect(@reflection_tester.reflection_for(:sub_posts)).not_to be_nil
24
24
  end
25
25
  it "should return association details on a MongoMapper association" do
26
26
  @reflection_tester = ReflectionTester.new(@new_mm_post)
27
- @reflection_tester.reflection_for(:sub_posts).should_not be_nil
27
+ expect(@reflection_tester.reflection_for(:sub_posts)).not_to be_nil
28
28
  end
29
29
  end
30
30