formtastic 3.0.0 → 5.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (175) hide show
  1. checksums.yaml +5 -13
  2. data/.gitattributes +1 -0
  3. data/.github/workflows/test.yml +61 -0
  4. data/.gitignore +3 -2
  5. data/CHANGELOG.md +61 -0
  6. data/Gemfile.lock +140 -0
  7. data/MIT-LICENSE +1 -1
  8. data/{README.textile → README.md} +191 -168
  9. data/RELEASE_PROCESS +3 -1
  10. data/Rakefile +24 -8
  11. data/app/assets/stylesheets/formtastic.css +1 -1
  12. data/bin/appraisal +8 -0
  13. data/formtastic.gemspec +13 -17
  14. data/gemfiles/rails_6.0/Gemfile +5 -0
  15. data/gemfiles/rails_6.1/Gemfile +5 -0
  16. data/gemfiles/rails_7.0/Gemfile +5 -0
  17. data/gemfiles/rails_7.1/Gemfile +5 -0
  18. data/gemfiles/rails_edge/Gemfile +13 -0
  19. data/lib/formtastic/action_class_finder.rb +19 -0
  20. data/lib/formtastic/actions/base.rb +1 -0
  21. data/lib/formtastic/actions/button_action.rb +56 -53
  22. data/lib/formtastic/actions/buttonish.rb +1 -0
  23. data/lib/formtastic/actions/input_action.rb +60 -57
  24. data/lib/formtastic/actions/link_action.rb +69 -67
  25. data/lib/formtastic/actions.rb +7 -3
  26. data/lib/formtastic/deprecation.rb +6 -0
  27. data/lib/formtastic/engine.rb +4 -1
  28. data/lib/formtastic/form_builder.rb +32 -25
  29. data/lib/formtastic/helpers/action_helper.rb +22 -31
  30. data/lib/formtastic/helpers/actions_helper.rb +1 -0
  31. data/lib/formtastic/helpers/enum.rb +14 -0
  32. data/lib/formtastic/helpers/errors_helper.rb +3 -2
  33. data/lib/formtastic/helpers/fieldset_wrapper.rb +16 -11
  34. data/lib/formtastic/helpers/file_column_detection.rb +1 -0
  35. data/lib/formtastic/helpers/form_helper.rb +4 -3
  36. data/lib/formtastic/helpers/input_helper.rb +59 -80
  37. data/lib/formtastic/helpers/inputs_helper.rb +33 -27
  38. data/lib/formtastic/helpers/reflection.rb +5 -4
  39. data/lib/formtastic/helpers.rb +2 -2
  40. data/lib/formtastic/html_attributes.rb +13 -1
  41. data/lib/formtastic/i18n.rb +2 -1
  42. data/lib/formtastic/input_class_finder.rb +19 -0
  43. data/lib/formtastic/inputs/base/associations.rb +1 -0
  44. data/lib/formtastic/inputs/base/choices.rb +4 -3
  45. data/lib/formtastic/inputs/base/collections.rb +47 -11
  46. data/lib/formtastic/inputs/base/database.rb +8 -5
  47. data/lib/formtastic/inputs/base/datetime_pickerish.rb +1 -0
  48. data/lib/formtastic/inputs/base/errors.rb +7 -6
  49. data/lib/formtastic/inputs/base/fileish.rb +1 -0
  50. data/lib/formtastic/inputs/base/hints.rb +2 -1
  51. data/lib/formtastic/inputs/base/html.rb +12 -10
  52. data/lib/formtastic/inputs/base/labelling.rb +3 -2
  53. data/lib/formtastic/inputs/base/naming.rb +5 -4
  54. data/lib/formtastic/inputs/base/numeric.rb +1 -0
  55. data/lib/formtastic/inputs/base/options.rb +3 -3
  56. data/lib/formtastic/inputs/base/placeholder.rb +1 -0
  57. data/lib/formtastic/inputs/base/stringish.rb +1 -0
  58. data/lib/formtastic/inputs/base/timeish.rb +9 -4
  59. data/lib/formtastic/inputs/base/validations.rb +39 -12
  60. data/lib/formtastic/inputs/base/wrapping.rb +2 -3
  61. data/lib/formtastic/inputs/base.rb +17 -12
  62. data/lib/formtastic/inputs/boolean_input.rb +2 -1
  63. data/lib/formtastic/inputs/check_boxes_input.rb +16 -24
  64. data/lib/formtastic/inputs/color_input.rb +1 -1
  65. data/lib/formtastic/inputs/country_input.rb +4 -1
  66. data/lib/formtastic/inputs/datalist_input.rb +42 -0
  67. data/lib/formtastic/inputs/date_picker_input.rb +1 -0
  68. data/lib/formtastic/inputs/date_select_input.rb +1 -0
  69. data/lib/formtastic/inputs/datetime_picker_input.rb +1 -0
  70. data/lib/formtastic/inputs/datetime_select_input.rb +1 -0
  71. data/lib/formtastic/inputs/email_input.rb +1 -0
  72. data/lib/formtastic/inputs/file_input.rb +3 -2
  73. data/lib/formtastic/inputs/hidden_input.rb +3 -2
  74. data/lib/formtastic/inputs/number_input.rb +1 -0
  75. data/lib/formtastic/inputs/password_input.rb +1 -0
  76. data/lib/formtastic/inputs/phone_input.rb +1 -0
  77. data/lib/formtastic/inputs/radio_input.rb +26 -21
  78. data/lib/formtastic/inputs/range_input.rb +1 -0
  79. data/lib/formtastic/inputs/search_input.rb +1 -0
  80. data/lib/formtastic/inputs/select_input.rb +32 -10
  81. data/lib/formtastic/inputs/string_input.rb +1 -0
  82. data/lib/formtastic/inputs/text_input.rb +1 -0
  83. data/lib/formtastic/inputs/time_picker_input.rb +1 -0
  84. data/lib/formtastic/inputs/time_select_input.rb +1 -0
  85. data/lib/formtastic/inputs/time_zone_input.rb +17 -6
  86. data/lib/formtastic/inputs/url_input.rb +1 -0
  87. data/lib/formtastic/inputs.rb +33 -28
  88. data/lib/formtastic/localized_string.rb +2 -1
  89. data/lib/formtastic/localizer.rb +23 -24
  90. data/lib/formtastic/namespaced_class_finder.rb +98 -0
  91. data/lib/formtastic/version.rb +2 -1
  92. data/lib/formtastic.rb +19 -14
  93. data/lib/generators/formtastic/form/form_generator.rb +8 -2
  94. data/lib/generators/formtastic/input/input_generator.rb +47 -0
  95. data/lib/generators/formtastic/install/install_generator.rb +2 -0
  96. data/lib/generators/templates/formtastic.rb +29 -7
  97. data/lib/generators/templates/input.rb +19 -0
  98. data/sample/basic_inputs.html +1 -1
  99. data/script/integration-template.rb +73 -0
  100. data/script/integration.sh +19 -0
  101. data/spec/action_class_finder_spec.rb +13 -0
  102. data/spec/actions/button_action_spec.rb +21 -20
  103. data/spec/actions/generic_action_spec.rb +134 -133
  104. data/spec/actions/input_action_spec.rb +20 -19
  105. data/spec/actions/link_action_spec.rb +30 -29
  106. data/spec/builder/custom_builder_spec.rb +39 -22
  107. data/spec/builder/error_proc_spec.rb +6 -5
  108. data/spec/builder/semantic_fields_for_spec.rb +46 -45
  109. data/spec/fast_spec_helper.rb +13 -0
  110. data/spec/generators/formtastic/form/form_generator_spec.rb +33 -32
  111. data/spec/generators/formtastic/input/input_generator_spec.rb +125 -0
  112. data/spec/generators/formtastic/install/install_generator_spec.rb +10 -9
  113. data/spec/helpers/action_helper_spec.rb +70 -97
  114. data/spec/helpers/actions_helper_spec.rb +43 -42
  115. data/spec/helpers/form_helper_spec.rb +56 -39
  116. data/spec/helpers/input_helper_spec.rb +314 -255
  117. data/spec/helpers/inputs_helper_spec.rb +217 -202
  118. data/spec/helpers/reflection_helper_spec.rb +7 -6
  119. data/spec/helpers/semantic_errors_helper_spec.rb +26 -25
  120. data/spec/i18n_spec.rb +30 -29
  121. data/spec/input_class_finder_spec.rb +11 -0
  122. data/spec/inputs/base/collections_spec.rb +78 -0
  123. data/spec/inputs/base/validations_spec.rb +481 -0
  124. data/spec/inputs/boolean_input_spec.rb +73 -72
  125. data/spec/inputs/check_boxes_input_spec.rb +174 -123
  126. data/spec/inputs/color_input_spec.rb +53 -64
  127. data/spec/inputs/country_input_spec.rb +23 -22
  128. data/spec/inputs/custom_input_spec.rb +3 -6
  129. data/spec/inputs/datalist_input_spec.rb +62 -0
  130. data/spec/inputs/date_picker_input_spec.rb +114 -113
  131. data/spec/inputs/date_select_input_spec.rb +76 -61
  132. data/spec/inputs/datetime_picker_input_spec.rb +123 -122
  133. data/spec/inputs/datetime_select_input_spec.rb +85 -68
  134. data/spec/inputs/email_input_spec.rb +17 -16
  135. data/spec/inputs/file_input_spec.rb +18 -17
  136. data/spec/inputs/hidden_input_spec.rb +32 -31
  137. data/spec/inputs/include_blank_spec.rb +10 -9
  138. data/spec/inputs/label_spec.rb +36 -31
  139. data/spec/inputs/number_input_spec.rb +212 -211
  140. data/spec/inputs/password_input_spec.rb +17 -16
  141. data/spec/inputs/phone_input_spec.rb +17 -16
  142. data/spec/inputs/placeholder_spec.rb +18 -17
  143. data/spec/inputs/radio_input_spec.rb +92 -65
  144. data/spec/inputs/range_input_spec.rb +136 -135
  145. data/spec/inputs/readonly_spec.rb +51 -0
  146. data/spec/inputs/search_input_spec.rb +16 -15
  147. data/spec/inputs/select_input_spec.rb +209 -102
  148. data/spec/inputs/string_input_spec.rb +51 -50
  149. data/spec/inputs/text_input_spec.rb +34 -33
  150. data/spec/inputs/time_picker_input_spec.rb +115 -114
  151. data/spec/inputs/time_select_input_spec.rb +84 -70
  152. data/spec/inputs/time_zone_input_spec.rb +58 -31
  153. data/spec/inputs/url_input_spec.rb +17 -16
  154. data/spec/inputs/with_options_spec.rb +9 -8
  155. data/spec/localizer_spec.rb +18 -17
  156. data/spec/namespaced_class_finder_spec.rb +91 -0
  157. data/spec/schema.rb +22 -0
  158. data/spec/spec_helper.rb +180 -249
  159. data/spec/support/custom_macros.rb +128 -98
  160. data/spec/support/deprecation.rb +2 -1
  161. data/spec/support/shared_examples.rb +13 -0
  162. data/spec/support/specialized_class_finder_shared_example.rb +28 -0
  163. data/spec/support/test_environment.rb +25 -10
  164. metadata +95 -136
  165. data/.travis.yml +0 -28
  166. data/Appraisals +0 -25
  167. data/CHANGELOG +0 -27
  168. data/gemfiles/rails_3.2.gemfile +0 -7
  169. data/gemfiles/rails_4.0.4.gemfile +0 -7
  170. data/gemfiles/rails_4.1.gemfile +0 -7
  171. data/gemfiles/rails_4.gemfile +0 -7
  172. data/gemfiles/rails_edge.gemfile +0 -10
  173. data/lib/formtastic/util.rb +0 -53
  174. data/spec/support/deferred_garbage_collection.rb +0 -21
  175. data/spec/util_spec.rb +0 -52
data/spec/spec_helper.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  # encoding: utf-8
2
+ # frozen_string_literal: true
2
3
  require 'rubygems'
3
4
  require 'bundler/setup'
4
5
  require 'active_support'
@@ -6,16 +7,12 @@ require 'action_pack'
6
7
  require 'action_view'
7
8
  require 'action_controller'
8
9
  require 'action_dispatch'
10
+ require 'active_record'
9
11
 
10
- require File.expand_path(File.join(File.dirname(__FILE__), '../lib/formtastic/util'))
11
- require File.expand_path(File.join(File.dirname(__FILE__), '../lib/formtastic'))
12
+ ActiveRecord::Base.establish_connection('url' => 'sqlite3::memory:', 'pool' => 1)
13
+ load 'spec/schema.rb'
12
14
 
13
- #rspec-rails 2-14 assumes a full rails install
14
- module Rails
15
- module VERSION
16
- include ActionPack::VERSION
17
- end
18
- end
15
+ require File.expand_path(File.join(File.dirname(__FILE__), '../lib/formtastic'))
19
16
 
20
17
  require 'ammeter/init'
21
18
 
@@ -52,8 +49,8 @@ module FormtasticSpecHelper
52
49
  include Formtastic::Helpers::FormHelper
53
50
 
54
51
  def default_input_type(column_type, column_name = :generic_column_name)
55
- @new_post.stub(column_name)
56
- @new_post.stub(:column_for_attribute).and_return(double('column', :type => column_type)) unless column_type.nil?
52
+ allow(@new_post).to receive(column_name)
53
+ allow(@new_post).to receive(:column_for_attribute).and_return(double('column', :type => column_type)) unless column_type.nil?
57
54
 
58
55
  semantic_form_for(@new_post) do |builder|
59
56
  @default_type = builder.send(:default_input_type, column_name)
@@ -64,7 +61,7 @@ module FormtasticSpecHelper
64
61
 
65
62
  def active_model_validator(kind, attributes, options = {})
66
63
  validator = double("ActiveModel::Validations::#{kind.to_s.titlecase}Validator", :attributes => attributes, :options => options)
67
- validator.stub(:kind).and_return(kind)
64
+ allow(validator).to receive(:kind).and_return(kind)
68
65
  validator
69
66
  end
70
67
 
@@ -107,26 +104,17 @@ module FormtasticSpecHelper
107
104
  end
108
105
 
109
106
  module ::Namespaced
110
- class Post
111
- extend ActiveModel::Naming if defined?(ActiveModel::Naming)
112
- include ActiveModel::Conversion if defined?(ActiveModel::Conversion)
113
-
114
- def id
115
- end
116
-
117
- def persisted?
118
- end
107
+ class Post < ActiveRecord::Base
119
108
  end
120
109
  end
121
110
 
122
- class ::Author
123
- extend ActiveModel::Naming if defined?(ActiveModel::Naming)
124
- include ActiveModel::Conversion if defined?(ActiveModel::Conversion)
125
-
126
- def to_label
111
+ class ::Author < ActiveRecord::Base
112
+ def new_record?
113
+ !id
127
114
  end
128
115
 
129
- def persisted?
116
+ def to_label
117
+ [name, surname].compact.join(' ')
130
118
  end
131
119
  end
132
120
 
@@ -139,6 +127,10 @@ module FormtasticSpecHelper
139
127
  end
140
128
  end
141
129
 
130
+ class ::LegacyPost < ActiveRecord::Base
131
+ belongs_to :author, foreign_key: :post_author
132
+ end
133
+
142
134
  class ::Continent
143
135
  extend ActiveModel::Naming if defined?(ActiveModel::Naming)
144
136
  include ActiveModel::Conversion if defined?(ActiveModel::Conversion)
@@ -151,7 +143,7 @@ module FormtasticSpecHelper
151
143
 
152
144
  ##
153
145
  # We can't mock :respond_to?, so we need a concrete class override
154
- class ::MongoidReflectionMock < RSpec::Mocks::Mock
146
+ class ::MongoidReflectionMock < RSpec::Mocks::Double
155
147
  def initialize(name=nil, stubs_and_options={})
156
148
  super name, stubs_and_options
157
149
  end
@@ -161,9 +153,8 @@ module FormtasticSpecHelper
161
153
  end
162
154
  end
163
155
 
164
- # In Rails 3 Model.all returns an array. In Rails 4, it returns an
165
- # association proxy, which quacks a lot like an array. We use this in stubs
166
- # or mocks where we need to return the later.
156
+ # Model.all returns an association proxy, which quacks a lot like an array.
157
+ # We use this in stubs or mocks where we need to return the later.
167
158
  #
168
159
  # TODO try delegate?
169
160
  # delegate :map, :size, :length, :first, :to_ary, :each, :include?, :to => :array
@@ -211,14 +202,15 @@ module FormtasticSpecHelper
211
202
 
212
203
  def _routes
213
204
  url_helpers = double('url_helpers')
214
- url_helpers.stub(:hash_for_posts_path).and_return({})
215
- url_helpers.stub(:hash_for_post_path).and_return({})
216
- url_helpers.stub(:hash_for_post_models_path).and_return({})
217
- url_helpers.stub(:hash_for_authors_path).and_return({})
205
+ allow(url_helpers).to receive(:hash_for_posts_path).and_return({})
206
+ allow(url_helpers).to receive(:hash_for_post_path).and_return({})
207
+ allow(url_helpers).to receive(:hash_for_post_models_path).and_return({})
208
+ allow(url_helpers).to receive(:hash_for_authors_path).and_return({})
218
209
 
219
210
  double('_routes',
220
211
  :url_helpers => url_helpers,
221
- :url_for => "/mock/path"
212
+ :url_for => "/mock/path",
213
+ :polymorphic_mappings => {}
222
214
  )
223
215
  end
224
216
 
@@ -246,222 +238,185 @@ module FormtasticSpecHelper
246
238
  def authors_path(*args); "/authors"; end
247
239
  def new_author_path(*args); "/authors/new"; end
248
240
 
249
- # Returns the array for Rails 3 and a thing that looks looks like an
250
- # association proxy for Rails 4+
251
241
  def author_array_or_scope(the_array = [@fred, @bob])
252
- if ::Formtastic::Util.rails3?
253
- the_array
254
- else
255
- MockScope.new(the_array)
256
- end
242
+ MockScope.new(the_array)
257
243
  end
258
-
259
- @fred = ::Author.new
260
- @fred.stub(:class).and_return(::Author)
261
- @fred.stub(:to_label).and_return('Fred Smith')
262
- @fred.stub(:login).and_return('fred_smith')
263
- @fred.stub(:age).and_return(27)
264
- @fred.stub(:id).and_return(37)
265
- @fred.stub(:new_record?).and_return(false)
266
- @fred.stub(:errors).and_return(double('errors', :[] => nil))
267
- @fred.stub(:to_key).and_return(nil)
268
- @fred.stub(:persisted?).and_return(nil)
269
- @fred.stub(:name).and_return('Fred')
270
-
271
- @bob = ::Author.new
272
- @bob.stub(:to_label).and_return('Bob Rock')
273
- @bob.stub(:login).and_return('bob')
274
- @bob.stub(:age).and_return(43)
275
- @bob.stub(:created_at)
276
- @bob.stub(:id).and_return(42)
277
- @bob.stub(:posts).and_return([])
278
- @bob.stub(:post_ids).and_return([])
279
- @bob.stub(:new_record?).and_return(false)
280
- @bob.stub(:errors).and_return(double('errors', :[] => nil))
281
- @bob.stub(:to_key).and_return(nil)
282
- @bob.stub(:persisted?).and_return(nil)
283
- @bob.stub(:name).and_return('Bob')
284
-
285
- @james = ::Author.new
286
- @james.stub(:to_label).and_return('James Shock')
287
- @james.stub(:login).and_return('james')
288
- @james.stub(:age).and_return(38)
289
- @james.stub(:id).and_return(75)
290
- @james.stub(:posts).and_return([])
291
- @james.stub(:post_ids).and_return([])
292
- @james.stub(:new_record?).and_return(false)
293
- @james.stub(:errors).and_return(double('errors', :[] => nil))
294
- @james.stub(:to_key).and_return(nil)
295
- @james.stub(:persisted?).and_return(nil)
296
- @james.stub(:name).and_return('James')
297
-
298
-
299
- ::Author.stub(:scoped).and_return(::Author)
300
- ::Author.stub(:find).and_return(author_array_or_scope)
301
- ::Author.stub(:all).and_return(author_array_or_scope)
302
- ::Author.stub(:where).and_return(author_array_or_scope)
303
- ::Author.stub(:human_attribute_name).and_return { |column_name| column_name.humanize }
304
- ::Author.stub(:human_name).and_return('::Author')
305
- ::Author.stub(:reflect_on_association).and_return { |column_name| double('reflection', :options => {}, :klass => Post, :macro => :has_many) if column_name == :posts }
306
- ::Author.stub(:content_columns).and_return([double('column', :name => 'login'), double('column', :name => 'created_at')])
307
- ::Author.stub(:to_key).and_return(nil)
308
- ::Author.stub(:persisted?).and_return(nil)
244
+
245
+ @fred = ::Author.new(login: 'fred_smith', age: 27, name: 'Fred', id: 37)
246
+ @bob = ::Author.new(login: 'bob', age: 43, name: 'Bob', id: 42)
247
+ @james = ::Author.new(age: 38, id: 75)
248
+
249
+ allow(::Author).to receive(:scoped).and_return(::Author)
250
+ allow(::Author).to receive(:find).and_return(author_array_or_scope)
251
+ allow(::Author).to receive(:all).and_return(author_array_or_scope)
252
+ allow(::Author).to receive(:where).and_return(author_array_or_scope)
253
+ allow(::Author).to receive(:human_attribute_name) { |column_name| column_name.humanize }
254
+ allow(::Author).to receive(:human_name).and_return('::Author')
255
+ allow(::Author).to receive(:reflect_on_association) { |column_name| double('reflection', :scope => nil, :options => {}, :klass => Post, :macro => :has_many) if column_name == :posts }
256
+ allow(::Author).to receive(:content_columns).and_return([double('column', :name => 'login'), double('column', :name => 'created_at')])
257
+ allow(::Author).to receive(:to_key).and_return(nil)
258
+ allow(::Author).to receive(:persisted?).and_return(nil)
309
259
 
310
260
  @hash_backed_author = HashBackedAuthor.new
311
261
 
312
262
  # Sometimes we need a mock @post object and some Authors for belongs_to
313
263
  @new_post = double('post')
314
- @new_post.stub(:class).and_return(::Post)
315
- @new_post.stub(:id).and_return(nil)
316
- @new_post.stub(:new_record?).and_return(true)
317
- @new_post.stub(:errors).and_return(double('errors', :[] => nil))
318
- @new_post.stub(:author).and_return(nil)
319
- @new_post.stub(:author_attributes=).and_return(nil)
320
- @new_post.stub(:authors).and_return(author_array_or_scope([@fred]))
321
- @new_post.stub(:authors_attributes=)
322
- @new_post.stub(:reviewer).and_return(nil)
323
- @new_post.stub(:main_post).and_return(nil)
324
- @new_post.stub(:sub_posts).and_return([]) #TODO should be a mock with methods for adding sub posts
325
- @new_post.stub(:to_key).and_return(nil)
326
- @new_post.stub(:to_model).and_return(@new_post)
327
- @new_post.stub(:persisted?).and_return(nil)
264
+ allow(@new_post).to receive(:class).and_return(::Post)
265
+ allow(@new_post).to receive(:id).and_return(nil)
266
+ allow(@new_post).to receive(:new_record?).and_return(true)
267
+ allow(@new_post).to receive(:errors).and_return(double('errors', :[] => nil))
268
+ allow(@new_post).to receive(:author).and_return(nil)
269
+ allow(@new_post).to receive(:author_attributes=).and_return(nil)
270
+ allow(@new_post).to receive(:authors).and_return(author_array_or_scope([@fred]))
271
+ allow(@new_post).to receive(:authors_attributes=)
272
+ allow(@new_post).to receive(:reviewer).and_return(nil)
273
+ allow(@new_post).to receive(:main_post).and_return(nil)
274
+ allow(@new_post).to receive(:sub_posts).and_return([]) #TODO should be a mock with methods for adding sub posts
275
+ allow(@new_post).to receive(:to_key).and_return(nil)
276
+ allow(@new_post).to receive(:to_model).and_return(@new_post)
277
+ allow(@new_post).to receive(:persisted?).and_return(nil)
278
+ allow(@new_post).to receive(:model_name){ @new_post.class.model_name}
328
279
 
329
280
  @freds_post = double('post')
330
- @freds_post.stub(:to_ary)
331
- @freds_post.stub(:class).and_return(::Post)
332
- @freds_post.stub(:to_label).and_return('Fred Smith')
333
- @freds_post.stub(:id).and_return(19)
334
- @freds_post.stub(:title).and_return("Hello World")
335
- @freds_post.stub(:author).and_return(@fred)
336
- @freds_post.stub(:author_id).and_return(@fred.id)
337
- @freds_post.stub(:authors).and_return([@fred])
338
- @freds_post.stub(:author_ids).and_return([@fred.id])
339
- @freds_post.stub(:new_record?).and_return(false)
340
- @freds_post.stub(:errors).and_return(double('errors', :[] => nil))
341
- @freds_post.stub(:to_key).and_return(nil)
342
- @freds_post.stub(:persisted?).and_return(nil)
343
- @fred.stub(:posts).and_return(author_array_or_scope([@freds_post]))
344
- @fred.stub(:post_ids).and_return([@freds_post.id])
345
-
346
- ::Post.stub(:scoped).and_return(::Post)
347
- ::Post.stub(:human_attribute_name).and_return { |column_name| column_name.humanize }
348
- ::Post.stub(:human_name).and_return('Post')
349
- ::Post.stub(:reflect_on_all_validations).and_return([])
350
- ::Post.stub(:reflect_on_validations_for).and_return([])
351
- ::Post.stub(:reflections).and_return({})
352
- ::Post.stub(:reflect_on_association).and_return do |column_name|
281
+ allow(@freds_post).to receive(:to_ary)
282
+ allow(@freds_post).to receive(:class).and_return(::Post)
283
+ allow(@freds_post).to receive(:to_label).and_return('Fred Smith')
284
+ allow(@freds_post).to receive(:id).and_return(19)
285
+ allow(@freds_post).to receive(:title).and_return("Hello World")
286
+ allow(@freds_post).to receive(:author).and_return(@fred)
287
+ allow(@freds_post).to receive(:author_id).and_return(@fred.id)
288
+ allow(@freds_post).to receive(:authors).and_return([@fred])
289
+ allow(@freds_post).to receive(:author_ids).and_return([@fred.id])
290
+ allow(@freds_post).to receive(:new_record?).and_return(false)
291
+ allow(@freds_post).to receive(:errors).and_return(double('errors', :[] => nil))
292
+ allow(@freds_post).to receive(:to_key).and_return(nil)
293
+ allow(@freds_post).to receive(:persisted?).and_return(nil)
294
+ allow(@freds_post).to receive(:model_name){ @freds_post.class.model_name}
295
+ allow(@freds_post).to receive(:to_model).and_return(@freds_post)
296
+ allow(@fred).to receive(:posts).and_return(author_array_or_scope([@freds_post]))
297
+ allow(@fred).to receive(:post_ids).and_return([@freds_post.id])
298
+
299
+ allow(::Post).to receive(:scoped).and_return(::Post)
300
+ allow(::Post).to receive(:human_attribute_name) { |column_name| column_name.humanize }
301
+ allow(::Post).to receive(:human_name).and_return('Post')
302
+ allow(::Post).to receive(:reflect_on_all_validations).and_return([])
303
+ allow(::Post).to receive(:reflect_on_validations_for).and_return([])
304
+ allow(::Post).to receive(:reflections).and_return({})
305
+ allow(::Post).to receive(:reflect_on_association) { |column_name|
353
306
  case column_name
354
307
  when :author, :author_status
355
- mock = double('reflection', :options => {}, :klass => ::Author, :macro => :belongs_to)
356
- mock.stub(:[]).with(:class_name).and_return("Author")
308
+ mock = double('reflection', :scope => nil, :options => {}, :klass => ::Author, :macro => :belongs_to)
309
+ allow(mock).to receive(:[]).with(:class_name).and_return("Author")
357
310
  mock
358
311
  when :reviewer
359
- mock = double('reflection', :options => {:class_name => 'Author'}, :klass => ::Author, :macro => :belongs_to)
360
- mock.stub(:[]).with(:class_name).and_return("Author")
312
+ mock = double('reflection', :scope => nil, :options => {:class_name => 'Author'}, :klass => ::Author, :macro => :belongs_to)
313
+ allow(mock).to receive(:[]).with(:class_name).and_return("Author")
361
314
  mock
362
315
  when :authors
363
- double('reflection', :options => {}, :klass => ::Author, :macro => :has_and_belongs_to_many)
316
+ double('reflection', :scope => nil, :options => {}, :klass => ::Author, :macro => :has_and_belongs_to_many)
364
317
  when :sub_posts
365
- double('reflection', :options => {}, :klass => ::Post, :macro => :has_many)
318
+ double('reflection', :scope => nil, :options => {}, :klass => ::Post, :macro => :has_many)
366
319
  when :main_post
367
- double('reflection', :options => {}, :klass => ::Post, :macro => :belongs_to)
320
+ double('reflection', :scope => nil, :options => {}, :klass => ::Post, :macro => :belongs_to)
368
321
  when :mongoid_reviewer
369
322
  ::MongoidReflectionMock.new('reflection',
323
+ :scope => nil,
370
324
  :options => Proc.new { raise NoMethodError, "Mongoid has no reflection.options" },
371
325
  :klass => ::Author, :macro => :referenced_in, :foreign_key => "reviewer_id") # custom id
372
326
  end
373
- end
374
- ::Post.stub(:find).and_return(author_array_or_scope([@freds_post]))
375
- ::Post.stub(:all).and_return(author_array_or_scope([@freds_post]))
376
- ::Post.stub(:where).and_return(author_array_or_scope([@freds_post]))
377
- ::Post.stub(:content_columns).and_return([double('column', :name => 'title'), double('column', :name => 'body'), double('column', :name => 'created_at')])
378
- ::Post.stub(:to_key).and_return(nil)
379
- ::Post.stub(:persisted?).and_return(nil)
380
- ::Post.stub(:to_ary)
381
-
382
- ::MongoPost.stub(:human_attribute_name).and_return { |column_name| column_name.humanize }
383
- ::MongoPost.stub(:human_name).and_return('MongoPost')
384
- ::MongoPost.stub(:associations).and_return({
327
+ }
328
+ allow(::Post).to receive(:find).and_return(author_array_or_scope([@freds_post]))
329
+ allow(::Post).to receive(:all).and_return(author_array_or_scope([@freds_post]))
330
+ allow(::Post).to receive(:where).and_return(author_array_or_scope([@freds_post]))
331
+ allow(::Post).to receive(:content_columns).and_return([double('column', :name => 'title'), double('column', :name => 'body'), double('column', :name => 'created_at')])
332
+ allow(::Post).to receive(:to_key).and_return(nil)
333
+ allow(::Post).to receive(:persisted?).and_return(nil)
334
+ allow(::Post).to receive(:to_ary)
335
+
336
+ allow(::MongoPost).to receive(:human_attribute_name) { |column_name| column_name.humanize }
337
+ allow(::MongoPost).to receive(:human_name).and_return('MongoPost')
338
+ allow(::MongoPost).to receive(:associations).and_return({
385
339
  :sub_posts => double('reflection', :options => {:polymorphic => true}, :klass => ::MongoPost, :macro => :has_many),
386
340
  :options => []
387
341
  })
388
- ::MongoPost.stub(:find).and_return(author_array_or_scope([@freds_post]))
389
- ::MongoPost.stub(:all).and_return(author_array_or_scope([@freds_post]))
390
- ::MongoPost.stub(:where).and_return(author_array_or_scope([@freds_post]))
391
- ::MongoPost.stub(:to_key).and_return(nil)
392
- ::MongoPost.stub(:persisted?).and_return(nil)
393
- ::MongoPost.stub(:to_ary)
394
- ::MongoPost.stub(:model_name).and_return( double(:model_name_mock, :singular => "post", :plural => "posts", :param_key => "post", :route_key => "posts") )
342
+ allow(::MongoPost).to receive(:find).and_return(author_array_or_scope([@freds_post]))
343
+ allow(::MongoPost).to receive(:all).and_return(author_array_or_scope([@freds_post]))
344
+ allow(::MongoPost).to receive(:where).and_return(author_array_or_scope([@freds_post]))
345
+ allow(::MongoPost).to receive(:to_key).and_return(nil)
346
+ allow(::MongoPost).to receive(:persisted?).and_return(nil)
347
+ allow(::MongoPost).to receive(:to_ary)
348
+ allow(::MongoPost).to receive(:model_name).and_return( double(:model_name_mock, :singular => "post", :plural => "posts", :param_key => "post", :route_key => "posts", :name => "post") )
395
349
 
396
350
  @new_mm_post = double('mm_post')
397
- @new_mm_post.stub(:class).and_return(::MongoPost)
398
- @new_mm_post.stub(:id).and_return(nil)
399
- @new_mm_post.stub(:new_record?).and_return(true)
400
- @new_mm_post.stub(:errors).and_return(double('errors', :[] => nil))
401
- @new_mm_post.stub(:title).and_return("Hello World")
402
- @new_mm_post.stub(:sub_posts).and_return([]) #TODO should be a mock with methods for adding sub posts
403
- @new_mm_post.stub(:to_key).and_return(nil)
404
- @new_mm_post.stub(:to_model).and_return(@new_mm_post)
405
- @new_mm_post.stub(:persisted?).and_return(nil)
351
+ allow(@new_mm_post).to receive(:class).and_return(::MongoPost)
352
+ allow(@new_mm_post).to receive(:id).and_return(nil)
353
+ allow(@new_mm_post).to receive(:new_record?).and_return(true)
354
+ allow(@new_mm_post).to receive(:errors).and_return(double('errors', :[] => nil))
355
+ allow(@new_mm_post).to receive(:title).and_return("Hello World")
356
+ allow(@new_mm_post).to receive(:sub_posts).and_return([]) #TODO should be a mock with methods for adding sub posts
357
+ allow(@new_mm_post).to receive(:to_key).and_return(nil)
358
+ allow(@new_mm_post).to receive(:to_model).and_return(@new_mm_post)
359
+ allow(@new_mm_post).to receive(:persisted?).and_return(nil)
360
+ allow(@new_mm_post).to receive(:model_name).and_return(::MongoPost.model_name)
406
361
 
407
362
  @mock_file = double('file')
408
363
  Formtastic::FormBuilder.file_methods.each do |method|
409
- @mock_file.stub(method).and_return(true)
364
+ allow(@mock_file).to receive(method).and_return(true)
410
365
  end
411
366
 
412
- @new_post.stub(:title)
413
- @new_post.stub(:email)
414
- @new_post.stub(:url)
415
- @new_post.stub(:phone)
416
- @new_post.stub(:search)
417
- @new_post.stub(:to_ary)
418
- @new_post.stub(:body)
419
- @new_post.stub(:published)
420
- @new_post.stub(:publish_at)
421
- @new_post.stub(:created_at)
422
- @new_post.stub(:secret).and_return(1)
423
- @new_post.stub(:url)
424
- @new_post.stub(:email)
425
- @new_post.stub(:color)
426
- @new_post.stub(:search)
427
- @new_post.stub(:phone)
428
- @new_post.stub(:time_zone)
429
- @new_post.stub(:category_name)
430
- @new_post.stub(:allow_comments).and_return(true)
431
- @new_post.stub(:answer_comments)
432
- @new_post.stub(:country)
433
- @new_post.stub(:country_subdivision)
434
- @new_post.stub(:country_code)
435
- @new_post.stub(:document).and_return(@mock_file)
436
- @new_post.stub(:column_for_attribute).with(:meta_description).and_return(double('column', :type => :string, :limit => 255))
437
- @new_post.stub(:column_for_attribute).with(:title).and_return(double('column', :type => :string, :limit => 50))
438
- @new_post.stub(:column_for_attribute).with(:body).and_return(double('column', :type => :text))
439
- @new_post.stub(:column_for_attribute).with(:published).and_return(double('column', :type => :boolean))
440
- @new_post.stub(:column_for_attribute).with(:publish_at).and_return(double('column', :type => :date))
441
- @new_post.stub(:column_for_attribute).with(:time_zone).and_return(double('column', :type => :string))
442
- @new_post.stub(:column_for_attribute).with(:allow_comments).and_return(double('column', :type => :boolean))
443
- @new_post.stub(:column_for_attribute).with(:author).and_return(double('column', :type => :integer))
444
- @new_post.stub(:column_for_attribute).with(:country).and_return(double('column', :type => :string, :limit => 255))
445
- @new_post.stub(:column_for_attribute).with(:country_subdivision).and_return(double('column', :type => :string, :limit => 255))
446
- @new_post.stub(:column_for_attribute).with(:country_code).and_return(double('column', :type => :string, :limit => 255))
447
- @new_post.stub(:column_for_attribute).with(:email).and_return(double('column', :type => :string, :limit => 255))
448
- @new_post.stub(:column_for_attribute).with(:color).and_return(double('column', :type => :string, :limit => 255))
449
- @new_post.stub(:column_for_attribute).with(:url).and_return(double('column', :type => :string, :limit => 255))
450
- @new_post.stub(:column_for_attribute).with(:phone).and_return(double('column', :type => :string, :limit => 255))
451
- @new_post.stub(:column_for_attribute).with(:search).and_return(double('column', :type => :string, :limit => 255))
452
- @new_post.stub(:column_for_attribute).with(:document).and_return(nil)
453
-
454
- @new_post.stub(:author).and_return(@bob)
455
- @new_post.stub(:author_id).and_return(@bob.id)
456
-
457
- @new_post.stub(:reviewer).and_return(@fred)
458
- @new_post.stub(:reviewer_id).and_return(@fred.id)
367
+ allow(@new_post).to receive(:title)
368
+ allow(@new_post).to receive(:email)
369
+ allow(@new_post).to receive(:url)
370
+ allow(@new_post).to receive(:phone)
371
+ allow(@new_post).to receive(:search)
372
+ allow(@new_post).to receive(:to_ary)
373
+ allow(@new_post).to receive(:body)
374
+ allow(@new_post).to receive(:published)
375
+ allow(@new_post).to receive(:publish_at)
376
+ allow(@new_post).to receive(:created_at)
377
+ allow(@new_post).to receive(:secret).and_return(1)
378
+ allow(@new_post).to receive(:url)
379
+ allow(@new_post).to receive(:email)
380
+ allow(@new_post).to receive(:color)
381
+ allow(@new_post).to receive(:search)
382
+ allow(@new_post).to receive(:phone)
383
+ allow(@new_post).to receive(:time_zone)
384
+ allow(@new_post).to receive(:category_name)
385
+ allow(@new_post).to receive(:allow_comments).and_return(true)
386
+ allow(@new_post).to receive(:answer_comments)
387
+ allow(@new_post).to receive(:country)
388
+ allow(@new_post).to receive(:country_subdivision)
389
+ allow(@new_post).to receive(:country_code)
390
+ allow(@new_post).to receive(:document).and_return(@mock_file)
391
+ allow(@new_post).to receive(:column_for_attribute).with(:meta_description).and_return(double('column', :type => :string, :limit => 255))
392
+ allow(@new_post).to receive(:column_for_attribute).with(:title).and_return(double('column', :type => :string, :limit => 50))
393
+ allow(@new_post).to receive(:column_for_attribute).with(:body).and_return(double('column', :type => :text))
394
+ allow(@new_post).to receive(:column_for_attribute).with(:published).and_return(double('column', :type => :boolean))
395
+ allow(@new_post).to receive(:column_for_attribute).with(:publish_at).and_return(double('column', :type => :date))
396
+ allow(@new_post).to receive(:column_for_attribute).with(:time_zone).and_return(double('column', :type => :string))
397
+ allow(@new_post).to receive(:column_for_attribute).with(:allow_comments).and_return(double('column', :type => :boolean))
398
+ allow(@new_post).to receive(:column_for_attribute).with(:author).and_return(double('column', :type => :integer))
399
+ allow(@new_post).to receive(:column_for_attribute).with(:country).and_return(double('column', :type => :string, :limit => 255))
400
+ allow(@new_post).to receive(:column_for_attribute).with(:country_subdivision).and_return(double('column', :type => :string, :limit => 255))
401
+ allow(@new_post).to receive(:column_for_attribute).with(:country_code).and_return(double('column', :type => :string, :limit => 255))
402
+ allow(@new_post).to receive(:column_for_attribute).with(:email).and_return(double('column', :type => :string, :limit => 255))
403
+ allow(@new_post).to receive(:column_for_attribute).with(:color).and_return(double('column', :type => :string, :limit => 255))
404
+ allow(@new_post).to receive(:column_for_attribute).with(:url).and_return(double('column', :type => :string, :limit => 255))
405
+ allow(@new_post).to receive(:column_for_attribute).with(:phone).and_return(double('column', :type => :string, :limit => 255))
406
+ allow(@new_post).to receive(:column_for_attribute).with(:search).and_return(double('column', :type => :string, :limit => 255))
407
+ allow(@new_post).to receive(:column_for_attribute).with(:document).and_return(nil)
408
+
409
+ allow(@new_post).to receive(:author).and_return(@bob)
410
+ allow(@new_post).to receive(:author_id).and_return(@bob.id)
411
+
412
+ allow(@new_post).to receive(:reviewer).and_return(@fred)
413
+ allow(@new_post).to receive(:reviewer_id).and_return(@fred.id)
459
414
 
460
415
  # @new_post.should_receive(:publish_at=).at_least(:once)
461
- @new_post.stub(:publish_at=)
416
+ allow(@new_post).to receive(:publish_at=)
462
417
  # @new_post.should_receive(:title=).at_least(:once)
463
- @new_post.stub(:title=)
464
- @new_post.stub(:main_post_id).and_return(nil)
418
+ allow(@new_post).to receive(:title=)
419
+ allow(@new_post).to receive(:main_post_id).and_return(nil)
465
420
 
466
421
  end
467
422
 
@@ -488,29 +443,8 @@ module FormtasticSpecHelper
488
443
  Formtastic::FormBuilder.send(:"#{config_method_name}=", old_value)
489
444
  end
490
445
 
491
- class ToSMatcher
492
- def initialize(str)
493
- @str=str.to_s
494
- end
495
-
496
- def matches?(value)
497
- value.to_s==@str
498
- end
499
-
500
- def failure_message_for_should
501
- "Expected argument that converted to #{@str}"
502
- end
503
- end
504
-
505
- def errors_matcher(method)
506
- # In edge rails (Rails 4) tags store method_name as a string and index the errors object using a string
507
- # therefore allow stubs to match on either string or symbol. The errors object calls to_sym on all index
508
- # accesses so @object.errors[:abc] is equivalent to @object.errors["abc"]
509
- if Rails::VERSION::MAJOR == 4
510
- ToSMatcher.new(method)
511
- else
512
- method
513
- end
446
+ RSpec::Matchers.define :errors_matcher do |expected|
447
+ match { |actual| actual.to_s == expected.to_s }
514
448
  end
515
449
  end
516
450
 
@@ -518,17 +452,14 @@ class ::ActionView::Base
518
452
  include Formtastic::Helpers::FormHelper
519
453
  end
520
454
 
521
- ::ActiveSupport::Deprecation.silenced = false
522
-
523
455
  RSpec.configure do |config|
524
- config.before(:each) do
456
+ config.infer_spec_type_from_file_location!
457
+
458
+ config.filter_run focus: true
459
+ config.filter_run_excluding skip: true
460
+ config.run_all_when_everything_filtered = true
461
+
462
+ config.before(:example) do
525
463
  Formtastic::Localizer.cache.clear!
526
464
  end
527
-
528
- config.before(:all) do
529
- DeferredGarbageCollection.start unless ENV["DEFER_GC"] == "false"
530
- end
531
- config.after(:all) do
532
- DeferredGarbageCollection.reconsider unless ENV["DEFER_GC"] == "false"
533
- end
534
465
  end