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.
- checksums.yaml +4 -4
- data/Rakefile +4 -0
- data/VERSION +1 -1
- data/lib/right_support/notifiers/airbrake.rb +194 -0
- data/lib/right_support/notifiers/base.rb +73 -0
- data/lib/right_support/notifiers/blacklisters/base.rb +48 -0
- data/lib/right_support/notifiers/blacklisters/canonical.rb +60 -0
- data/lib/right_support/notifiers/blacklisters/regular_expression.rb +86 -0
- data/{features/support/file_utils_bundler_mixin.rb → lib/right_support/notifiers/blacklisters/simple.rb} +21 -20
- data/lib/right_support/notifiers/blacklisters/snake_case.rb +60 -0
- data/lib/right_support/notifiers/blacklisters/wildcard.rb +65 -0
- data/lib/right_support/notifiers/blacklisters.rb +34 -0
- data/lib/right_support/notifiers/logger.rb +94 -0
- data/lib/right_support/notifiers/notification.rb +57 -0
- data/lib/right_support/notifiers/utilities/backtrace_decoder.rb +234 -0
- data/lib/right_support/notifiers/utilities.rb +29 -0
- data/lib/right_support/notifiers.rb +32 -0
- data/lib/right_support/rack/request_logger.rb +13 -9
- data/lib/right_support.rb +1 -0
- data/right_support.gemspec +19 -70
- metadata +17 -69
- data/.coveralls.yml +0 -2
- data/.rspec +0 -3
- data/.simplecov +0 -6
- data/.travis.yml +0 -13
- data/Gemfile +0 -51
- data/Gemfile.lock +0 -153
- data/features/balancer_error_handling.feature +0 -34
- data/features/balancer_health_check.feature +0 -33
- data/features/hash_tools.feature +0 -27
- data/features/http_client_timeout.feature +0 -19
- data/features/serialization.feature +0 -113
- data/features/step_definitions/hash_tools_steps.rb +0 -41
- data/features/step_definitions/http_client_steps.rb +0 -27
- data/features/step_definitions/request_balancer_steps.rb +0 -93
- data/features/step_definitions/ruby_steps.rb +0 -176
- data/features/step_definitions/serialization_steps.rb +0 -133
- data/features/step_definitions/server_steps.rb +0 -134
- data/features/support/env.rb +0 -148
- data/right_support.rconf +0 -9
- data/spec/config/feature_set_spec.rb +0 -83
- data/spec/crypto/signed_hash_spec.rb +0 -73
- data/spec/data/hash_tools_spec.rb +0 -602
- data/spec/data/mash_spec.rb +0 -313
- data/spec/data/token_spec.rb +0 -21
- data/spec/data/uuid_spec.rb +0 -45
- data/spec/db/cassandra_model_part1_spec.rb +0 -84
- data/spec/db/cassandra_model_part2_spec.rb +0 -73
- data/spec/db/cassandra_model_spec.rb +0 -375
- data/spec/fixtures/encrypted_priv_rsa.pem +0 -30
- data/spec/fixtures/good_priv_dsa.pem +0 -12
- data/spec/fixtures/good_priv_rsa.pem +0 -15
- data/spec/fixtures/good_pub_dsa.ssh +0 -1
- data/spec/fixtures/good_pub_rsa.pem +0 -5
- data/spec/fixtures/good_pub_rsa.ssh +0 -1
- data/spec/log/exception_logger_spec.rb +0 -76
- data/spec/log/filter_logger_spec.rb +0 -66
- data/spec/log/mixin_spec.rb +0 -141
- data/spec/log/multiplexer_spec.rb +0 -54
- data/spec/log/null_logger_spec.rb +0 -36
- data/spec/log/step_level_logger_spec.rb +0 -49
- data/spec/log/system_logger_spec.rb +0 -172
- data/spec/net/address_helper_spec.rb +0 -57
- data/spec/net/dns_spec.rb +0 -187
- data/spec/net/http_client_spec.rb +0 -181
- data/spec/net/lb/health_check_spec.rb +0 -417
- data/spec/net/lb/round_robin_spec.rb +0 -15
- data/spec/net/lb/sticky_spec.rb +0 -92
- data/spec/net/request_balancer_spec.rb +0 -690
- data/spec/net/s3_helper_spec.rb +0 -160
- data/spec/net/ssl_spec.rb +0 -42
- data/spec/net/string_encoder_spec.rb +0 -58
- data/spec/rack/log_setter_spec.rb +0 -5
- data/spec/rack/request_logger_spec.rb +0 -225
- data/spec/rack/request_tracker_spec.rb +0 -115
- data/spec/rack/runtime_spec.rb +0 -49
- data/spec/ruby/easy_singleton_spec.rb +0 -72
- data/spec/ruby/object_extensions_spec.rb +0 -27
- data/spec/ruby/string_extensions_spec.rb +0 -98
- data/spec/spec_helper.rb +0 -188
- data/spec/stats/activity_spec.rb +0 -425
- data/spec/stats/exceptions_spec.rb +0 -247
- data/spec/stats/helpers_spec.rb +0 -685
- data/spec/validation/openssl_spec.rb +0 -37
- 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
|