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,31 +1,24 @@
1
1
  # encoding: utf-8
2
+ # frozen_string_literal: true
2
3
  require 'spec_helper'
3
4
 
4
- describe 'Formtastic::FormBuilder#input' do
5
-
6
- include FormtasticSpecHelper
5
+ RSpec.describe 'with input class finder' do
6
+ include_context 'form builder'
7
7
 
8
8
  before do
9
- @output_buffer = ''
10
- mock_everything
11
-
12
9
  @errors = double('errors')
13
- @errors.stub(:[]).and_return([])
14
- @new_post.stub(:errors).and_return(@errors)
15
- end
16
-
17
- after do
18
- ::I18n.backend.reload!
10
+ allow(@errors).to receive(:[]).and_return([])
11
+ allow(@new_post).to receive(:errors).and_return(@errors)
19
12
  end
20
13
 
21
14
  describe 'arguments and options' do
22
15
 
23
16
  it 'should require the first argument (the method on form\'s object)' do
24
- lambda {
17
+ expect {
25
18
  concat(semantic_form_for(@new_post) do |builder|
26
19
  concat(builder.input()) # no args passed in at all
27
20
  end)
28
- }.should raise_error(ArgumentError)
21
+ }.to raise_error(ArgumentError)
29
22
  end
30
23
 
31
24
  describe ':required option' do
@@ -37,8 +30,8 @@ describe 'Formtastic::FormBuilder#input' do
37
30
  concat(semantic_form_for(@new_post) do |builder|
38
31
  concat(builder.input(:title, :required => true))
39
32
  end)
40
- output_buffer.should_not have_tag('form li.optional')
41
- output_buffer.should have_tag('form li.required')
33
+ expect(output_buffer.to_str).not_to have_tag('form li.optional')
34
+ expect(output_buffer.to_str).to have_tag('form li.required')
42
35
  end
43
36
  end
44
37
 
@@ -47,7 +40,7 @@ describe 'Formtastic::FormBuilder#input' do
47
40
  concat(semantic_form_for(@new_post) do |builder|
48
41
  concat(builder.input(:title, :required => true))
49
42
  end)
50
- output_buffer.should have_tag('form li.required label', /required yo/)
43
+ expect(output_buffer.to_str).to have_tag('form li.required label', :text => /required yo/)
51
44
  end
52
45
  end
53
46
  end
@@ -56,7 +49,7 @@ describe 'Formtastic::FormBuilder#input' do
56
49
 
57
50
  before do
58
51
  @string = Formtastic::FormBuilder.optional_string = " optional yo!" # ensure there's something in the string
59
- @new_post.class.should_not_receive(:reflect_on_all_validations)
52
+ expect(@new_post.class).not_to receive(:reflect_on_all_validations)
60
53
  end
61
54
 
62
55
  after do
@@ -67,26 +60,26 @@ describe 'Formtastic::FormBuilder#input' do
67
60
  concat(semantic_form_for(@new_post) do |builder|
68
61
  concat(builder.input(:title, :required => false))
69
62
  end)
70
- output_buffer.should_not have_tag('form li.required')
71
- output_buffer.should have_tag('form li.optional')
63
+ expect(output_buffer.to_str).not_to have_tag('form li.required')
64
+ expect(output_buffer.to_str).to have_tag('form li.optional')
72
65
  end
73
66
 
74
67
  it 'should set and "optional" class also when there is presence validator' do
75
- @new_post.class.should_receive(:validators_on).with(:title).at_least(:once).and_return([
76
- active_model_presence_validator([:title])
77
- ])
68
+ expect(@new_post.class).to receive(:validators_on).with(:title).at_least(:once).and_return([
69
+ active_model_presence_validator([:title])
70
+ ])
78
71
  concat(semantic_form_for(@new_post) do |builder|
79
72
  concat(builder.input(:title, :required => false))
80
73
  end)
81
- output_buffer.should_not have_tag('form li.required')
82
- output_buffer.should have_tag('form li.optional')
74
+ expect(output_buffer.to_str).not_to have_tag('form li.required')
75
+ expect(output_buffer.to_str).to have_tag('form li.optional')
83
76
  end
84
77
 
85
78
  it 'should append the "optional" string to the label' do
86
79
  concat(semantic_form_for(@new_post) do |builder|
87
80
  concat(builder.input(:title, :required => false))
88
81
  end)
89
- output_buffer.should have_tag('form li.optional label', /#{@string}$/)
82
+ expect(output_buffer.to_str).to have_tag('form li.optional label', :text => /#{@string}$/)
90
83
  end
91
84
 
92
85
  end
@@ -96,14 +89,14 @@ describe 'Formtastic::FormBuilder#input' do
96
89
  describe 'and an object was not given' do
97
90
 
98
91
  it 'should use the default value' do
99
- Formtastic::FormBuilder.all_fields_required_by_default.should == true
92
+ expect(Formtastic::FormBuilder.all_fields_required_by_default).to eq(true)
100
93
  Formtastic::FormBuilder.all_fields_required_by_default = false
101
94
 
102
95
  concat(semantic_form_for(:project, :url => 'http://test.host/') do |builder|
103
96
  concat(builder.input(:title))
104
97
  end)
105
- output_buffer.should_not have_tag('form li.required')
106
- output_buffer.should have_tag('form li.optional')
98
+ expect(output_buffer.to_str).not_to have_tag('form li.required')
99
+ expect(output_buffer.to_str).to have_tag('form li.optional')
107
100
 
108
101
  Formtastic::FormBuilder.all_fields_required_by_default = true
109
102
  end
@@ -112,90 +105,151 @@ describe 'Formtastic::FormBuilder#input' do
112
105
 
113
106
  describe 'and an object with :validators_on was given (ActiveModel, Active Resource)' do
114
107
  before do
115
- @new_post.stub(:class).and_return(::PostModel)
108
+ allow(@new_post).to receive(:class).and_return(::PostModel)
116
109
  end
117
110
 
118
111
  after do
119
- @new_post.stub(:class).and_return(::Post)
112
+ allow(@new_post).to receive(:class).and_return(::Post)
120
113
  end
121
114
  describe 'and validates_presence_of was called for the method' do
122
115
  it 'should be required' do
123
116
 
124
- @new_post.class.should_receive(:validators_on).with(:title).at_least(:once).and_return([
125
- active_model_presence_validator([:title])
126
- ])
117
+ expect(@new_post.class).to receive(:validators_on).with(:title).at_least(:once).and_return([
118
+ active_model_presence_validator([:title])
119
+ ])
127
120
 
128
- @new_post.class.should_receive(:validators_on).with(:body).at_least(:once).and_return([
129
- active_model_presence_validator([:body], {:if => true})
130
- ])
121
+ expect(@new_post.class).to receive(:validators_on).with(:body).at_least(:once).and_return([
122
+ active_model_presence_validator([:body], {:if => true})
123
+ ])
131
124
 
132
125
  concat(semantic_form_for(@new_post) do |builder|
133
126
  concat(builder.input(:title))
134
127
  concat(builder.input(:body))
135
128
  end)
136
- output_buffer.should have_tag('form li.required')
137
- output_buffer.should_not have_tag('form li.optional')
129
+ expect(output_buffer.to_str).to have_tag('form li.required')
130
+ expect(output_buffer.to_str).not_to have_tag('form li.optional')
138
131
  end
139
132
 
140
133
  it 'should be required when there is :on => :create option on create' do
141
134
  with_config :required_string, " required yo!" do
142
- @new_post.class.should_receive(:validators_on).with(:title).at_least(:once).and_return([
143
- active_model_presence_validator([:title], {:on => :create})
144
- ])
135
+ expect(@new_post.class).to receive(:validators_on).with(:title).at_least(:once).and_return([
136
+ active_model_presence_validator([:title], {:on => :create})
137
+ ])
138
+ concat(semantic_form_for(@new_post) do |builder|
139
+ concat(builder.input(:title))
140
+ end)
141
+ expect(output_buffer.to_str).to have_tag('form li.required')
142
+ expect(output_buffer.to_str).not_to have_tag('form li.optional')
143
+ end
144
+ end
145
+
146
+ it 'should be required when there is :create option in validation contexts array on create' do
147
+ with_config :required_string, " required yo!" do
148
+ expect(@new_post.class).to receive(:validators_on).with(:title).at_least(:once).and_return([
149
+ active_model_presence_validator([:title], {:on => [:create]})
150
+ ])
145
151
  concat(semantic_form_for(@new_post) do |builder|
146
152
  concat(builder.input(:title))
147
153
  end)
148
- output_buffer.should have_tag('form li.required')
149
- output_buffer.should_not have_tag('form li.optional')
154
+ expect(output_buffer.to_str).to have_tag('form li.required')
155
+ expect(output_buffer.to_str).not_to have_tag('form li.optional')
150
156
  end
151
157
  end
152
158
 
153
159
  it 'should be required when there is :on => :save option on create' do
154
160
  with_config :required_string, " required yo!" do
155
- @new_post.class.should_receive(:validators_on).with(:title).at_least(:once).and_return([
156
- active_model_presence_validator([:title], {:on => :save})
157
- ])
161
+ expect(@new_post.class).to receive(:validators_on).with(:title).at_least(:once).and_return([
162
+ active_model_presence_validator([:title], {:on => :save})
163
+ ])
164
+ concat(semantic_form_for(@new_post) do |builder|
165
+ concat(builder.input(:title))
166
+ end)
167
+ expect(output_buffer.to_str).to have_tag('form li.required')
168
+ expect(output_buffer.to_str).not_to have_tag('form li.optional')
169
+ end
170
+ end
171
+
172
+ it 'should be required when there is :save option in validation contexts array on create' do
173
+ with_config :required_string, " required yo!" do
174
+ expect(@new_post.class).to receive(:validators_on).with(:title).at_least(:once).and_return([
175
+ active_model_presence_validator([:title], {:on => [:save]})
176
+ ])
158
177
  concat(semantic_form_for(@new_post) do |builder|
159
178
  concat(builder.input(:title))
160
179
  end)
161
- output_buffer.should have_tag('form li.required')
162
- output_buffer.should_not have_tag('form li.optional')
180
+ expect(output_buffer.to_str).to have_tag('form li.required')
181
+ expect(output_buffer.to_str).not_to have_tag('form li.optional')
163
182
  end
164
183
  end
165
184
 
166
185
  it 'should be required when there is :on => :save option on update' do
167
186
  with_config :required_string, " required yo!" do
168
- @fred.class.should_receive(:validators_on).with(:login).at_least(:once).and_return([
169
- active_model_presence_validator([:login], {:on => :save})
170
- ])
187
+ expect(@fred.class).to receive(:validators_on).with(:login).at_least(:once).and_return([
188
+ active_model_presence_validator([:login], {:on => :save})
189
+ ])
171
190
  concat(semantic_form_for(@fred) do |builder|
172
191
  concat(builder.input(:login))
173
192
  end)
174
- output_buffer.should have_tag('form li.required')
175
- output_buffer.should_not have_tag('form li.optional')
193
+ expect(output_buffer.to_str).to have_tag('form li.required')
194
+ expect(output_buffer.to_str).not_to have_tag('form li.optional')
195
+ end
196
+ end
197
+
198
+ it 'should be required when there is :save option in validation contexts array on update' do
199
+ with_config :required_string, " required yo!" do
200
+ expect(@fred.class).to receive(:validators_on).with(:login).at_least(:once).and_return([
201
+ active_model_presence_validator([:login], {:on => [:save]})
202
+ ])
203
+ concat(semantic_form_for(@fred) do |builder|
204
+ concat(builder.input(:login))
205
+ end)
206
+ expect(output_buffer.to_str).to have_tag('form li.required')
207
+ expect(output_buffer.to_str).not_to have_tag('form li.optional')
176
208
  end
177
209
  end
178
210
 
179
211
  it 'should not be required when there is :on => :create option on update' do
180
- @fred.class.should_receive(:validators_on).with(:login).at_least(:once).and_return([
181
- active_model_presence_validator([:login], {:on => :create})
182
- ])
212
+ expect(@fred.class).to receive(:validators_on).with(:login).at_least(:once).and_return([
213
+ active_model_presence_validator([:login], {:on => :create})
214
+ ])
215
+ concat(semantic_form_for(@fred) do |builder|
216
+ concat(builder.input(:login))
217
+ end)
218
+ expect(output_buffer.to_str).not_to have_tag('form li.required')
219
+ expect(output_buffer.to_str).to have_tag('form li.optional')
220
+ end
221
+
222
+ it 'should not be required when there is :create option in validation contexts array on update' do
223
+ expect(@fred.class).to receive(:validators_on).with(:login).at_least(:once).and_return([
224
+ active_model_presence_validator([:login], {:on => [:create]})
225
+ ])
183
226
  concat(semantic_form_for(@fred) do |builder|
184
227
  concat(builder.input(:login))
185
228
  end)
186
- output_buffer.should_not have_tag('form li.required')
187
- output_buffer.should have_tag('form li.optional')
229
+ expect(output_buffer.to_str).not_to have_tag('form li.required')
230
+ expect(output_buffer.to_str).to have_tag('form li.optional')
188
231
  end
189
232
 
190
233
  it 'should not be required when there is :on => :update option on create' do
191
- @new_post.class.should_receive(:validators_on).with(:title).at_least(:once).and_return([
192
- active_model_presence_validator([:title], {:on => :update})
193
- ])
234
+ expect(@new_post.class).to receive(:validators_on).with(:title).at_least(:once).and_return([
235
+ active_model_presence_validator([:title], {:on => :update})
236
+ ])
194
237
  concat(semantic_form_for(@new_post) do |builder|
195
238
  concat(builder.input(:title))
196
239
  end)
197
- output_buffer.should_not have_tag('form li.required')
198
- output_buffer.should have_tag('form li.optional')
240
+ expect(output_buffer.to_str).not_to have_tag('form li.required')
241
+ expect(output_buffer.to_str).to have_tag('form li.optional')
242
+ end
243
+
244
+ it 'should not be required when there is :update option in validation contexts array on create' do
245
+ expect(@new_post.class).to receive(:validators_on).with(:title).at_least(:once).and_return([
246
+ active_model_presence_validator([:title], {:on => [:update]})
247
+ ])
248
+ concat(semantic_form_for(@new_post) do |builder|
249
+ concat(builder.input(:title))
250
+ end)
251
+ expect(output_buffer.to_str).not_to have_tag('form li.required')
252
+ expect(output_buffer.to_str).to have_tag('form li.optional')
199
253
  end
200
254
 
201
255
  it 'should be not be required if the optional :if condition is not satisifed' do
@@ -219,38 +273,38 @@ describe 'Formtastic::FormBuilder#input' do
219
273
  end
220
274
 
221
275
  it 'should be required if the optional :if with a method string evaluates to true' do
222
- @new_post.should_receive(:required_condition).and_return(true)
276
+ expect(@new_post).to receive(:required_condition).and_return(true)
223
277
  presence_should_be_required(:required => true, :tag => :body, :options => { :if => :required_condition })
224
278
  end
225
279
 
226
280
  it 'should be required if the optional :if with a method string evaluates to false' do
227
- @new_post.should_receive(:required_condition).and_return(false)
281
+ expect(@new_post).to receive(:required_condition).and_return(false)
228
282
  presence_should_be_required(:required => false, :tag => :body, :options => { :if => :required_condition })
229
283
  end
230
284
 
231
285
  it 'should be required if the optional :unless with a method string evaluates to false' do
232
- @new_post.should_receive(:required_condition).and_return(false)
286
+ expect(@new_post).to receive(:required_condition).and_return(false)
233
287
  presence_should_be_required(:required => true, :tag => :body, :options => { :unless => :required_condition })
234
288
  end
235
289
 
236
- it 'should not be required if the optional :unless with a method string evaluates to true' do
237
- @new_post.should_receive(:required_condition).and_return(true)
238
- presence_should_be_required(:required => false, :tag => :body, :options => { :unless => :required_condition })
239
- end
290
+ it 'should not be required if the optional :unless with a method string evaluates to true' do
291
+ expect(@new_post).to receive(:required_condition).and_return(true)
292
+ presence_should_be_required(:required => false, :tag => :body, :options => { :unless => :required_condition })
293
+ end
240
294
  end
241
295
 
242
296
  describe 'and validates_inclusion_of was called for the method' do
243
297
  it 'should be required' do
244
- @new_post.class.should_receive(:validators_on).with(:published).at_least(:once).and_return([
245
- active_model_inclusion_validator([:published], {:in => [false, true]})
246
- ])
298
+ expect(@new_post.class).to receive(:validators_on).with(:published).at_least(:once).and_return([
299
+ active_model_inclusion_validator([:published], {:in => [false, true]})
300
+ ])
247
301
  should_be_required(:tag => :published, :required => true)
248
302
  end
249
303
 
250
304
  it 'should not be required if allow_blank is true' do
251
- @new_post.class.should_receive(:validators_on).with(:published).at_least(:once).and_return([
252
- active_model_inclusion_validator([:published], {:in => [false, true], :allow_blank => true})
253
- ])
305
+ expect(@new_post.class).to receive(:validators_on).with(:published).at_least(:once).and_return([
306
+ active_model_inclusion_validator([:published], {:in => [false, true], :allow_blank => true})
307
+ ])
254
308
  should_be_required(:tag => :published, :required => false)
255
309
  end
256
310
  end
@@ -282,14 +336,14 @@ describe 'Formtastic::FormBuilder#input' do
282
336
  end
283
337
 
284
338
  def add_presence_validator(options)
285
- @new_post.class.stub(:validators_on).with(options[:tag]).and_return([
286
- active_model_presence_validator([options[:tag]], options[:options])
287
- ])
339
+ allow(@new_post.class).to receive(:validators_on).with(options[:tag]).and_return([
340
+ active_model_presence_validator([options[:tag]], options[:options])
341
+ ])
288
342
  end
289
343
 
290
344
  def add_length_validator(options)
291
- @new_post.class.should_receive(:validators_on).with(options[:tag]).at_least(:once) {[
292
- active_model_length_validator([options[:tag]], options[:options])
345
+ expect(@new_post.class).to receive(:validators_on).with(options[:tag]).at_least(:once) {[
346
+ active_model_length_validator([options[:tag]], options[:options])
293
347
  ]}
294
348
  end
295
349
 
@@ -300,11 +354,11 @@ describe 'Formtastic::FormBuilder#input' do
300
354
  end)
301
355
 
302
356
  if options[:required]
303
- output_buffer.should_not have_tag('form li.optional')
304
- output_buffer.should have_tag('form li.required')
357
+ expect(output_buffer.to_str).not_to have_tag('form li.optional')
358
+ expect(output_buffer.to_str).to have_tag('form li.required')
305
359
  else
306
- output_buffer.should have_tag('form li.optional')
307
- output_buffer.should_not have_tag('form li.required')
360
+ expect(output_buffer.to_str).to have_tag('form li.optional')
361
+ expect(output_buffer.to_str).not_to have_tag('form li.required')
308
362
  end
309
363
  end
310
364
 
@@ -321,15 +375,15 @@ describe 'Formtastic::FormBuilder#input' do
321
375
  # TODO JF reversed this during refactor, need to make sure
322
376
  describe 'and there are no requirement validations on the method' do
323
377
  before do
324
- @new_post.class.should_receive(:validators_on).with(:title).and_return([])
378
+ expect(@new_post.class).to receive(:validators_on).with(:title).and_return([])
325
379
  end
326
380
 
327
381
  it 'should not be required' do
328
382
  concat(semantic_form_for(@new_post) do |builder|
329
383
  concat(builder.input(:title))
330
384
  end)
331
- output_buffer.should_not have_tag('form li.required')
332
- output_buffer.should have_tag('form li.optional')
385
+ expect(output_buffer.to_str).not_to have_tag('form li.required')
386
+ expect(output_buffer.to_str).to have_tag('form li.optional')
333
387
  end
334
388
  end
335
389
 
@@ -337,21 +391,21 @@ describe 'Formtastic::FormBuilder#input' do
337
391
 
338
392
  describe 'and an object without :validators_on' do
339
393
 
340
- it 'should use the default value' do
341
- Formtastic::FormBuilder.all_fields_required_by_default.should == true
342
- Formtastic::FormBuilder.all_fields_required_by_default = false
343
-
344
- concat(semantic_form_for(@new_post) do |builder|
345
- concat(builder.input(:title))
346
- end)
347
- output_buffer.should_not have_tag('form li.required')
348
- output_buffer.should have_tag('form li.optional')
394
+ it 'should use the default value' do
395
+ expect(Formtastic::FormBuilder.all_fields_required_by_default).to eq(true)
396
+ Formtastic::FormBuilder.all_fields_required_by_default = false
349
397
 
350
- Formtastic::FormBuilder.all_fields_required_by_default = true
351
- end
398
+ concat(semantic_form_for(@new_post) do |builder|
399
+ concat(builder.input(:title))
400
+ end)
401
+ expect(output_buffer.to_str).not_to have_tag('form li.required')
402
+ expect(output_buffer.to_str).to have_tag('form li.optional')
352
403
 
404
+ Formtastic::FormBuilder.all_fields_required_by_default = true
353
405
  end
354
406
 
407
+ end
408
+
355
409
  end
356
410
 
357
411
  end
@@ -364,7 +418,7 @@ describe 'Formtastic::FormBuilder#input' do
364
418
  concat(semantic_form_for(:project, :url => 'http://test.host') do |builder|
365
419
  concat(builder.input(:anything))
366
420
  end)
367
- output_buffer.should have_tag('form li.string')
421
+ expect(output_buffer.to_str).to have_tag('form li.string')
368
422
  end
369
423
 
370
424
  it 'should default to password for forms without objects if column is password' do
@@ -373,107 +427,129 @@ describe 'Formtastic::FormBuilder#input' do
373
427
  concat(builder.input(:password_confirmation))
374
428
  concat(builder.input(:confirm_password))
375
429
  end)
376
- output_buffer.should have_tag('form li.password', :count => 3)
430
+ expect(output_buffer.to_str).to have_tag('form li.password', :count => 3)
377
431
  end
378
432
 
379
433
  it 'should default to a string for methods on objects that don\'t respond to "column_for_attribute"' do
380
- @new_post.stub(:method_without_a_database_column)
381
- @new_post.stub(:column_for_attribute).and_return(nil)
382
- default_input_type(nil, :method_without_a_database_column).should == :string
434
+ allow(@new_post).to receive(:method_without_a_database_column)
435
+ allow(@new_post).to receive(:column_for_attribute).and_return(nil)
436
+ expect(default_input_type(nil, :method_without_a_database_column)).to eq(:string)
383
437
  end
384
438
 
385
439
  it 'should default to :password for methods that don\'t have a column in the database but "password" is in the method name' do
386
- @new_post.stub(:password_method_without_a_database_column)
387
- @new_post.stub(:column_for_attribute).and_return(nil)
388
- default_input_type(nil, :password_method_without_a_database_column).should == :password
440
+ allow(@new_post).to receive(:password_method_without_a_database_column)
441
+ allow(@new_post).to receive(:column_for_attribute).and_return(nil)
442
+ expect(default_input_type(nil, :password_method_without_a_database_column)).to eq(:password)
389
443
  end
390
444
 
391
445
  it 'should default to :password for methods on objects that don\'t respond to "column_for_attribute" but "password" is in the method name' do
392
- @new_post.stub(:password_method_without_a_database_column)
393
- @new_post.stub(:column_for_attribute).and_return(nil)
394
- default_input_type(nil, :password_method_without_a_database_column).should == :password
446
+ allow(@new_post).to receive(:password_method_without_a_database_column)
447
+ allow(@new_post).to receive(:column_for_attribute).and_return(nil)
448
+ expect(default_input_type(nil, :password_method_without_a_database_column)).to eq(:password)
395
449
  end
396
450
 
397
451
  it 'should default to :number for "integer" column with name ending in "_id"' do
398
- @new_post.stub(:aws_instance_id)
399
- @new_post.stub(:column_for_attribute).with(:aws_instance_id).and_return(double('column', :type => :integer))
400
- default_input_type(:integer, :aws_instance_id).should == :number
452
+ allow(@new_post).to receive(:aws_instance_id)
453
+ allow(@new_post).to receive(:column_for_attribute).with(:aws_instance_id).and_return(double('column', :type => :integer))
454
+ expect(default_input_type(:integer, :aws_instance_id)).to eq(:number)
401
455
  end
402
456
 
403
457
  it 'should default to :select for associations' do
404
- @new_post.class.stub(:reflect_on_association).with(:user_id).and_return(double('ActiveRecord::Reflection::AssociationReflection'))
405
- @new_post.class.stub(:reflect_on_association).with(:section_id).and_return(double('ActiveRecord::Reflection::AssociationReflection'))
406
- default_input_type(:integer, :user_id).should == :select
407
- default_input_type(:integer, :section_id).should == :select
458
+ allow(@new_post.class).to receive(:reflect_on_association).with(:user_id).and_return(double('ActiveRecord::Reflection::AssociationReflection'))
459
+ allow(@new_post.class).to receive(:reflect_on_association).with(:section_id).and_return(double('ActiveRecord::Reflection::AssociationReflection'))
460
+ expect(default_input_type(:integer, :user_id)).to eq(:select)
461
+ expect(default_input_type(:integer, :section_id)).to eq(:select)
462
+ end
463
+
464
+ it 'should default to :select for enum' do
465
+ statuses = ActiveSupport::HashWithIndifferentAccess.new("active"=>0, "inactive"=>1)
466
+ allow(@new_post.class).to receive(:statuses) { statuses }
467
+ allow(@new_post).to receive(:defined_enums) { {"status" => statuses } }
468
+
469
+ expect(default_input_type(:integer, :status)).to eq(:select)
408
470
  end
409
471
 
410
472
  it 'should default to :password for :string column types with "password" in the method name' do
411
- default_input_type(:string, :password).should == :password
412
- default_input_type(:string, :hashed_password).should == :password
413
- default_input_type(:string, :password_hash).should == :password
473
+ expect(default_input_type(:string, :password)).to eq(:password)
474
+ expect(default_input_type(:string, :hashed_password)).to eq(:password)
475
+ expect(default_input_type(:string, :password_hash)).to eq(:password)
414
476
  end
415
477
 
416
478
  it 'should default to :text for :text column types' do
417
- default_input_type(:text).should == :text
479
+ expect(default_input_type(:text)).to eq(:text)
418
480
  end
419
481
 
420
482
  it 'should default to :date_select for :date column types' do
421
- default_input_type(:date).should == :date_select
483
+ expect(default_input_type(:date)).to eq(:date_select)
484
+ end
485
+
486
+ it 'should default to :text for :hstore, :json and :jsonb column types' do
487
+ expect(default_input_type(:hstore)).to eq(:text)
488
+ expect(default_input_type(:json)).to eq(:text)
489
+ expect(default_input_type(:jsonb)).to eq(:text)
422
490
  end
423
491
 
424
492
  it 'should default to :datetime_select for :datetime and :timestamp column types' do
425
- default_input_type(:datetime).should == :datetime_select
426
- default_input_type(:timestamp).should == :datetime_select
493
+ expect(default_input_type(:datetime)).to eq(:datetime_select)
494
+ expect(default_input_type(:timestamp)).to eq(:datetime_select)
427
495
  end
428
496
 
429
497
  it 'should default to :time_select for :time column types' do
430
- default_input_type(:time).should == :time_select
498
+ expect(default_input_type(:time)).to eq(:time_select)
431
499
  end
432
500
 
433
501
  it 'should default to :boolean for :boolean column types' do
434
- default_input_type(:boolean).should == :boolean
502
+ expect(default_input_type(:boolean)).to eq(:boolean)
435
503
  end
436
504
 
437
505
  it 'should default to :string for :string column types' do
438
- default_input_type(:string).should == :string
506
+ expect(default_input_type(:string)).to eq(:string)
507
+ end
508
+
509
+ it 'should default to :string for :citext column types' do
510
+ expect(default_input_type(:citext)).to eq(:string)
511
+ end
512
+
513
+ it 'should default to :string for :inet column types' do
514
+ expect(default_input_type(:inet)).to eq(:string)
439
515
  end
440
516
 
441
517
  it 'should default to :number for :integer, :float and :decimal column types' do
442
- default_input_type(:integer).should == :number
443
- default_input_type(:float).should == :number
444
- default_input_type(:decimal).should == :number
518
+ expect(default_input_type(:integer)).to eq(:number)
519
+ expect(default_input_type(:float)).to eq(:number)
520
+ expect(default_input_type(:decimal)).to eq(:number)
445
521
  end
446
522
 
447
523
  it 'should default to :country for :string columns named country' do
448
- default_input_type(:string, :country).should == :country
524
+ expect(default_input_type(:string, :country)).to eq(:country)
449
525
  end
450
526
 
451
527
  it 'should default to :email for :string columns matching email' do
452
- default_input_type(:string, :email).should == :email
453
- default_input_type(:string, :customer_email).should == :email
454
- default_input_type(:string, :email_work).should == :email
528
+ expect(default_input_type(:string, :email)).to eq(:email)
529
+ expect(default_input_type(:string, :customer_email)).to eq(:email)
530
+ expect(default_input_type(:string, :email_work)).to eq(:email)
455
531
  end
456
532
 
457
533
  it 'should default to :url for :string columns named url or website' do
458
- default_input_type(:string, :url).should == :url
459
- default_input_type(:string, :website).should == :url
460
- default_input_type(:string, :my_url).should == :url
461
- default_input_type(:string, :hurl).should_not == :url
534
+ expect(default_input_type(:string, :url)).to eq(:url)
535
+ expect(default_input_type(:string, :website)).to eq(:url)
536
+ expect(default_input_type(:string, :my_url)).to eq(:url)
537
+ expect(default_input_type(:string, :hurl)).not_to eq(:url)
462
538
  end
463
539
 
464
540
  it 'should default to :phone for :string columns named phone or fax' do
465
- default_input_type(:string, :phone).should == :phone
466
- default_input_type(:string, :fax).should == :phone
541
+ expect(default_input_type(:string, :phone)).to eq(:phone)
542
+ expect(default_input_type(:string, :fax)).to eq(:phone)
467
543
  end
468
544
 
469
545
  it 'should default to :search for :string columns named search' do
470
- default_input_type(:string, :search).should == :search
546
+ expect(default_input_type(:string, :search)).to eq(:search)
471
547
  end
472
548
 
473
549
  it 'should default to :color for :string columns matching color' do
474
- default_input_type(:string, :color).should == :color
475
- default_input_type(:string, :user_color).should == :color
476
- default_input_type(:string, :color_for_image).should == :color
550
+ expect(default_input_type(:string, :color)).to eq(:color)
551
+ expect(default_input_type(:string, :user_color)).to eq(:color)
552
+ expect(default_input_type(:string, :color_for_image)).to eq(:color)
477
553
  end
478
554
 
479
555
  describe 'defaulting to file column' do
@@ -483,13 +559,13 @@ describe 'Formtastic::FormBuilder#input' do
483
559
 
484
560
  Formtastic::FormBuilder.file_methods.each do |test|
485
561
  ### TODO: Check if this is ok
486
- column.stub(method).with(test).and_return(method == test)
562
+ allow(column).to receive(method).with(test).and_return(method == test)
487
563
  end
488
564
 
489
- @new_post.should_receive(method).and_return(column)
565
+ expect(@new_post).to receive(method).and_return(column)
490
566
 
491
567
  semantic_form_for(@new_post) do |builder|
492
- builder.send(:default_input_type, method).should == :file
568
+ expect(builder.send(:default_input_type, method)).to eq(:file)
493
569
  end
494
570
  end
495
571
  end
@@ -499,15 +575,15 @@ describe 'Formtastic::FormBuilder#input' do
499
575
 
500
576
  it 'should call the corresponding input class with .to_html' do
501
577
  [:select, :time_zone, :radio, :date_select, :datetime_select, :time_select, :boolean, :check_boxes, :hidden, :string, :password, :number, :text, :file].each do |input_style|
502
- @new_post.stub(:generic_column_name)
503
- @new_post.stub(:column_for_attribute).and_return(double('column', :type => :string, :limit => 255))
578
+ allow(@new_post).to receive(:generic_column_name)
579
+ allow(@new_post).to receive(:column_for_attribute).and_return(double('column', :type => :string, :limit => 255))
504
580
  semantic_form_for(@new_post) do |builder|
505
581
  input_instance = double('Input instance')
506
582
  input_class = "#{input_style.to_s}_input".classify
507
583
  input_constant = "Formtastic::Inputs::#{input_class}".constantize
508
584
 
509
- input_constant.should_receive(:new).and_return(input_instance)
510
- input_instance.should_receive(:to_html).and_return("some HTML")
585
+ expect(input_constant).to receive(:new).and_return(input_instance)
586
+ expect(input_instance).to receive(:to_html).and_return("some HTML")
511
587
 
512
588
  concat(builder.input(:generic_column_name, :as => input_style))
513
589
  end
@@ -523,21 +599,21 @@ describe 'Formtastic::FormBuilder#input' do
523
599
  concat(semantic_form_for(@new_post) do |builder|
524
600
  concat(builder.input(:title, :label => "Kustom"))
525
601
  end)
526
- output_buffer.should have_tag("form li label", /Kustom/)
602
+ expect(output_buffer.to_str).to have_tag("form li label", :text => /Kustom/)
527
603
  end
528
604
 
529
605
  it 'should not generate a label if false' do
530
606
  concat(semantic_form_for(@new_post) do |builder|
531
607
  concat(builder.input(:title, :label => false))
532
608
  end)
533
- output_buffer.should_not have_tag("form li label")
609
+ expect(output_buffer.to_str).not_to have_tag("form li label")
534
610
  end
535
611
 
536
612
  it 'should be dupped if frozen' do
537
613
  concat(semantic_form_for(@new_post) do |builder|
538
614
  concat(builder.input(:title, :label => "Kustom".freeze))
539
615
  end)
540
- output_buffer.should have_tag("form li label", /Kustom/)
616
+ expect(output_buffer.to_str).to have_tag("form li label", :text => /Kustom/)
541
617
  end
542
618
  end
543
619
 
@@ -548,18 +624,18 @@ describe 'Formtastic::FormBuilder#input' do
548
624
  it 'should render a label with localized text and not apply the label_str_method' do
549
625
  with_config :label_str_method, :reverse do
550
626
  @localized_label_text = 'Localized title'
551
- @new_post.stub(:meta_description)
627
+ allow(@new_post).to receive(:meta_description)
552
628
  ::I18n.backend.store_translations :en,
553
- :formtastic => {
554
- :labels => {
555
- :meta_description => @localized_label_text
556
- }
557
- }
629
+ :formtastic => {
630
+ :labels => {
631
+ :meta_description => @localized_label_text
632
+ }
633
+ }
558
634
 
559
635
  concat(semantic_form_for(@new_post) do |builder|
560
636
  concat(builder.input(:meta_description))
561
637
  end)
562
- output_buffer.should have_tag('form li label', /Localized title/)
638
+ expect(output_buffer.to_str).to have_tag('form li label', :text => /Localized title/)
563
639
  end
564
640
  end
565
641
  end
@@ -574,32 +650,32 @@ describe 'Formtastic::FormBuilder#input' do
574
650
  concat(semantic_form_for(:project, :url => 'http://test.host') do |builder|
575
651
  concat(builder.input(:meta_description))
576
652
  end)
577
- output_buffer.should have_tag("form li label", /#{'meta_description'.humanize}/)
653
+ expect(output_buffer.to_str).to have_tag("form li label", :text => /#{'meta_description'.humanize}/)
578
654
  end
579
655
  end
580
656
  end
581
657
 
582
658
  describe 'and object is given' do
583
659
  it 'should delegate the label logic to class human attribute name and pass it down to the label tag' do
584
- @new_post.stub(:meta_description) # a two word method name
585
- @new_post.class.should_receive(:human_attribute_name).with('meta_description').and_return('meta_description'.humanize)
660
+ allow(@new_post).to receive(:meta_description) # a two word method name
661
+ expect(@new_post.class).to receive(:human_attribute_name).with('meta_description').and_return('meta_description'.humanize)
586
662
 
587
663
  concat(semantic_form_for(@new_post) do |builder|
588
664
  concat(builder.input(:meta_description))
589
665
  end)
590
- output_buffer.should have_tag("form li label", /#{'meta_description'.humanize}/)
666
+ expect(output_buffer.to_str).to have_tag("form li label", :text => /#{'meta_description'.humanize}/)
591
667
  end
592
668
  end
593
669
 
594
670
  describe 'and object is given with label_str_method set to :capitalize' do
595
671
  it 'should capitalize method name, passing it down to the label tag' do
596
672
  with_config :label_str_method, :capitalize do
597
- @new_post.stub(:meta_description)
673
+ allow(@new_post).to receive(:meta_description)
598
674
 
599
675
  concat(semantic_form_for(@new_post) do |builder|
600
676
  concat(builder.input(:meta_description))
601
677
  end)
602
- output_buffer.should have_tag("form li label", /#{'meta_description'.capitalize}/)
678
+ expect(output_buffer.to_str).to have_tag("form li label", :text => /#{'meta_description'.capitalize}/)
603
679
  end
604
680
  end
605
681
  end
@@ -610,16 +686,16 @@ describe 'Formtastic::FormBuilder#input' do
610
686
  @localized_label_text = 'Localized title'
611
687
  @default_localized_label_text = 'Default localized title'
612
688
  ::I18n.backend.store_translations :en,
613
- :formtastic => {
614
- :labels => {
615
- :title => @default_localized_label_text,
616
- :published => @default_localized_label_text,
617
- :post => {
618
- :title => @localized_label_text,
619
- :published => @default_localized_label_text
620
- }
621
- }
622
- }
689
+ :formtastic => {
690
+ :labels => {
691
+ :title => @default_localized_label_text,
692
+ :published => @default_localized_label_text,
693
+ :post => {
694
+ :title => @localized_label_text,
695
+ :published => @default_localized_label_text
696
+ }
697
+ }
698
+ }
623
699
  end
624
700
 
625
701
  it 'should render a label with localized label (I18n)' do
@@ -628,26 +704,26 @@ describe 'Formtastic::FormBuilder#input' do
628
704
  concat(builder.input(:title, :label => true))
629
705
  concat(builder.input(:published, :as => :boolean, :label => true))
630
706
  end)
631
- output_buffer.should have_tag('form li label', Regexp.new('^' + @localized_label_text))
707
+ expect(output_buffer.to_str).to have_tag('form li label', :text => Regexp.new('^' + @localized_label_text))
632
708
  end
633
709
  end
634
710
 
635
711
  it 'should render a hint paragraph containing an optional localized label (I18n) if first is not set' do
636
712
  with_config :i18n_lookups_by_default, false do
637
713
  ::I18n.backend.store_translations :en,
638
- :formtastic => {
639
- :labels => {
640
- :post => {
641
- :title => nil,
642
- :published => nil
643
- }
644
- }
645
- }
714
+ :formtastic => {
715
+ :labels => {
716
+ :post => {
717
+ :title => nil,
718
+ :published => nil
719
+ }
720
+ }
721
+ }
646
722
  concat(semantic_form_for(@new_post) do |builder|
647
723
  concat(builder.input(:title, :label => true))
648
724
  concat(builder.input(:published, :as => :boolean, :label => true))
649
725
  end)
650
- output_buffer.should have_tag('form li label', Regexp.new('^' + @default_localized_label_text))
726
+ expect(output_buffer.to_str).to have_tag('form li label', :text => Regexp.new('^' + @default_localized_label_text))
651
727
  end
652
728
  end
653
729
  end
@@ -668,7 +744,7 @@ describe 'Formtastic::FormBuilder#input' do
668
744
  concat(semantic_form_for(@new_post) do |builder|
669
745
  concat(builder.input(:title, :hint => hint_text))
670
746
  end)
671
- output_buffer.should have_tag("form li p.inline-hints", hint_text)
747
+ expect(output_buffer.to_str).to have_tag("form li p.inline-hints", :text => hint_text)
672
748
  end
673
749
 
674
750
  it 'should have a custom hint class defaulted for all forms' do
@@ -677,7 +753,7 @@ describe 'Formtastic::FormBuilder#input' do
677
753
  concat(semantic_form_for(@new_post) do |builder|
678
754
  concat(builder.input(:title, :hint => hint_text))
679
755
  end)
680
- output_buffer.should have_tag("form li p.custom-hint-class", hint_text)
756
+ expect(output_buffer.to_str).to have_tag("form li p.custom-hint-class", :text => hint_text)
681
757
  end
682
758
  end
683
759
 
@@ -687,11 +763,11 @@ describe 'Formtastic::FormBuilder#input' do
687
763
  @localized_hint_text = "This is the localized hint."
688
764
  @default_localized_hint_text = "This is the default localized hint."
689
765
  ::I18n.backend.store_translations :en,
690
- :formtastic => {
691
- :hints => {
692
- :title => @default_localized_hint_text,
693
- }
694
- }
766
+ :formtastic => {
767
+ :hints => {
768
+ :title => @default_localized_hint_text,
769
+ }
770
+ }
695
771
  end
696
772
 
697
773
  after do
@@ -702,17 +778,17 @@ describe 'Formtastic::FormBuilder#input' do
702
778
  it 'should render a hint paragraph containing a localized hint (I18n)' do
703
779
  with_config :i18n_lookups_by_default, false do
704
780
  ::I18n.backend.store_translations :en,
705
- :formtastic => {
706
- :hints => {
707
- :post => {
708
- :title => @localized_hint_text
709
- }
710
- }
711
- }
781
+ :formtastic => {
782
+ :hints => {
783
+ :post => {
784
+ :title => @localized_hint_text
785
+ }
786
+ }
787
+ }
712
788
  concat(semantic_form_for(@new_post) do |builder|
713
789
  concat(builder.input(:title, :hint => true))
714
790
  end)
715
- output_buffer.should have_tag('form li p.inline-hints', @localized_hint_text)
791
+ expect(output_buffer.to_str).to have_tag('form li p.inline-hints', :text => @localized_hint_text)
716
792
  end
717
793
  end
718
794
 
@@ -721,7 +797,7 @@ describe 'Formtastic::FormBuilder#input' do
721
797
  concat(semantic_form_for(@new_post) do |builder|
722
798
  concat(builder.input(:title, :hint => true))
723
799
  end)
724
- output_buffer.should have_tag('form li p.inline-hints', @default_localized_hint_text)
800
+ expect(output_buffer.to_str).to have_tag('form li p.inline-hints', :text => @default_localized_hint_text)
725
801
  end
726
802
  end
727
803
  end
@@ -732,7 +808,7 @@ describe 'Formtastic::FormBuilder#input' do
732
808
  concat(semantic_form_for(@new_post) do |builder|
733
809
  concat(builder.input(:title, :hint => false))
734
810
  end)
735
- output_buffer.should_not have_tag('form li p.inline-hints', @localized_hint_text)
811
+ expect(output_buffer.to_str).not_to have_tag('form li p.inline-hints', :text => @localized_hint_text)
736
812
  end
737
813
  end
738
814
  end
@@ -742,17 +818,17 @@ describe 'Formtastic::FormBuilder#input' do
742
818
  it "should see the provided hash as a blank entry" do
743
819
  with_config :i18n_lookups_by_default, false do
744
820
  ::I18n.backend.store_translations :en,
745
- :formtastic => {
746
- :hints => {
747
- :title => { # movie title
748
- :summary => @localized_hint_text # summary of movie
749
- }
750
- }
751
- }
821
+ :formtastic => {
822
+ :hints => {
823
+ :title => { # movie title
824
+ :summary => @localized_hint_text # summary of movie
825
+ }
826
+ }
827
+ }
752
828
  semantic_form_for(@new_post) do |builder|
753
829
  concat(builder.input(:title, :hint => true))
754
830
  end
755
- output_buffer.should_not have_tag('form li p.inline-hints', @localized_hint_text)
831
+ expect(output_buffer.to_str).not_to have_tag('form li p.inline-hints', :text => @localized_hint_text)
756
832
  end
757
833
  end
758
834
  end
@@ -763,7 +839,7 @@ describe 'Formtastic::FormBuilder#input' do
763
839
  concat(semantic_form_for(@new_post) do |builder|
764
840
  concat(builder.input(:title))
765
841
  end)
766
- output_buffer.should_not have_tag('form li p.inline-hints')
842
+ expect(output_buffer.to_str).not_to have_tag('form li p.inline-hints')
767
843
  end
768
844
  end
769
845
  end
@@ -778,25 +854,25 @@ describe 'Formtastic::FormBuilder#input' do
778
854
  concat(semantic_form_for(@new_post) do |builder|
779
855
  concat(builder.input(:title, :wrapper_html => {:id => :another_id}))
780
856
  end)
781
- output_buffer.should have_tag("form li#another_id")
857
+ expect(output_buffer.to_str).to have_tag("form li#another_id")
782
858
  end
783
859
 
784
860
  it 'should append given classes to li default classes' do
785
861
  concat(semantic_form_for(@new_post) do |builder|
786
862
  concat(builder.input(:title, :wrapper_html => {:class => :another_class}, :required => true))
787
863
  end)
788
- output_buffer.should have_tag("form li.string")
789
- output_buffer.should have_tag("form li.required")
790
- output_buffer.should have_tag("form li.another_class")
864
+ expect(output_buffer.to_str).to have_tag("form li.string")
865
+ expect(output_buffer.to_str).to have_tag("form li.required")
866
+ expect(output_buffer.to_str).to have_tag("form li.another_class")
791
867
  end
792
868
 
793
869
  it 'should allow classes to be an array' do
794
870
  concat(semantic_form_for(@new_post) do |builder|
795
871
  concat(builder.input(:title, :wrapper_html => {:class => [ :my_class, :another_class ]}))
796
872
  end)
797
- output_buffer.should have_tag("form li.string")
798
- output_buffer.should have_tag("form li.my_class")
799
- output_buffer.should have_tag("form li.another_class")
873
+ expect(output_buffer.to_str).to have_tag("form li.string")
874
+ expect(output_buffer.to_str).to have_tag("form li.my_class")
875
+ expect(output_buffer.to_str).to have_tag("form li.another_class")
800
876
  end
801
877
 
802
878
  describe 'when nil' do
@@ -804,7 +880,7 @@ describe 'Formtastic::FormBuilder#input' do
804
880
  concat(semantic_form_for(@new_post) do |builder|
805
881
  concat(builder.input(:title, :wrapper_html => {:id => nil}))
806
882
  end)
807
- output_buffer.should have_tag('form li:not([id])')
883
+ expect(output_buffer.to_str).to have_tag('form li:not([id])')
808
884
  end
809
885
  end
810
886
  end
@@ -814,8 +890,8 @@ describe 'Formtastic::FormBuilder#input' do
814
890
  concat(semantic_form_for(@new_post) do |builder|
815
891
  concat(builder.input(:title))
816
892
  end)
817
- output_buffer.should have_tag("form li#post_title_input")
818
- output_buffer.should have_tag("form li.string")
893
+ expect(output_buffer.to_str).to have_tag("form li#post_title_input")
894
+ expect(output_buffer.to_str).to have_tag("form li.string")
819
895
  end
820
896
  end
821
897
 
@@ -824,15 +900,15 @@ describe 'Formtastic::FormBuilder#input' do
824
900
  describe ':collection option' do
825
901
 
826
902
  it "should be required on polymorphic associations" do
827
- @new_post.stub(:commentable)
828
- @new_post.class.stub(:reflections).and_return({
829
- :commentable => double('macro_reflection', :options => { :polymorphic => true }, :macro => :belongs_to)
830
- })
831
- @new_post.stub(:column_for_attribute).with(:commentable).and_return(
832
- double('column', :type => :integer)
903
+ allow(@new_post).to receive(:commentable)
904
+ allow(@new_post.class).to receive(:reflections).and_return({
905
+ :commentable => double('macro_reflection', :options => { :polymorphic => true }, :macro => :belongs_to)
906
+ })
907
+ allow(@new_post).to receive(:column_for_attribute).with(:commentable).and_return(
908
+ double('column', :type => :integer)
833
909
  )
834
- @new_post.class.stub(:reflect_on_association).with(:commentable).and_return(
835
- double('reflection', :macro => :belongs_to, :options => { :polymorphic => true })
910
+ allow(@new_post.class).to receive(:reflect_on_association).with(:commentable).and_return(
911
+ double('reflection', :macro => :belongs_to, :options => { :polymorphic => true })
836
912
  )
837
913
  expect {
838
914
  concat(semantic_form_for(@new_post) do |builder|
@@ -857,21 +933,18 @@ describe 'Formtastic::FormBuilder#input' do
857
933
  concat(builder.input(:title, my_options))
858
934
  concat(builder.input(:publish_at, my_options))
859
935
  end)
860
- output_buffer.should have_tag 'li.string', :count => 2
936
+ expect(output_buffer.to_str).to have_tag 'li.string', :count => 2
861
937
  end
862
-
863
-
864
938
  end
865
939
 
866
940
  describe 'instantiating an input class' do
867
-
868
941
  context 'when a class does not exist' do
869
942
  it "should raise an error" do
870
- lambda {
943
+ expect {
871
944
  concat(semantic_form_for(@new_post) do |builder|
872
945
  builder.input(:title, :as => :non_existant)
873
946
  end)
874
- }.should raise_error(Formtastic::UnknownInputError)
947
+ }.to raise_error(Formtastic::UnknownInputError)
875
948
  end
876
949
  end
877
950
 
@@ -879,7 +952,7 @@ describe 'Formtastic::FormBuilder#input' do
879
952
 
880
953
  it 'should instantiate the Formtastic input' do
881
954
  input = double('input', :to_html => 'some HTML')
882
- Formtastic::Inputs::StringInput.should_receive(:new).and_return(input)
955
+ expect(Formtastic::Inputs::StringInput).to receive(:new).and_return(input)
883
956
  concat(semantic_form_for(@new_post) do |builder|
884
957
  builder.input(:title, :as => :string)
885
958
  end)
@@ -893,8 +966,8 @@ describe 'Formtastic::FormBuilder#input' do
893
966
  end
894
967
 
895
968
  input = double('input', :to_html => 'some HTML')
896
- Formtastic::Inputs::StringInput.should_not_receive(:new)
897
- ::StringInput.should_receive(:new).and_return(input)
969
+ expect(Formtastic::Inputs::StringInput).not_to receive(:new)
970
+ expect(::StringInput).to receive(:new).and_return(input)
898
971
 
899
972
  concat(semantic_form_for(@new_post) do |builder|
900
973
  builder.input(:title, :as => :string)
@@ -902,20 +975,6 @@ describe 'Formtastic::FormBuilder#input' do
902
975
  end
903
976
  end
904
977
 
905
- describe 'when instantiated multiple times with the same input type' do
906
-
907
- it "should be cached (not calling the internal methods)" do
908
- # TODO this is really tied to the underlying implementation
909
- concat(semantic_form_for(@new_post) do |builder|
910
- builder.should_receive(:custom_input_class_name).with(:string).once.and_return(::Formtastic::Inputs::StringInput)
911
- builder.input(:title, :as => :string)
912
- builder.input(:title, :as => :string)
913
- end)
914
- end
915
-
916
- end
917
978
 
918
979
  end
919
-
920
980
  end
921
-