right_support 2.11.3 → 2.12.1

Sign up to get free protection for your applications and to get access to all the features.
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