shoulda-matchers 2.7.0 → 2.8.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (190) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +13 -3
  3. data/Appraisals +18 -0
  4. data/CONTRIBUTING.md +13 -29
  5. data/Gemfile +1 -4
  6. data/Gemfile.lock +2 -10
  7. data/NEWS.md +100 -14
  8. data/README.md +62 -58
  9. data/Rakefile +9 -16
  10. data/gemfiles/3.0.gemfile +11 -12
  11. data/gemfiles/3.0.gemfile.lock +15 -10
  12. data/gemfiles/3.1.gemfile +11 -12
  13. data/gemfiles/3.1.gemfile.lock +14 -10
  14. data/gemfiles/3.1_1.9.2.gemfile +12 -11
  15. data/gemfiles/3.1_1.9.2.gemfile.lock +14 -3
  16. data/gemfiles/3.2.gemfile +11 -12
  17. data/gemfiles/3.2.gemfile.lock +15 -10
  18. data/gemfiles/3.2_1.9.2.gemfile +12 -11
  19. data/gemfiles/3.2_1.9.2.gemfile.lock +14 -2
  20. data/gemfiles/4.0.0.gemfile +10 -12
  21. data/gemfiles/4.0.0.gemfile.lock +13 -10
  22. data/gemfiles/4.0.1.gemfile +10 -12
  23. data/gemfiles/4.0.1.gemfile.lock +13 -10
  24. data/gemfiles/4.1.gemfile +13 -15
  25. data/gemfiles/4.1.gemfile.lock +45 -50
  26. data/gemfiles/4.2.gemfile +36 -0
  27. data/gemfiles/4.2.gemfile.lock +245 -0
  28. data/lib/shoulda/matchers.rb +3 -1
  29. data/lib/shoulda/matchers/action_controller.rb +1 -1
  30. data/lib/shoulda/matchers/action_controller/redirect_to_matcher.rb +1 -1
  31. data/lib/shoulda/matchers/action_controller/route_params.rb +9 -4
  32. data/lib/shoulda/matchers/action_controller/{set_the_flash_matcher.rb → set_flash_matcher.rb} +34 -26
  33. data/lib/shoulda/matchers/action_controller/set_session_matcher.rb +125 -69
  34. data/lib/shoulda/matchers/active_model.rb +1 -2
  35. data/lib/shoulda/matchers/active_model/allow_value_matcher.rb +18 -5
  36. data/lib/shoulda/matchers/active_model/exception_message_finder.rb +2 -2
  37. data/lib/shoulda/matchers/active_model/helpers.rb +4 -4
  38. data/lib/shoulda/matchers/active_model/validate_confirmation_of_matcher.rb +10 -3
  39. data/lib/shoulda/matchers/active_model/validate_exclusion_of_matcher.rb +1 -1
  40. data/lib/shoulda/matchers/active_model/validate_inclusion_of_matcher.rb +3 -1
  41. data/lib/shoulda/matchers/active_model/{ensure_length_of_matcher.rb → validate_length_of_matcher.rb} +30 -20
  42. data/lib/shoulda/matchers/active_model/validate_presence_of_matcher.rb +21 -0
  43. data/lib/shoulda/matchers/active_model/validation_message_finder.rb +2 -2
  44. data/lib/shoulda/matchers/active_record.rb +2 -0
  45. data/lib/shoulda/matchers/active_record/association_matcher.rb +96 -2
  46. data/lib/shoulda/matchers/active_record/association_matchers/join_table_matcher.rb +1 -1
  47. data/lib/shoulda/matchers/active_record/association_matchers/model_reflection.rb +3 -3
  48. data/lib/shoulda/matchers/active_record/association_matchers/option_verifier.rb +22 -2
  49. data/lib/shoulda/matchers/active_record/have_db_column_matcher.rb +30 -4
  50. data/lib/shoulda/matchers/active_record/serialize_matcher.rb +19 -3
  51. data/lib/shoulda/matchers/active_record/uniqueness.rb +14 -0
  52. data/lib/shoulda/matchers/active_record/uniqueness/model.rb +45 -0
  53. data/lib/shoulda/matchers/active_record/uniqueness/namespace.rb +36 -0
  54. data/lib/shoulda/matchers/active_record/uniqueness/test_model_creator.rb +50 -0
  55. data/lib/shoulda/matchers/active_record/uniqueness/test_models.rb +24 -0
  56. data/lib/shoulda/matchers/{active_model → active_record}/validate_uniqueness_of_matcher.rb +76 -16
  57. data/lib/shoulda/matchers/independent/delegate_method_matcher.rb +117 -51
  58. data/lib/shoulda/matchers/independent/delegate_method_matcher/target_not_defined_error.rb +1 -1
  59. data/lib/shoulda/matchers/matcher_context.rb +35 -0
  60. data/lib/shoulda/matchers/rails_shim.rb +23 -0
  61. data/lib/shoulda/matchers/util.rb +28 -0
  62. data/lib/shoulda/matchers/version.rb +1 -1
  63. data/script/SUPPORTED_VERSIONS +1 -1
  64. data/spec/acceptance/active_model_integration_spec.rb +20 -0
  65. data/spec/acceptance/independent_matchers_spec.rb +64 -0
  66. data/spec/acceptance/rails_integration_spec.rb +142 -0
  67. data/spec/acceptance_spec_helper.rb +23 -0
  68. data/spec/support/acceptance/helpers.rb +29 -0
  69. data/spec/support/acceptance/helpers/active_model_helpers.rb +11 -0
  70. data/spec/support/acceptance/helpers/array_helpers.rb +13 -0
  71. data/spec/support/acceptance/helpers/base_helpers.rb +14 -0
  72. data/spec/support/acceptance/helpers/command_helpers.rb +51 -0
  73. data/spec/support/acceptance/helpers/file_helpers.rb +19 -0
  74. data/spec/support/acceptance/helpers/gem_helpers.rb +31 -0
  75. data/spec/support/acceptance/helpers/minitest_helpers.rb +19 -0
  76. data/spec/support/acceptance/helpers/pluralization_helpers.rb +13 -0
  77. data/spec/support/acceptance/helpers/rails_version_helpers.rb +11 -0
  78. data/spec/support/acceptance/helpers/rspec_helpers.rb +26 -0
  79. data/spec/support/acceptance/helpers/ruby_version_helpers.rb +9 -0
  80. data/spec/support/acceptance/helpers/step_helpers.rb +117 -0
  81. data/spec/support/acceptance/matchers/have_output.rb +31 -0
  82. data/spec/support/acceptance/matchers/indicate_number_of_tests_was_run_matcher.rb +55 -0
  83. data/spec/support/acceptance/matchers/indicate_that_tests_were_run_matcher.rb +103 -0
  84. data/spec/support/tests/bundle.rb +94 -0
  85. data/spec/support/tests/command_runner.rb +214 -0
  86. data/spec/support/tests/filesystem.rb +77 -0
  87. data/spec/support/tests/version.rb +45 -0
  88. data/spec/support/unit/capture.rb +34 -0
  89. data/spec/support/unit/helpers/active_model_helpers.rb +25 -0
  90. data/spec/support/unit/helpers/active_model_versions.rb +20 -0
  91. data/spec/support/unit/helpers/active_resource_builder.rb +27 -0
  92. data/spec/support/unit/helpers/allow_value_matcher_helpers.rb +15 -0
  93. data/spec/support/unit/helpers/class_builder.rb +72 -0
  94. data/spec/support/unit/helpers/confirmation_matcher_helpers.rb +17 -0
  95. data/spec/support/unit/helpers/controller_builder.rb +91 -0
  96. data/spec/support/unit/helpers/i18n_faker.rb +15 -0
  97. data/spec/support/unit/helpers/mailer_builder.rb +12 -0
  98. data/spec/support/unit/helpers/model_builder.rb +102 -0
  99. data/spec/support/unit/helpers/rails_versions.rb +28 -0
  100. data/spec/support/unit/i18n.rb +7 -0
  101. data/spec/support/unit/matchers/deprecate.rb +60 -0
  102. data/spec/support/unit/matchers/fail_with_message_including_matcher.rb +50 -0
  103. data/spec/support/unit/matchers/fail_with_message_matcher.rb +50 -0
  104. data/spec/support/unit/matchers/print_warning_including.rb +59 -0
  105. data/spec/support/unit/rails_application.rb +110 -0
  106. data/spec/support/unit/record_builder_with_i18n_validation_message.rb +69 -0
  107. data/spec/support/unit/record_validating_confirmation_builder.rb +56 -0
  108. data/spec/support/unit/record_with_different_error_attribute_builder.rb +92 -0
  109. data/spec/support/{shared_examples → unit/shared_examples}/numerical_submatcher.rb +0 -2
  110. data/spec/support/{shared_examples → unit/shared_examples}/numerical_type_submatcher.rb +0 -2
  111. data/spec/{shoulda → unit/shoulda}/matchers/action_controller/callback_matcher_spec.rb +2 -2
  112. data/spec/{shoulda → unit/shoulda}/matchers/action_controller/filter_param_matcher_spec.rb +2 -2
  113. data/spec/{shoulda → unit/shoulda}/matchers/action_controller/redirect_to_matcher_spec.rb +3 -3
  114. data/spec/{shoulda → unit/shoulda}/matchers/action_controller/render_template_matcher_spec.rb +2 -4
  115. data/spec/{shoulda → unit/shoulda}/matchers/action_controller/render_with_layout_matcher_spec.rb +9 -6
  116. data/spec/{shoulda → unit/shoulda}/matchers/action_controller/rescue_from_matcher_spec.rb +2 -2
  117. data/spec/{shoulda → unit/shoulda}/matchers/action_controller/respond_with_matcher_spec.rb +2 -2
  118. data/spec/unit/shoulda/matchers/action_controller/route_matcher_spec.rb +126 -0
  119. data/spec/{shoulda → unit/shoulda}/matchers/action_controller/route_params_spec.rb +2 -2
  120. data/spec/unit/shoulda/matchers/action_controller/set_flash_matcher_spec.rb +167 -0
  121. data/spec/unit/shoulda/matchers/action_controller/set_session_matcher_spec.rb +294 -0
  122. data/spec/{shoulda → unit/shoulda}/matchers/action_controller/strong_parameters_matcher_spec.rb +19 -11
  123. data/spec/{shoulda → unit/shoulda}/matchers/active_model/allow_mass_assignment_of_matcher_spec.rb +2 -2
  124. data/spec/{shoulda → unit/shoulda}/matchers/active_model/allow_value_matcher_spec.rb +49 -21
  125. data/spec/{shoulda → unit/shoulda}/matchers/active_model/disallow_value_matcher_spec.rb +8 -4
  126. data/spec/{shoulda → unit/shoulda}/matchers/active_model/exception_message_finder_spec.rb +4 -4
  127. data/spec/{shoulda → unit/shoulda}/matchers/active_model/have_secure_password_matcher_spec.rb +2 -2
  128. data/spec/{shoulda → unit/shoulda}/matchers/active_model/helpers_spec.rb +7 -3
  129. data/spec/{shoulda → unit/shoulda}/matchers/active_model/numericality_matchers/comparison_matcher_spec.rb +1 -1
  130. data/spec/{shoulda → unit/shoulda}/matchers/active_model/numericality_matchers/even_number_matcher_spec.rb +1 -1
  131. data/spec/{shoulda → unit/shoulda}/matchers/active_model/numericality_matchers/odd_number_matcher_spec.rb +1 -1
  132. data/spec/{shoulda → unit/shoulda}/matchers/active_model/numericality_matchers/only_integer_matcher_spec.rb +1 -1
  133. data/spec/{shoulda → unit/shoulda}/matchers/active_model/validate_absence_of_matcher_spec.rb +3 -3
  134. data/spec/{shoulda → unit/shoulda}/matchers/active_model/validate_acceptance_of_matcher_spec.rb +2 -2
  135. data/spec/unit/shoulda/matchers/active_model/validate_confirmation_of_matcher_spec.rb +63 -0
  136. data/spec/{shoulda → unit/shoulda}/matchers/active_model/validate_exclusion_of_matcher_spec.rb +5 -4
  137. data/spec/{shoulda → unit/shoulda}/matchers/active_model/validate_inclusion_of_matcher_spec.rb +7 -14
  138. data/spec/{shoulda/matchers/active_model/ensure_length_of_matcher_spec.rb → unit/shoulda/matchers/active_model/validate_length_of_matcher_spec.rb} +43 -23
  139. data/spec/{shoulda → unit/shoulda}/matchers/active_model/validate_numericality_of_matcher_spec.rb +3 -4
  140. data/spec/{shoulda → unit/shoulda}/matchers/active_model/validate_presence_of_matcher_spec.rb +3 -3
  141. data/spec/{shoulda → unit/shoulda}/matchers/active_model/validate_uniqueness_of_matcher_spec.rb +127 -2
  142. data/spec/{shoulda → unit/shoulda}/matchers/active_model/validation_message_finder_spec.rb +8 -6
  143. data/spec/{shoulda → unit/shoulda}/matchers/active_record/accept_nested_attributes_for_matcher_spec.rb +2 -2
  144. data/spec/{shoulda → unit/shoulda}/matchers/active_record/association_matcher_spec.rb +217 -26
  145. data/spec/{shoulda → unit/shoulda}/matchers/active_record/association_matchers/model_reflection_spec.rb +2 -2
  146. data/spec/{shoulda → unit/shoulda}/matchers/active_record/define_enum_for_matcher_spec.rb +2 -2
  147. data/spec/{shoulda → unit/shoulda}/matchers/active_record/have_db_column_matcher_spec.rb +2 -2
  148. data/spec/{shoulda → unit/shoulda}/matchers/active_record/have_db_index_matcher_spec.rb +8 -5
  149. data/spec/{shoulda → unit/shoulda}/matchers/active_record/have_readonly_attributes_matcher_spec.rb +2 -2
  150. data/spec/{shoulda → unit/shoulda}/matchers/active_record/serialize_matcher_spec.rb +3 -3
  151. data/spec/{shoulda → unit/shoulda}/matchers/doublespeak/double_collection_spec.rb +29 -7
  152. data/spec/{shoulda → unit/shoulda}/matchers/doublespeak/double_implementation_registry_spec.rb +1 -1
  153. data/spec/{shoulda → unit/shoulda}/matchers/doublespeak/double_spec.rb +20 -10
  154. data/spec/{shoulda → unit/shoulda}/matchers/doublespeak/object_double_spec.rb +1 -1
  155. data/spec/{shoulda → unit/shoulda}/matchers/doublespeak/proxy_implementation_spec.rb +13 -6
  156. data/spec/{shoulda → unit/shoulda}/matchers/doublespeak/stub_implementation_spec.rb +2 -2
  157. data/spec/unit/shoulda/matchers/doublespeak/world_spec.rb +77 -0
  158. data/spec/{shoulda → unit/shoulda}/matchers/doublespeak_spec.rb +11 -3
  159. data/spec/{shoulda → unit/shoulda}/matchers/independent/delegate_method_matcher/stubbed_target_spec.rb +1 -1
  160. data/spec/unit/shoulda/matchers/independent/delegate_method_matcher_spec.rb +517 -0
  161. data/spec/unit_spec_helper.rb +66 -0
  162. data/spec/warnings_spy/partitioner.rb +10 -3
  163. data/spec/warnings_spy/reader.rb +9 -20
  164. data/spec/warnings_spy/reporter.rb +2 -1
  165. metadata +212 -149
  166. data/features/activemodel_integration.feature +0 -15
  167. data/features/rails_integration.feature +0 -160
  168. data/features/step_definitions/activemodel_steps.rb +0 -21
  169. data/features/step_definitions/rails_steps.rb +0 -227
  170. data/features/support/env.rb +0 -6
  171. data/spec/shoulda/matchers/action_controller/route_matcher_spec.rb +0 -70
  172. data/spec/shoulda/matchers/action_controller/set_session_matcher_spec.rb +0 -113
  173. data/spec/shoulda/matchers/action_controller/set_the_flash_matcher_spec.rb +0 -153
  174. data/spec/shoulda/matchers/active_model/validate_confirmation_of_matcher_spec.rb +0 -47
  175. data/spec/shoulda/matchers/doublespeak/world_spec.rb +0 -70
  176. data/spec/shoulda/matchers/independent/delegate_method_matcher_spec.rb +0 -309
  177. data/spec/spec_helper.rb +0 -42
  178. data/spec/support/active_model_versions.rb +0 -13
  179. data/spec/support/active_resource_builder.rb +0 -29
  180. data/spec/support/activemodel_helpers.rb +0 -23
  181. data/spec/support/capture_helpers.rb +0 -19
  182. data/spec/support/class_builder.rb +0 -46
  183. data/spec/support/controller_builder.rb +0 -102
  184. data/spec/support/fail_with_message_including_matcher.rb +0 -44
  185. data/spec/support/fail_with_message_matcher.rb +0 -44
  186. data/spec/support/i18n_faker.rb +0 -10
  187. data/spec/support/mailer_builder.rb +0 -10
  188. data/spec/support/model_builder.rb +0 -81
  189. data/spec/support/rails_versions.rb +0 -26
  190. data/spec/support/test_application.rb +0 -120
@@ -31,9 +31,24 @@ module Shoulda
31
31
  # should delegate_method(:deliver).to(:post_office)
32
32
  # end
33
33
  #
34
+ # You can also use `delegate_method` with Rails's `delegate` macro:
35
+ #
36
+ # class Courier
37
+ # attr_reader :post_office
38
+ # delegate :deliver, to: :post_office
39
+ #
40
+ # def initialize
41
+ # @post_office = PostOffice.new
42
+ # end
43
+ # end
44
+ #
45
+ # describe Courier do
46
+ # it { should delegate_method(:deliver).to(:post_office) }
47
+ # end
48
+ #
34
49
  # To employ some terminology, we would say that Courier's #deliver method
35
- # is the delegating method, PostOffice is the delegate object, and
36
- # PostOffice#deliver is the delegate method.
50
+ # is the *delegating method*, PostOffice is the *delegate object*, and
51
+ # PostOffice#deliver is the *delegate method*.
37
52
  #
38
53
  # #### Qualifiers
39
54
  #
@@ -67,6 +82,31 @@ module Shoulda
67
82
  # should delegate_method(:deliver).to(:post_office).as(:ship)
68
83
  # end
69
84
  #
85
+ # ##### with_prefix
86
+ #
87
+ # Use `with_prefix` when using Rails's `delegate` helper along with the
88
+ # `:prefix` option.
89
+ #
90
+ # class Page < ActiveRecord::Base
91
+ # belongs_to :site
92
+ # delegate :name, to: :site, prefix: true
93
+ # delegate :title, to: :site, prefix: :root
94
+ # end
95
+ #
96
+ # # RSpec
97
+ # describe Page do
98
+ # it { should delegate_method(:name).to(:site).with_prefix }
99
+ # it { should delegate_method(:name).to(:site).with_prefix(true) }
100
+ # it { should delegate_method(:title).to(:site).with_prefix(:root) }
101
+ # end
102
+ #
103
+ # # Test::Unit
104
+ # class PageTest < Test::Unit::TestCase
105
+ # should delegate_method(:name).to(:site).with_prefix
106
+ # should delegate_method(:name).to(:site).with_prefix(true)
107
+ # should delegate_method(:title).to(:site).with_prefix(:root)
108
+ # end
109
+ #
70
110
  # ##### with_arguments
71
111
  #
72
112
  # Use `with_arguments` to assert that the delegate method is called with
@@ -108,56 +148,60 @@ module Shoulda
108
148
  # @return [DelegateMethodMatcher]
109
149
  #
110
150
  def delegate_method(delegating_method)
111
- DelegateMethodMatcher.new(delegating_method, self)
151
+ DelegateMethodMatcher.new(delegating_method).in_context(self)
112
152
  end
113
153
 
114
154
  # @private
115
155
  class DelegateMethodMatcher
116
- def initialize(delegating_method, context)
156
+ def initialize(delegating_method)
117
157
  @delegating_method = delegating_method
118
- @context = context
119
158
 
120
- @method_on_target = @delegating_method
121
- @target_double = Doublespeak::ObjectDouble.new
159
+ @delegate_method = @delegating_method
160
+ @delegate_object = Doublespeak::ObjectDouble.new
122
161
 
123
162
  @delegated_arguments = []
124
- @target_method = nil
163
+ @delegate_object_reader_method = nil
125
164
  @subject = nil
126
165
  @subject_double_collection = nil
127
166
  end
128
167
 
168
+ def in_context(context)
169
+ @context = MatcherContext.new(context)
170
+ self
171
+ end
172
+
129
173
  def matches?(subject)
130
174
  @subject = subject
131
175
 
132
- ensure_target_method_is_present!
176
+ ensure_delegate_object_has_been_specified!
133
177
 
134
178
  subject_has_delegating_method? &&
135
- subject_has_target_method? &&
136
- subject_delegates_to_target_correctly?
179
+ subject_has_delegate_object_reader_method? &&
180
+ subject_delegates_to_delegate_object_correctly?
137
181
  end
138
182
 
139
183
  def description
140
184
  string = "delegate #{formatted_delegating_method_name} to " +
141
- "#{formatted_target_method_name} object"
185
+ "#{formatted_delegate_object_reader_method_name} object"
142
186
 
143
187
  if delegated_arguments.any?
144
188
  string << " passing arguments #{delegated_arguments.inspect}"
145
189
  end
146
190
 
147
- if method_on_target != delegating_method
148
- string << " as #{formatted_method_on_target}"
191
+ if delegate_method != delegating_method
192
+ string << " as #{formatted_delegate_method}"
149
193
  end
150
194
 
151
195
  string
152
196
  end
153
197
 
154
- def to(target_method)
155
- @target_method = target_method
198
+ def to(delegate_object_reader_method)
199
+ @delegate_object_reader_method = delegate_object_reader_method
156
200
  self
157
201
  end
158
202
 
159
- def as(method_on_target)
160
- @method_on_target = method_on_target
203
+ def as(delegate_method)
204
+ @delegate_method = delegate_method
161
205
  self
162
206
  end
163
207
 
@@ -166,11 +210,25 @@ module Shoulda
166
210
  self
167
211
  end
168
212
 
213
+ def with_prefix(prefix = nil)
214
+ @delegating_method =
215
+ :"#{build_delegating_method_prefix(prefix)}_#{delegate_method}"
216
+ delegate_method
217
+ self
218
+ end
219
+
220
+ def build_delegating_method_prefix(prefix)
221
+ case prefix
222
+ when true, nil then delegate_object_reader_method
223
+ else prefix
224
+ end
225
+ end
226
+
169
227
  def failure_message
170
228
  "Expected #{class_under_test} to #{description}\n" +
171
229
  "Method calls sent to " +
172
- "#{formatted_target_method_name(include_module: true)}:" +
173
- formatted_calls_on_target
230
+ "#{formatted_delegate_object_reader_method_name(include_module: true)}:" +
231
+ formatted_calls_on_delegate_object
174
232
  end
175
233
  alias failure_message_for_should failure_message
176
234
 
@@ -186,33 +244,41 @@ module Shoulda
186
244
  :delegated_arguments,
187
245
  :delegating_method,
188
246
  :method,
189
- :method_on_target,
247
+ :delegate_method,
190
248
  :subject_double_collection,
191
- :target_double,
192
- :target_method
249
+ :delegate_object,
250
+ :delegate_object_reader_method
193
251
 
194
252
  def subject
195
- @subject || context.subject
253
+ @subject
254
+ end
255
+
256
+ def subject_is_a_class?
257
+ if @subject
258
+ @subject.is_a?(Class)
259
+ else
260
+ context.subject_is_a_class?
261
+ end
196
262
  end
197
263
 
198
264
  def class_under_test
199
- if subject.is_a?(Class)
265
+ if subject_is_a_class?
200
266
  subject
201
267
  else
202
268
  subject.class
203
269
  end
204
270
  end
205
271
 
206
- def formatted_method_on_target(options = {})
207
- formatted_method_name_for(method_on_target, options)
272
+ def formatted_delegate_method(options = {})
273
+ formatted_method_name_for(delegate_method, options)
208
274
  end
209
275
 
210
276
  def formatted_delegating_method_name(options = {})
211
277
  formatted_method_name_for(delegating_method, options)
212
278
  end
213
279
 
214
- def formatted_target_method_name(options = {})
215
- formatted_method_name_for(target_method, options)
280
+ def formatted_delegate_object_reader_method_name(options = {})
281
+ formatted_method_name_for(delegate_object_reader_method, options)
216
282
  end
217
283
 
218
284
  def formatted_method_name_for(method_name, options)
@@ -230,19 +296,19 @@ module Shoulda
230
296
  end
231
297
 
232
298
  def class_or_instance_method_indicator
233
- if subject.is_a?(Class)
299
+ if subject_is_a_class?
234
300
  '.'
235
301
  else
236
302
  '#'
237
303
  end
238
304
  end
239
305
 
240
- def target_received_method?
241
- calls_to_method_on_target.any?
306
+ def delegate_object_received_call?
307
+ calls_to_delegate_method.any?
242
308
  end
243
309
 
244
- def target_received_method_with_delegated_arguments?
245
- calls_to_method_on_target.any? do |call|
310
+ def delegate_object_received_call_with_delegated_arguments?
311
+ calls_to_delegate_method.any? do |call|
246
312
  call.args == delegated_arguments
247
313
  end
248
314
  end
@@ -251,17 +317,17 @@ module Shoulda
251
317
  subject.respond_to?(delegating_method)
252
318
  end
253
319
 
254
- def subject_has_target_method?
255
- subject.respond_to?(target_method, true)
320
+ def subject_has_delegate_object_reader_method?
321
+ subject.respond_to?(delegate_object_reader_method, true)
256
322
  end
257
323
 
258
- def ensure_target_method_is_present!
259
- if target_method.to_s.empty?
260
- raise TargetNotDefinedError
324
+ def ensure_delegate_object_has_been_specified!
325
+ if delegate_object_reader_method.to_s.empty?
326
+ raise DelegateObjectNotSpecified
261
327
  end
262
328
  end
263
329
 
264
- def subject_delegates_to_target_correctly?
330
+ def subject_delegates_to_delegate_object_correctly?
265
331
  register_subject_double_collection
266
332
 
267
333
  Doublespeak.with_doubles_activated do
@@ -269,35 +335,35 @@ module Shoulda
269
335
  end
270
336
 
271
337
  if delegated_arguments.any?
272
- target_received_method_with_delegated_arguments?
338
+ delegate_object_received_call_with_delegated_arguments?
273
339
  else
274
- target_received_method?
340
+ delegate_object_received_call?
275
341
  end
276
342
  end
277
343
 
278
344
  def register_subject_double_collection
279
345
  double_collection =
280
346
  Doublespeak.double_collection_for(subject.singleton_class)
281
- double_collection.register_stub(target_method).
282
- to_return(target_double)
347
+ double_collection.register_stub(delegate_object_reader_method).
348
+ to_return(delegate_object)
283
349
 
284
350
  @subject_double_collection = double_collection
285
351
  end
286
352
 
287
- def calls_to_method_on_target
288
- target_double.calls_to(method_on_target)
353
+ def calls_to_delegate_method
354
+ delegate_object.calls_to(delegate_method)
289
355
  end
290
356
 
291
- def calls_on_target
292
- target_double.calls
357
+ def calls_on_delegate_object
358
+ delegate_object.calls
293
359
  end
294
360
 
295
- def formatted_calls_on_target
361
+ def formatted_calls_on_delegate_object
296
362
  string = ""
297
363
 
298
- if calls_on_target.any?
364
+ if calls_on_delegate_object.any?
299
365
  string << "\n"
300
- calls_on_target.each_with_index do |call, i|
366
+ calls_on_delegate_object.each_with_index do |call, i|
301
367
  name = call.method_name
302
368
  args = call.args.map { |arg| arg.inspect }.join(', ')
303
369
  string << "#{i+1}) #{name}(#{args})\n"
@@ -3,7 +3,7 @@ module Shoulda
3
3
  module Independent
4
4
  class DelegateMethodMatcher
5
5
  # @private
6
- class TargetNotDefinedError < StandardError
6
+ class DelegateObjectNotSpecified < StandardError
7
7
  def message
8
8
  'Delegation needs a target. Use the #to method to define one, e.g.
9
9
  `post_office.should delegate(:deliver_mail).to(:mailman)`'.squish
@@ -0,0 +1,35 @@
1
+ module Shoulda
2
+ module Matchers
3
+ class MatcherContext
4
+ def initialize(context)
5
+ @context = context
6
+ end
7
+
8
+ def subject_is_a_class?
9
+ if inside_a_shoulda_context_project? && outside_a_should_block?
10
+ assume_that_subject_is_not_a_class
11
+ else
12
+ context.subject.is_a?(Class)
13
+ end
14
+ end
15
+
16
+ protected
17
+
18
+ attr_reader :context
19
+
20
+ private
21
+
22
+ def inside_a_shoulda_context_project?
23
+ defined?(Shoulda::Context)
24
+ end
25
+
26
+ def outside_a_should_block?
27
+ context.is_a?(Class)
28
+ end
29
+
30
+ def assume_that_subject_is_not_a_class
31
+ false
32
+ end
33
+ end
34
+ end
35
+ end
@@ -42,6 +42,29 @@ module Shoulda
42
42
  end
43
43
  end
44
44
 
45
+ def self.type_cast_default_for(model, column)
46
+ if model.respond_to?(:column_defaults)
47
+ # Rails 4.2
48
+ model.column_defaults[column.name]
49
+ else
50
+ column.default
51
+ end
52
+ end
53
+
54
+ def self.serialized_attributes_for(model)
55
+ if defined?(::ActiveRecord::Type::Serialized)
56
+ # Rails 5+
57
+ model.columns.select do |column|
58
+ column.cast_type.is_a?(::ActiveRecord::Type::Serialized)
59
+ end.inject({}) do |hash, column|
60
+ hash[column.name.to_s] = column.cast_type.coder
61
+ hash
62
+ end
63
+ else
64
+ model.serialized_attributes
65
+ end
66
+ end
67
+
45
68
  def self.active_record_major_version
46
69
  ::ActiveRecord::VERSION::MAJOR
47
70
  end
@@ -0,0 +1,28 @@
1
+ module Shoulda
2
+ module Matchers
3
+ # @private
4
+ module Util
5
+ def self.deconstantize(path)
6
+ if defined?(ActiveSupport::Inflector) &&
7
+ ActiveSupport::Inflector.respond_to?(:deconstantize)
8
+ ActiveSupport::Inflector.deconstantize(path)
9
+ else
10
+ path.to_s[0...(path.to_s.rindex('::') || 0)]
11
+ end
12
+ end
13
+
14
+ def self.safe_constantize(camel_cased_word)
15
+ if defined?(ActiveSupport::Inflector) &&
16
+ ActiveSupport::Inflector.respond_to?(:safe_constantize)
17
+ ActiveSupport::Inflector.safe_constantize(camel_cased_word)
18
+ else
19
+ begin
20
+ camel_cased_word.constantize
21
+ rescue NameError
22
+ nil
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -1,6 +1,6 @@
1
1
  module Shoulda
2
2
  module Matchers
3
3
  # @private
4
- VERSION = '2.7.0'.freeze
4
+ VERSION = '2.8.0.rc1'.freeze
5
5
  end
6
6
  end
@@ -1 +1 @@
1
- 1.9.2 1.9.3 2.0.0 2.1.1
1
+ 1.9.2 1.9.3 2.0.0 2.1.5
@@ -0,0 +1,20 @@
1
+ require 'acceptance_spec_helper'
2
+
3
+ describe 'shoulda-matchers integrates with an ActiveModel project' do
4
+ specify 'and loads without errors' do
5
+ create_active_model_project
6
+
7
+ add_shoulda_matchers_to_project
8
+
9
+ write_file 'load_dependencies.rb', <<-FILE
10
+ require 'active_model'
11
+ require 'shoulda-matchers'
12
+
13
+ puts ActiveModel::VERSION::STRING
14
+ puts "Loaded all dependencies without errors"
15
+ FILE
16
+
17
+ result = run_command_within_bundle('ruby load_dependencies.rb')
18
+ expect(result).to have_output('Loaded all dependencies without errors')
19
+ end
20
+ end