shoulda-matchers 4.1.0 → 4.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1856891b0a96aaa5ed99a48490288b2bbd3547c7779ab1d8477a33b61cbb0c7d
4
- data.tar.gz: b3768f6532318b37de78e6959a1c7be2e28e19b4618d966a7ca0dab0cfa96ceb
3
+ metadata.gz: f55ad44dc8280d7bb9598c809562c5d4b4bd174e78bdc8323898bdb7a3e8665a
4
+ data.tar.gz: 80ddb4b8e6c0ab63c4b9225a1a75789d058d1e664c1b2248680469868072e724
5
5
  SHA512:
6
- metadata.gz: dc99bd232c8f9a3eeff2ea7b82b36821339b20090b40c750c282b48d413b99028fcb69ec775ecb37a43d7e6d59a0c090213c35ede384ed95303d010a5e00ed90
7
- data.tar.gz: 56dbd1bd6978b59743e6936118a535e276b7672f12a0b46b69b3baf164b6dcac0688ee26ec66ccb11b2d0af8d1374567d401ef1f46d3f54bd6d3ccee8cf55085
6
+ metadata.gz: b912596ee8e4a25b1cbd98bca2878ac52cc19b54ab6014bbff0952b7449294e26a6d82b21a6d871b897eb23b26fb82bbc7b328d4de28bb73191fccf53e4e9c1b
7
+ data.tar.gz: 168c002e0ed67d1a2dfde0465e2f48c2fcd4177810479f9c4d5970949f4fbec7db7cb5c71c33b7a341174d5c97fbbfb0782b18ada9f30695048bf25c64777875
data/README.md CHANGED
@@ -19,7 +19,7 @@ complex, and error-prone.
19
19
 
20
20
  ## Quick links
21
21
 
22
- 📖 **[Read the documentation for the latest version (4.1.0)][rubydocs].**
22
+ 📖 **[Read the documentation for the latest version (4.1.1)][rubydocs].**
23
23
  📢 **[See what's changed in a recent version][news].**
24
24
 
25
25
  [rubydocs]: http://matchers.shoulda.io/docs
@@ -170,7 +170,7 @@ module Shoulda
170
170
  allows_and_double_checks_value_of!(value)
171
171
  end
172
172
  else
173
- (expects_to_allow_nil? && !allows_value_of(nil)) ||
173
+ (expects_to_allow_nil? && disallows_value_of(nil)) ||
174
174
  disallowed_values.any? do |value|
175
175
  allows_original_or_typecast_value?(value)
176
176
  end
@@ -234,12 +234,14 @@ validation for you? Instead of using `validate_presence_of`, try
234
234
  end
235
235
 
236
236
  def disallowed_values
237
- if collection?
237
+ if collection_association?
238
238
  [Array.new]
239
+ elsif attachment?
240
+ [nil]
239
241
  else
240
242
  values = []
241
243
 
242
- if !association_being_validated?
244
+ if attribute_accepts_string_values?
243
245
  values << ''
244
246
  end
245
247
 
@@ -251,16 +253,6 @@ validation for you? Instead of using `validate_presence_of`, try
251
253
  end
252
254
  end
253
255
 
254
- def collection?
255
- if association_reflection
256
- [:has_many, :has_and_belongs_to_many].include?(
257
- association_reflection.macro,
258
- )
259
- else
260
- false
261
- end
262
- end
263
-
264
256
  def should_add_footnote_about_belongs_to?
265
257
  belongs_to_association_being_validated? &&
266
258
  presence_validation_exists_on_attribute?
@@ -316,12 +308,33 @@ validation for you? Instead of using `validate_presence_of`, try
316
308
  end
317
309
 
318
310
  def belongs_to_association_being_validated?
319
- association_being_validated? &&
320
- association_reflection.macro == :belongs_to
311
+ association? && association_reflection.macro == :belongs_to
312
+ end
313
+
314
+ def attribute_accepts_string_values?
315
+ if association?
316
+ false
317
+ elsif attribute_serializer
318
+ attribute_serializer.object_class == String
319
+ else
320
+ attribute_type.try(:type) == :string
321
+ end
322
+ end
323
+
324
+ def association?
325
+ association_reflection.present?
321
326
  end
322
327
 
323
- def association_being_validated?
324
- !!association_reflection
328
+ def collection_association?
329
+ association? && association_reflection.macro.in?(
330
+ [:has_many, :has_and_belongs_to_many],
331
+ )
332
+ end
333
+
334
+ def attachment?
335
+ model_has_associations?(
336
+ ["#{@attribute}_attachment", "#{@attribute}_attachments"],
337
+ )
325
338
  end
326
339
 
327
340
  def association_name
@@ -333,8 +346,25 @@ validation for you? Instead of using `validate_presence_of`, try
333
346
  end
334
347
 
335
348
  def association_reflection
336
- model.respond_to?(:reflect_on_association) &&
337
- model.reflect_on_association(@attribute)
349
+ model.try(:reflect_on_association, @attribute)
350
+ end
351
+
352
+ def model_has_associations?(associations)
353
+ associations.any? do |association|
354
+ !!model.try(:reflect_on_association, association)
355
+ end
356
+ end
357
+
358
+ def attribute_serializer
359
+ if attribute_type.respond_to?(:coder)
360
+ attribute_type.coder
361
+ else
362
+ nil
363
+ end
364
+ end
365
+
366
+ def attribute_type
367
+ RailsShim.attribute_type_for(model, @attribute)
338
368
  end
339
369
 
340
370
  def presence_validation_exists_on_attribute?
@@ -2,7 +2,7 @@ module Shoulda
2
2
  module Matchers
3
3
  module ActiveRecord
4
4
  # The `define_enum_for` matcher is used to test that the `enum` macro has
5
- # been used to decorate an attribute with enum methods.
5
+ # been used to decorate an attribute with enum capabilities.
6
6
  #
7
7
  # class Process < ActiveRecord::Base
8
8
  # enum status: [:running, :stopped, :suspended]
@@ -22,8 +22,8 @@ module Shoulda
22
22
  #
23
23
  # ##### with_values
24
24
  #
25
- # Use `with_values` to test that the attribute has been defined with a
26
- # certain set of possible values.
25
+ # Use `with_values` to test that the attribute can only receive a certain
26
+ # set of possible values.
27
27
  #
28
28
  # class Process < ActiveRecord::Base
29
29
  # enum status: [:running, :stopped, :suspended]
@@ -43,10 +43,37 @@ module Shoulda
43
43
  # with_values([:running, :stopped, :suspended])
44
44
  # end
45
45
  #
46
+ # If the values backing your enum attribute are arbitrary instead of a
47
+ # series of integers starting from 0, pass a hash to `with_values` instead
48
+ # of an array:
49
+ #
50
+ # class Process < ActiveRecord::Base
51
+ # enum status: {
52
+ # running: 0,
53
+ # stopped: 1,
54
+ # suspended: 3,
55
+ # other: 99
56
+ # }
57
+ # end
58
+ #
59
+ # # RSpec
60
+ # RSpec.describe Process, type: :model do
61
+ # it do
62
+ # should define_enum_for(:status).
63
+ # with_values(running: 0, stopped: 1, suspended: 3, other: 99)
64
+ # end
65
+ # end
66
+ #
67
+ # # Minitest (Shoulda)
68
+ # class ProcessTest < ActiveSupport::TestCase
69
+ # should define_enum_for(:status).
70
+ # with_values(running: 0, stopped: 1, suspended: 3, other: 99)
71
+ # end
72
+ #
46
73
  # ##### backed_by_column_of_type
47
74
  #
48
- # Use `backed_by_column_of_type` to test that the attribute is of a
49
- # certain column type. (The default is `:integer`.)
75
+ # Use `backed_by_column_of_type` when the column backing your column type
76
+ # is a string instead of an integer:
50
77
  #
51
78
  # class LoanApplication < ActiveRecord::Base
52
79
  # enum status: {
@@ -156,6 +156,14 @@ module Shoulda
156
156
  nil
157
157
  end
158
158
 
159
+ def attribute_type_for(model, attribute_name)
160
+ if supports_full_attributes_api?(model)
161
+ model.attribute_types[attribute_name.to_s]
162
+ else
163
+ LegacyAttributeType.new(model, attribute_name)
164
+ end
165
+ end
166
+
159
167
  private
160
168
 
161
169
  def simply_generate_validation_message(
@@ -179,6 +187,30 @@ module Shoulda
179
187
  { default: default_translation_keys }.merge(options)
180
188
  I18n.translate(primary_translation_key, translate_options)
181
189
  end
190
+
191
+ def supports_full_attributes_api?(model)
192
+ defined?(::ActiveModel::Attributes) &&
193
+ model.respond_to?(:attribute_types)
194
+ end
195
+
196
+ class LegacyAttributeType
197
+ def initialize(model, attribute_name)
198
+ @model = model
199
+ @attribute_name = attribute_name
200
+ end
201
+
202
+ def coder
203
+ if model.respond_to?(:serialized_attributes)
204
+ ActiveSupport::Deprecation.silence do
205
+ model.serialized_attributes[attribute_name.to_s]
206
+ end
207
+ end
208
+ end
209
+
210
+ private
211
+
212
+ attr_reader :model, :attribute_name
213
+ end
182
214
  end
183
215
  end
184
216
  end
@@ -1,6 +1,6 @@
1
1
  module Shoulda
2
2
  module Matchers
3
3
  # @private
4
- VERSION = '4.1.0'.freeze
4
+ VERSION = '4.1.1'.freeze
5
5
  end
6
6
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: shoulda-matchers
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.1.0
4
+ version: 4.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tammer Saleh
@@ -14,7 +14,7 @@ authors:
14
14
  autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
- date: 2019-06-09 00:00:00.000000000 Z
17
+ date: 2019-07-15 00:00:00.000000000 Z
18
18
  dependencies:
19
19
  - !ruby/object:Gem::Dependency
20
20
  name: activesupport