nice_hash 1.1.0 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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
+