nice_hash 1.1.0 → 1.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (6) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +4 -4
  3. data/README.md +515 -515
  4. data/lib/nice/hash/add_to_ruby.rb +127 -127
  5. data/lib/nice_hash.rb +582 -582
  6. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fb7ee5f4b573f8086229554d2faa0b453a3151b0d1079de3506a91576e6e1fdb
4
- data.tar.gz: 682b00b149237da2b21c039ad405583389cde10b9a8a7051ecf86212d762f8ca
3
+ metadata.gz: 79c328a7e4b1555ec566a2a551440bab304a53a64f69e0bd4413f8a8d9645e5b
4
+ data.tar.gz: 1091f1704b10cba8103d91fd0fdb710c9edbf1dd74fe07b7ca298f324b936986
5
5
  SHA512:
6
- metadata.gz: 507dc1d466f6fa6a34708a716f778b33d1c77608ad11ad8f58c853e47de41c9f8023f3ec486412c8c655691bee689bfc495bd3cbabb2aed4a1eb82ea6e57fd08
7
- data.tar.gz: 3cfb95b45dd3931f02d91d572a568f032be4fcec3d0386541b75a6fe2ab106f9532348148f557b564c5ccc1d81a8254692fec066cf0c667b1d1124f605280113
6
+ metadata.gz: b1397ecb7a9b47a3c4bb28cfe7fd50b28ea4b33254eaa02c8db55555cae4d5a48e65fb42dd251f2269b5b6514910bff89fd1bfdd6d56467e846b8688bd0f1a24
7
+ data.tar.gz: fd3cd525b602085a769c57ae84406be49fd0d03a162742cfaf193ede2134d394ec98c260bd6849da35daf295f2905cecf24c7e9abdfe0b2752ea2ea9e0868009
data/.yardopts CHANGED
@@ -1,5 +1,5 @@
1
- --readme README.md
2
- --title 'nice_hash - NiceHash creates hashes following certain patterns so your testing will be much easier. You can easily generates all the hashes you want following the criteria you specify.'
3
- --charset utf-8
4
- --markup markdown
1
+ --readme README.md
2
+ --title 'nice_hash - NiceHash creates hashes following certain patterns so your testing will be much easier. You can easily generates all the hashes you want following the criteria you specify.'
3
+ --charset utf-8
4
+ --markup markdown
5
5
  'lib/**/*.rb' - '*.md' - 'LICENSE'
data/README.md CHANGED
@@ -1,515 +1,515 @@
1
- # NiceHash
2
-
3
- [![Gem Version](https://badge.fury.io/rb/nice_hash.svg)](https://rubygems.org/gems/nice_hash)
4
-
5
- NiceHash creates hashes following certain patterns so your testing will be much easier.
6
-
7
- You can easily generates all the hashes you want following the criteria you specify.
8
-
9
- Many other features coming to Hash class like the methods 'bury' or select_key, access the keys like methods: my_hash.my_key.other_key. You will be able to generate thousands of different hashes just declaring one and test easily APIs based on JSON for example.
10
-
11
- To generate the strings following a pattern take a look at the documentation for string_pattern gem: https://github.com/MarioRuiz/string_pattern
12
-
13
- ## Installation
14
-
15
- Add this line to your application's Gemfile:
16
-
17
- ```ruby
18
- gem 'nice_hash'
19
- ```
20
-
21
- And then execute:
22
-
23
- $ bundle
24
-
25
- Or install it yourself as:
26
-
27
- $ gem install nice_hash
28
-
29
- ## Usage
30
-
31
- Remember!! To generate the strings following a pattern take a look at the documentation for string_pattern gem: https://github.com/MarioRuiz/string_pattern
32
-
33
- This is he Hash we will be using on our examples:
34
-
35
- ```ruby
36
-
37
- require 'nice_hash'
38
-
39
- my_hash={
40
- loginame: :"5-10:/xn/",
41
- [:pwd1, :pwd2, :pwd3] => :"5-10:L/n/",
42
- name: :"10-20:T_/x/",
43
- draws: [
44
- {
45
- drawId: :"5:N",
46
- drawName: :"10:Ln",
47
- type: :"Weekely|Daily",
48
- owner: {
49
- default: 'admin',
50
- correct: :"20:L"
51
- }
52
- },
53
- {
54
- drawId: :"5:N",
55
- drawName: :"10:Ln",
56
- type: :"Weekely|Daily",
57
- owner: {
58
- default: 'admin',
59
- correct: :"20:L"
60
- }
61
- }
62
- ],
63
- zip: {default: '00000', correct: :'5:N'},
64
- address: "21 Doom Av",
65
- city: {
66
- default: "Madrid",
67
- correct: "London|Rome"
68
- },
69
- wagers: ['34AAB', 'dfffDD', '33499A'],
70
- country: {default: 'Spain', correct: ["Spain", "Iceland", "Serbia", "Denmark", "Canada", "Italy", "Austria"].join("|")}, #one of these values
71
- mobilePhone: {default: '(987)654321', correct: ['(', :'3:N', ')', :'6-8:N']},
72
- sex: :"male|female", #any of these values
73
- display: true
74
- }
75
- ```
76
-
77
- Explanations of the different fields:
78
-
79
- loginname: from 5 to 10 characters, mandatory to have lower letters and numbers
80
- pwd, pwd2, pwd3: will have the same value. The value from 5 to 10 chars, optional capital and lower letters, necessary to contain numbers
81
- name: from 10 to 20 chars. Optional national characters and space, necessary lower letters.
82
- drawId: 5 numbers
83
- drawName: 10 letters and/or numbers
84
- type: 'Weekely' or 'Daily'
85
- owner: correct: 20 letters
86
- zip: correct: 5 numbers
87
- city: correct: 'London' or 'Rome'
88
- country: correct: one of these values "Spain", "Iceland", "Serbia", "Denmark", "Canada", "Italy", "Austria"
89
- mobilePhone: correct: a sting pattern with one of the next: "(nnn) nnnnnn", "(nnn) nnnnnnn", "(nnn) nnnnnnnn"
90
- sex: 'male' or 'female'
91
-
92
- So in case you want to assign to a key a string pattern value like for example in loginame, you need to specify the string pattern as a symbol :"5-10:/xn/"
93
-
94
- You can also supply an array of strings and string patterns, like on mobilePhone.correct: ['(', :'3:N', ')', :'6-8:N']}
95
-
96
- Also you can specify to select one of the values you want by separating them with |, like for example on sex field: "male|female"
97
-
98
- ### How to access the different keys
99
-
100
- You can access the keys of the hash like always, but now we added to the Hash class the posibility of accessing it using:
101
-
102
- ```ruby
103
- puts my_hash[:address] # like usually is done
104
- puts my_hash.address
105
- my_hash.address = '99 Danish Street' #assignment
106
- puts my_hash.loginame
107
- puts my_hash.mobilePhone.correct
108
- puts my_hash.draws[1].owner.correct
109
- ```
110
- Also another way to access the different keys is by adding first underscore.
111
- By doing it this way we are avoiding the cases where already exists a method with the same name on Hash class, for example: zip, display, default, select...
112
-
113
- ```ruby
114
- puts my_hash._address
115
- my_hash._address = '99 Danish Street' #assignment
116
- my_hash._display = false #assignment
117
- puts my_hash._loginame
118
- puts my_hash._mobilePhone._correct
119
- puts my_hash._draws[1]._owner._correct
120
- puts my_hash._zip.correct #you can mix both also
121
- ```
122
-
123
- By using the string_pattern gem you can generate single strings following the specific pattern on the field:
124
-
125
- ```ruby
126
- puts my_hash.loginame.generate #>s93owuvkh
127
- puts my_hash.mobilePhone.correct.generate #>(039)5669558
128
- puts my_hash._zip._correct.gen # gen is an alias for generate method #>84584
129
- ```
130
-
131
- ### Filtering / Selecting an specific key on the hash and subhashes
132
-
133
- In case you supply different possibilities to be used like for example on fields: owner, zip, city and mobilePhone, and you one to use a concrete one, use the method select_key
134
-
135
- ```ruby
136
- #using NiceHash class
137
- new_hash = NiceHash.select_key(my_hash, :correct)
138
- #using select_key method on Hash class
139
- new_hash = my_hash.select_key(:correct)
140
- default_hash = my_hash.select_key(:default)
141
- ```
142
-
143
- On this example new_hash will contain:
144
-
145
- ```ruby
146
- {
147
- loginame: :"5-10:/xn/",
148
- [:pwd1, :pwd2, :pwd3] => :"5-10:L/n/",
149
- name: :"10-20:T_/x/",
150
- draws: [
151
- {
152
- drawId: :"5:N",
153
- drawName: :"10:Ln",
154
- type: :"Weekely|Daily",
155
- owner: :"20:L"
156
- },
157
- {
158
- drawId: :"5:N",
159
- drawName: :"10:Ln",
160
- type: :"Weekely|Daily",
161
- owner: :"20:L"
162
- }
163
- ],
164
- zip: :'5:N',
165
- address: "21 Doom Av",
166
- city: "London|Rome",
167
- wagers: ['34AAB', 'dfffDD', '33499A'],
168
- country: ["Spain", "Iceland", "Serbia", "Denmark", "Canada", "Italy", "Austria"].join("|"), #one of these values
169
- mobilePhone: ['(', :'3:N', ')', :'6-8:N'],
170
- sex: :"male|female", #any of these values
171
- display: true
172
- }
173
- ```
174
-
175
- ### How to generate the hash with the criteria we want
176
-
177
- You can use the 'generate' method and everytime will be generated a different hash with different values.
178
-
179
- Remember you can filter/select by a hash key
180
-
181
- Using the NiceHash class:
182
- ```ruby
183
- #without filtering
184
- new_hash = NiceHash.generate(my_hash)
185
- #filtering by a key passing the key on parameters
186
- new_hash = NiceHash.generate(my_hash, :correct)
187
- ```
188
-
189
- Using Hash class (you can use the alias 'gen' for 'generate'):
190
- ```ruby
191
- #without filtering
192
- new_hash = my_hash.generate
193
- #filtering by a key passing the key on parameters
194
- new_hash = my_hash.generate(:correct)
195
- #filtering by a key using select_key method
196
- new_hash = my_hash.select_key(:correct).generate
197
- ```
198
-
199
-
200
- In case of filtering by :correct new_hash would have a value like this for example:
201
-
202
- ```ruby
203
- {:loginame=>"s45x029o",
204
- :pwd1=>"E6hz9YS7",
205
- :pwd2=>"E6hz9YS7",
206
- :pwd3=>"E6hz9YS7",
207
- :name=>"OyTQNfEyPOzVYMxPym",
208
- :draws=>
209
- [{:drawId=>"54591",
210
- :drawName=>"cr5Q7pq4G8",
211
- :type=>"Weekely",
212
- :owner=>"nKEasYWInPGJxxElBZUB"},
213
- {:drawId=>"73307",
214
- :drawName=>"FnHPM4CsRC",
215
- :type=>"Weekely",
216
- :owner=>"cNGpHDhDLcxSFbOGqvNy"}],
217
- :zip=>"47537",
218
- :address=>"21 Doom Av",
219
- :city=>"London",
220
- :wagers=>["34AAB", "dfffDD", "33499A"],
221
- :country=>"Denmark",
222
- :mobilePhone=>"(707)8782080",
223
- :sex=>"male",
224
- :display=>true}
225
- ```
226
-
227
- In case no filtering you will get all the values for all keys
228
-
229
- ### How to generate the hash with wrong values for the string patterns specified on the hash
230
-
231
- We can generate wrong values passing the keyword argument: expected_errors (alias: errors)
232
-
233
- The possible values you can specify is one or more of these ones: :length, :min_length, :max_length, :value, :required_data, :excluded_data, :string_set_not_allowed
234
-
235
- :length: wrong length, minimum or maximum
236
- :min_length: wrong minimum length
237
- :max_length: wrong maximum length
238
- :value: wrong resultant value
239
- :required_data: the output string won't include all necessary required data. It works only if required data supplied on the pattern.
240
- :excluded_data: the resultant string will include one or more characters that should be excluded. It works only if excluded data supplied on the pattern.
241
- :string_set_not_allowed: it will include one or more characters that are not supposed to be on the string.
242
-
243
- Examples:
244
-
245
- ```ruby
246
- wrong_values = my_hash.generate(:correct, expected_errors: [:value])
247
-
248
- wrong_max_length = my_hash.generate(:correct, errors: :max_length)
249
-
250
- wrong_min_length = my_hash.generate(:correct, expected_errors: :min_length)
251
-
252
- wrong_min_length = my_hash.select_key(:correct).generate(errors: :min_length)
253
-
254
- valid_values = my_hash.generate(:correct)
255
- ```
256
-
257
- On this example wrong_min_length will contain something like:
258
-
259
- ```ruby
260
- {:loginame=>"0u",
261
- :pwd1=>"4XDx",
262
- :pwd2=>"4XDx",
263
- :pwd3=>"4XDx",
264
- :name=>"bU",
265
- :draws=>
266
- [{:drawId=>"", :drawName=>"P03AgdMqV", :type=>"Dail", :owner=>"dYzLRMCnVc"},
267
- {:drawId=>"", :drawName=>"qw", :type=>"Dail", :owner=>"zkHhTEzM"}],
268
- :zip=>"7168",
269
- :address=>"21 Doom Av",
270
- :city=>"Rom",
271
- :wagers=>["34AAB", "dfffDD", "33499A"],
272
- :country=>"Spai",
273
- :mobilePhone=>"(237)17640431",
274
- :sex=>"mal",
275
- :display=>true}
276
- ```
277
-
278
- ### Return the select_fields or the pattern_fields
279
-
280
- If you need a list of select fields or pattern fields that exist on your hash you can use the methods: select_fields and pattern_fields
281
-
282
- It will return an array with all the fields found. On every entry of the array you will see keys to the field.
283
-
284
- ```ruby
285
- all_select_fields = my_hash.select_fields
286
- select_fields_on_correct = my_hash.select_fields(:correct)
287
-
288
- all_pattern_fields = my_hash.pattern_fields
289
- pattern_fields_on_correct = my_hash.pattern_fields(:correct)
290
- ```
291
-
292
- all_select_fields contains:
293
-
294
- ```ruby
295
- [[:draws, 0, :type],
296
- [:draws, 1, :type],
297
- [:city, :correct],
298
- [:country, :correct],
299
- [:sex]]
300
- ```
301
-
302
- select_fields_on_correct contains:
303
-
304
- ```ruby
305
- [[:draws, 0, :type],
306
- [:draws, 1, :type],
307
- [:city],
308
- [:country],
309
- [:sex]]
310
- ```
311
-
312
- all_pattern_fields contains:
313
-
314
- ```ruby
315
- [[:loginame],
316
- [[:pwd1, :pwd2, :pwd3]],
317
- [:name],
318
- [:draws, 0, :drawId],
319
- [:draws, 0, :drawName],
320
- [:draws, 0, :owner, :correct],
321
- [:draws, 1, :drawId],
322
- [:draws, 1, :drawName],
323
- [:draws, 1, :owner, :correct],
324
- [:zip, :correct],
325
- [:mobilePhone, :correct]]
326
- ```
327
-
328
- pattern_fields_on_correct contains:
329
-
330
- ```ruby
331
- [[:loginame],
332
- [[:pwd1, :pwd2, :pwd3]],
333
- [:name],
334
- [:draws, 0, :drawId],
335
- [:draws, 0, :drawName],
336
- [:draws, 0, :owner],
337
- [:draws, 1, :drawId],
338
- [:draws, 1, :drawName],
339
- [:draws, 1, :owner],
340
- [:zip],
341
- [:mobilePhone]]
342
- ```
343
-
344
-
345
- #### dig and bury Hash methods
346
- In case you want to access the values on a hash structure by using the key array location, you can use the 'dig' method on the Hash class:
347
-
348
- ```ruby
349
- min_length_error = my_hash.generate :correct, errors: :min_length
350
-
351
- patterns = my_hash.pattern_fields :correct
352
-
353
- patterns.each{|key|
354
- if key[0].kind_of?(Array) # same values, like in pwd1, pwd2 and pwd3
355
- puts "#{key} same values"
356
- value = min_length_error.dig(key[0][0])
357
- else
358
- value = min_length_error.dig(*key)
359
- end
360
-
361
- pattern = my_hash.select_key(:correct).dig(*key)
362
- puts "the value: '#{value}' was generated from the key: #{key} with pattern: #{pattern}"
363
- }
364
- ```
365
-
366
- This returns something like:
367
-
368
- ```
369
- the value: '5z' was generated from the key: [:loginame] with pattern: 5-10:/xn/
370
- [[:pwd1, :pwd2, :pwd3]] same values
371
- the value: '5' was generated from the key: [[:pwd1, :pwd2, :pwd3]] with pattern: 5-10:L/n/
372
- the value: 'KshiYAmp' was generated from the key: [:name] with pattern: 10-20:T_/x/
373
- the value: '722' was generated from the key: [:draws, 0, :drawId] with pattern: 5:N
374
- the value: '4' was generated from the key: [:draws, 0, :drawName] with pattern: 10:Ln
375
- the value: 'jhVZkII' was generated from the key: [:draws, 0, :owner] with pattern: 20:L
376
- the value: '260' was generated from the key: [:draws, 1, :drawId] with pattern: 5:N
377
- the value: 'ssty8hlnJ' was generated from the key: [:draws, 1, :drawName] with pattern: 10:Ln
378
- the value: 'zPvcwOyyXvWSgNHsuv' was generated from the key: [:draws, 1, :owner] with pattern: 20:L
379
- the value: '242' was generated from the key: [:zip] with pattern: 5:N
380
- the value: '(91)7606' was generated from the key: [:mobilePhone] with pattern: ["(", :"3:N", ")", :"6-8:N"]
381
- ```
382
-
383
- Ruby Hash class doesn't have a method to allocate a value using the key array location so we added to Hash class a method for that purpose, the 'bury' method.
384
-
385
- ```ruby
386
- default_values = my_hash.generate :default
387
-
388
- default_values.bury([:draws, 0, :drawName], "FirstDraw")
389
- ```
390
-
391
- After using the bury method default_values will contain:
392
-
393
- ```ruby
394
- {:loginame=>"i0v2jy",
395
- :pwd1=>"x33exx",
396
- :pwd2=>"x33exx",
397
- :pwd3=>"x33exx",
398
- :name=>"HdmsjLxlEgYIFY",
399
- :draws=>
400
- [{:drawId=>"12318",
401
- :drawName=>"FirstDraw",
402
- :type=>"Weekely",
403
- :owner=>"admin"},
404
- {:drawId=>"18947",
405
- :drawName=>"LPgf2ZQvkG",
406
- :type=>"Weekely",
407
- :owner=>"admin"}],
408
- :zip=>"00000",
409
- :address=>"21 Doom Av",
410
- :city=>"Madrid",
411
- :wagers=>["34AAB", "dfffDD", "33499A"],
412
- :country=>"Spain",
413
- :mobilePhone=>"(987)654321",
414
- :sex=>"male",
415
- :display=>true}
416
- ```
417
-
418
- ### Validating hashes
419
-
420
- If you have a Hash that should follow the patterns you specified (in this example declared on my_hash) and you want to validate, then use the 'validate' method.
421
-
422
- This is particulary useful to test REST APIs responses in JSON
423
-
424
- If we have a hash with these values:
425
-
426
- ```ruby
427
- {:loginame=>"rdewvqur",
428
- :pwd1=>"d3ulo",
429
- :pwd2=>"d3ulo",
430
- :pwd3=>"d3ulo",
431
- :name=>"LTqVKxxFCTqpkdjFkxU",
432
- :draws=>
433
- [{:drawId=>"54a43",
434
- :drawName=>"h3F24yjMWp",
435
- :type=>"Daily",
436
- :owner=>"abIZMRxTDsWjQcpdspZt"},
437
- {:drawId=>"13010",
438
- :drawName=>"NurCEAtE1M",
439
- :type=>"Daily",
440
- :owner=>"vSVoqtSzHkbvRNyJoYGz"}],
441
- :zip=>"30222",
442
- :address=>"21 Doom Av",
443
- :city=>"New York",
444
- :wagers=>["34AAB", "dfffDD", "33499A"],
445
- :country=>"Iceland",
446
- :mobilePhone=>"(441)97037845",
447
- :sex=>"male",
448
- :display=>true}
449
- ```
450
-
451
- To validate those values taking in consideration was is stated on my_hash:
452
-
453
- ```ruby
454
- results_all_fields = my_hash.validate :correct, values
455
-
456
- results_pattern_fields = my_hash.validate_patterns :correct, values
457
- ```
458
-
459
- results_all_fields will contain all the validation errors:
460
-
461
- ```ruby
462
- {:loginame=>[:value, :required_data],
463
- :draws=>[{:drawId=>[:value, :string_set_not_allowed]}],
464
- :city=>false}
465
- ```
466
-
467
- and results_pattern_fields will contain only the validation errors for the fields containing patterns:
468
-
469
- ```ruby
470
- {:loginame=>[:value, :required_data],
471
- :draws=>[{:drawId=>[:value, :string_set_not_allowed]}]}
472
- ```
473
-
474
- The possible validation values returned:
475
-
476
- :length: wrong length, minimum or maximum
477
- :min_length: wrong minimum length
478
- :max_length: wrong maximum length
479
- :value: wrong resultant value
480
- :required_data: the output string won't include all necessary required data. It works only if required data supplied on the pattern.
481
- :excluded_data: the resultant string will include one or more characters that should be excluded. It works only if excluded data supplied on the pattern.
482
- :string_set_not_allowed: it will include one or more characters that are not supposed to be on the string.
483
-
484
-
485
- ### Change only one value at a time and return an Array of Hashes
486
-
487
- Let's guess we need to test a typical registration REST service and the service has many fields with many validations but we want to test it one field at a time.
488
-
489
- Then the best thing you can do is to use the method NiceHash.change_one_by_one.
490
-
491
-
492
- ```ruby
493
-
494
- wrong_min_length_hash = my_hash.generate(:correct, errors: :min_length)
495
-
496
- array_of_hashes = NiceHash.change_one_by_one([my_hash, :correct], wrong_min_length_hash)
497
-
498
- array_of_hashes.each {|hash_with_one_wrong_field|
499
- #Here your code to send through http the JSON data stored in hash_with_one_wrong_field
500
-
501
- #if you want to know which field is the one that is wrong:
502
- res = my_hash.validate(:correct, hash_with_one_wrong_field)
503
- }
504
- ```
505
-
506
- ## Contributing
507
-
508
- Bug reports and pull requests are welcome on GitHub at https://github.com/marioruiz/nice_hash.
509
-
510
-
511
- ## License
512
-
513
- The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
514
-
515
-
1
+ # NiceHash
2
+
3
+ [![Gem Version](https://badge.fury.io/rb/nice_hash.svg)](https://rubygems.org/gems/nice_hash)
4
+
5
+ NiceHash creates hashes following certain patterns so your testing will be much easier.
6
+
7
+ You can easily generates all the hashes you want following the criteria you specify.
8
+
9
+ Many other features coming to Hash class like the methods 'bury' or select_key, access the keys like methods: my_hash.my_key.other_key. You will be able to generate thousands of different hashes just declaring one and test easily APIs based on JSON for example.
10
+
11
+ To generate the strings following a pattern take a look at the documentation for string_pattern gem: https://github.com/MarioRuiz/string_pattern
12
+
13
+ ## Installation
14
+
15
+ Add this line to your application's Gemfile:
16
+
17
+ ```ruby
18
+ gem 'nice_hash'
19
+ ```
20
+
21
+ And then execute:
22
+
23
+ $ bundle
24
+
25
+ Or install it yourself as:
26
+
27
+ $ gem install nice_hash
28
+
29
+ ## Usage
30
+
31
+ Remember!! To generate the strings following a pattern take a look at the documentation for string_pattern gem: https://github.com/MarioRuiz/string_pattern
32
+
33
+ This is he Hash we will be using on our examples:
34
+
35
+ ```ruby
36
+
37
+ require 'nice_hash'
38
+
39
+ my_hash={
40
+ loginame: :"5-10:/xn/",
41
+ [:pwd1, :pwd2, :pwd3] => :"5-10:L/n/",
42
+ name: :"10-20:T_/x/",
43
+ draws: [
44
+ {
45
+ drawId: :"5:N",
46
+ drawName: :"10:Ln",
47
+ type: :"Weekely|Daily",
48
+ owner: {
49
+ default: 'admin',
50
+ correct: :"20:L"
51
+ }
52
+ },
53
+ {
54
+ drawId: :"5:N",
55
+ drawName: :"10:Ln",
56
+ type: :"Weekely|Daily",
57
+ owner: {
58
+ default: 'admin',
59
+ correct: :"20:L"
60
+ }
61
+ }
62
+ ],
63
+ zip: {default: '00000', correct: :'5:N'},
64
+ address: "21 Doom Av",
65
+ city: {
66
+ default: "Madrid",
67
+ correct: "London|Rome"
68
+ },
69
+ wagers: ['34AAB', 'dfffDD', '33499A'],
70
+ country: {default: 'Spain', correct: ["Spain", "Iceland", "Serbia", "Denmark", "Canada", "Italy", "Austria"].join("|")}, #one of these values
71
+ mobilePhone: {default: '(987)654321', correct: ['(', :'3:N', ')', :'6-8:N']},
72
+ sex: :"male|female|other", #any of these values
73
+ display: true
74
+ }
75
+ ```
76
+
77
+ Explanations of the different fields:
78
+
79
+ loginname: from 5 to 10 characters, mandatory to have lower letters and numbers
80
+ pwd, pwd2, pwd3: will have the same value. The value from 5 to 10 chars, optional capital and lower letters, necessary to contain numbers
81
+ name: from 10 to 20 chars. Optional national characters and space, necessary lower letters.
82
+ drawId: 5 numbers
83
+ drawName: 10 letters and/or numbers
84
+ type: 'Weekely' or 'Daily'
85
+ owner: correct: 20 letters
86
+ zip: correct: 5 numbers
87
+ city: correct: 'London' or 'Rome'
88
+ country: correct: one of these values "Spain", "Iceland", "Serbia", "Denmark", "Canada", "Italy", "Austria"
89
+ mobilePhone: correct: a sting pattern with one of the next: "(nnn) nnnnnn", "(nnn) nnnnnnn", "(nnn) nnnnnnnn"
90
+ sex: 'male' or 'female' or 'other'
91
+
92
+ So in case you want to assign to a key a string pattern value like for example in loginame, you need to specify the string pattern as a symbol :"5-10:/xn/"
93
+
94
+ You can also supply an array of strings and string patterns, like on mobilePhone.correct: ['(', :'3:N', ')', :'6-8:N']}
95
+
96
+ Also you can specify to select one of the values you want by separating them with |, like for example on sex field: "male|female|other"
97
+
98
+ ### How to access the different keys
99
+
100
+ You can access the keys of the hash like always, but now we added to the Hash class the posibility of accessing it using:
101
+
102
+ ```ruby
103
+ puts my_hash[:address] # like usually is done
104
+ puts my_hash.address
105
+ my_hash.address = '99 Danish Street' #assignment
106
+ puts my_hash.loginame
107
+ puts my_hash.mobilePhone.correct
108
+ puts my_hash.draws[1].owner.correct
109
+ ```
110
+ Also another way to access the different keys is by adding first underscore.
111
+ By doing it this way we are avoiding the cases where already exists a method with the same name on Hash class, for example: zip, display, default, select...
112
+
113
+ ```ruby
114
+ puts my_hash._address
115
+ my_hash._address = '99 Danish Street' #assignment
116
+ my_hash._display = false #assignment
117
+ puts my_hash._loginame
118
+ puts my_hash._mobilePhone._correct
119
+ puts my_hash._draws[1]._owner._correct
120
+ puts my_hash._zip.correct #you can mix both also
121
+ ```
122
+
123
+ By using the string_pattern gem you can generate single strings following the specific pattern on the field:
124
+
125
+ ```ruby
126
+ puts my_hash.loginame.generate #>s93owuvkh
127
+ puts my_hash.mobilePhone.correct.generate #>(039)5669558
128
+ puts my_hash._zip._correct.gen # gen is an alias for generate method #>84584
129
+ ```
130
+
131
+ ### Filtering / Selecting an specific key on the hash and subhashes
132
+
133
+ In case you supply different possibilities to be used like for example on fields: owner, zip, city and mobilePhone, and you one to use a concrete one, use the method select_key
134
+
135
+ ```ruby
136
+ #using NiceHash class
137
+ new_hash = NiceHash.select_key(my_hash, :correct)
138
+ #using select_key method on Hash class
139
+ new_hash = my_hash.select_key(:correct)
140
+ default_hash = my_hash.select_key(:default)
141
+ ```
142
+
143
+ On this example new_hash will contain:
144
+
145
+ ```ruby
146
+ {
147
+ loginame: :"5-10:/xn/",
148
+ [:pwd1, :pwd2, :pwd3] => :"5-10:L/n/",
149
+ name: :"10-20:T_/x/",
150
+ draws: [
151
+ {
152
+ drawId: :"5:N",
153
+ drawName: :"10:Ln",
154
+ type: :"Weekely|Daily",
155
+ owner: :"20:L"
156
+ },
157
+ {
158
+ drawId: :"5:N",
159
+ drawName: :"10:Ln",
160
+ type: :"Weekely|Daily",
161
+ owner: :"20:L"
162
+ }
163
+ ],
164
+ zip: :'5:N',
165
+ address: "21 Doom Av",
166
+ city: "London|Rome",
167
+ wagers: ['34AAB', 'dfffDD', '33499A'],
168
+ country: ["Spain", "Iceland", "Serbia", "Denmark", "Canada", "Italy", "Austria"].join("|"), #one of these values
169
+ mobilePhone: ['(', :'3:N', ')', :'6-8:N'],
170
+ sex: :"male|female|other", #any of these values
171
+ display: true
172
+ }
173
+ ```
174
+
175
+ ### How to generate the hash with the criteria we want
176
+
177
+ You can use the 'generate' method and everytime will be generated a different hash with different values.
178
+
179
+ Remember you can filter/select by a hash key
180
+
181
+ Using the NiceHash class:
182
+ ```ruby
183
+ #without filtering
184
+ new_hash = NiceHash.generate(my_hash)
185
+ #filtering by a key passing the key on parameters
186
+ new_hash = NiceHash.generate(my_hash, :correct)
187
+ ```
188
+
189
+ Using Hash class (you can use the alias 'gen' for 'generate'):
190
+ ```ruby
191
+ #without filtering
192
+ new_hash = my_hash.generate
193
+ #filtering by a key passing the key on parameters
194
+ new_hash = my_hash.generate(:correct)
195
+ #filtering by a key using select_key method
196
+ new_hash = my_hash.select_key(:correct).generate
197
+ ```
198
+
199
+
200
+ In case of filtering by :correct new_hash would have a value like this for example:
201
+
202
+ ```ruby
203
+ {:loginame=>"s45x029o",
204
+ :pwd1=>"E6hz9YS7",
205
+ :pwd2=>"E6hz9YS7",
206
+ :pwd3=>"E6hz9YS7",
207
+ :name=>"OyTQNfEyPOzVYMxPym",
208
+ :draws=>
209
+ [{:drawId=>"54591",
210
+ :drawName=>"cr5Q7pq4G8",
211
+ :type=>"Weekely",
212
+ :owner=>"nKEasYWInPGJxxElBZUB"},
213
+ {:drawId=>"73307",
214
+ :drawName=>"FnHPM4CsRC",
215
+ :type=>"Weekely",
216
+ :owner=>"cNGpHDhDLcxSFbOGqvNy"}],
217
+ :zip=>"47537",
218
+ :address=>"21 Doom Av",
219
+ :city=>"London",
220
+ :wagers=>["34AAB", "dfffDD", "33499A"],
221
+ :country=>"Denmark",
222
+ :mobilePhone=>"(707)8782080",
223
+ :sex=>"male",
224
+ :display=>true}
225
+ ```
226
+
227
+ In case no filtering you will get all the values for all keys
228
+
229
+ ### How to generate the hash with wrong values for the string patterns specified on the hash
230
+
231
+ We can generate wrong values passing the keyword argument: expected_errors (alias: errors)
232
+
233
+ The possible values you can specify is one or more of these ones: :length, :min_length, :max_length, :value, :required_data, :excluded_data, :string_set_not_allowed
234
+
235
+ :length: wrong length, minimum or maximum
236
+ :min_length: wrong minimum length
237
+ :max_length: wrong maximum length
238
+ :value: wrong resultant value
239
+ :required_data: the output string won't include all necessary required data. It works only if required data supplied on the pattern.
240
+ :excluded_data: the resultant string will include one or more characters that should be excluded. It works only if excluded data supplied on the pattern.
241
+ :string_set_not_allowed: it will include one or more characters that are not supposed to be on the string.
242
+
243
+ Examples:
244
+
245
+ ```ruby
246
+ wrong_values = my_hash.generate(:correct, expected_errors: [:value])
247
+
248
+ wrong_max_length = my_hash.generate(:correct, errors: :max_length)
249
+
250
+ wrong_min_length = my_hash.generate(:correct, expected_errors: :min_length)
251
+
252
+ wrong_min_length = my_hash.select_key(:correct).generate(errors: :min_length)
253
+
254
+ valid_values = my_hash.generate(:correct)
255
+ ```
256
+
257
+ On this example wrong_min_length will contain something like:
258
+
259
+ ```ruby
260
+ {:loginame=>"0u",
261
+ :pwd1=>"4XDx",
262
+ :pwd2=>"4XDx",
263
+ :pwd3=>"4XDx",
264
+ :name=>"bU",
265
+ :draws=>
266
+ [{:drawId=>"", :drawName=>"P03AgdMqV", :type=>"Dail", :owner=>"dYzLRMCnVc"},
267
+ {:drawId=>"", :drawName=>"qw", :type=>"Dail", :owner=>"zkHhTEzM"}],
268
+ :zip=>"7168",
269
+ :address=>"21 Doom Av",
270
+ :city=>"Rom",
271
+ :wagers=>["34AAB", "dfffDD", "33499A"],
272
+ :country=>"Spai",
273
+ :mobilePhone=>"(237)17640431",
274
+ :sex=>"mal",
275
+ :display=>true}
276
+ ```
277
+
278
+ ### Return the select_fields or the pattern_fields
279
+
280
+ If you need a list of select fields or pattern fields that exist on your hash you can use the methods: select_fields and pattern_fields
281
+
282
+ It will return an array with all the fields found. On every entry of the array you will see keys to the field.
283
+
284
+ ```ruby
285
+ all_select_fields = my_hash.select_fields
286
+ select_fields_on_correct = my_hash.select_fields(:correct)
287
+
288
+ all_pattern_fields = my_hash.pattern_fields
289
+ pattern_fields_on_correct = my_hash.pattern_fields(:correct)
290
+ ```
291
+
292
+ all_select_fields contains:
293
+
294
+ ```ruby
295
+ [[:draws, 0, :type],
296
+ [:draws, 1, :type],
297
+ [:city, :correct],
298
+ [:country, :correct],
299
+ [:sex]]
300
+ ```
301
+
302
+ select_fields_on_correct contains:
303
+
304
+ ```ruby
305
+ [[:draws, 0, :type],
306
+ [:draws, 1, :type],
307
+ [:city],
308
+ [:country],
309
+ [:sex]]
310
+ ```
311
+
312
+ all_pattern_fields contains:
313
+
314
+ ```ruby
315
+ [[:loginame],
316
+ [[:pwd1, :pwd2, :pwd3]],
317
+ [:name],
318
+ [:draws, 0, :drawId],
319
+ [:draws, 0, :drawName],
320
+ [:draws, 0, :owner, :correct],
321
+ [:draws, 1, :drawId],
322
+ [:draws, 1, :drawName],
323
+ [:draws, 1, :owner, :correct],
324
+ [:zip, :correct],
325
+ [:mobilePhone, :correct]]
326
+ ```
327
+
328
+ pattern_fields_on_correct contains:
329
+
330
+ ```ruby
331
+ [[:loginame],
332
+ [[:pwd1, :pwd2, :pwd3]],
333
+ [:name],
334
+ [:draws, 0, :drawId],
335
+ [:draws, 0, :drawName],
336
+ [:draws, 0, :owner],
337
+ [:draws, 1, :drawId],
338
+ [:draws, 1, :drawName],
339
+ [:draws, 1, :owner],
340
+ [:zip],
341
+ [:mobilePhone]]
342
+ ```
343
+
344
+
345
+ #### dig and bury Hash methods
346
+ In case you want to access the values on a hash structure by using the key array location, you can use the 'dig' method on the Hash class:
347
+
348
+ ```ruby
349
+ min_length_error = my_hash.generate :correct, errors: :min_length
350
+
351
+ patterns = my_hash.pattern_fields :correct
352
+
353
+ patterns.each{|key|
354
+ if key[0].kind_of?(Array) # same values, like in pwd1, pwd2 and pwd3
355
+ puts "#{key} same values"
356
+ value = min_length_error.dig(key[0][0])
357
+ else
358
+ value = min_length_error.dig(*key)
359
+ end
360
+
361
+ pattern = my_hash.select_key(:correct).dig(*key)
362
+ puts "the value: '#{value}' was generated from the key: #{key} with pattern: #{pattern}"
363
+ }
364
+ ```
365
+
366
+ This returns something like:
367
+
368
+ ```
369
+ the value: '5z' was generated from the key: [:loginame] with pattern: 5-10:/xn/
370
+ [[:pwd1, :pwd2, :pwd3]] same values
371
+ the value: '5' was generated from the key: [[:pwd1, :pwd2, :pwd3]] with pattern: 5-10:L/n/
372
+ the value: 'KshiYAmp' was generated from the key: [:name] with pattern: 10-20:T_/x/
373
+ the value: '722' was generated from the key: [:draws, 0, :drawId] with pattern: 5:N
374
+ the value: '4' was generated from the key: [:draws, 0, :drawName] with pattern: 10:Ln
375
+ the value: 'jhVZkII' was generated from the key: [:draws, 0, :owner] with pattern: 20:L
376
+ the value: '260' was generated from the key: [:draws, 1, :drawId] with pattern: 5:N
377
+ the value: 'ssty8hlnJ' was generated from the key: [:draws, 1, :drawName] with pattern: 10:Ln
378
+ the value: 'zPvcwOyyXvWSgNHsuv' was generated from the key: [:draws, 1, :owner] with pattern: 20:L
379
+ the value: '242' was generated from the key: [:zip] with pattern: 5:N
380
+ the value: '(91)7606' was generated from the key: [:mobilePhone] with pattern: ["(", :"3:N", ")", :"6-8:N"]
381
+ ```
382
+
383
+ Ruby Hash class doesn't have a method to allocate a value using the key array location so we added to Hash class a method for that purpose, the 'bury' method.
384
+
385
+ ```ruby
386
+ default_values = my_hash.generate :default
387
+
388
+ default_values.bury([:draws, 0, :drawName], "FirstDraw")
389
+ ```
390
+
391
+ After using the bury method default_values will contain:
392
+
393
+ ```ruby
394
+ {:loginame=>"i0v2jy",
395
+ :pwd1=>"x33exx",
396
+ :pwd2=>"x33exx",
397
+ :pwd3=>"x33exx",
398
+ :name=>"HdmsjLxlEgYIFY",
399
+ :draws=>
400
+ [{:drawId=>"12318",
401
+ :drawName=>"FirstDraw",
402
+ :type=>"Weekely",
403
+ :owner=>"admin"},
404
+ {:drawId=>"18947",
405
+ :drawName=>"LPgf2ZQvkG",
406
+ :type=>"Weekely",
407
+ :owner=>"admin"}],
408
+ :zip=>"00000",
409
+ :address=>"21 Doom Av",
410
+ :city=>"Madrid",
411
+ :wagers=>["34AAB", "dfffDD", "33499A"],
412
+ :country=>"Spain",
413
+ :mobilePhone=>"(987)654321",
414
+ :sex=>"male",
415
+ :display=>true}
416
+ ```
417
+
418
+ ### Validating hashes
419
+
420
+ If you have a Hash that should follow the patterns you specified (in this example declared on my_hash) and you want to validate, then use the 'validate' method.
421
+
422
+ This is particulary useful to test REST APIs responses in JSON
423
+
424
+ If we have a hash with these values:
425
+
426
+ ```ruby
427
+ {:loginame=>"rdewvqur",
428
+ :pwd1=>"d3ulo",
429
+ :pwd2=>"d3ulo",
430
+ :pwd3=>"d3ulo",
431
+ :name=>"LTqVKxxFCTqpkdjFkxU",
432
+ :draws=>
433
+ [{:drawId=>"54a43",
434
+ :drawName=>"h3F24yjMWp",
435
+ :type=>"Daily",
436
+ :owner=>"abIZMRxTDsWjQcpdspZt"},
437
+ {:drawId=>"13010",
438
+ :drawName=>"NurCEAtE1M",
439
+ :type=>"Daily",
440
+ :owner=>"vSVoqtSzHkbvRNyJoYGz"}],
441
+ :zip=>"30222",
442
+ :address=>"21 Doom Av",
443
+ :city=>"New York",
444
+ :wagers=>["34AAB", "dfffDD", "33499A"],
445
+ :country=>"Iceland",
446
+ :mobilePhone=>"(441)97037845",
447
+ :sex=>"male",
448
+ :display=>true}
449
+ ```
450
+
451
+ To validate those values taking in consideration was is stated on my_hash:
452
+
453
+ ```ruby
454
+ results_all_fields = my_hash.validate :correct, values
455
+
456
+ results_pattern_fields = my_hash.validate_patterns :correct, values
457
+ ```
458
+
459
+ results_all_fields will contain all the validation errors:
460
+
461
+ ```ruby
462
+ {:loginame=>[:value, :required_data],
463
+ :draws=>[{:drawId=>[:value, :string_set_not_allowed]}],
464
+ :city=>false}
465
+ ```
466
+
467
+ and results_pattern_fields will contain only the validation errors for the fields containing patterns:
468
+
469
+ ```ruby
470
+ {:loginame=>[:value, :required_data],
471
+ :draws=>[{:drawId=>[:value, :string_set_not_allowed]}]}
472
+ ```
473
+
474
+ The possible validation values returned:
475
+
476
+ :length: wrong length, minimum or maximum
477
+ :min_length: wrong minimum length
478
+ :max_length: wrong maximum length
479
+ :value: wrong resultant value
480
+ :required_data: the output string won't include all necessary required data. It works only if required data supplied on the pattern.
481
+ :excluded_data: the resultant string will include one or more characters that should be excluded. It works only if excluded data supplied on the pattern.
482
+ :string_set_not_allowed: it will include one or more characters that are not supposed to be on the string.
483
+
484
+
485
+ ### Change only one value at a time and return an Array of Hashes
486
+
487
+ Let's guess we need to test a typical registration REST service and the service has many fields with many validations but we want to test it one field at a time.
488
+
489
+ Then the best thing you can do is to use the method NiceHash.change_one_by_one.
490
+
491
+
492
+ ```ruby
493
+
494
+ wrong_min_length_hash = my_hash.generate(:correct, errors: :min_length)
495
+
496
+ array_of_hashes = NiceHash.change_one_by_one([my_hash, :correct], wrong_min_length_hash)
497
+
498
+ array_of_hashes.each {|hash_with_one_wrong_field|
499
+ #Here your code to send through http the JSON data stored in hash_with_one_wrong_field
500
+
501
+ #if you want to know which field is the one that is wrong:
502
+ res = my_hash.validate(:correct, hash_with_one_wrong_field)
503
+ }
504
+ ```
505
+
506
+ ## Contributing
507
+
508
+ Bug reports and pull requests are welcome on GitHub at https://github.com/marioruiz/nice_hash.
509
+
510
+
511
+ ## License
512
+
513
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
514
+
515
+