nice_hash 1.8.1 → 1.9.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +38 -0
- data/lib/nice_hash.rb +316 -276
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8a6794b7445afc2d92574c62a5d3828dea4466b75d01798e3696c9b4b9d7600f
|
4
|
+
data.tar.gz: 355f72c6905723c0661f8e35bf5bfb2b7a72d7af86412204be79dc6a61edf58e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0117c9c08fdbeade95163ee9e4b996f5d8fc79c3f26065ce91a541498a7064c33941af1b915e13ac4659915d93971ea23a0bf53fba4e277be6e908377a5f3e9f
|
7
|
+
data.tar.gz: d9bb73186497690eba76d112b9351a5690ed3295ed79925ace8ccc599a2f8e02973a32342be033028bde4167425a493cf5267ad4ebc44cdd8b28ae7a8c662e05
|
data/README.md
CHANGED
@@ -618,6 +618,44 @@ This is a possible output of the previous code:
|
|
618
618
|
{:loginname=>"XlMpgNPlLR", :send_email=>"false", :email=>""}
|
619
619
|
```
|
620
620
|
|
621
|
+
### Compare the structure of a replica with the supplied structure
|
622
|
+
|
623
|
+
By using the NiceHash.compare_structure method you can analyze the supplied replica and verify that the structure follows the one supplied on structure. It supports nested combination of arrays and hashes. It will return true if the comparison is successful.
|
624
|
+
|
625
|
+
```ruby
|
626
|
+
my_structure = [
|
627
|
+
{ name: 'xxx',
|
628
|
+
zip: 'yyyy',
|
629
|
+
customer: true,
|
630
|
+
product_ids: [1]
|
631
|
+
}
|
632
|
+
]
|
633
|
+
my_replica = [ {name: 'Peter Ben', zip: '1121A', customer: false, product_ids: []},
|
634
|
+
{name: 'John Woop', zip: '74014', customer: true, product_ids: [10,120,301]}]
|
635
|
+
|
636
|
+
NiceHash.compare_structure(my_structure, my_replica)
|
637
|
+
#>true
|
638
|
+
```
|
639
|
+
|
640
|
+
Another example that will return false since customer key is missing on first value in replica and the product_ids in the second value of replica contains an string instead of an integer.
|
641
|
+
|
642
|
+
```ruby
|
643
|
+
my_structure = [
|
644
|
+
{ name: 'xxx',
|
645
|
+
zip: 'yyyy',
|
646
|
+
customer: true,
|
647
|
+
product_ids: [1]
|
648
|
+
}
|
649
|
+
]
|
650
|
+
my_replica = [ {name: 'Peter Ben', zip: '1121A', product_ids: []},
|
651
|
+
{name: 'John Woop', zip: '74014', customer: true, product_ids: [10,'120',301]}]
|
652
|
+
|
653
|
+
NiceHash.compare_structure(my_structure, my_replica)
|
654
|
+
#>false
|
655
|
+
```
|
656
|
+
|
657
|
+
Also you can use a third parameter, compare_only_if_exist_key (Boolean), by default false. If true, in case an element exist on structure but doesn't exist on replica won't be verified.
|
658
|
+
|
621
659
|
### Other useful methods
|
622
660
|
|
623
661
|
In case you need the time stamp, we added the method `stamp` to the `Time` class
|
data/lib/nice_hash.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
SP_ADD_TO_RUBY = true if !defined?(SP_ADD_TO_RUBY)
|
2
|
-
require_relative
|
2
|
+
require_relative "nice/hash/add_to_ruby" if SP_ADD_TO_RUBY
|
3
3
|
|
4
|
-
require
|
4
|
+
require "string_pattern"
|
5
5
|
|
6
6
|
###########################################################################
|
7
7
|
# NiceHash creates hashes following certain patterns so your testing will be much easier.
|
@@ -48,37 +48,36 @@ class NiceHash
|
|
48
48
|
# new_hash = my_hash.select_key(:wrong)
|
49
49
|
###########################################################################
|
50
50
|
def NiceHash.select_key(pattern_hash, select_hash_key)
|
51
|
-
hashv=Hash.new()
|
52
|
-
|
53
|
-
if pattern_hash.kind_of?(Hash) and pattern_hash.size>0
|
54
|
-
pattern_hash.each {|key, value|
|
51
|
+
hashv = Hash.new()
|
55
52
|
|
53
|
+
if pattern_hash.kind_of?(Hash) and pattern_hash.size > 0
|
54
|
+
pattern_hash.each { |key, value|
|
56
55
|
if value.kind_of?(Hash)
|
57
56
|
if value.keys.include?(select_hash_key)
|
58
|
-
value=value[select_hash_key]
|
57
|
+
value = value[select_hash_key]
|
59
58
|
else
|
60
|
-
value=NiceHash.select_key(value, select_hash_key)
|
59
|
+
value = NiceHash.select_key(value, select_hash_key)
|
61
60
|
end
|
62
61
|
end
|
63
62
|
if value.kind_of?(Array)
|
64
|
-
array_pattern=false
|
65
|
-
value.each {|v|
|
63
|
+
array_pattern = false
|
64
|
+
value.each { |v|
|
66
65
|
if (v.kind_of?(String) or v.kind_of?(Symbol)) and StringPattern.analyze(v, silent: true).kind_of?(StringPattern::Pattern)
|
67
|
-
hashv[key]=value
|
68
|
-
array_pattern=true
|
66
|
+
hashv[key] = value
|
67
|
+
array_pattern = true
|
69
68
|
break
|
70
69
|
end
|
71
70
|
}
|
72
71
|
unless array_pattern
|
73
|
-
value_ret=Array.new
|
74
|
-
value.each {|v|
|
75
|
-
ret=NiceHash.select_key(v, select_hash_key)
|
76
|
-
value_ret<<ret
|
72
|
+
value_ret = Array.new
|
73
|
+
value.each { |v|
|
74
|
+
ret = NiceHash.select_key(v, select_hash_key)
|
75
|
+
value_ret << ret
|
77
76
|
}
|
78
|
-
hashv[key]=value_ret
|
77
|
+
hashv[key] = value_ret
|
79
78
|
end
|
80
79
|
else
|
81
|
-
hashv[key]=value
|
80
|
+
hashv[key] = value
|
82
81
|
end
|
83
82
|
}
|
84
83
|
else
|
@@ -121,50 +120,49 @@ class NiceHash
|
|
121
120
|
def NiceHash.pattern_fields(pattern_hash, *select_hash_key)
|
122
121
|
pattern_fields = Array.new
|
123
122
|
|
124
|
-
if pattern_hash.kind_of?(Hash) and pattern_hash.size>0
|
125
|
-
pattern_hash.each {|key, value|
|
126
|
-
key=[key]
|
123
|
+
if pattern_hash.kind_of?(Hash) and pattern_hash.size > 0
|
124
|
+
pattern_hash.each { |key, value|
|
125
|
+
key = [key]
|
127
126
|
if value.kind_of?(Hash)
|
128
|
-
if select_hash_key.size==1 and value.keys.include?(select_hash_key[0])
|
129
|
-
value=value[select_hash_key[0]]
|
127
|
+
if select_hash_key.size == 1 and value.keys.include?(select_hash_key[0])
|
128
|
+
value = value[select_hash_key[0]]
|
130
129
|
else
|
131
|
-
res=NiceHash.pattern_fields(value, *select_hash_key)
|
132
|
-
if res.size>0
|
133
|
-
res.each {|r|
|
134
|
-
pattern_fields<<(r.unshift(key)).flatten
|
130
|
+
res = NiceHash.pattern_fields(value, *select_hash_key)
|
131
|
+
if res.size > 0
|
132
|
+
res.each { |r|
|
133
|
+
pattern_fields << (r.unshift(key)).flatten
|
135
134
|
}
|
136
135
|
end
|
137
136
|
next
|
138
137
|
end
|
139
138
|
end
|
140
139
|
if value.kind_of?(String)
|
141
|
-
if StringPattern.optimistic and value.to_s.scan(/^!?\d+-?\d*:.+/).size>0
|
140
|
+
if StringPattern.optimistic and value.to_s.scan(/^!?\d+-?\d*:.+/).size > 0
|
142
141
|
pattern_fields << key
|
143
142
|
end
|
144
143
|
elsif value.kind_of?(Symbol)
|
145
|
-
if value.to_s.scan(/^!?\d+-?\d*:.+/).size>0
|
144
|
+
if value.to_s.scan(/^!?\d+-?\d*:.+/).size > 0
|
146
145
|
pattern_fields << key
|
147
146
|
end
|
148
147
|
elsif value.kind_of?(Array)
|
149
|
-
|
150
|
-
|
151
|
-
value.each {|v|
|
148
|
+
array_pattern = false
|
149
|
+
value.each { |v|
|
152
150
|
if (v.kind_of?(String) or v.kind_of?(Symbol)) and StringPattern.analyze(v, silent: true).kind_of?(StringPattern::Pattern)
|
153
151
|
pattern_fields << key
|
154
|
-
array_pattern=true
|
152
|
+
array_pattern = true
|
155
153
|
break
|
156
154
|
end
|
157
155
|
}
|
158
156
|
unless array_pattern
|
159
|
-
i=0
|
160
|
-
value.each {|v|
|
161
|
-
res=NiceHash.pattern_fields(v, *select_hash_key)
|
162
|
-
if res.size>0
|
163
|
-
res.each {|r|
|
164
|
-
pattern_fields<<(r.unshift(i).unshift(key)).flatten
|
157
|
+
i = 0
|
158
|
+
value.each { |v|
|
159
|
+
res = NiceHash.pattern_fields(v, *select_hash_key)
|
160
|
+
if res.size > 0
|
161
|
+
res.each { |r|
|
162
|
+
pattern_fields << (r.unshift(i).unshift(key)).flatten
|
165
163
|
}
|
166
164
|
end
|
167
|
-
i+=1
|
165
|
+
i += 1
|
168
166
|
}
|
169
167
|
end
|
170
168
|
end
|
@@ -195,49 +193,48 @@ class NiceHash
|
|
195
193
|
def NiceHash.select_fields(pattern_hash, *select_hash_key)
|
196
194
|
select_fields = Array.new
|
197
195
|
|
198
|
-
if pattern_hash.kind_of?(Hash) and pattern_hash.size>0
|
199
|
-
pattern_hash.each {|key, value|
|
200
|
-
key=[key]
|
196
|
+
if pattern_hash.kind_of?(Hash) and pattern_hash.size > 0
|
197
|
+
pattern_hash.each { |key, value|
|
198
|
+
key = [key]
|
201
199
|
if value.kind_of?(Hash)
|
202
|
-
if select_hash_key.size==1 and value.keys.include?(select_hash_key[0])
|
203
|
-
value=value[select_hash_key[0]]
|
200
|
+
if select_hash_key.size == 1 and value.keys.include?(select_hash_key[0])
|
201
|
+
value = value[select_hash_key[0]]
|
204
202
|
else
|
205
|
-
res=NiceHash.select_fields(value, *select_hash_key)
|
206
|
-
if res.size>0
|
207
|
-
res.each {|r|
|
208
|
-
select_fields<<(r.unshift(key)).flatten
|
203
|
+
res = NiceHash.select_fields(value, *select_hash_key)
|
204
|
+
if res.size > 0
|
205
|
+
res.each { |r|
|
206
|
+
select_fields << (r.unshift(key)).flatten
|
209
207
|
}
|
210
208
|
end
|
211
209
|
next
|
212
210
|
end
|
213
211
|
end
|
214
212
|
if value.kind_of?(String)
|
215
|
-
if StringPattern.optimistic and value.to_s.scan(/^([\w\s\-]+\|)+[\w\s\-]+$/).size>0
|
213
|
+
if StringPattern.optimistic and value.to_s.scan(/^([\w\s\-]+\|)+[\w\s\-]+$/).size > 0
|
216
214
|
select_fields << key
|
217
215
|
end
|
218
216
|
elsif value.kind_of?(Symbol)
|
219
|
-
if value.to_s.scan(/^([\w\s\-]+\|)+[\w\s\-]+$/).size>0
|
217
|
+
if value.to_s.scan(/^([\w\s\-]+\|)+[\w\s\-]+$/).size > 0
|
220
218
|
select_fields << key
|
221
219
|
end
|
222
220
|
elsif value.kind_of?(Array)
|
223
|
-
|
224
|
-
|
225
|
-
value.each {|v|
|
221
|
+
array_pattern = false
|
222
|
+
value.each { |v|
|
226
223
|
if (v.kind_of?(String) or v.kind_of?(Symbol)) and StringPattern.analyze(v, silent: true).kind_of?(StringPattern::Pattern)
|
227
|
-
array_pattern=true
|
224
|
+
array_pattern = true
|
228
225
|
break
|
229
226
|
end
|
230
227
|
}
|
231
228
|
unless array_pattern
|
232
|
-
i=0
|
233
|
-
value.each {|v|
|
234
|
-
res=NiceHash.select_fields(v, *select_hash_key)
|
235
|
-
if res.size>0
|
236
|
-
res.each {|r|
|
237
|
-
select_fields<<(r.unshift(i).unshift(key)).flatten
|
229
|
+
i = 0
|
230
|
+
value.each { |v|
|
231
|
+
res = NiceHash.select_fields(v, *select_hash_key)
|
232
|
+
if res.size > 0
|
233
|
+
res.each { |r|
|
234
|
+
select_fields << (r.unshift(i).unshift(key)).flatten
|
238
235
|
}
|
239
236
|
end
|
240
|
-
i+=1
|
237
|
+
i += 1
|
241
238
|
}
|
242
239
|
end
|
243
240
|
end
|
@@ -247,7 +244,6 @@ class NiceHash
|
|
247
244
|
return select_fields
|
248
245
|
end
|
249
246
|
|
250
|
-
|
251
247
|
###########################################################################
|
252
248
|
# It will generate a new hash with the values generated from the string patterns and select fields specified.
|
253
249
|
# In case supplied select_hash_key and a subhash specified on a value it will be selected only the value of the key specified on select_hash_key
|
@@ -299,107 +295,104 @@ class NiceHash
|
|
299
295
|
# new_hash = my_hash.gen(:correct)
|
300
296
|
# new_hash = my_hash.generate(:correct, errors: [:min_length])
|
301
297
|
###########################################################################
|
302
|
-
def NiceHash.generate(pattern_hash, select_hash_key=nil, expected_errors: [], **synonyms)
|
303
|
-
hashv=Hash.new()
|
304
|
-
same_values=Hash.new()
|
305
|
-
expected_errors=synonyms[:errors] if synonyms.keys.include?(:errors)
|
298
|
+
def NiceHash.generate(pattern_hash, select_hash_key = nil, expected_errors: [], **synonyms)
|
299
|
+
hashv = Hash.new()
|
300
|
+
same_values = Hash.new()
|
301
|
+
expected_errors = synonyms[:errors] if synonyms.keys.include?(:errors)
|
306
302
|
if expected_errors.kind_of?(Symbol)
|
307
|
-
expected_errors=[expected_errors]
|
303
|
+
expected_errors = [expected_errors]
|
308
304
|
end
|
309
305
|
|
310
|
-
if pattern_hash.kind_of?(Hash) and pattern_hash.size>0
|
311
|
-
pattern_hash.each {|key, value|
|
312
|
-
|
306
|
+
if pattern_hash.kind_of?(Hash) and pattern_hash.size > 0
|
307
|
+
pattern_hash.each { |key, value|
|
313
308
|
if key.kind_of?(Array)
|
314
|
-
same_values[key[0]]=key.dup
|
309
|
+
same_values[key[0]] = key.dup
|
315
310
|
same_values[key[0]].shift
|
316
|
-
key=key[0]
|
311
|
+
key = key[0]
|
317
312
|
end
|
318
313
|
if value.kind_of?(Hash)
|
319
314
|
if value.keys.include?(select_hash_key)
|
320
|
-
value=value[select_hash_key]
|
315
|
+
value = value[select_hash_key]
|
321
316
|
else
|
322
|
-
value=NiceHash.generate(value, select_hash_key, expected_errors: expected_errors)
|
317
|
+
value = NiceHash.generate(value, select_hash_key, expected_errors: expected_errors)
|
323
318
|
end
|
324
319
|
end
|
325
320
|
|
326
321
|
if value.kind_of?(String) or value.kind_of?(Symbol)
|
327
|
-
if ((StringPattern.optimistic and value.kind_of?(String)) or value.kind_of?(Symbol)) and value.to_s.scan(/^!?\d+-?\d*:.+/).size>0
|
328
|
-
hashv[key]=StringPattern.generate(value, expected_errors: expected_errors)
|
329
|
-
elsif ((StringPattern.optimistic and value.kind_of?(String)) or value.kind_of?(Symbol)) and value.to_s.scan(/^([\w\s\-]+\|)+[\w\s\-]+$/).size>0
|
330
|
-
if expected_errors.include?(:min_length) or (expected_errors.include?(:length) and rand.round==0)
|
331
|
-
min=value.to_s.split("|").min {|a, b| a.size <=> b.size}
|
332
|
-
hashv[key]=min[0..-2] unless min==""
|
322
|
+
if ((StringPattern.optimistic and value.kind_of?(String)) or value.kind_of?(Symbol)) and value.to_s.scan(/^!?\d+-?\d*:.+/).size > 0
|
323
|
+
hashv[key] = StringPattern.generate(value, expected_errors: expected_errors)
|
324
|
+
elsif ((StringPattern.optimistic and value.kind_of?(String)) or value.kind_of?(Symbol)) and value.to_s.scan(/^([\w\s\-]+\|)+[\w\s\-]+$/).size > 0
|
325
|
+
if expected_errors.include?(:min_length) or (expected_errors.include?(:length) and rand.round == 0)
|
326
|
+
min = value.to_s.split("|").min { |a, b| a.size <=> b.size }
|
327
|
+
hashv[key] = min[0..-2] unless min == ""
|
333
328
|
end
|
334
329
|
if !hashv.keys.include?(key) and (expected_errors.include?(:max_length) or expected_errors.include?(:length))
|
335
|
-
max=value.to_s.split("|").max {|a, b| a.size <=> b.size}
|
336
|
-
hashv[key]=max+max[-1]
|
330
|
+
max = value.to_s.split("|").max { |a, b| a.size <=> b.size }
|
331
|
+
hashv[key] = max + max[-1]
|
337
332
|
end
|
338
333
|
if expected_errors.include?(:value) or
|
339
|
-
|
340
|
-
|
334
|
+
expected_errors.include?(:string_set_not_allowed) or
|
335
|
+
expected_errors.include?(:required_data)
|
341
336
|
if hashv.keys.include?(key)
|
342
|
-
v=hashv[key]
|
337
|
+
v = hashv[key]
|
343
338
|
else
|
344
|
-
v=value.to_s.split("|").sample
|
339
|
+
v = value.to_s.split("|").sample
|
345
340
|
end
|
346
341
|
unless expected_errors.include?(:string_set_not_allowed)
|
347
|
-
v=StringPattern.generate(:"#{v.size}:[#{value.to_s.split("|").join.split(//).uniq.join}]")
|
348
|
-
hashv[key]=v unless value.to_s.split("|").include?(v)
|
342
|
+
v = StringPattern.generate(:"#{v.size}:[#{value.to_s.split("|").join.split(//).uniq.join}]")
|
343
|
+
hashv[key] = v unless value.to_s.split("|").include?(v)
|
349
344
|
end
|
350
345
|
unless hashv.keys.include?(key)
|
351
|
-
one_wrong_letter=StringPattern.generate(:"1:LN$[%#{value.to_s.split("|").join.split(//).uniq.join}%]")
|
352
|
-
v[rand(v.size)]=one_wrong_letter
|
353
|
-
hashv[key]=v unless value.to_s.split("|").include?(v)
|
346
|
+
one_wrong_letter = StringPattern.generate(:"1:LN$[%#{value.to_s.split("|").join.split(//).uniq.join}%]")
|
347
|
+
v[rand(v.size)] = one_wrong_letter
|
348
|
+
hashv[key] = v unless value.to_s.split("|").include?(v)
|
354
349
|
end
|
355
350
|
end
|
356
351
|
unless hashv.keys.include?(key)
|
357
|
-
hashv[key]=value.to_s.split("|").sample
|
352
|
+
hashv[key] = value.to_s.split("|").sample
|
358
353
|
end
|
359
354
|
else
|
360
|
-
hashv[key]=value
|
355
|
+
hashv[key] = value
|
361
356
|
end
|
362
357
|
elsif value.kind_of?(Array)
|
363
|
-
array_pattern=false
|
364
|
-
value.each {|v|
|
358
|
+
array_pattern = false
|
359
|
+
value.each { |v|
|
365
360
|
if (v.kind_of?(String) or v.kind_of?(Symbol)) and StringPattern.analyze(v, silent: true).kind_of?(StringPattern::Pattern)
|
366
|
-
hashv[key]=StringPattern.generate(value, expected_errors: expected_errors)
|
367
|
-
array_pattern=true
|
361
|
+
hashv[key] = StringPattern.generate(value, expected_errors: expected_errors)
|
362
|
+
array_pattern = true
|
368
363
|
break
|
369
364
|
end
|
370
365
|
}
|
371
366
|
unless array_pattern
|
372
|
-
value_ret=Array.new
|
373
|
-
value.each {|v|
|
374
|
-
ret=NiceHash.generate(v, select_hash_key, expected_errors: expected_errors)
|
375
|
-
ret=v if ret.kind_of?(Hash) and ret.size==0
|
376
|
-
value_ret<<ret
|
367
|
+
value_ret = Array.new
|
368
|
+
value.each { |v|
|
369
|
+
ret = NiceHash.generate(v, select_hash_key, expected_errors: expected_errors)
|
370
|
+
ret = v if ret.kind_of?(Hash) and ret.size == 0
|
371
|
+
value_ret << ret
|
377
372
|
}
|
378
|
-
hashv[key]=value_ret
|
373
|
+
hashv[key] = value_ret
|
379
374
|
end
|
380
375
|
elsif value.kind_of?(Proc)
|
381
|
-
hashv[key]=value.call
|
376
|
+
hashv[key] = value.call
|
382
377
|
elsif value.kind_of?(Regexp)
|
383
|
-
hashv[key]=value.generate
|
378
|
+
hashv[key] = value.generate
|
384
379
|
else
|
385
|
-
hashv[key]=value
|
380
|
+
hashv[key] = value
|
386
381
|
end
|
387
382
|
|
388
383
|
if same_values.include?(key)
|
389
|
-
same_values[key].each {|k|
|
390
|
-
hashv[k]=hashv[key]
|
384
|
+
same_values[key].each { |k|
|
385
|
+
hashv[k] = hashv[key]
|
391
386
|
}
|
392
387
|
end
|
393
388
|
|
394
389
|
@values = hashv
|
395
|
-
|
396
390
|
}
|
397
391
|
end
|
398
392
|
|
399
393
|
return hashv
|
400
394
|
end
|
401
395
|
|
402
|
-
|
403
396
|
###########################################################################
|
404
397
|
# Validates a given values_hash_to_validate with string patterns and select fields from pattern_hash
|
405
398
|
# input:
|
@@ -448,95 +441,90 @@ class NiceHash
|
|
448
441
|
###########################################################################
|
449
442
|
def NiceHash.validate(patterns_hash, values_hash_to_validate, only_patterns: true)
|
450
443
|
if patterns_hash.kind_of?(Array)
|
451
|
-
pattern_hash=patterns_hash[0]
|
452
|
-
select_hash_key=patterns_hash[1]
|
444
|
+
pattern_hash = patterns_hash[0]
|
445
|
+
select_hash_key = patterns_hash[1]
|
453
446
|
elsif patterns_hash.kind_of?(Hash)
|
454
|
-
pattern_hash=patterns_hash
|
455
|
-
select_hash_key=nil
|
447
|
+
pattern_hash = patterns_hash
|
448
|
+
select_hash_key = nil
|
456
449
|
else
|
457
450
|
puts "NiceHash.validate wrong pattern_hash supplied #{patterns_hash.inspect}"
|
458
451
|
return {error: :error}
|
459
452
|
end
|
460
453
|
values = values_hash_to_validate
|
461
|
-
results={}
|
462
|
-
same_values={}
|
463
|
-
if pattern_hash.kind_of?(Hash) and pattern_hash.size>0
|
464
|
-
pattern_hash.each {|key, value|
|
465
|
-
|
454
|
+
results = {}
|
455
|
+
same_values = {}
|
456
|
+
if pattern_hash.kind_of?(Hash) and pattern_hash.size > 0
|
457
|
+
pattern_hash.each { |key, value|
|
466
458
|
if key.kind_of?(Array)
|
467
|
-
same_values[key[0]]=key.dup
|
459
|
+
same_values[key[0]] = key.dup
|
468
460
|
same_values[key[0]].shift
|
469
|
-
key=key[0]
|
461
|
+
key = key[0]
|
470
462
|
end
|
471
463
|
if value.kind_of?(Hash)
|
472
464
|
if !select_hash_key.nil? and value.keys.include?(select_hash_key)
|
473
|
-
value=value[select_hash_key]
|
465
|
+
value = value[select_hash_key]
|
474
466
|
elsif values.keys.include?(key) and values[key].kind_of?(Hash)
|
475
|
-
res=NiceHash.validate([value, select_hash_key], values[key], only_patterns: only_patterns)
|
476
|
-
results[key]=res if res.size>0
|
467
|
+
res = NiceHash.validate([value, select_hash_key], values[key], only_patterns: only_patterns)
|
468
|
+
results[key] = res if res.size > 0
|
477
469
|
next
|
478
470
|
end
|
479
471
|
end
|
480
472
|
|
481
473
|
if values.keys.include?(key)
|
482
474
|
if value.kind_of?(String) or value.kind_of?(Symbol)
|
483
|
-
if ((StringPattern.optimistic and value.kind_of?(String)) or value.kind_of?(Symbol)) and value.to_s.scan(/^!?\d+-?\d*:.+/).size>0
|
484
|
-
res=StringPattern.validate(pattern: value, text: values[key])
|
485
|
-
results[key]=res if res.size>0
|
486
|
-
elsif !only_patterns and ((StringPattern.optimistic and value.kind_of?(String)) or value.kind_of?(Symbol)) and value.to_s.scan(/^([\w\s\-]+\|)+[\w\s\-]+$/).size>0
|
487
|
-
results[key]=false unless value.to_s.split("|").include?(values[key])
|
475
|
+
if ((StringPattern.optimistic and value.kind_of?(String)) or value.kind_of?(Symbol)) and value.to_s.scan(/^!?\d+-?\d*:.+/).size > 0
|
476
|
+
res = StringPattern.validate(pattern: value, text: values[key])
|
477
|
+
results[key] = res if res.size > 0
|
478
|
+
elsif !only_patterns and ((StringPattern.optimistic and value.kind_of?(String)) or value.kind_of?(Symbol)) and value.to_s.scan(/^([\w\s\-]+\|)+[\w\s\-]+$/).size > 0
|
479
|
+
results[key] = false unless value.to_s.split("|").include?(values[key])
|
488
480
|
elsif !only_patterns
|
489
|
-
results[key]=false unless value.to_s==values[key].to_s
|
481
|
+
results[key] = false unless value.to_s == values[key].to_s
|
490
482
|
end
|
491
483
|
elsif value.kind_of?(Array)
|
492
|
-
array_pattern=false
|
493
|
-
complex_data=false
|
494
|
-
value.each {|v|
|
484
|
+
array_pattern = false
|
485
|
+
complex_data = false
|
486
|
+
value.each { |v|
|
495
487
|
if (v.kind_of?(String) or v.kind_of?(Symbol)) and StringPattern.analyze(v, silent: true).kind_of?(StringPattern::Pattern)
|
496
|
-
res=StringPattern.validate(pattern: value, text: values[key])
|
497
|
-
results[key]=res if res==false
|
498
|
-
array_pattern=true
|
488
|
+
res = StringPattern.validate(pattern: value, text: values[key])
|
489
|
+
results[key] = res if res == false
|
490
|
+
array_pattern = true
|
499
491
|
break
|
500
492
|
elsif v.kind_of?(Hash) or v.kind_of?(Array) or v.kind_of?(Struct)
|
501
|
-
complex_data=true
|
493
|
+
complex_data = true
|
502
494
|
break
|
503
495
|
end
|
504
496
|
}
|
505
497
|
unless array_pattern or results.include?(key)
|
506
|
-
i=0
|
507
|
-
value.each {|v|
|
508
|
-
res=NiceHash.validate([v, select_hash_key], values[key][i], only_patterns: only_patterns)
|
509
|
-
if res.size>0
|
510
|
-
results[key]=Array.new() if !results.keys.include?(key)
|
511
|
-
results[key][i]=res
|
498
|
+
i = 0
|
499
|
+
value.each { |v|
|
500
|
+
res = NiceHash.validate([v, select_hash_key], values[key][i], only_patterns: only_patterns)
|
501
|
+
if res.size > 0
|
502
|
+
results[key] = Array.new() if !results.keys.include?(key)
|
503
|
+
results[key][i] = res
|
512
504
|
end
|
513
|
-
i+=1
|
505
|
+
i += 1
|
514
506
|
}
|
515
|
-
|
516
507
|
end
|
517
508
|
unless array_pattern or only_patterns or results.include?(key) or complex_data
|
518
|
-
results[key]=false unless value==values[key]
|
509
|
+
results[key] = false unless value == values[key]
|
519
510
|
end
|
520
|
-
|
521
511
|
else
|
522
512
|
unless only_patterns or value.kind_of?(Proc)
|
523
|
-
results[key]=false unless value==values[key]
|
513
|
+
results[key] = false unless value == values[key]
|
524
514
|
end
|
525
515
|
end
|
526
516
|
|
527
517
|
if same_values.include?(key)
|
528
|
-
same_values[key].each {|k|
|
518
|
+
same_values[key].each { |k|
|
529
519
|
if values.keys.include?(k)
|
530
|
-
if values[key]!=values[k]
|
531
|
-
results[k]="Not equal to #{key}"
|
520
|
+
if values[key] != values[k]
|
521
|
+
results[k] = "Not equal to #{key}"
|
532
522
|
end
|
533
523
|
end
|
534
524
|
}
|
535
525
|
end
|
536
|
-
|
537
526
|
end
|
538
527
|
}
|
539
|
-
|
540
528
|
end
|
541
529
|
|
542
530
|
return results
|
@@ -563,158 +551,210 @@ class NiceHash
|
|
563
551
|
###########################################################################
|
564
552
|
def NiceHash.change_one_by_one(patterns_hash, values_hash)
|
565
553
|
if patterns_hash.kind_of?(Array)
|
566
|
-
select_key=patterns_hash[1]
|
567
|
-
pattern_hash=patterns_hash[0]
|
554
|
+
select_key = patterns_hash[1]
|
555
|
+
pattern_hash = patterns_hash[0]
|
568
556
|
else
|
569
|
-
pattern_hash=patterns_hash
|
570
|
-
select_key=[]
|
557
|
+
pattern_hash = patterns_hash
|
558
|
+
select_key = []
|
571
559
|
end
|
572
|
-
array=Array.new
|
573
|
-
good_values=NiceHash.generate(pattern_hash, select_key)
|
574
|
-
select_keys=pattern_hash.pattern_fields(select_key)+pattern_hash.select_fields(select_key)
|
575
|
-
select_keys.each {|field|
|
576
|
-
new_hash=Marshal.load(Marshal.dump(good_values))
|
560
|
+
array = Array.new
|
561
|
+
good_values = NiceHash.generate(pattern_hash, select_key)
|
562
|
+
select_keys = pattern_hash.pattern_fields(select_key) + pattern_hash.select_fields(select_key)
|
563
|
+
select_keys.each { |field|
|
564
|
+
new_hash = Marshal.load(Marshal.dump(good_values))
|
577
565
|
# to deal with the case same values... like in pwd1, pwd2, pwd3
|
578
566
|
if field[-1].kind_of?(Array)
|
579
|
-
last_to_set=field[-1]
|
567
|
+
last_to_set = field[-1]
|
580
568
|
else
|
581
|
-
last_to_set=[field[-1]]
|
569
|
+
last_to_set = [field[-1]]
|
582
570
|
end
|
583
|
-
last_to_set.each {|f|
|
584
|
-
keys=field[0..-2]<<f
|
571
|
+
last_to_set.each { |f|
|
572
|
+
keys = field[0..-2] << f
|
585
573
|
new_hash.bury(keys, values_hash.dig(*keys))
|
586
574
|
}
|
587
|
-
array<<new_hash
|
575
|
+
array << new_hash
|
588
576
|
}
|
589
577
|
return array
|
590
578
|
end
|
591
579
|
|
592
|
-
|
593
580
|
##################################################
|
594
|
-
|
595
|
-
|
596
|
-
|
597
|
-
|
598
|
-
|
599
|
-
|
600
|
-
|
601
|
-
|
602
|
-
|
603
|
-
|
604
|
-
|
605
|
-
|
606
|
-
|
607
|
-
|
608
|
-
|
609
|
-
|
610
|
-
|
611
|
-
|
612
|
-
|
613
|
-
|
614
|
-
|
615
|
-
|
616
|
-
|
617
|
-
|
618
|
-
|
619
|
-
|
620
|
-
|
621
|
-
|
622
|
-
|
623
|
-
|
624
|
-
|
625
|
-
|
626
|
-
|
627
|
-
|
628
|
-
|
629
|
-
|
630
|
-
|
631
|
-
|
632
|
-
|
633
|
-
|
634
|
-
|
635
|
-
|
636
|
-
|
637
|
-
|
638
|
-
else
|
639
|
-
res_tx=result[n_key]
|
640
|
-
end
|
641
|
-
result[n_key]=Array.new()
|
642
|
-
result[n_key].push(res_tx)
|
643
|
-
result[n_key].push(n_value)
|
581
|
+
# Get values from the Hash structure (array of Hashes allowed)
|
582
|
+
# In case the key supplied doesn't exist in the hash then it will be return nil for that one
|
583
|
+
# input:
|
584
|
+
# hashv: a simple hash or a hash containing arrays. Example:
|
585
|
+
# example={"id"=>344,
|
586
|
+
# "customer"=>{
|
587
|
+
# "name"=>"Peter Smith",
|
588
|
+
# "phone"=>334334333
|
589
|
+
# },
|
590
|
+
# "tickets"=>[
|
591
|
+
# {"idt"=>345,"name"=>"myFavor1"},
|
592
|
+
# {"idt"=>3123},
|
593
|
+
# {"idt"=>3145,"name"=>"Special ticket"}
|
594
|
+
# ]
|
595
|
+
# }
|
596
|
+
# keys: one key (string) or an array of keys
|
597
|
+
# output:
|
598
|
+
# a Hash of Arrays with all values found.
|
599
|
+
# Example of output with example.get_values("id","name")
|
600
|
+
# {"id"=>[334],"name"=>["Peter North"]}
|
601
|
+
# Example of output with example.get_values("idt")
|
602
|
+
# {"idt"=>[345,3123,3145]}
|
603
|
+
#
|
604
|
+
####################################################
|
605
|
+
def NiceHash.get_values(hashv, keys)
|
606
|
+
if keys.kind_of?(String) or keys.kind_of?(Symbol)
|
607
|
+
keys = [keys]
|
608
|
+
end
|
609
|
+
result = Hash.new()
|
610
|
+
number_of_results = Hash.new()
|
611
|
+
keys.each { |key|
|
612
|
+
number_of_results[key] = 0
|
613
|
+
}
|
614
|
+
if hashv.kind_of?(Array)
|
615
|
+
hashv.each { |tmp|
|
616
|
+
if tmp.kind_of?(Array) or tmp.kind_of?(Hash)
|
617
|
+
n_result = get_values(tmp, keys)
|
618
|
+
if n_result != :error
|
619
|
+
n_result.each { |n_key, n_value|
|
620
|
+
if result.has_key?(n_key)
|
621
|
+
if !result[n_key].kind_of?(Array) or
|
622
|
+
(result[n_key].kind_of?(Array) and number_of_results[n_key] < result[n_key].size)
|
623
|
+
if result[n_key].kind_of?(Hash) or result[n_key].kind_of?(Array)
|
624
|
+
res_tx = result[n_key].dup()
|
644
625
|
else
|
645
|
-
result[n_key]
|
626
|
+
res_tx = result[n_key]
|
646
627
|
end
|
628
|
+
result[n_key] = Array.new()
|
629
|
+
result[n_key].push(res_tx)
|
630
|
+
result[n_key].push(n_value)
|
647
631
|
else
|
648
|
-
result[n_key]
|
632
|
+
result[n_key].push(n_value)
|
649
633
|
end
|
650
|
-
|
651
|
-
|
652
|
-
|
634
|
+
else
|
635
|
+
result[n_key] = n_value
|
636
|
+
end
|
637
|
+
number_of_results[n_key] += 1
|
638
|
+
}
|
653
639
|
end
|
654
|
-
|
655
|
-
|
656
|
-
|
657
|
-
|
640
|
+
end
|
641
|
+
}
|
642
|
+
elsif hashv.kind_of?(Hash)
|
643
|
+
hashv.each { |key, value|
|
644
|
+
#if keys.include?(key) then
|
645
|
+
#added to be able to access the keys with symbols to strings and opposite
|
646
|
+
if keys.include?(key) or keys.include?(key.to_s) or keys.include?(key.to_sym)
|
658
647
|
#added to be able to access the keys with symbols to strings and opposite
|
659
|
-
|
660
|
-
|
661
|
-
|
662
|
-
|
663
|
-
|
664
|
-
|
665
|
-
if
|
666
|
-
|
667
|
-
if result[key].kind_of?(Hash) or result[key].kind_of?(Array) then
|
668
|
-
res_tx=result[key].dup()
|
669
|
-
else
|
670
|
-
res_tx=result[key]
|
671
|
-
end
|
672
|
-
result[key]=Array.new()
|
673
|
-
result[key].push(res_tx)
|
674
|
-
result[key].push(value)
|
648
|
+
key = key.to_s() if keys.include?(key.to_s)
|
649
|
+
key = key.to_sym() if keys.include?(key.to_sym)
|
650
|
+
|
651
|
+
if result.has_key?(key)
|
652
|
+
if !result[key].kind_of?(Array) or
|
653
|
+
(result[key].kind_of?(Array) and number_of_results[key] < result[key].size)
|
654
|
+
if result[key].kind_of?(Hash) or result[key].kind_of?(Array)
|
655
|
+
res_tx = result[key].dup()
|
675
656
|
else
|
676
|
-
result[key]
|
657
|
+
res_tx = result[key]
|
677
658
|
end
|
659
|
+
result[key] = Array.new()
|
660
|
+
result[key].push(res_tx)
|
661
|
+
result[key].push(value)
|
678
662
|
else
|
679
|
-
result[key]
|
663
|
+
result[key].push(value)
|
680
664
|
end
|
681
|
-
|
665
|
+
else
|
666
|
+
result[key] = value
|
682
667
|
end
|
683
|
-
|
684
|
-
|
685
|
-
|
686
|
-
|
687
|
-
|
688
|
-
|
689
|
-
|
690
|
-
|
691
|
-
|
692
|
-
|
693
|
-
|
694
|
-
end
|
695
|
-
result[n_key]=Array.new()
|
696
|
-
result[n_key].push(res_tx)
|
697
|
-
result[n_key].push(n_value)
|
668
|
+
number_of_results[key] += 1
|
669
|
+
end
|
670
|
+
if value.kind_of?(Array) or value.kind_of?(Hash)
|
671
|
+
n_result = get_values(value, keys)
|
672
|
+
if n_result != :error
|
673
|
+
n_result.each { |n_key, n_value|
|
674
|
+
if result.has_key?(n_key)
|
675
|
+
if !result[n_key].kind_of?(Array) or
|
676
|
+
(result[n_key].kind_of?(Array) and number_of_results[n_key] < result[n_key].size)
|
677
|
+
if result[n_key].kind_of?(Hash) or result[n_key].kind_of?(Array)
|
678
|
+
res_tx = result[n_key].dup()
|
698
679
|
else
|
699
|
-
result[n_key]
|
680
|
+
res_tx = result[n_key]
|
700
681
|
end
|
682
|
+
result[n_key] = Array.new()
|
683
|
+
result[n_key].push(res_tx)
|
684
|
+
result[n_key].push(n_value)
|
701
685
|
else
|
702
|
-
result[n_key]
|
686
|
+
result[n_key].push(n_value)
|
703
687
|
end
|
704
|
-
|
705
|
-
|
706
|
-
|
688
|
+
else
|
689
|
+
result[n_key] = n_value
|
690
|
+
end
|
691
|
+
number_of_results[n_key] += 1
|
692
|
+
}
|
707
693
|
end
|
708
|
-
|
709
|
-
|
710
|
-
|
694
|
+
end
|
695
|
+
}
|
696
|
+
else
|
697
|
+
return :error
|
698
|
+
end
|
699
|
+
if result.kind_of?(Hash) and caller[0]["get_values"].nil? #no error or anything weird
|
700
|
+
(keys - result.keys).each { |k| #in case some keys don't exist in the hash
|
701
|
+
result[k] = nil
|
702
|
+
}
|
703
|
+
end
|
704
|
+
return result
|
705
|
+
end
|
706
|
+
|
707
|
+
##################################################
|
708
|
+
# Analyzes the supplied replica and verifies that the structure follows the one supplied on structure
|
709
|
+
#
|
710
|
+
# @param structure [Array] [Hash] Contains the structure that should follow the replica. It can be a nested combination of arrays and hashes.
|
711
|
+
# @param replica [Array] [Hash] Contains the element to be verified on following the supplied structure. It can be a nested combination of arrays and hashes.
|
712
|
+
# @param compare_only_if_exist_key [Boolean] (Default false) If true, in case an element exist on structure but doesn't exist on replica won't be verified.
|
713
|
+
#
|
714
|
+
# @return [Boolean] true in case replica follows the structure supplied
|
715
|
+
#
|
716
|
+
# @example
|
717
|
+
# my_structure = [
|
718
|
+
# { name: 'xxx',
|
719
|
+
# zip: 'yyyy',
|
720
|
+
# customer: true,
|
721
|
+
# product_ids: [1]
|
722
|
+
# }
|
723
|
+
# ]
|
724
|
+
# my_replica = [ {name: 'Peter Ben', zip: '1121A', customer: false, product_ids: []},
|
725
|
+
# {name: 'John Woop', zip: '74014', customer: true, product_ids: [10,120,301]}]
|
726
|
+
# NiceHash.compare_structure(my_structure, my_replica)
|
727
|
+
# #>true
|
728
|
+
##################################################
|
729
|
+
def NiceHash.compare_structure(structure, replica, compare_only_if_exist_key = false)
|
730
|
+
return false unless structure.class == replica.class or
|
731
|
+
((structure.is_a?(TrueClass) or structure.is_a?(FalseClass)) and (replica.is_a?(TrueClass) or replica.is_a?(FalseClass)))
|
732
|
+
if structure.is_a?(Hash)
|
733
|
+
structure.each do |key, value|
|
734
|
+
if compare_only_if_exist_key and replica.key?(key)
|
735
|
+
unless compare_structure(value, replica[key], compare_only_if_exist_key)
|
736
|
+
return false
|
737
|
+
end
|
738
|
+
elsif compare_only_if_exist_key == false
|
739
|
+
return false unless replica.key?(key)
|
740
|
+
return false unless compare_structure(value, replica[key], compare_only_if_exist_key)
|
741
|
+
end
|
711
742
|
end
|
712
|
-
|
713
|
-
|
714
|
-
|
715
|
-
|
743
|
+
elsif structure.is_a?(Array)
|
744
|
+
if structure.size == 1
|
745
|
+
# compare all elements of replica with the structure of the only element on structure
|
746
|
+
replica.each do |elem|
|
747
|
+
return false unless compare_structure(structure[0], elem, compare_only_if_exist_key)
|
748
|
+
end
|
749
|
+
else
|
750
|
+
# compare every element on structure with replica
|
751
|
+
i = 0
|
752
|
+
structure.each do |elem|
|
753
|
+
return false unless compare_structure(elem, replica[i], compare_only_if_exist_key)
|
754
|
+
i += 1
|
755
|
+
end
|
716
756
|
end
|
717
|
-
return result
|
718
757
|
end
|
719
|
-
|
758
|
+
return true
|
759
|
+
end
|
720
760
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: nice_hash
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.9.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mario Ruiz
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-02-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: string_pattern
|