hashie 3.4.3 → 5.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (73) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +516 -129
  3. data/CONTRIBUTING.md +24 -7
  4. data/LICENSE +1 -1
  5. data/README.md +408 -50
  6. data/Rakefile +18 -1
  7. data/UPGRADING.md +157 -7
  8. data/hashie.gemspec +14 -8
  9. data/lib/hashie/array.rb +21 -0
  10. data/lib/hashie/clash.rb +24 -12
  11. data/lib/hashie/dash.rb +56 -31
  12. data/lib/hashie/extensions/active_support/core_ext/hash.rb +14 -0
  13. data/lib/hashie/extensions/array/pretty_inspect.rb +19 -0
  14. data/lib/hashie/extensions/coercion.rb +30 -17
  15. data/lib/hashie/extensions/dash/indifferent_access.rb +30 -1
  16. data/lib/hashie/extensions/dash/predefined_values.rb +88 -0
  17. data/lib/hashie/extensions/dash/property_translation.rb +59 -28
  18. data/lib/hashie/extensions/deep_fetch.rb +5 -3
  19. data/lib/hashie/extensions/deep_find.rb +14 -5
  20. data/lib/hashie/extensions/deep_locate.rb +40 -21
  21. data/lib/hashie/extensions/deep_merge.rb +26 -10
  22. data/lib/hashie/extensions/ignore_undeclared.rb +6 -4
  23. data/lib/hashie/extensions/indifferent_access.rb +49 -8
  24. data/lib/hashie/extensions/key_conflict_warning.rb +55 -0
  25. data/lib/hashie/extensions/mash/define_accessors.rb +90 -0
  26. data/lib/hashie/extensions/mash/keep_original_keys.rb +53 -0
  27. data/lib/hashie/extensions/mash/permissive_respond_to.rb +61 -0
  28. data/lib/hashie/extensions/mash/safe_assignment.rb +3 -1
  29. data/lib/hashie/extensions/mash/symbolize_keys.rb +38 -0
  30. data/lib/hashie/extensions/method_access.rb +77 -19
  31. data/lib/hashie/extensions/parsers/yaml_erb_parser.rb +29 -5
  32. data/lib/hashie/extensions/ruby_version.rb +60 -0
  33. data/lib/hashie/extensions/ruby_version_check.rb +21 -0
  34. data/lib/hashie/extensions/strict_key_access.rb +16 -13
  35. data/lib/hashie/extensions/stringify_keys.rb +1 -1
  36. data/lib/hashie/extensions/symbolize_keys.rb +13 -2
  37. data/lib/hashie/hash.rb +18 -11
  38. data/lib/hashie/logger.rb +18 -0
  39. data/lib/hashie/mash.rb +177 -43
  40. data/lib/hashie/railtie.rb +21 -0
  41. data/lib/hashie/rash.rb +7 -7
  42. data/lib/hashie/utils.rb +44 -0
  43. data/lib/hashie/version.rb +1 -1
  44. data/lib/hashie.rb +33 -17
  45. metadata +28 -95
  46. data/spec/hashie/clash_spec.rb +0 -48
  47. data/spec/hashie/dash_spec.rb +0 -513
  48. data/spec/hashie/extensions/autoload_spec.rb +0 -24
  49. data/spec/hashie/extensions/coercion_spec.rb +0 -625
  50. data/spec/hashie/extensions/dash/coercion_spec.rb +0 -13
  51. data/spec/hashie/extensions/dash/indifferent_access_spec.rb +0 -84
  52. data/spec/hashie/extensions/deep_fetch_spec.rb +0 -97
  53. data/spec/hashie/extensions/deep_find_spec.rb +0 -45
  54. data/spec/hashie/extensions/deep_locate_spec.rb +0 -124
  55. data/spec/hashie/extensions/deep_merge_spec.rb +0 -65
  56. data/spec/hashie/extensions/ignore_undeclared_spec.rb +0 -46
  57. data/spec/hashie/extensions/indifferent_access_spec.rb +0 -219
  58. data/spec/hashie/extensions/indifferent_access_with_rails_hwia_spec.rb +0 -208
  59. data/spec/hashie/extensions/key_conversion_spec.rb +0 -12
  60. data/spec/hashie/extensions/mash/safe_assignment_spec.rb +0 -50
  61. data/spec/hashie/extensions/merge_initializer_spec.rb +0 -23
  62. data/spec/hashie/extensions/method_access_spec.rb +0 -184
  63. data/spec/hashie/extensions/strict_key_access_spec.rb +0 -110
  64. data/spec/hashie/extensions/stringify_keys_spec.rb +0 -124
  65. data/spec/hashie/extensions/symbolize_keys_spec.rb +0 -129
  66. data/spec/hashie/hash_spec.rb +0 -84
  67. data/spec/hashie/mash_spec.rb +0 -680
  68. data/spec/hashie/parsers/yaml_erb_parser_spec.rb +0 -29
  69. data/spec/hashie/rash_spec.rb +0 -77
  70. data/spec/hashie/trash_spec.rb +0 -268
  71. data/spec/hashie/version_spec.rb +0 -7
  72. data/spec/spec_helper.rb +0 -16
  73. data/spec/support/module_context.rb +0 -11
@@ -1,513 +0,0 @@
1
- require 'spec_helper'
2
-
3
- Hashie::Hash.class_eval do
4
- def self.inherited(klass)
5
- klass.instance_variable_set('@inheritance_test', true)
6
- end
7
- end
8
-
9
- class DashTest < Hashie::Dash
10
- property :first_name, required: true
11
- property :email
12
- property :count, default: 0
13
- end
14
-
15
- class DashNoRequiredTest < Hashie::Dash
16
- property :first_name
17
- property :email
18
- property :count, default: 0
19
- end
20
-
21
- class DashWithCoercion < Hashie::Dash
22
- include Hashie::Extensions::Coercion
23
- property :person
24
- property :city
25
-
26
- coerce_key :person, ::DashNoRequiredTest
27
- end
28
-
29
- class PropertyBangTest < Hashie::Dash
30
- property :important!
31
- end
32
-
33
- class SubclassedTest < DashTest
34
- property :last_name, required: true
35
- end
36
-
37
- class RequiredMessageTest < DashTest
38
- property :first_name, required: true, message: 'must be set.'
39
- end
40
-
41
- class DashDefaultTest < Hashie::Dash
42
- property :aliases, default: ['Snake']
43
- end
44
-
45
- class DeferredTest < Hashie::Dash
46
- property :created_at, default: proc { Time.now }
47
- end
48
-
49
- class DeferredWithSelfTest < Hashie::Dash
50
- property :created_at, default: -> { Time.now }
51
- property :updated_at, default: ->(test) { test.created_at }
52
- end
53
-
54
- describe DashTest do
55
- def property_required_error(property)
56
- [ArgumentError, "The property '#{property}' is required for #{subject.class.name}."]
57
- end
58
-
59
- def property_required_custom_error(property)
60
- [ArgumentError, "The property '#{property}' must be set."]
61
- end
62
-
63
- def property_message_without_required_error
64
- [ArgumentError, 'The :message option should be used with :required option.']
65
- end
66
-
67
- def no_property_error(property)
68
- [NoMethodError, "The property '#{property}' is not defined for #{subject.class.name}."]
69
- end
70
-
71
- subject { DashTest.new(first_name: 'Bob', email: 'bob@example.com') }
72
- let(:required_message) { RequiredMessageTest.new(first_name: 'Bob') }
73
-
74
- it('subclasses Hashie::Hash') { should respond_to(:to_mash) }
75
-
76
- describe '#to_s' do
77
- subject { super().to_s }
78
- it { should eq '#<DashTest count=0 email="bob@example.com" first_name="Bob">' }
79
- end
80
-
81
- it 'lists all set properties in inspect' do
82
- subject.first_name = 'Bob'
83
- subject.email = 'bob@example.com'
84
- expect(subject.inspect).to eq '#<DashTest count=0 email="bob@example.com" first_name="Bob">'
85
- end
86
-
87
- describe '#count' do
88
- subject { super().count }
89
- it { should be_zero }
90
- end
91
-
92
- it { should respond_to(:first_name) }
93
- it { should respond_to(:first_name=) }
94
- it { should_not respond_to(:nonexistent) }
95
-
96
- it 'errors out for a non-existent property' do
97
- expect { subject['nonexistent'] }.to raise_error(*no_property_error('nonexistent'))
98
- end
99
-
100
- it 'errors out when attempting to set a required property to nil' do
101
- expect { subject.first_name = nil }.to raise_error(*property_required_error('first_name'))
102
- end
103
-
104
- it 'errors out when message added to not required property' do
105
- expect do
106
- class DashMessageOptionWithoutRequiredTest < Hashie::Dash
107
- property :first_name, message: 'is required.'
108
- end
109
- end.to raise_error(*property_message_without_required_error)
110
-
111
- expect do
112
- class DashMessageOptionWithoutRequiredTest < Hashie::Dash
113
- property :first_name, required: false, message: 'is required.'
114
- end
115
- end.to raise_error(*property_message_without_required_error)
116
- end
117
-
118
- context 'writing to properties' do
119
- it 'fails writing a required property to nil' do
120
- expect { subject.first_name = nil }.to raise_error(*property_required_error('first_name'))
121
- expect { required_message.first_name = nil }.to raise_error(*property_required_custom_error('first_name'))
122
- end
123
-
124
- it 'fails writing a required property to nil using []=' do
125
- expect { subject[:first_name] = nil }.to raise_error(*property_required_error('first_name'))
126
- expect { required_message[:first_name] = nil }.to raise_error(*property_required_custom_error('first_name'))
127
- end
128
-
129
- it 'fails writing to a non-existent property using []=' do
130
- expect { subject['nonexistent'] = 123 }.to raise_error(*no_property_error('nonexistent'))
131
- end
132
-
133
- it 'works for an existing property using []=' do
134
- subject[:first_name] = 'Bob'
135
- expect(subject[:first_name]).to eq 'Bob'
136
- expect { subject['first_name'] }.to raise_error(*no_property_error('first_name'))
137
- end
138
-
139
- it 'works for an existing property using a method call' do
140
- subject.first_name = 'Franklin'
141
- expect(subject.first_name).to eq 'Franklin'
142
- end
143
- end
144
-
145
- context 'reading from properties' do
146
- it 'fails reading from a non-existent property using []' do
147
- expect { subject['nonexistent'] }.to raise_error(*no_property_error('nonexistent'))
148
- end
149
-
150
- it 'is able to retrieve properties through blocks' do
151
- subject[:first_name] = 'Aiden'
152
- value = nil
153
- subject.[](:first_name) { |v| value = v }
154
- expect(value).to eq 'Aiden'
155
- end
156
-
157
- it 'is able to retrieve properties through blocks with method calls' do
158
- subject[:first_name] = 'Frodo'
159
- value = nil
160
- subject.first_name { |v| value = v }
161
- expect(value).to eq 'Frodo'
162
- end
163
- end
164
-
165
- context 'reading from deferred properties' do
166
- it 'evaluates proc after initial read' do
167
- expect(DeferredTest.new[:created_at]).to be_instance_of(Time)
168
- end
169
-
170
- it 'does not evalute proc after subsequent reads' do
171
- deferred = DeferredTest.new
172
- expect(deferred[:created_at].object_id).to eq deferred[:created_at].object_id
173
- end
174
- end
175
-
176
- context 'reading from a deferred property based on context' do
177
- it 'provides the current hash as context for evaluation' do
178
- deferred = DeferredWithSelfTest.new
179
- expect(deferred[:created_at].object_id).to eq deferred[:created_at].object_id
180
- expect(deferred[:updated_at].object_id).to eq deferred[:created_at].object_id
181
- end
182
- end
183
-
184
- describe '#new' do
185
- it 'fails with non-existent properties' do
186
- expect { described_class.new(bork: '') }.to raise_error(*no_property_error('bork'))
187
- end
188
-
189
- it 'sets properties that it is able to' do
190
- obj = described_class.new first_name: 'Michael'
191
- expect(obj.first_name).to eq 'Michael'
192
- end
193
-
194
- it 'accepts nil' do
195
- expect { DashNoRequiredTest.new(nil) }.not_to raise_error
196
- end
197
-
198
- it 'accepts block to define a global default' do
199
- obj = described_class.new { |_, key| key.to_s.upcase }
200
- expect(obj.first_name).to eq 'FIRST_NAME'
201
- expect(obj.count).to be_zero
202
- end
203
-
204
- it 'fails when required values are missing' do
205
- expect { DashTest.new }.to raise_error(*property_required_error('first_name'))
206
- end
207
-
208
- it 'does not overwrite default values' do
209
- obj1 = DashDefaultTest.new
210
- obj1.aliases << 'El Rey'
211
- obj2 = DashDefaultTest.new
212
- expect(obj2.aliases).not_to include 'El Rey'
213
- end
214
- end
215
-
216
- describe '#merge' do
217
- it 'creates a new instance of the Dash' do
218
- new_dash = subject.merge(first_name: 'Robert')
219
- expect(subject.object_id).not_to eq new_dash.object_id
220
- end
221
-
222
- it 'merges the given hash' do
223
- new_dash = subject.merge(first_name: 'Robert', email: 'robert@example.com')
224
- expect(new_dash.first_name).to eq 'Robert'
225
- expect(new_dash.email).to eq 'robert@example.com'
226
- end
227
-
228
- it 'fails with non-existent properties' do
229
- expect { subject.merge(middle_name: 'James') }.to raise_error(*no_property_error('middle_name'))
230
- end
231
-
232
- it 'errors out when attempting to set a required property to nil' do
233
- expect { subject.merge(first_name: nil) }.to raise_error(*property_required_error('first_name'))
234
- end
235
-
236
- context 'given a block' do
237
- it "sets merged key's values to the block's return value" do
238
- expect(subject.merge(first_name: 'Jim') do |key, oldval, newval|
239
- "#{key}: #{newval} #{oldval}"
240
- end.first_name).to eq 'first_name: Jim Bob'
241
- end
242
- end
243
- end
244
-
245
- describe '#merge!' do
246
- it 'modifies the existing instance of the Dash' do
247
- original_dash = subject.merge!(first_name: 'Robert')
248
- expect(subject.object_id).to eq original_dash.object_id
249
- end
250
-
251
- it 'merges the given hash' do
252
- subject.merge!(first_name: 'Robert', email: 'robert@example.com')
253
- expect(subject.first_name).to eq 'Robert'
254
- expect(subject.email).to eq 'robert@example.com'
255
- end
256
-
257
- it 'fails with non-existent properties' do
258
- expect { subject.merge!(middle_name: 'James') }.to raise_error(NoMethodError)
259
- end
260
-
261
- it 'errors out when attempting to set a required property to nil' do
262
- expect { subject.merge!(first_name: nil) }.to raise_error(ArgumentError)
263
- end
264
-
265
- context 'given a block' do
266
- it "sets merged key's values to the block's return value" do
267
- expect(subject.merge!(first_name: 'Jim') do |key, oldval, newval|
268
- "#{key}: #{newval} #{oldval}"
269
- end.first_name).to eq 'first_name: Jim Bob'
270
- end
271
- end
272
- end
273
-
274
- describe 'properties' do
275
- it 'lists defined properties' do
276
- expect(described_class.properties).to eq Set.new([:first_name, :email, :count])
277
- end
278
-
279
- it 'checks if a property exists' do
280
- expect(described_class.property?(:first_name)).to be_truthy
281
- expect(described_class.property?('first_name')).to be_falsy
282
- end
283
-
284
- it 'checks if a property is required' do
285
- expect(described_class.required?(:first_name)).to be_truthy
286
- expect(described_class.required?('first_name')).to be_falsy
287
- end
288
-
289
- it 'doesnt include property from subclass' do
290
- expect(described_class.property?(:last_name)).to be_falsy
291
- end
292
-
293
- it 'lists declared defaults' do
294
- expect(described_class.defaults).to eq(count: 0)
295
- end
296
-
297
- it 'allows properties that end in bang' do
298
- expect(PropertyBangTest.property?(:important!)).to be_truthy
299
- end
300
- end
301
-
302
- describe '#replace' do
303
- before { subject.replace(first_name: 'Cain') }
304
-
305
- it 'return self' do
306
- expect(subject.replace(email: 'bar').to_hash).to eq(email: 'bar', count: 0)
307
- end
308
-
309
- it 'sets all specified keys to their corresponding values' do
310
- expect(subject.first_name).to eq 'Cain'
311
- end
312
-
313
- it 'leaves only specified keys and keys with default values' do
314
- expect(subject.keys.sort_by(&:to_s)).to eq [:count, :first_name]
315
- expect(subject.email).to be_nil
316
- expect(subject.count).to eq 0
317
- end
318
-
319
- context 'when replacing keys with default values' do
320
- before { subject.replace(count: 3) }
321
-
322
- it 'sets all specified keys to their corresponding values' do
323
- expect(subject.count).to eq 3
324
- end
325
- end
326
- end
327
-
328
- describe '#update_attributes!(params)' do
329
- let(:params) { { first_name: 'Alice', email: 'alice@example.com' } }
330
-
331
- context 'when there is coercion' do
332
- let(:params_before) { { city: 'nyc', person: { first_name: 'Bob', email: 'bob@example.com' } } }
333
- let(:params_after) { { city: 'sfo', person: { first_name: 'Alice', email: 'alice@example.com' } } }
334
-
335
- subject { DashWithCoercion.new(params_before) }
336
-
337
- it 'update the attributes' do
338
- expect(subject.person.first_name).to eq params_before[:person][:first_name]
339
- subject.update_attributes!(params_after)
340
- expect(subject.person.first_name).to eq params_after[:person][:first_name]
341
- end
342
- end
343
-
344
- it 'update the attributes' do
345
- subject.update_attributes!(params)
346
- expect(subject.first_name).to eq params[:first_name]
347
- expect(subject.email).to eq params[:email]
348
- expect(subject.count).to eq subject.class.defaults[:count]
349
- end
350
-
351
- context 'when required property is update to nil' do
352
- let(:params) { { first_name: nil, email: 'alice@example.com' } }
353
-
354
- it 'raise an ArgumentError' do
355
- expect { subject.update_attributes!(params) }.to raise_error(ArgumentError)
356
- end
357
- end
358
-
359
- context 'when a default property is update to nil' do
360
- let(:params) { { count: nil, email: 'alice@example.com' } }
361
-
362
- it 'set the property back to the default value' do
363
- subject.update_attributes!(params)
364
- expect(subject.email).to eq params[:email]
365
- expect(subject.count).to eq subject.class.defaults[:count]
366
- end
367
- end
368
- end
369
- end
370
-
371
- describe Hashie::Dash, 'inheritance' do
372
- before do
373
- @top = Class.new(Hashie::Dash)
374
- @middle = Class.new(@top)
375
- @bottom = Class.new(@middle)
376
- end
377
-
378
- it 'reports empty properties when nothing defined' do
379
- expect(@top.properties).to be_empty
380
- expect(@top.defaults).to be_empty
381
- end
382
-
383
- it 'inherits properties downwards' do
384
- @top.property :echo
385
- expect(@middle.properties).to include(:echo)
386
- expect(@bottom.properties).to include(:echo)
387
- end
388
-
389
- it 'doesnt inherit properties upwards' do
390
- @middle.property :echo
391
- expect(@top.properties).not_to include(:echo)
392
- expect(@bottom.properties).to include(:echo)
393
- end
394
-
395
- it 'allows overriding a default on an existing property' do
396
- @top.property :echo
397
- @middle.property :echo, default: 123
398
- expect(@bottom.properties.to_a).to eq [:echo]
399
- expect(@bottom.new.echo).to eq 123
400
- end
401
-
402
- it 'allows clearing an existing default' do
403
- @top.property :echo
404
- @middle.property :echo, default: 123
405
- @bottom.property :echo
406
- expect(@bottom.properties.to_a).to eq [:echo]
407
- expect(@bottom.new.echo).to be_nil
408
- end
409
-
410
- it 'allows nil defaults' do
411
- @bottom.property :echo, default: nil
412
- expect(@bottom.new).to have_key(:echo)
413
- expect(@bottom.new).to_not have_key('echo')
414
- end
415
- end
416
-
417
- describe SubclassedTest do
418
- subject { SubclassedTest.new(first_name: 'Bob', last_name: 'McNob', email: 'bob@example.com') }
419
-
420
- describe '#count' do
421
- subject { super().count }
422
- it { should be_zero }
423
- end
424
-
425
- it { should respond_to(:first_name) }
426
- it { should respond_to(:first_name=) }
427
- it { should respond_to(:last_name) }
428
- it { should respond_to(:last_name=) }
429
-
430
- it 'has one additional property' do
431
- expect(described_class.property?(:last_name)).to be_truthy
432
- end
433
-
434
- it "didn't override superclass inheritance logic" do
435
- expect(described_class.instance_variable_get('@inheritance_test')).to be_truthy
436
- end
437
- end
438
-
439
- class ConditionallyRequiredTest < Hashie::Dash
440
- property :username
441
- property :password, required: -> { !username.nil? }, message: 'must be set, too.'
442
- end
443
-
444
- describe ConditionallyRequiredTest do
445
- it 'does not allow a conditionally required property to be set to nil if required' do
446
- expect { ConditionallyRequiredTest.new(username: 'bob.smith', password: nil) }.to raise_error(ArgumentError, "The property 'password' must be set, too.")
447
- end
448
-
449
- it 'allows a conditionally required property to be set to nil if not required' do
450
- expect { ConditionallyRequiredTest.new(username: nil, password: nil) }.not_to raise_error
451
- end
452
-
453
- it 'allows a conditionally required property to be set if required' do
454
- expect { ConditionallyRequiredTest.new(username: 'bob.smith', password: '$ecure!') }.not_to raise_error
455
- end
456
- end
457
-
458
- class MixedPropertiesTest < Hashie::Dash
459
- property :symbol
460
- property 'string'
461
- end
462
-
463
- describe MixedPropertiesTest do
464
- subject { MixedPropertiesTest.new('string' => 'string', symbol: 'symbol') }
465
-
466
- it { should respond_to('string') }
467
- it { should respond_to(:symbol) }
468
-
469
- it 'property?' do
470
- expect(described_class.property?('string')).to be_truthy
471
- expect(described_class.property?(:symbol)).to be_truthy
472
- end
473
-
474
- it 'fetch' do
475
- expect(subject['string']).to eq('string')
476
- expect { subject[:string] }.to raise_error(NoMethodError)
477
- expect(subject[:symbol]).to eq('symbol')
478
- expect { subject['symbol'] }.to raise_error(NoMethodError)
479
- end
480
-
481
- it 'double define' do
482
- klass = Class.new(MixedPropertiesTest) do
483
- property 'symbol'
484
- end
485
- instance = klass.new(symbol: 'one', 'symbol' => 'two')
486
- expect(instance[:symbol]).to eq('one')
487
- expect(instance['symbol']).to eq('two')
488
- end
489
-
490
- it 'assign' do
491
- subject['string'] = 'updated'
492
- expect(subject['string']).to eq('updated')
493
-
494
- expect { subject[:string] = 'updated' }.to raise_error(NoMethodError)
495
-
496
- subject[:symbol] = 'updated'
497
- expect(subject[:symbol]).to eq('updated')
498
-
499
- expect { subject['symbol'] = 'updated' }.to raise_error(NoMethodError)
500
- end
501
- end
502
-
503
- context 'Dynamic Dash Class' do
504
- it 'define property' do
505
- klass = Class.new(Hashie::Dash)
506
- my_property = 'my_property'
507
- my_orig = my_property.dup
508
-
509
- klass.property(my_property)
510
-
511
- expect(my_property).to eq(my_orig)
512
- end
513
- end
@@ -1,24 +0,0 @@
1
- require 'spec_helper'
2
- require 'hashie'
3
-
4
- describe Hashie::Extensions do
5
- describe 'autloads constants' do
6
- it { is_expected.to be_const_defined(:MethodAccess) }
7
- it { is_expected.to be_const_defined(:Coercion) }
8
- it { is_expected.to be_const_defined(:DeepMerge) }
9
- it { is_expected.to be_const_defined(:IgnoreUndeclared) }
10
- it { is_expected.to be_const_defined(:IndifferentAccess) }
11
- it { is_expected.to be_const_defined(:MergeInitializer) }
12
- it { is_expected.to be_const_defined(:MethodAccess) }
13
- it { is_expected.to be_const_defined(:MethodQuery) }
14
- it { is_expected.to be_const_defined(:MethodReader) }
15
- it { is_expected.to be_const_defined(:MethodWriter) }
16
- it { is_expected.to be_const_defined(:StringifyKeys) }
17
- it { is_expected.to be_const_defined(:SymbolizeKeys) }
18
- it { is_expected.to be_const_defined(:DeepFetch) }
19
- it { is_expected.to be_const_defined(:DeepFind) }
20
- it { is_expected.to be_const_defined(:PrettyInspect) }
21
- it { is_expected.to be_const_defined(:KeyConversion) }
22
- it { is_expected.to be_const_defined(:MethodAccessWithOverride) }
23
- end
24
- end