hoodoo 2.10.0 → 2.11.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 558f4ad8d5dd9efe88b282630fcb24a5fc244382e7dc3ff769b21998c38c058e
4
- data.tar.gz: 0b2b67b5d32e25c160f1a4ec755898b294fb742044615557c05a9d18769e8699
3
+ metadata.gz: 46ac63e8aa118e94f032e34184b681adb622215fdd8fce503980461dbf5917bd
4
+ data.tar.gz: 7c4f3a6e0f3237cd1accd3159029081a7e8ef58797da65e3d986dec464709797
5
5
  SHA512:
6
- metadata.gz: 9dc89cb9a030e29d0c678a4cef606fff9ad2bee6761148573c4c5ea8e8fa173ffc99dcf0f2e50f7ca6ac7f90baac80a6854314159cc53adc2624e2326478622b
7
- data.tar.gz: de09f589b82a11eec89cd494860b9b2c3ee00262fd16cd18307296d88caf3ab3b5eef2ce28387adc525dc924a9d34d1074dd13233edb6346e9b61470eb8d9804
6
+ metadata.gz: 684ffccf17fc0aead47c9abfbc413ce8cb9fd60efd4798eb61a7dfef928d9f31acc76ad3818cd6f6a26db0b5b5857c7e723e27a111b4911b3c2ae12b0787d16a
7
+ data.tar.gz: 3a9c95d8e592dec3f6037eb551e142d433449e4d5805317109ed0b3f8aa6701c8518fba91cdca2e634cd809073908a292c3a3f9be0649095c767eecaecb010ae
@@ -7,8 +7,13 @@
7
7
  # validation errors.
8
8
  # ----------------------------------------------------------------------
9
9
  # 17-Nov-2014 (ADH): Created.
10
+ # 12-Dec-2018 (ADH): Moved most of the error mapping code out
11
+ # to Hoodoo::ActiveRecord::Support, so that
12
+ # it can be reused more easily.
10
13
  ########################################################################
11
14
 
15
+ require 'hoodoo/active/active_record/support'
16
+
12
17
  module Hoodoo
13
18
 
14
19
  # Support mixins for models subclassed from ActiveRecord::Base. See:
@@ -39,7 +44,11 @@ module Hoodoo
39
44
  # Returns +true+ if any errors were added (model instance is invalid)
40
45
  # else +false+ if everything is OK (model instance is valid).
41
46
  #
42
- # == Mapping ActiveRecord errors to API errors
47
+ # Uses Hoodoo::ActiveRecord::Support#translate_errors_on to perform
48
+ # the mapping. For detailed information on how the mapping works,
49
+ # please see that method.
50
+ #
51
+ # == Mapping ActiveRecord errors to Hoodoo errors
43
52
  #
44
53
  # The method makes an idiomatic example for "check errors in the model,
45
54
  # map them to platform errors in my service's response and return the
@@ -107,69 +116,6 @@ module Hoodoo
107
116
  # possible - provided one assumes that the non-error path is the much
108
117
  # more common case!
109
118
  #
110
- # == Associations
111
- #
112
- # When a model has associations and nested attributes are accepted for
113
- # those associations, a validity query on an instance constructed with
114
- # nested attributes will cause ActiveRecord to traverse all such
115
- # attributes and aggregate specific errors on the parent object. This
116
- # is specifically different from +validates_associated+, wherein
117
- # associations constructed and attached through any means are validated
118
- # independently, with validation errors independently added to those
119
- # objects and the parent only gaining a generic "foo is invalid" error.
120
- #
121
- # In such cases, the error mapper will attempt to path-traverse the
122
- # error's column references to determine the association's column type
123
- # and produce a fully mapped error with a reference to the full path.
124
- # Service authors are encouraged to use this approach if associations
125
- # are involved, as it yields the most comprehensive mapped error
126
- # collection.
127
- #
128
- # In the example below, note how the Child model does not need to
129
- # include Hoodoo error mapping (though it can do so harmlessly if it so
130
- # wishes) because it is the Parent model that drives the mapping of all
131
- # the validations aggregated by ActiveRecord into an instance of Parent
132
- # due to +accepts_nested_attributes_for+.
133
- #
134
- # So, given this:
135
- #
136
- # def Parent < ActiveRecord::Base
137
- # include Hoodoo::ActiveRecord::ErrorMapping
138
- #
139
- # has_many :children
140
- # accepts_nested_attributes_for :children
141
- # end
142
- #
143
- # def Child < ActiveRecord::Base
144
- # belongs_to :parent
145
- #
146
- # # ...then add ActiveRecord validations - e.g.:
147
- #
148
- # validates :some_child_field, :length => { :maximum => 5 }
149
- # end
150
- #
151
- # ...then if a Parent were to be constructed thus:
152
- #
153
- # parent = Parent.new( {
154
- # "parent_field_1" = "foo",
155
- # "parent_field_2" = "bar",
156
- # "children_attributes" = [
157
- # { "some_child_field" = "child_1_foo" },
158
- # { "some_child_field" = "child_2_foo" },
159
- # # ...
160
- # ],
161
- # # ...
162
- # } )
163
- #
164
- # ...then <tt>parent.adds_errors_to?( some_collection )</tt> could lead
165
- # to +some_collection+ containing errors such as:
166
- #
167
- # {
168
- # "code" => "generic.invalid_string",
169
- # "message => "is too long (maximum is 5 characters)",
170
- # "reference" => "children.some_child_field"
171
- # }
172
- #
173
119
  # +collection+:: A Hoodoo::Errors instance, typically obtained
174
120
  # from the Hoodoo::Services::Context instance passed to
175
121
  # a service implementation in calls like
@@ -183,34 +129,8 @@ module Hoodoo
183
129
  # the collection.
184
130
  #
185
131
  def adds_errors_to?( collection )
186
-
187
132
  self.validate()
188
-
189
- self.errors.messages.each_pair do | attribute_name, message_array |
190
- attribute_name = attribute_name.to_s
191
-
192
- attribute_type = nz_co_loyalty_determine_deep_attribute_type( attribute_name )
193
- attribute_name = 'model instance' if attribute_name == 'base'
194
-
195
- message_array.each do | message |
196
- error_code = case message
197
- when 'has already been taken'
198
- 'generic.invalid_duplication'
199
- else
200
- attribute_type == 'text' ? 'generic.invalid_string' : "generic.invalid_#{ attribute_type }"
201
- end
202
-
203
- unless collection.descriptions.recognised?( error_code )
204
- error_code = 'generic.invalid_parameters'
205
- end
206
-
207
- collection.add_error(
208
- error_code,
209
- :message => message,
210
- :reference => { :field_name => attribute_name }
211
- )
212
- end
213
- end
133
+ Hoodoo::ActiveRecord::Support.translate_errors_on( self, collection )
214
134
 
215
135
  return self.errors.any?
216
136
  end
@@ -254,98 +174,6 @@ module Hoodoo
254
174
  return collection
255
175
  end
256
176
 
257
- private
258
-
259
- # Given an attribute for this model as a string, return the column type
260
- # associated with it.
261
- #
262
- # The attribute name intended for use here comes from validation and,
263
- # when there are unsaved associations in an ActiveRecord graph that is
264
- # being saved, ActiveRecord aggregates child object errors into the
265
- # target parent being saved with the attribute names using a dot
266
- # notation to indicate the path of methods to get from one instance to
267
- # the next. This is resolved. For example:
268
- #
269
- # * <tt>address</tt> would look up the type of a column called
270
- # "address" in 'this' model.
271
- #
272
- # * <tt>addresses.home</tt> would look up the type of a column called
273
- # "home" in whatever is accessed by "model.addresses". If this gives
274
- # an array, the first entry in the array is taken for column type
275
- # retrieval.
276
- #
277
- # This path chasing will be done to an arbitrary depth. If at any point
278
- # there is a failure to follow the path, the path follower exits and
279
- # the top-level error is used instead, with a generic unknown column
280
- # type returned.
281
- #
282
- # Parameters:
283
- #
284
- # +attribute_path+:: _String_ attribute path. Not a Symbol or Array!
285
- #
286
- # Return values are any ActiveRecord column type or these special
287
- # values:
288
- #
289
- # * +unknown+ for any unrecognised attribute name or an attribute name
290
- # that is a path (it has one or more "."s in it) but where the path
291
- # cannot be followed.
292
- #
293
- # * +array+ for columns that appear to respond to the +array+ method.
294
- #
295
- # * +uuid+ for columns of any known but non-array type, where there is
296
- # a UuidValidator present.
297
- #
298
- def nz_co_loyalty_determine_deep_attribute_type( attribute_path )
299
-
300
- attribute_name = attribute_path
301
- target_instance = self
302
-
303
- # Descend a path of "foo.bar.baz" dereferencing associations from the
304
- # field names in the dot-separated path until we're at the lowest leaf
305
- # object with "baz" as its errant field.
306
-
307
- if attribute_path.include?( '.' )
308
-
309
- leaf_instance = target_instance
310
- leaf_field = attribute_path
311
-
312
- fields = attribute_path.split( '.' )
313
- leaf_field = fields.pop() # (remove final entry - the leaf object's errant field)
314
- reached_field = nil
315
-
316
- fields.each do | field |
317
- object_at_field = leaf_instance.send( field ) if leaf_instance.respond_to?( field )
318
- object_at_field = object_at_field.first if object_at_field.respond_to?( :first )
319
-
320
- break if object_at_field.nil?
321
-
322
- leaf_instance = object_at_field
323
- reached_field = field
324
- end
325
-
326
- if reached_field == fields.last
327
- attribute_name = leaf_field
328
- target_instance = leaf_instance
329
- end
330
- end
331
-
332
- column = target_instance.class.columns_hash[ attribute_name ]
333
-
334
- attribute_type = if column.nil?
335
- 'unknown'
336
- elsif column.respond_to?( :array ) && column.array
337
- 'array'
338
- elsif target_instance.class.validators_on( attribute_name ).any? { | v |
339
- v.instance_of?( UuidValidator )
340
- } # Considered a UUID since it uses the UUID validator
341
- 'uuid'
342
- else
343
- column.type.to_s()
344
- end
345
-
346
- return attribute_type
347
- end
348
-
349
177
  end
350
178
  end
351
179
  end
@@ -183,6 +183,219 @@ module Hoodoo
183
183
  return base_scope
184
184
  end
185
185
 
186
+ # When given an ActiveRecord model instance which may have errors set
187
+ # on it as a result of a prior #validate or #save call, map any found
188
+ # errors from ActiveRecord to a Hoodoo::Errors instance. The mapping is
189
+ # comprehensive; it even checks the data type of errant columns and
190
+ # tries to find a +generic...+ family error to use for mapped result
191
+ # (e.g. +generic.invalid_string+ or +generic.invalid_integer+).
192
+ #
193
+ # Usually, the Hoodoo:ActiveRecord::ErrorMapping mixin is included into
194
+ # an ActiveRecord model directly and this method is therefore not used
195
+ # directly; Hoodoo:ActiveRecord::ErrorMapping.adds_errors_to? or
196
+ # similar is called instead.
197
+ #
198
+ # == Associations
199
+ #
200
+ # When a model has associations and nested attributes are accepted for
201
+ # those associations, a validity query on an instance constructed with
202
+ # nested attributes will cause ActiveRecord to traverse all such
203
+ # attributes and aggregate specific errors on the parent object. This
204
+ # is specifically different from +validates_associated+, wherein
205
+ # associations constructed and attached through any means are validated
206
+ # independently, with validation errors independently added to those
207
+ # objects and the parent only gaining a generic "foo is invalid" error.
208
+ #
209
+ # In such cases, the error mapper will attempt to path-traverse the
210
+ # error's column references to determine the association's column type
211
+ # and produce a fully mapped error with a reference to the full path.
212
+ # Service authors are encouraged to use this approach if associations
213
+ # are involved, as it yields the most comprehensive mapped error
214
+ # collection.
215
+ #
216
+ # In the example below, note how the Child model does not need to
217
+ # include Hoodoo error mapping (though it can do so harmlessly if it so
218
+ # wishes) because it is the Parent model that drives the mapping of all
219
+ # the validations aggregated by ActiveRecord into an instance of Parent
220
+ # due to +accepts_nested_attributes_for+.
221
+ #
222
+ # So, given this:
223
+ #
224
+ # def Parent < ActiveRecord::Base
225
+ # has_many :children
226
+ # accepts_nested_attributes_for :children
227
+ # end
228
+ #
229
+ # def Child < ActiveRecord::Base
230
+ # belongs_to :parent
231
+ #
232
+ # # ...then add ActiveRecord validations - e.g.:
233
+ #
234
+ # validates :some_child_field, :length => { :maximum => 5 }
235
+ # end
236
+ #
237
+ # ...then if a Parent were to be constructed thus:
238
+ #
239
+ # parent = Parent.new( {
240
+ # "parent_field_1" = "foo",
241
+ # "parent_field_2" = "bar",
242
+ # "children_attributes" = [
243
+ # { "some_child_field" = "child_1_foo" },
244
+ # { "some_child_field" = "child_2_foo" },
245
+ # # ...
246
+ # ],
247
+ # # ...
248
+ # } )
249
+ #
250
+ # ...then <tt>translate_errors_on( parent )</tt> could return a
251
+ # Hoodoo::Errors collection containing entries such as:
252
+ #
253
+ # {
254
+ # "code" => "generic.invalid_string",
255
+ # "message => "is too long (maximum is 5 characters)",
256
+ # "reference" => "children.some_child_field"
257
+ # }
258
+ #
259
+ # +model_instance+:: The ActiveRecord model which may have errors set
260
+ # as a result of a prior validation failure.
261
+ #
262
+ # +hoodoo_errors+:: Optional Hoodoo::Errors instance. If provided, any
263
+ # mapped errors are added onto this existing set. If
264
+ # omitted, the method returns a new collection.
265
+ #
266
+ # Returns a new Hoodoo::Errors collection (which may have no errors in
267
+ # it, if the model had not validation errors) or the value given in the
268
+ # +hoodoo_errors+ parameter with zero or more new errors added.
269
+ #
270
+ def self.translate_errors_on( model_instance, hoodoo_errors = nil )
271
+ hoodoo_errors ||= Hoodoo::Errors.new
272
+
273
+ if model_instance.errors.any?
274
+ model_instance.errors.messages.each_pair do | attribute_name, message_array |
275
+ attribute_name = attribute_name.to_s
276
+
277
+ attribute_type = determine_deep_attribute_type( model_instance, attribute_name )
278
+ attribute_name = 'model instance' if attribute_name == 'base'
279
+
280
+ message_array.each do | message |
281
+ error_code = case message
282
+ when 'has already been taken'
283
+ 'generic.invalid_duplication'
284
+ else
285
+ attribute_type == 'text' ? 'generic.invalid_string' : "generic.invalid_#{ attribute_type }"
286
+ end
287
+
288
+ unless hoodoo_errors.descriptions.recognised?( error_code )
289
+ error_code = 'generic.invalid_parameters'
290
+ end
291
+
292
+ hoodoo_errors.add_error(
293
+ error_code,
294
+ :message => message,
295
+ :reference => { :field_name => attribute_name }
296
+ )
297
+ end
298
+ end
299
+ end
300
+
301
+ return hoodoo_errors
302
+ end
303
+
304
+ private
305
+
306
+ # Given an attribute for a given model as a string, return the column
307
+ # type associated with it.
308
+ #
309
+ # The attribute name intended for use here comes from validation and,
310
+ # when there are unsaved associations in an ActiveRecord graph that is
311
+ # being saved, ActiveRecord aggregates child object errors into the
312
+ # target parent being saved with the attribute names using a dot
313
+ # notation to indicate the path of methods to get from one instance to
314
+ # the next. This is resolved. For example:
315
+ #
316
+ # * <tt>address</tt> would look up the type of a column called
317
+ # "address" in 'this' model.
318
+ #
319
+ # * <tt>addresses.home</tt> would look up the type of a column called
320
+ # "home" in whatever is accessed by "model.addresses". If this gives
321
+ # an array, the first entry in the array is taken for column type
322
+ # retrieval.
323
+ #
324
+ # This path chasing will be done to an arbitrary depth. If at any point
325
+ # there is a failure to follow the path, the path follower exits and
326
+ # the top-level error is used instead, with a generic unknown column
327
+ # type returned.
328
+ #
329
+ # Parameters:
330
+ #
331
+ # +model_instance+:: The ActiveRecord model instance to inspect.
332
+ # +attribute_path+:: _String_ attribute path. Not a Symbol or Array!
333
+ #
334
+ # Return values are any ActiveRecord column type or these special
335
+ # values:
336
+ #
337
+ # * +unknown+ for any unrecognised attribute name or an attribute name
338
+ # that is a path (it has one or more "."s in it) but where the path
339
+ # cannot be followed.
340
+ #
341
+ # * +array+ for columns that appear to respond to the +array+ method.
342
+ #
343
+ # * +uuid+ for columns of any known but non-array type, where there is
344
+ # a UuidValidator present.
345
+ #
346
+ def self.determine_deep_attribute_type( model_instance, attribute_path )
347
+
348
+ attribute_name = attribute_path
349
+ target_instance = model_instance
350
+
351
+ # Descend a path of "foo.bar.baz" dereferencing associations from the
352
+ # field names in the dot-separated path until we're at the lowest leaf
353
+ # object with "baz" as its errant field.
354
+
355
+ if attribute_path.include?( '.' )
356
+
357
+ leaf_instance = target_instance
358
+ leaf_field = attribute_path
359
+
360
+ fields = attribute_path.split( '.' )
361
+ leaf_field = fields.pop() # (remove final entry - the leaf object's errant field)
362
+ reached_field = nil
363
+
364
+ fields.each do | field |
365
+ object_at_field = leaf_instance.send( field ) if leaf_instance.respond_to?( field )
366
+ object_at_field = object_at_field.first if object_at_field.respond_to?( :first )
367
+
368
+ break if object_at_field.nil?
369
+
370
+ leaf_instance = object_at_field
371
+ reached_field = field
372
+ end
373
+
374
+ if reached_field == fields.last
375
+ attribute_name = leaf_field
376
+ target_instance = leaf_instance
377
+ end
378
+ end
379
+
380
+ column = target_instance.class.columns_hash[ attribute_name ]
381
+
382
+ attribute_type = if column.nil?
383
+ 'unknown'
384
+ elsif column.respond_to?( :array ) && column.array
385
+ 'array'
386
+ elsif target_instance.class.validators_on( attribute_name ).any? { | v |
387
+ v.instance_of?( UuidValidator )
388
+ } # Considered a UUID since it uses the UUID validator
389
+ 'uuid'
390
+ else
391
+ column.type.to_s()
392
+ end
393
+
394
+ return attribute_type
395
+ end
396
+
397
+ private_class_method( :determine_deep_attribute_type )
398
+
186
399
  end
187
400
  end
188
401
  end
@@ -12,11 +12,11 @@ module Hoodoo
12
12
  # The Hoodoo gem version. If this changes, be sure to re-run
13
13
  # <tt>bundle install</tt> or <tt>bundle update</tt>.
14
14
  #
15
- VERSION = '2.10.0'
15
+ VERSION = '2.11.0'
16
16
 
17
17
  # The Hoodoo gem date. If this changes, be sure to re-run
18
18
  # <tt>bundle install</tt> or <tt>bundle update</tt>.
19
19
  #
20
- DATE = '2018-12-04'
20
+ DATE = '2018-12-12'
21
21
 
22
22
  end
@@ -0,0 +1,95 @@
1
+ shared_context 'error mapping' do
2
+ before :all do
3
+ spec_helper_silence_stdout() do
4
+ ActiveRecord::Migration.create_table( :r_spec_model_error_mapping_tests ) do | t |
5
+ t.string :uuid
6
+ t.boolean :boolean
7
+ t.date :date
8
+ t.datetime :datetime
9
+ t.decimal :decimal, :precision => 5, :scale => 2
10
+ t.float :float
11
+ t.integer :integer
12
+ t.string :string, :limit => 16
13
+ t.text :text
14
+ t.time :time
15
+ t.text :array, :array => true
16
+ end unless ActiveRecord::Base.connection.table_exists?( :r_spec_model_error_mapping_tests )
17
+
18
+ ActiveRecord::Migration.create_table( :r_spec_model_associated_error_mapping_tests ) do | t |
19
+ t.string :other_string
20
+
21
+ # For 'has_many' - can't use "t.reference" as the generated
22
+ # column name is too long!
23
+ #
24
+ t.integer :many_id
25
+ t.index :many_id
26
+ end unless ActiveRecord::Base.connection.table_exists?( :r_spec_model_associated_error_mapping_tests )
27
+
28
+ class RSpecModelErrorMappingTest < ActiveRecord::Base
29
+ include Hoodoo::ActiveRecord::ErrorMapping
30
+
31
+ has_many :r_spec_model_associated_error_mapping_tests,
32
+ :foreign_key => :many_id,
33
+ :class_name => :RSpecModelAssociatedErrorMappingTest
34
+
35
+ accepts_nested_attributes_for :r_spec_model_associated_error_mapping_tests
36
+
37
+ validates_presence_of :boolean,
38
+ :date,
39
+ :datetime,
40
+ :decimal,
41
+ :float,
42
+ :integer,
43
+ :string,
44
+ :text,
45
+ :time,
46
+ :array
47
+
48
+ validates_uniqueness_of :integer
49
+ validates :string, :length => { :maximum => 16 }
50
+ validates :uuid, :uuid => true
51
+
52
+ validate do
53
+ if string == 'magic'
54
+ errors.add( 'this.thing', 'is not a column' )
55
+ end
56
+ end
57
+ end
58
+
59
+ class RSpecModelAssociatedErrorMappingTest < ActiveRecord::Base
60
+ belongs_to :r_spec_model_error_mapping_test,
61
+ :foreign_key => :many_id,
62
+ :class_name => :RSpecModelErrorMappingTest
63
+
64
+ validates :other_string, :length => { :maximum => 6 }
65
+ end
66
+
67
+ class RSpecModelErrorMappingTestBase < ActiveRecord::Base
68
+ self.table_name = RSpecModelErrorMappingTest.table_name
69
+
70
+ include Hoodoo::ActiveRecord::ErrorMapping
71
+
72
+ validate do | instance |
73
+ instance.errors.clear()
74
+ instance.errors.add( :base, 'this is a test' )
75
+ end
76
+ end
77
+ end
78
+ end
79
+
80
+ let( :valid_model ) {
81
+ RSpecModelErrorMappingTest.new( {
82
+ :uuid => Hoodoo::UUID.generate(),
83
+ :boolean => true,
84
+ :date => Time.now,
85
+ :datetime => Time.now,
86
+ :decimal => 2.3,
87
+ :float => 2.3,
88
+ :integer => 42,
89
+ :string => "hello",
90
+ :text => "hello",
91
+ :time => Time.now,
92
+ :array => [ 'hello' ]
93
+ } )
94
+ }
95
+ end
@@ -1,106 +1,15 @@
1
1
  require 'spec_helper'
2
2
  require 'active_record'
3
+ require 'active/active_record/error_mapping_shared_context'
3
4
 
4
5
  describe Hoodoo::ActiveRecord::ErrorMapping do
5
- before :all do
6
- spec_helper_silence_stdout() do
7
- ActiveRecord::Migration.create_table( :r_spec_model_error_mapping_tests ) do | t |
8
- t.string :uuid
9
- t.boolean :boolean
10
- t.date :date
11
- t.datetime :datetime
12
- t.decimal :decimal, :precision => 5, :scale => 2
13
- t.float :float
14
- t.integer :integer
15
- t.string :string, :limit => 16
16
- t.text :text
17
- t.time :time
18
- t.text :array, :array => true
19
- end
20
-
21
- ActiveRecord::Migration.create_table( :r_spec_model_associated_error_mapping_tests ) do | t |
22
- t.string :other_string
23
-
24
- # For 'has_many' - can't use "t.reference" as the generated
25
- # column name is too long!
26
- #
27
- t.integer :many_id
28
- t.index :many_id
29
- end
30
-
31
- class RSpecModelErrorMappingTest < ActiveRecord::Base
32
- include Hoodoo::ActiveRecord::ErrorMapping
33
-
34
- has_many :r_spec_model_associated_error_mapping_tests,
35
- :foreign_key => :many_id,
36
- :class_name => :RSpecModelAssociatedErrorMappingTest
37
-
38
- accepts_nested_attributes_for :r_spec_model_associated_error_mapping_tests
39
-
40
- validates_presence_of :boolean,
41
- :date,
42
- :datetime,
43
- :decimal,
44
- :float,
45
- :integer,
46
- :string,
47
- :text,
48
- :time,
49
- :array
50
-
51
- validates_uniqueness_of :integer
52
- validates :string, :length => { :maximum => 16 }
53
- validates :uuid, :uuid => true
54
-
55
- validate do
56
- if string == 'magic'
57
- errors.add( 'this.thing', 'is not a column' )
58
- end
59
- end
60
- end
61
-
62
- class RSpecModelAssociatedErrorMappingTest < ActiveRecord::Base
63
- belongs_to :r_spec_model_error_mapping_test,
64
- :foreign_key => :many_id,
65
- :class_name => :RSpecModelErrorMappingTest
66
-
67
- validates :other_string, :length => { :maximum => 6 }
68
- end
69
-
70
- class RSpecModelErrorMappingTestBase < ActiveRecord::Base
71
- self.table_name = RSpecModelErrorMappingTest.table_name
72
-
73
- include Hoodoo::ActiveRecord::ErrorMapping
74
-
75
- validate do | instance |
76
- instance.errors.add( :base, 'this is a test' )
77
- end
78
- end
79
- end
80
- end
6
+ include_context 'error mapping'
81
7
 
82
8
  before :each do
83
9
  @errors = Hoodoo::Errors.new( Hoodoo::ErrorDescriptions.new )
84
10
  end
85
11
 
86
- let( :valid_model ) {
87
- RSpecModelErrorMappingTest.new( {
88
- :uuid => Hoodoo::UUID.generate(),
89
- :boolean => true,
90
- :date => Time.now,
91
- :datetime => Time.now,
92
- :decimal => 2.3,
93
- :float => 2.3,
94
- :integer => 42,
95
- :string => "hello",
96
- :text => "hello",
97
- :time => Time.now,
98
- :array => [ 'hello' ]
99
- } )
100
- }
101
-
102
12
  it 'auto-validates and maps errors correctly' do
103
-
104
13
  m = RSpecModelErrorMappingTest.new( :uuid => 'not a valid UUID' )
105
14
  expect( m.adds_errors_to?( @errors ) ).to eq( true )
106
15
 
@@ -170,6 +79,7 @@ describe Hoodoo::ActiveRecord::ErrorMapping do
170
79
  m = RSpecModelErrorMappingTestBase.new
171
80
 
172
81
  expect( m.adds_errors_to?( @errors ) ).to eq( true )
82
+
173
83
  expect( @errors.errors ).to eq( [
174
84
  {
175
85
  "code" => "generic.invalid_parameters",
@@ -273,44 +183,51 @@ describe Hoodoo::ActiveRecord::ErrorMapping do
273
183
  ] )
274
184
  end
275
185
 
276
- it 'handles downgrade to generic error code' do
277
-
186
+ context 'downgrade to generic error code' do
278
187
  class LocalHackableErrors < Hoodoo::ErrorDescriptions
279
188
  end
280
189
 
281
- @errors = Hoodoo::Errors.new( Hoodoo::ErrorDescriptions.new )
282
-
283
190
  # We have to hack to test this...
284
191
  #
285
- desc = @errors.descriptions.instance_variable_get( '@descriptions' )
286
- desc.delete( 'generic.invalid_boolean' )
287
- desc.delete( 'generic.invalid_date' )
288
-
289
- m = RSpecModelErrorMappingTest.new( {
290
- :datetime => Time.now,
291
- :decimal => 2.3,
292
- :float => 2.3,
293
- :integer => 42,
294
- :string => "hello",
295
- :text => "hello",
296
- :time => Time.now,
297
- :array => [ 'hello' ]
298
- } )
192
+ before :all do
193
+ @collection = Hoodoo::Errors.new( Hoodoo::ErrorDescriptions.new )
194
+ @desc = @collection.descriptions.instance_variable_get( '@descriptions' )
195
+ @val1 = @desc.delete( 'generic.invalid_boolean' )
196
+ @val2 = @desc.delete( 'generic.invalid_date' )
197
+ end
299
198
 
300
- m.adds_errors_to?( @errors )
199
+ after :all do
200
+ @desc[ 'generic.invalid_boolean' ] = @val1
201
+ @desc[ 'generic.invalid_date' ] = @val2
202
+ end
301
203
 
302
- expect( @errors.errors ).to eq( [
303
- {
304
- "code" => "generic.invalid_parameters",
305
- "message" => "can't be blank",
306
- "reference" => "boolean"
307
- },
308
- {
309
- "code" => "generic.invalid_parameters",
310
- "message" => "can't be blank",
311
- "reference" => "date"
312
- }
313
- ] )
204
+ it "is handled" do
205
+ m = RSpecModelErrorMappingTest.new( {
206
+ :datetime => Time.now,
207
+ :decimal => 2.3,
208
+ :float => 2.3,
209
+ :integer => 42,
210
+ :string => "hello",
211
+ :text => "hello",
212
+ :time => Time.now,
213
+ :array => [ 'hello' ]
214
+ } )
215
+
216
+ m.adds_errors_to?( @collection )
217
+
218
+ expect( @collection.errors ).to eq( [
219
+ {
220
+ "code" => "generic.invalid_parameters",
221
+ "message" => "can't be blank",
222
+ "reference" => "boolean"
223
+ },
224
+ {
225
+ "code" => "generic.invalid_parameters",
226
+ "message" => "can't be blank",
227
+ "reference" => "date"
228
+ }
229
+ ] )
230
+ end
314
231
  end
315
232
 
316
233
  it 'adds nothing if the model is valid' do
@@ -1,4 +1,5 @@
1
- require 'spec_helper.rb'
1
+ require 'spec_helper'
2
+ require 'active/active_record/error_mapping_shared_context'
2
3
 
3
4
  describe Hoodoo::ActiveRecord::Support do
4
5
  context '#framework_search_and_filter_data' do
@@ -312,4 +313,262 @@ describe Hoodoo::ActiveRecord::Support do
312
313
  end
313
314
  end
314
315
  end
316
+
317
+ context '#translate_errors_to' do
318
+ include_context 'error mapping'
319
+
320
+ it 'adds nothing if the model is valid' do
321
+ m = valid_model
322
+ expect( described_class.translate_errors_on( m ).errors ).to eq( [] )
323
+ expect { m.save! }.to_not raise_error
324
+ end
325
+
326
+ it 'maps column types correctly' do
327
+ m = RSpecModelErrorMappingTest.new( :uuid => 'not a valid UUID' )
328
+ m.validate()
329
+
330
+ expect( described_class.translate_errors_on( m ).errors ).to eq( [
331
+ {
332
+ "code" => "generic.invalid_boolean",
333
+ "message" => "can't be blank",
334
+ "reference" => "boolean"
335
+ },
336
+ {
337
+ "code" => "generic.invalid_date",
338
+ "message" => "can't be blank",
339
+ "reference" => "date"
340
+ },
341
+ {
342
+ "code" => "generic.invalid_datetime",
343
+ "message" => "can't be blank",
344
+ "reference" => "datetime"
345
+ },
346
+ {
347
+ "code" => "generic.invalid_decimal",
348
+ "message" => "can't be blank",
349
+ "reference" => "decimal"
350
+ },
351
+ {
352
+ "code" => "generic.invalid_float",
353
+ "message" => "can't be blank",
354
+ "reference" => "float"
355
+ },
356
+ {
357
+ "code" => "generic.invalid_integer",
358
+ "message" => "can't be blank",
359
+ "reference" => "integer"
360
+ },
361
+ {
362
+ "code" => "generic.invalid_string",
363
+ "message" => "can't be blank",
364
+ "reference" => "string"
365
+ },
366
+ {
367
+ "code" => "generic.invalid_string",
368
+ "message" => "can't be blank",
369
+ "reference" => "text"
370
+ },
371
+ {
372
+ "code" => "generic.invalid_time",
373
+ "message" => "can't be blank",
374
+ "reference" => "time"
375
+ },
376
+ {
377
+ "code" => "generic.invalid_array",
378
+ "message" => "can't be blank",
379
+ "reference" => "array"
380
+ },
381
+
382
+ # Checks that custom UUID validator is working.
383
+
384
+ {
385
+ "code" => "generic.invalid_uuid",
386
+ "message" => "is invalid",
387
+ "reference" => "uuid"
388
+ }
389
+ ] )
390
+ end
391
+
392
+ it 'maps "base" errors correctly' do
393
+ m = RSpecModelErrorMappingTestBase.new
394
+
395
+ m.validate()
396
+ expect( described_class.translate_errors_on( m ).errors ).to eq( [
397
+ {
398
+ "code" => "generic.invalid_parameters",
399
+ "message" => "this is a test",
400
+ "reference" => "model instance"
401
+ }
402
+ ] )
403
+ end
404
+
405
+ it 'adds to an existing collection' do
406
+ m = RSpecModelErrorMappingTestBase.new
407
+ collection = Hoodoo::Errors.new
408
+
409
+ collection.add_error( 'platform.timeout' )
410
+
411
+ m.validate()
412
+ expect( described_class.translate_errors_on( m, collection ).errors ).to eq( [
413
+ {
414
+ "code" => "platform.timeout",
415
+ "message" => "Request timeout"
416
+ },
417
+ {
418
+ "code" => "generic.invalid_parameters",
419
+ "message" => "this is a test",
420
+ "reference" => "model instance"
421
+ }
422
+ ] )
423
+ end
424
+
425
+ it 'handles varying validation types' do
426
+ m = RSpecModelErrorMappingTest.new( {
427
+ :boolean => true,
428
+ :date => Time.now,
429
+ :datetime => Time.now,
430
+ :decimal => 2.3,
431
+ :float => 2.3,
432
+ :integer => 42,
433
+ :string => "hello - this is far too long for the maximum field length",
434
+ :text => "hello",
435
+ :time => Time.now,
436
+ :array => [ 'hello' ]
437
+ } )
438
+
439
+ m.validate()
440
+ expect( described_class.translate_errors_on( m ).errors ).to eq( [
441
+ {
442
+ "code" => "generic.invalid_string",
443
+ "message" => "is too long (maximum is 16 characters)",
444
+ "reference" => "string"
445
+ }
446
+ ] )
447
+ end
448
+
449
+ it 'handles arrays' do
450
+ m = RSpecModelErrorMappingTest.new( {
451
+ :boolean => true,
452
+ :date => Time.now,
453
+ :datetime => Time.now,
454
+ :decimal => 2.3,
455
+ :float => 2.3,
456
+ :integer => 42,
457
+ :string => 'hello',
458
+ :text => 'world',
459
+ :time => Time.now,
460
+ :array => []
461
+ } )
462
+
463
+ array_col = RSpecModelErrorMappingTest.columns_hash[ 'array' ]
464
+ expect( array_col ).to receive( :array ).once.and_return( true )
465
+
466
+ m.validate()
467
+ expect( described_class.translate_errors_on( m ).errors ).to eq( [
468
+ {
469
+ "code" => "generic.invalid_array",
470
+ "message" => "can't be blank",
471
+ "reference" => "array"
472
+ }
473
+ ] )
474
+ end
475
+
476
+ it 'maps duplicates' do
477
+ m = valid_model
478
+
479
+ m.validate()
480
+ expect( described_class.translate_errors_on( m ).errors ).to eq( [] )
481
+ m.save!
482
+
483
+ n = m.dup
484
+ n.validate()
485
+ expect( described_class.translate_errors_on( n ).errors ).to eq( [
486
+ {
487
+ "code" => "generic.invalid_duplication",
488
+ "message" => "has already been taken",
489
+ "reference" => "integer"
490
+ }
491
+ ] )
492
+ end
493
+
494
+ context 'downgrade to generic error code' do
495
+ class LocalHackableErrors < Hoodoo::ErrorDescriptions
496
+ end
497
+
498
+ # We have to hack to test this...
499
+ #
500
+ before :all do
501
+ @collection = Hoodoo::Errors.new( Hoodoo::ErrorDescriptions.new )
502
+ @desc = @collection.descriptions.instance_variable_get( '@descriptions' )
503
+ @val1 = @desc.delete( 'generic.invalid_boolean' )
504
+ @val2 = @desc.delete( 'generic.invalid_date' )
505
+ end
506
+
507
+ after :all do
508
+ @desc[ 'generic.invalid_boolean' ] = @val1
509
+ @desc[ 'generic.invalid_date' ] = @val2
510
+ end
511
+
512
+ it "is handled" do
513
+ m = RSpecModelErrorMappingTest.new( {
514
+ :datetime => Time.now,
515
+ :decimal => 2.3,
516
+ :float => 2.3,
517
+ :integer => 42,
518
+ :string => "hello",
519
+ :text => "hello",
520
+ :time => Time.now,
521
+ :array => [ 'hello' ]
522
+ } )
523
+
524
+ m.validate()
525
+ expect( described_class.translate_errors_on( m, @collection ).errors ).to eq( [
526
+ {
527
+ "code" => "generic.invalid_parameters",
528
+ "message" => "can't be blank",
529
+ "reference" => "boolean"
530
+ },
531
+ {
532
+ "code" => "generic.invalid_parameters",
533
+ "message" => "can't be blank",
534
+ "reference" => "date"
535
+ }
536
+ ] )
537
+ end
538
+ end
539
+
540
+ it 'has-many associations are dereferenced' do
541
+ attrs = valid_model.attributes
542
+ attrs[ 'r_spec_model_associated_error_mapping_tests_attributes' ] = [
543
+ { :other_string => 'ok 1' },
544
+ { :other_string => 'ok 2' },
545
+ { :other_string => 'too long, so fails validation' }
546
+ ]
547
+
548
+ m = RSpecModelErrorMappingTest.new( attrs )
549
+
550
+ m.validate()
551
+ expect( described_class.translate_errors_on( m ).errors ).to eq( [
552
+ {
553
+ "code" => "generic.invalid_string",
554
+ "message" => "is too long (maximum is 6 characters)",
555
+ "reference" => "r_spec_model_associated_error_mapping_tests.other_string"
556
+ }
557
+ ] )
558
+ end
559
+
560
+ it 'works with dot-separated non-attribute paths' do
561
+ m = valid_model
562
+ m.string = 'magic'
563
+
564
+ m.validate()
565
+ expect( described_class.translate_errors_on( m ).errors ).to eq( [
566
+ {
567
+ "code" => "generic.invalid_parameters",
568
+ "message" => "is not a column",
569
+ "reference" => "this.thing"
570
+ }
571
+ ] )
572
+ end
573
+ end
315
574
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hoodoo
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.10.0
4
+ version: 2.11.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Loyalty New Zealand
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-12-04 00:00:00.000000000 Z
11
+ date: 2018-12-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rack
@@ -458,6 +458,7 @@ files:
458
458
  - spec/active/active_record/base_spec.rb
459
459
  - spec/active/active_record/creator_spec.rb
460
460
  - spec/active/active_record/dated_spec.rb
461
+ - spec/active/active_record/error_mapping_shared_context.rb
461
462
  - spec/active/active_record/error_mapping_spec.rb
462
463
  - spec/active/active_record/finder_spec.rb
463
464
  - spec/active/active_record/manually_dated_spec.rb
@@ -603,126 +604,127 @@ signing_key:
603
604
  specification_version: 4
604
605
  summary: Opinionated APIs
605
606
  test_files:
606
- - spec/active/active_record/base_spec.rb
607
- - spec/active/active_record/creator_spec.rb
608
- - spec/active/active_record/dated_spec.rb
609
- - spec/active/active_record/error_mapping_spec.rb
610
- - spec/active/active_record/finder_spec.rb
611
- - spec/active/active_record/manually_dated_spec.rb
612
- - spec/active/active_record/search_helper_spec.rb
613
- - spec/active/active_record/secure_spec.rb
614
- - spec/active/active_record/security_helper_spec.rb
615
- - spec/active/active_record/support_spec.rb
616
- - spec/active/active_record/translated_spec.rb
617
- - spec/active/active_record/uuid_spec.rb
618
- - spec/active/active_record/writer_spec.rb
619
- - spec/client/augmented_array_spec.rb
620
- - spec/client/augmented_base_spec.rb
621
- - spec/client/augmented_hash_spec.rb
622
- - spec/client/client_spec.rb
623
- - spec/client/endpoint/endpoint_spec.rb
624
- - spec/client/endpoint/endpoints/amqp_spec.rb
625
- - spec/client/endpoint/endpoints/auto_session_spec.rb
626
- - spec/client/endpoint/endpoints/http_based_spec.rb
627
- - spec/client/endpoint/endpoints/http_spec.rb
628
- - spec/client/endpoint/endpoints/not_found_spec.rb
629
- - spec/client/headers_spec.rb
630
- - spec/client/paginated_enumeration_spec.rb
631
- - spec/communicators/fast_spec.rb
632
- - spec/communicators/pool_spec.rb
633
- - spec/communicators/slow_spec.rb
634
- - spec/data/resources/caller_spec.rb
635
- - spec/data/resources/errors_spec.rb
636
- - spec/data/resources/log_spec.rb
637
- - spec/data/resources/session_spec.rb
638
- - spec/data/types/error_primitive_spec.rb
639
- - spec/data/types/permissions_defaults_spec.rb
640
- - spec/data/types/permissions_full_spec.rb
641
- - spec/data/types/permissions_resources_spec.rb
642
- - spec/data/types/permissions_spec.rb
643
- - spec/ddtrace.rb
607
+ - spec/shared_examples/middleware_amqp.rb
608
+ - spec/newrelic_rpm.rb
644
609
  - spec/errors/error_descriptions_spec.rb
645
610
  - spec/errors/errors_spec.rb
646
- - spec/files/regenerate.rb
647
- - spec/integration/service_actions_spec.rb
648
- - spec/logger/fast_writer_spec.rb
649
- - spec/logger/logger_spec.rb
650
- - spec/logger/slow_writer_spec.rb
651
- - spec/logger/writers/file_writer_spec.rb
652
- - spec/logger/writers/log_entries_dot_com_writer_spec.rb
653
- - spec/logger/writers/stream_writer_spec.rb
654
- - spec/monkey/monkey_spec.rb
655
- - spec/monkey/patch/datadog_traced_amqp_spec.rb
656
- - spec/monkey/patch/newrelic_middleware_analytics_spec.rb
657
- - spec/monkey/patch/newrelic_traced_amqp_spec.rb
658
- - spec/new_relic/agent/logger.rb
659
- - spec/new_relic/agent/method_tracer.rb
660
- - spec/new_relic/agent/transaction.rb
661
- - spec/newrelic_rpm.rb
662
- - spec/presenters/base_dsl_spec.rb
663
- - spec/presenters/base_spec.rb
664
- - spec/presenters/common_resource_fields_spec.rb
665
- - spec/presenters/embedding_spec.rb
666
- - spec/presenters/types/array_spec.rb
667
- - spec/presenters/types/boolean_spec.rb
668
- - spec/presenters/types/date_spec.rb
669
- - spec/presenters/types/date_time_spec.rb
670
- - spec/presenters/types/decimal_spec.rb
671
- - spec/presenters/types/enum_spec.rb
672
- - spec/presenters/types/field_spec.rb
673
- - spec/presenters/types/float_spec.rb
674
- - spec/presenters/types/hash_spec.rb
675
- - spec/presenters/types/integer_spec.rb
676
- - spec/presenters/types/object_spec.rb
677
- - spec/presenters/types/string_spec.rb
678
- - spec/presenters/types/tags_spec.rb
679
- - spec/presenters/types/text_spec.rb
680
- - spec/presenters/types/uuid_spec.rb
681
- - spec/presenters/walk_spec.rb
682
- - spec/services/discovery/discoverers/by_convention_spec.rb
683
- - spec/services/discovery/discoverers/by_drb/by_drb_spec.rb
684
- - spec/services/discovery/discoverers/by_drb/drb_server_spec.rb
685
- - spec/services/discovery/discoverers/by_flux_spec.rb
611
+ - spec/ddtrace.rb
612
+ - spec/services/services/interface_spec.rb
613
+ - spec/services/services/application_spec.rb
614
+ - spec/services/services/session_spec.rb
615
+ - spec/services/services/response_spec.rb
616
+ - spec/services/services/permissions_spec.rb
617
+ - spec/services/services/request_spec.rb
618
+ - spec/services/services/implementation_spec.rb
619
+ - spec/services/services/context_spec.rb
686
620
  - spec/services/discovery/discovery_spec.rb
687
- - spec/services/discovery/results/for_amqp_spec.rb
621
+ - spec/services/discovery/results/for_remote_spec.rb
688
622
  - spec/services/discovery/results/for_http_spec.rb
623
+ - spec/services/discovery/results/for_amqp_spec.rb
689
624
  - spec/services/discovery/results/for_local_spec.rb
690
- - spec/services/discovery/results/for_remote_spec.rb
691
- - spec/services/middleware/amqp_log_writer_spec.rb
692
- - spec/services/middleware/endpoints/inter_resource_local_spec.rb
625
+ - spec/services/discovery/discoverers/by_convention_spec.rb
626
+ - spec/services/discovery/discoverers/by_flux_spec.rb
627
+ - spec/services/discovery/discoverers/by_drb/by_drb_spec.rb
628
+ - spec/services/discovery/discoverers/by_drb/drb_server_spec.rb
693
629
  - spec/services/middleware/endpoints/inter_resource_remote_spec.rb
694
- - spec/services/middleware/exception_reporting/base_reporter_spec.rb
695
- - spec/services/middleware/exception_reporting/exception_reporting_spec.rb
696
- - spec/services/middleware/exception_reporting/reporters/airbrake_reporter_spec.rb
697
- - spec/services/middleware/exception_reporting/reporters/raygun_reporter_spec.rb
630
+ - spec/services/middleware/endpoints/inter_resource_local_spec.rb
698
631
  - spec/services/middleware/middleware_assumed_identity_spec.rb
699
- - spec/services/middleware/middleware_cors_spec.rb
700
632
  - spec/services/middleware/middleware_create_update_spec.rb
701
- - spec/services/middleware/middleware_dated_at_spec.rb
633
+ - spec/services/middleware/middleware_spec.rb
702
634
  - spec/services/middleware/middleware_exotic_communication_spec.rb
635
+ - spec/services/middleware/string_inquirer_spec.rb
636
+ - spec/services/middleware/middleware_public_spec.rb
703
637
  - spec/services/middleware/middleware_logging_spec.rb
638
+ - spec/services/middleware/middleware_dated_at_spec.rb
704
639
  - spec/services/middleware/middleware_multi_local_spec.rb
705
- - spec/services/middleware/middleware_multi_remote_spec.rb
640
+ - spec/services/middleware/amqp_log_writer_spec.rb
641
+ - spec/services/middleware/middleware_cors_spec.rb
706
642
  - spec/services/middleware/middleware_permissions_spec.rb
707
- - spec/services/middleware/middleware_public_spec.rb
708
- - spec/services/middleware/middleware_spec.rb
709
- - spec/services/middleware/string_inquirer_spec.rb
710
- - spec/services/services/application_spec.rb
711
- - spec/services/services/context_spec.rb
712
- - spec/services/services/implementation_spec.rb
713
- - spec/services/services/interface_spec.rb
714
- - spec/services/services/permissions_spec.rb
715
- - spec/services/services/request_spec.rb
716
- - spec/services/services/response_spec.rb
717
- - spec/services/services/session_spec.rb
718
- - spec/shared_examples/middleware_amqp.rb
719
- - spec/spec_helper.rb
720
- - spec/transient_store/transient_store/base_spec.rb
721
- - spec/transient_store/transient_store/memcached_redis_mirror_spec.rb
722
- - spec/transient_store/transient_store/memcached_spec.rb
643
+ - spec/services/middleware/exception_reporting/exception_reporting_spec.rb
644
+ - spec/services/middleware/exception_reporting/reporters/airbrake_reporter_spec.rb
645
+ - spec/services/middleware/exception_reporting/reporters/raygun_reporter_spec.rb
646
+ - spec/services/middleware/exception_reporting/base_reporter_spec.rb
647
+ - spec/services/middleware/middleware_multi_remote_spec.rb
648
+ - spec/files/regenerate.rb
649
+ - spec/integration/service_actions_spec.rb
650
+ - spec/new_relic/agent/transaction.rb
651
+ - spec/new_relic/agent/method_tracer.rb
652
+ - spec/new_relic/agent/logger.rb
653
+ - spec/communicators/pool_spec.rb
654
+ - spec/communicators/slow_spec.rb
655
+ - spec/communicators/fast_spec.rb
723
656
  - spec/transient_store/transient_store/mocks/dalli_client_spec.rb
724
657
  - spec/transient_store/transient_store/mocks/redis_spec.rb
658
+ - spec/transient_store/transient_store/memcached_redis_mirror_spec.rb
659
+ - spec/transient_store/transient_store/base_spec.rb
725
660
  - spec/transient_store/transient_store/redis_spec.rb
661
+ - spec/transient_store/transient_store/memcached_spec.rb
726
662
  - spec/transient_store/transient_store_spec.rb
727
- - spec/utilities/utilities_spec.rb
663
+ - spec/spec_helper.rb
728
664
  - spec/utilities/uuid_spec.rb
665
+ - spec/utilities/utilities_spec.rb
666
+ - spec/presenters/common_resource_fields_spec.rb
667
+ - spec/presenters/embedding_spec.rb
668
+ - spec/presenters/base_spec.rb
669
+ - spec/presenters/walk_spec.rb
670
+ - spec/presenters/types/float_spec.rb
671
+ - spec/presenters/types/text_spec.rb
672
+ - spec/presenters/types/date_spec.rb
673
+ - spec/presenters/types/uuid_spec.rb
674
+ - spec/presenters/types/object_spec.rb
675
+ - spec/presenters/types/hash_spec.rb
676
+ - spec/presenters/types/field_spec.rb
677
+ - spec/presenters/types/array_spec.rb
678
+ - spec/presenters/types/decimal_spec.rb
679
+ - spec/presenters/types/string_spec.rb
680
+ - spec/presenters/types/enum_spec.rb
681
+ - spec/presenters/types/boolean_spec.rb
682
+ - spec/presenters/types/date_time_spec.rb
683
+ - spec/presenters/types/integer_spec.rb
684
+ - spec/presenters/types/tags_spec.rb
685
+ - spec/presenters/base_dsl_spec.rb
686
+ - spec/monkey/patch/newrelic_traced_amqp_spec.rb
687
+ - spec/monkey/patch/datadog_traced_amqp_spec.rb
688
+ - spec/monkey/patch/newrelic_middleware_analytics_spec.rb
689
+ - spec/monkey/monkey_spec.rb
690
+ - spec/logger/slow_writer_spec.rb
691
+ - spec/logger/logger_spec.rb
692
+ - spec/logger/fast_writer_spec.rb
693
+ - spec/logger/writers/stream_writer_spec.rb
694
+ - spec/logger/writers/file_writer_spec.rb
695
+ - spec/logger/writers/log_entries_dot_com_writer_spec.rb
696
+ - spec/client/augmented_array_spec.rb
697
+ - spec/client/paginated_enumeration_spec.rb
698
+ - spec/client/endpoint/endpoints/http_spec.rb
699
+ - spec/client/endpoint/endpoints/http_based_spec.rb
700
+ - spec/client/endpoint/endpoints/amqp_spec.rb
701
+ - spec/client/endpoint/endpoints/not_found_spec.rb
702
+ - spec/client/endpoint/endpoints/auto_session_spec.rb
703
+ - spec/client/endpoint/endpoint_spec.rb
704
+ - spec/client/headers_spec.rb
705
+ - spec/client/augmented_hash_spec.rb
706
+ - spec/client/augmented_base_spec.rb
707
+ - spec/client/client_spec.rb
708
+ - spec/active/active_record/translated_spec.rb
709
+ - spec/active/active_record/secure_spec.rb
710
+ - spec/active/active_record/support_spec.rb
711
+ - spec/active/active_record/search_helper_spec.rb
712
+ - spec/active/active_record/uuid_spec.rb
713
+ - spec/active/active_record/security_helper_spec.rb
714
+ - spec/active/active_record/dated_spec.rb
715
+ - spec/active/active_record/base_spec.rb
716
+ - spec/active/active_record/manually_dated_spec.rb
717
+ - spec/active/active_record/error_mapping_shared_context.rb
718
+ - spec/active/active_record/writer_spec.rb
719
+ - spec/active/active_record/error_mapping_spec.rb
720
+ - spec/active/active_record/finder_spec.rb
721
+ - spec/active/active_record/creator_spec.rb
722
+ - spec/data/resources/log_spec.rb
723
+ - spec/data/resources/errors_spec.rb
724
+ - spec/data/resources/session_spec.rb
725
+ - spec/data/resources/caller_spec.rb
726
+ - spec/data/types/error_primitive_spec.rb
727
+ - spec/data/types/permissions_defaults_spec.rb
728
+ - spec/data/types/permissions_resources_spec.rb
729
+ - spec/data/types/permissions_full_spec.rb
730
+ - spec/data/types/permissions_spec.rb