right_support 2.11.3 → 2.12.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +4 -0
  3. data/VERSION +1 -1
  4. data/lib/right_support/notifiers/airbrake.rb +194 -0
  5. data/lib/right_support/notifiers/base.rb +73 -0
  6. data/lib/right_support/notifiers/blacklisters/base.rb +48 -0
  7. data/lib/right_support/notifiers/blacklisters/canonical.rb +60 -0
  8. data/lib/right_support/notifiers/blacklisters/regular_expression.rb +86 -0
  9. data/{features/support/file_utils_bundler_mixin.rb → lib/right_support/notifiers/blacklisters/simple.rb} +21 -20
  10. data/lib/right_support/notifiers/blacklisters/snake_case.rb +60 -0
  11. data/lib/right_support/notifiers/blacklisters/wildcard.rb +65 -0
  12. data/lib/right_support/notifiers/blacklisters.rb +34 -0
  13. data/lib/right_support/notifiers/logger.rb +94 -0
  14. data/lib/right_support/notifiers/notification.rb +57 -0
  15. data/lib/right_support/notifiers/utilities/backtrace_decoder.rb +234 -0
  16. data/lib/right_support/notifiers/utilities.rb +29 -0
  17. data/lib/right_support/notifiers.rb +32 -0
  18. data/lib/right_support/rack/request_logger.rb +13 -9
  19. data/lib/right_support.rb +1 -0
  20. data/right_support.gemspec +19 -70
  21. metadata +17 -69
  22. data/.coveralls.yml +0 -2
  23. data/.rspec +0 -3
  24. data/.simplecov +0 -6
  25. data/.travis.yml +0 -13
  26. data/Gemfile +0 -51
  27. data/Gemfile.lock +0 -153
  28. data/features/balancer_error_handling.feature +0 -34
  29. data/features/balancer_health_check.feature +0 -33
  30. data/features/hash_tools.feature +0 -27
  31. data/features/http_client_timeout.feature +0 -19
  32. data/features/serialization.feature +0 -113
  33. data/features/step_definitions/hash_tools_steps.rb +0 -41
  34. data/features/step_definitions/http_client_steps.rb +0 -27
  35. data/features/step_definitions/request_balancer_steps.rb +0 -93
  36. data/features/step_definitions/ruby_steps.rb +0 -176
  37. data/features/step_definitions/serialization_steps.rb +0 -133
  38. data/features/step_definitions/server_steps.rb +0 -134
  39. data/features/support/env.rb +0 -148
  40. data/right_support.rconf +0 -9
  41. data/spec/config/feature_set_spec.rb +0 -83
  42. data/spec/crypto/signed_hash_spec.rb +0 -73
  43. data/spec/data/hash_tools_spec.rb +0 -602
  44. data/spec/data/mash_spec.rb +0 -313
  45. data/spec/data/token_spec.rb +0 -21
  46. data/spec/data/uuid_spec.rb +0 -45
  47. data/spec/db/cassandra_model_part1_spec.rb +0 -84
  48. data/spec/db/cassandra_model_part2_spec.rb +0 -73
  49. data/spec/db/cassandra_model_spec.rb +0 -375
  50. data/spec/fixtures/encrypted_priv_rsa.pem +0 -30
  51. data/spec/fixtures/good_priv_dsa.pem +0 -12
  52. data/spec/fixtures/good_priv_rsa.pem +0 -15
  53. data/spec/fixtures/good_pub_dsa.ssh +0 -1
  54. data/spec/fixtures/good_pub_rsa.pem +0 -5
  55. data/spec/fixtures/good_pub_rsa.ssh +0 -1
  56. data/spec/log/exception_logger_spec.rb +0 -76
  57. data/spec/log/filter_logger_spec.rb +0 -66
  58. data/spec/log/mixin_spec.rb +0 -141
  59. data/spec/log/multiplexer_spec.rb +0 -54
  60. data/spec/log/null_logger_spec.rb +0 -36
  61. data/spec/log/step_level_logger_spec.rb +0 -49
  62. data/spec/log/system_logger_spec.rb +0 -172
  63. data/spec/net/address_helper_spec.rb +0 -57
  64. data/spec/net/dns_spec.rb +0 -187
  65. data/spec/net/http_client_spec.rb +0 -181
  66. data/spec/net/lb/health_check_spec.rb +0 -417
  67. data/spec/net/lb/round_robin_spec.rb +0 -15
  68. data/spec/net/lb/sticky_spec.rb +0 -92
  69. data/spec/net/request_balancer_spec.rb +0 -690
  70. data/spec/net/s3_helper_spec.rb +0 -160
  71. data/spec/net/ssl_spec.rb +0 -42
  72. data/spec/net/string_encoder_spec.rb +0 -58
  73. data/spec/rack/log_setter_spec.rb +0 -5
  74. data/spec/rack/request_logger_spec.rb +0 -225
  75. data/spec/rack/request_tracker_spec.rb +0 -115
  76. data/spec/rack/runtime_spec.rb +0 -49
  77. data/spec/ruby/easy_singleton_spec.rb +0 -72
  78. data/spec/ruby/object_extensions_spec.rb +0 -27
  79. data/spec/ruby/string_extensions_spec.rb +0 -98
  80. data/spec/spec_helper.rb +0 -188
  81. data/spec/stats/activity_spec.rb +0 -425
  82. data/spec/stats/exceptions_spec.rb +0 -247
  83. data/spec/stats/helpers_spec.rb +0 -685
  84. data/spec/validation/openssl_spec.rb +0 -37
  85. data/spec/validation/ssh_spec.rb +0 -39
@@ -1,602 +0,0 @@
1
- require 'spec_helper'
2
-
3
- module RightSupport::Data::HashToolsSpec
4
-
5
- class BetterHash < Hash
6
- def bells_and_whistles; true; end
7
- end
8
-
9
- class HashLike
10
- def initialize; @inner_hash = {}; end
11
- def has_key?(key); @inner_hash.has_key?(key); end
12
- def [](key); @inner_hash[key]; end
13
- def []=(key, value); @inner_hash[key] = value; end
14
- def delete(key); @inner_hash.delete(key); end
15
- def merge!(other); @inner_hash.merge!(other); self; end
16
- def ==(other); @inner_hash == other; end
17
- end
18
-
19
- class DuplicableValue
20
- def initialize(value); @value = value; end
21
- attr_accessor :value
22
- def duplicable?; true; end
23
- def ==(other); other.kind_of?(DuplicableValue) && value == other.value; end
24
- end
25
-
26
- end
27
-
28
- describe RightSupport::Data::HashTools do
29
- subject { RightSupport::Data::HashTools }
30
-
31
- context '#hashable?' do
32
- it 'should be true for hashes' do
33
- subject.hashable?({}).should be_true
34
- end
35
-
36
- it 'should be true for hash-based objects' do
37
- subject.hashable?(::RightSupport::Data::HashToolsSpec::BetterHash.new).should be_true
38
- end
39
-
40
- it 'should be true for hash-like objects' do
41
- subject.hashable?(::RightSupport::Data::HashToolsSpec::HashLike.new).should be_true
42
- end
43
-
44
- it 'should be false for unhashable objects' do
45
- subject.hashable?([1, 2, 3]).should be_false
46
- subject.hashable?("hi there").should be_false
47
- end
48
- end
49
-
50
- context '#hash_like?' do
51
- it 'should be true for Hash' do
52
- subject.hash_like?(::Hash).should be_true
53
- end
54
-
55
- it 'should be true for hash-based classes' do
56
- subject.hash_like?(::RightSupport::Data::HashToolsSpec::BetterHash).should be_true
57
- end
58
-
59
- it 'should be true for hash-like classes' do
60
- subject.hash_like?(::RightSupport::Data::HashToolsSpec::HashLike).should be_true
61
- end
62
-
63
- it 'should be false for non-hash classes' do
64
- subject.hash_like?(Array).should be_false
65
- subject.hash_like?(String).should be_false
66
- end
67
- end
68
-
69
- context '#deep_get' do
70
- hash = { 'tree' => { 'branch' => { 'leaf' => 42, 'other' => 41 },
71
- 'other' => { 'leaf' => 43 } } }
72
- {
73
- :valid_leaf => {
74
- :path => ['tree', 'branch', 'leaf'],
75
- :expected => 42 },
76
- :valid_other_leaf => {
77
- :path => ['tree', 'branch', 'other'],
78
- :expected => 41 },
79
- :valid_branch => {
80
- :path => ['tree', 'branch'],
81
- :expected => { 'leaf' => 42, 'other' => 41 } },
82
- :valid_other_branch => {
83
- :path => ['tree', 'other'],
84
- :expected => { 'leaf' => 43 } },
85
- :invalid_leaf => {
86
- :path => ['tree', 'branch', 'leaf', 'bogus'],
87
- :expected => nil },
88
- :invalid_branch => {
89
- :path => ['tree', 'bogus'],
90
- :expected => nil },
91
- :nil => {
92
- :path => nil,
93
- :expected => nil },
94
- :empty => {
95
- :path => [],
96
- :expected => nil }
97
- }.each do |kind, data|
98
- it "should deep get #{kind} paths" do
99
- actual = subject.deep_get(hash, data[:path])
100
- actual.should == data[:expected]
101
- end
102
- end
103
- end
104
-
105
- context '#deep_set!' do
106
- {
107
- :empty => {
108
- :target => {},
109
- :path => ['tree', 'branch', 'leaf'],
110
- :value => 42,
111
- :expected => { 'tree' => { 'branch' => { 'leaf' => 42 } } } },
112
- :identical_structure => {
113
- :target => { 'tree' => { 'branch' => { 'leaf' => 42 } } },
114
- :path => ['tree', 'branch', 'leaf'],
115
- :value => 41,
116
- :expected => { 'tree' => { 'branch' => { 'leaf' => 41 } } } },
117
- :similar_structure => {
118
- :target => { 'tree' => { 'branch' => { 'other' => 41 } } },
119
- :path => ['tree', 'branch', 'leaf'],
120
- :value => 42,
121
- :expected => { 'tree' => { 'branch' => { 'leaf' => 42, 'other' => 41 } } } },
122
- :different_hash_subclass => {
123
- :target => {},
124
- :path => ['tree', 'branch', 'leaf'],
125
- :value => 42,
126
- :clazz => ::RightSupport::Data::HashToolsSpec::BetterHash,
127
- :expected => { 'tree' => { 'branch' => { 'leaf' => 42 } } } },
128
- :different_hash_like_class => {
129
- :target => {},
130
- :path => ['tree', 'branch', 'leaf'],
131
- :value => 42,
132
- :clazz => ::RightSupport::Data::HashToolsSpec::HashLike,
133
- :expected => { 'tree' => { 'branch' => { 'leaf' => 42 } } } }
134
- }.each do |kind, data|
135
- it "should deep set values in #{kind} hashes" do
136
- subject.deep_set!(data[:target], data[:path], data[:value], data[:clazz])
137
- data[:target].should == data[:expected]
138
- expected_class = data[:clazz] || data[:target].class
139
- data[:target].values.first.class.should == expected_class
140
- end
141
- end
142
- end
143
-
144
- context '#deep_clone' do
145
- def deep_check_object_id(a, b, &leaf_callback)
146
- a.object_id.should_not == b.object_id
147
- a.each do |k, v|
148
- if subject.hashable?(v)
149
- deep_check_object_id(v, b[k])
150
- elsif leaf_callback
151
- leaf_callback.call(v, b[k])
152
- elsif v.respond_to?(:duplicable?) && v.duplicable?
153
- v.object_id.should_not == b[k].object_id
154
- else
155
- v.object_id.should == b[k].object_id
156
- end
157
- end
158
- end
159
-
160
- {
161
- :empty => {},
162
- :shallow => { :x => 1, :y => 2 },
163
- :deep => { :x => 1, :y => { :a => 'A' }, :z => { :b => 'B', :c => { :foo => :bar }} },
164
- :duplicable => {
165
- :tree => {
166
- :branch => {
167
- :a => ::RightSupport::Data::HashToolsSpec::DuplicableValue.new(1),
168
- :b => ::RightSupport::Data::HashToolsSpec::DuplicableValue.new('hi there') } } }
169
- }.each do |kind, data|
170
- it "should deep clone values in #{kind} hashes" do
171
- actual = subject.deep_clone(data)
172
- actual.should == data
173
- if :duplicable == kind
174
- # verify that leaves are duplicable
175
- data[:tree][:branch][:a].duplicable?.should be_true
176
- data[:tree][:branch][:b].duplicable?.should be_true
177
- end
178
- deep_check_object_id(data, actual)
179
- end
180
- end
181
-
182
- it 'should deep clone leaves using callback when given' do
183
- initial = { :x => 'a', :y => { :a => ['b', 'c'], :b => ['d', ['e', 'f']] } }
184
- actual = subject.deep_clone(initial) { |value| value.clone }
185
- actual.should == initial
186
- deep_check_object_id(actual, initial) do |a, b|
187
- a.object_id.should_not == b.object_id
188
- end
189
- end
190
- end
191
-
192
- # also tests deep_clone2
193
- context '#deep_mash' do
194
- def deep_check_object_id(a, b, &leaf_callback)
195
- a.object_id.should_not == b.object_id
196
- if subject.hashable?(a)
197
- b.class.should == RightSupport::Data::Mash
198
- a.each do |k, v|
199
- other = b[k]
200
- if subject.hashable?(v)
201
- deep_check_object_id(v, other)
202
- elsif v.kind_of?(::Array)
203
- v.object_id.should_not == other.object_id
204
- other.class.should == ::Array
205
- v.size.should == other.size
206
- v.each_with_index do |e, idx|
207
- deep_check_object_id(e, other[idx])
208
- end
209
- elsif leaf_callback
210
- leaf_callback.call(v, other)
211
- elsif v.respond_to?(:duplicable?) && v.duplicable?
212
- v.object_id.should_not == other.object_id
213
- else
214
- v.object_id.should == other.object_id
215
- end
216
- end
217
- end
218
- end
219
-
220
- {
221
- :empty => {},
222
- :shallow => { :x => 1, :y => 2 },
223
- :deep => {
224
- :x => 1,
225
- :y => { :a => 'A' },
226
- :z => { :b => 'B',
227
- :c => { :foo => :bar } } },
228
- :arrayed => [
229
- { :x => 1 },
230
- { :y => { :a => 'A' } },
231
- { :z => { :b => 'B',
232
- :c => { :foo => :bar } } }
233
- ],
234
- :duplicable => {
235
- :tree => {
236
- :branch => {
237
- :a => ::RightSupport::Data::HashToolsSpec::DuplicableValue.new(1),
238
- :b => ::RightSupport::Data::HashToolsSpec::DuplicableValue.new('hi there') } } }
239
- }.each do |kind, data|
240
- it "should deep mash values in #{kind} hashes" do
241
- actual = subject.deep_mash(data)
242
- if :duplicable == kind
243
- # verify that leaves are duplicable
244
- data[:tree][:branch][:a].duplicable?.should be_true
245
- data[:tree][:branch][:b].duplicable?.should be_true
246
- end
247
- deep_check_object_id(data, actual)
248
- end
249
- end
250
-
251
- it 'should deep clone leaves using callback when given' do
252
- initial = { :x => 'a', :y => { :a => ['b', 'c'], :b => ['d', ['e', 'f']] } }
253
- actual = subject.deep_mash(initial) { |value| value.clone }
254
- deep_check_object_id(initial, actual) do |a, b|
255
- a.object_id.should_not == b.object_id
256
- end
257
- end
258
- end
259
-
260
- context '#deep_freeze!' do
261
- it "should deep freeze hashes and arrays" do
262
- original = {
263
- 'a' => ' s ',
264
- 'b' => {
265
- 'h' => ' s2 ',
266
- 'a' => [ 1, { :nested => ' s3 ' } ]
267
- }
268
- }
269
- original.each do |k, v|
270
- # note that Hash freezes keys upon insertion out of necessity to avoid
271
- # spontaneous rehashing.
272
- k.should be_frozen
273
- v.should_not be_frozen
274
- end
275
- original['b']['a'][1][:nested].should_not be_frozen
276
- subject.deep_freeze!(original)
277
- original.each do |k, v|
278
- k.should be_frozen
279
- v.should be_frozen
280
- end
281
- original['b']['a'][1][:nested].should be_frozen
282
- end
283
- end
284
-
285
- context '#deep_merge' do
286
- {
287
- :identical => {
288
- :left => { :one => 1 },
289
- :right => { :one => 1 },
290
- :expected => { :one => 1 } },
291
- :disjoint => {
292
- :left => { :one => 1 },
293
- :right => { :two => 1 },
294
- :expected => { :one => 1, :two => 1 } },
295
- :value_diff => {
296
- :left => { :one => 1 },
297
- :right => { :one => 2 },
298
- :expected => { :one => 2 } },
299
- :recursive_disjoint => {
300
- :left => { :one => { :a => 1, :b => 2 }, :two => 3 },
301
- :right => { :one => { :a => 1 }, :two => 3 },
302
- :expected => { :one => { :a => 1, :b => 2 }, :two => 3 } },
303
- :recursive_value_diff => {
304
- :left => { :one => { :a => 1, :b => 2 }, :two => 3 },
305
- :right => { :one => { :a => 1, :b => 3 }, :two => 3 },
306
- :expected => { :one => { :a => 1, :b => 3 }, :two => 3 } },
307
- :recursive_disjoint_and_value_diff => {
308
- :left => { :one => { :a => 1, :b => 2, :c => 3 }, :two => 3, :three => 4 },
309
- :right => { :one => { :a => 1, :b => 3, :d => 4 }, :two => 5, :four => 6 },
310
- :expected => { :one => { :a => 1, :b => 3, :c => 3 , :d => 4 }, :two => 5, :three => 4, :four => 6 } }
311
- }.each do |kind, data|
312
- it "should deep merge #{kind} hashes" do
313
- left_same_as_expected = data[:left] == data[:expected]
314
- actual = subject.deep_merge(data[:left], data[:right])
315
- actual.should == data[:expected]
316
-
317
- # original should be unmodified.
318
- actual.object_id.should_not == data[:left].object_id
319
- unless left_same_as_expected
320
- data[:left].should_not == data[:expected]
321
- end
322
- end
323
- end
324
- end
325
-
326
- context '#deep_merge!' do
327
- {
328
- :identical => {
329
- :left => { :one => 1 },
330
- :right => { :one => 1 },
331
- :expected => { :one => 1 } },
332
- :disjoint => {
333
- :left => { :one => 1 },
334
- :right => { :two => 1 },
335
- :expected => { :one => 1, :two => 1 } },
336
- :value_diff => {
337
- :left => { :one => 1 },
338
- :right => { :one => 2 },
339
- :expected => { :one => 2 } },
340
- :recursive_disjoint => {
341
- :left => { :one => { :a => 1, :b => 2 }, :two => 3 },
342
- :right => { :one => { :a => 1 }, :two => 3 },
343
- :expected => { :one => { :a => 1, :b => 2 }, :two => 3 } },
344
- :recursive_value_diff => {
345
- :left => { :one => { :a => 1, :b => 2 }, :two => 3 },
346
- :right => { :one => { :a => 1, :b => 3 }, :two => 3 },
347
- :expected => { :one => { :a => 1, :b => 3 }, :two => 3 } },
348
- :recursive_disjoint_and_value_diff => {
349
- :left => { :one => { :a => 1, :b => 2, :c => 3 }, :two => 3, :three => 4 },
350
- :right => { :one => { :a => 1, :b => 3, :d => 4 }, :two => 5, :four => 6 },
351
- :expected => { :one => { :a => 1, :b => 3, :c => 3 , :d => 4 }, :two => 5, :three => 4, :four => 6 } }
352
- }.each do |kind, data|
353
- it "should deep merge #{kind} hashes" do
354
- actual = subject.deep_merge!(data[:left], data[:right])
355
- actual.should == data[:expected]
356
- actual.object_id.should == data[:left].object_id # original returned modified
357
- end
358
- end
359
- end
360
-
361
- context "#deep_remove!" do
362
- {
363
- :empty => {
364
- :target => {},
365
- :source => {},
366
- :expected => {} },
367
- :identical => {
368
- :target => { :x => 1, :y => { :foo => :bar } },
369
- :source => { :x => 1, :y => { :foo => :bar } },
370
- :expected => {} },
371
- :greater_target => {
372
- :target => { :x => 1, :y => { :a => 'a', :b => 'b' } },
373
- :source => { :x => 1, :y => { :a => 'a' } },
374
- :expected => { :y => { :b => 'b' } } },
375
- :greater_source => {
376
- :target => { :x => 1, :y => { :a => 'a' } },
377
- :source => { :x => 1, :y => { :a => 'a', :b => 'b' } },
378
- :expected => { :y => {} } },
379
- :disjoint => {
380
- :target => { :x => 1, :y => { :a => 'a' } },
381
- :source => { :x => 2, :y => { :b => 'b' } },
382
- :expected => { :x => 1, :y => { :a => 'a' } } }
383
- }.each do |kind, data|
384
- it "should deep remove values from #{kind} hashes" do
385
- actual = subject.deep_remove!(data[:target], data[:source])
386
- actual.should == data[:expected]
387
- end
388
- end
389
- end
390
-
391
- context "#deep_create_patch" do
392
- {
393
- :identical => {
394
- :left => { :one => 1 },
395
- :right => { :one => 1 },
396
- :expected => { :left_only => {},
397
- :right_only => {},
398
- :diff => {} } },
399
- :disjoint => {
400
- :left => { :one => 1 },
401
- :right => { :two => 1 },
402
- :expected => { :left_only => { :one => 1},
403
- :right_only => { :two => 1},
404
- :diff => {} }
405
- },
406
- :value_diff => {
407
- :left => { :one => 1 },
408
- :right => { :one => 2 },
409
- :expected => { :left_only => {},
410
- :right_only => {},
411
- :diff => { :one => { :left => 1, :right => 2} } } },
412
- :recursive_disjoint => {
413
- :left => { :one => { :a => 1, :b => 2 }, :two => 3 },
414
- :right => { :one => { :a => 1 }, :two => 3 },
415
- :expected => { :left_only => { :one => { :b => 2 }},
416
- :right_only => {},
417
- :diff => {} } },
418
- :recursive_value_diff => {
419
- :left => { :one => { :a => 1, :b => 2 }, :two => 3 },
420
- :right => { :one => { :a => 1, :b => 3 }, :two => 3 },
421
- :expected => { :left_only => {},
422
- :right_only => {},
423
- :diff => { :one => { :b => { :left => 2, :right => 3 }} } } },
424
- :recursive_disjoint_and_value_diff => {
425
- :left => { :one => { :a => 1, :b => 2, :c => 3 }, :two => 3, :three => 4 },
426
- :right => { :one => { :a => 1, :b => 3, :d => 4 }, :two => 5, :four => 6 },
427
- :expected => { :left_only => { :one => { :c => 3 }, :three => 4 },
428
- :right_only => { :one => { :d => 4 }, :four => 6 },
429
- :diff => { :one => { :b => { :left => 2, :right => 3 }}, :two => { :left => 3, :right => 5 } } } }
430
- }.each do |kind, data|
431
- it "should deep create patch for #{kind} hashes" do
432
- actual = subject.deep_create_patch(data[:left], data[:right])
433
- actual.should == data[:expected]
434
- end
435
- end
436
- end
437
-
438
- context '#deep_apply_patch!' do
439
- {
440
- :empty_patch => {
441
- :target => { :one => 1 },
442
- :patch => { :left_only => {}, :right_only => {}, :diff => {} },
443
- :expected => { :one => 1 } },
444
- :disjoint => {
445
- :target => { :one => 1 },
446
- :patch => { :left_only => { :one => 2 }, :right_only => {}, :diff => { :one => { :left => 3, :right => 4 } } },
447
- :expected => { :one => 1 } },
448
- :removal => {
449
- :target => { :one => 1 },
450
- :patch => { :left_only => { :one => 1 }, :right_only => {}, :diff => {} },
451
- :expected => {} },
452
- :addition => {
453
- :target => { :one => 1 },
454
- :patch => { :left_only => {}, :right_only => { :two => 2 }, :diff => {} },
455
- :expected => { :one => 1, :two => 2 } },
456
- :substitution => {
457
- :target => { :one => 1 },
458
- :patch => { :left_only => {}, :right_only => {}, :diff => { :one => { :left => 1, :right => 2 } } },
459
- :expected => { :one => 2 } },
460
- :recursive_removal => {
461
- :target => { :one => { :a => 1, :b => 2 } },
462
- :patch => { :left_only => { :one => { :a => 1 }}, :right_only => {}, :diff => {} },
463
- :expected => { :one => { :b => 2 } } },
464
- :recursive_addition => {
465
- :target => { :one => { :a => 1 } },
466
- :patch => { :left_only => {}, :right_only => { :one => { :b => 2 } }, :diff => {} },
467
- :expected => { :one => { :a => 1, :b => 2 } } },
468
- :recursive_substitution => {
469
- :target => { :one => { :a => 1 } },
470
- :patch => { :left_only => {}, :right_only => {}, :diff => { :one => { :a => { :left => 1, :right => 2 } } } },
471
- :expected => { :one => { :a => 2 } } },
472
- :combined => {
473
- :target => { :one => { :a => 1, :b => 2 } },
474
- :patch => { :left_only => { :one => { :a => 1 } }, :right_only => { :one => { :c => 3 }}, :diff => { :one => { :b => { :left => 2, :right => 3 } } } },
475
- :expected => { :one => { :b => 3, :c => 3 } } }
476
- }.each do |kind, data|
477
- it "should deep apply #{kind} patches" do
478
- actual = subject.deep_apply_patch!(data[:target], data[:patch])
479
- actual.should == data[:expected]
480
- end
481
- end
482
- end
483
-
484
- context '#deep_sorted_json' do
485
-
486
- let(:flat_hash) do
487
- result = {}
488
- 10.times do |i|
489
- # try to ensure insertion order does not affect the unsorted extraction
490
- # order by inserting keys out-of-order. insertion order historically has
491
- # no affect on extraction order, but you never know about future Hash.
492
- # if the Hash of tomorrow is always sorted, then goody.
493
- i = (13 - i) % 10
494
- key = (i + ?a.ord).chr
495
- key = key.to_sym if 0 == (i % 2) # every other key is a symbol
496
- result[key] = i
497
- end
498
- result
499
- end
500
-
501
- let(:deep_hash) do
502
- result = {}
503
- result['y'] = flat_hash.dup
504
- result['y'][:z] = flat_hash.dup
505
- result[:x] = flat_hash.dup
506
- result.merge!(flat_hash)
507
- result
508
- end
509
-
510
- it 'should produce sorted json from a flat hash' do
511
- expected = "{\"a\":0,\"b\":1,\"c\":2,\"d\":3,\"e\":4,\"f\":5,\"g\":6,\"h\":7,\"i\":8,\"j\":9}"
512
- actual = subject.deep_sorted_json(flat_hash)
513
- actual.should == expected
514
- end
515
-
516
- it 'should produce pretty sorted json from a flat hash' do
517
- expected = <<EOF
518
- {
519
- "a": 0,
520
- "b": 1,
521
- "c": 2,
522
- "d": 3,
523
- "e": 4,
524
- "f": 5,
525
- "g": 6,
526
- "h": 7,
527
- "i": 8,
528
- "j": 9
529
- }
530
- EOF
531
- expected = expected.strip
532
- actual = subject.deep_sorted_json(flat_hash, pretty=true)
533
- actual.should == expected
534
- end
535
-
536
- it 'should produce sorted json from a deep hash' do
537
- expected = "{\"a\":0,\"b\":1,\"c\":2,\"d\":3,\"e\":4,\"f\":5,\"g\":6,\"h\":7,\"i\":8,\"j\":9," +
538
- "\"x\":{\"a\":0,\"b\":1,\"c\":2,\"d\":3,\"e\":4,\"f\":5,\"g\":6,\"h\":7,\"i\":8,\"j\":9}," +
539
- "\"y\":{\"a\":0,\"b\":1,\"c\":2,\"d\":3,\"e\":4,\"f\":5,\"g\":6,\"h\":7,\"i\":8,\"j\":9," +
540
- "\"z\":{\"a\":0,\"b\":1,\"c\":2,\"d\":3,\"e\":4,\"f\":5,\"g\":6,\"h\":7,\"i\":8,\"j\":9}}}"
541
- actual = subject.deep_sorted_json(deep_hash)
542
- actual.should == expected
543
- end
544
-
545
- it 'should produce pretty sorted json from a deep hash' do
546
- expected = <<EOF
547
- {
548
- "a": 0,
549
- "b": 1,
550
- "c": 2,
551
- "d": 3,
552
- "e": 4,
553
- "f": 5,
554
- "g": 6,
555
- "h": 7,
556
- "i": 8,
557
- "j": 9,
558
- "x": {
559
- "a": 0,
560
- "b": 1,
561
- "c": 2,
562
- "d": 3,
563
- "e": 4,
564
- "f": 5,
565
- "g": 6,
566
- "h": 7,
567
- "i": 8,
568
- "j": 9
569
- },
570
- "y": {
571
- "a": 0,
572
- "b": 1,
573
- "c": 2,
574
- "d": 3,
575
- "e": 4,
576
- "f": 5,
577
- "g": 6,
578
- "h": 7,
579
- "i": 8,
580
- "j": 9,
581
- "z": {
582
- "a": 0,
583
- "b": 1,
584
- "c": 2,
585
- "d": 3,
586
- "e": 4,
587
- "f": 5,
588
- "g": 6,
589
- "h": 7,
590
- "i": 8,
591
- "j": 9
592
- }
593
- }
594
- }
595
- EOF
596
- expected = expected.strip
597
- actual = subject.deep_sorted_json(deep_hash, pretty=true)
598
- actual.should == expected
599
- end
600
-
601
- end
602
- end