nice_hash 1.8.0 → 1.8.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (7) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +4 -4
  3. data/LICENSE +21 -21
  4. data/README.md +654 -654
  5. data/lib/nice/hash/add_to_ruby.rb +263 -240
  6. data/lib/nice_hash.rb +720 -720
  7. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9b19675c206242087298496e99fc64cb6ebd813748885ed75b655a3e48aaf006
4
- data.tar.gz: a63d861a62fbd6abae7e85e674813f69f6f6a50f6913e674ca33b6873bbb9363
3
+ metadata.gz: afcd58615d2567b5e2d12e9b2702d589766e21ee49d59a39124938b6d4479525
4
+ data.tar.gz: 78256ced5fc9b5824304607840396c911ffb5f088f6176293fb7f0b52c3c1b93
5
5
  SHA512:
6
- metadata.gz: '049d6d04e49c2d73500084a0b74e63f0f70ad793330964ae19118f86801b2625bb60bf1277e993d3df0e6fb9900996d5a6ca71e0c8197d3f461a2d346eaee900'
7
- data.tar.gz: d226631ac37fc239cc12a6967efe8b22528097e67f1bb370643caeebe00853b7d2ac0c71ce7f793d328587e7471cd64267de9566d44d1cb746c4d0d51f7b4299
6
+ metadata.gz: b750b37f3f2c4401e30c3ce713e9e203161dda153b2a19ffcdbb71553a576c4b2e0a22a441d783a07ff39c2aeb0126f76e73da0d701b9a6b36d556d43005037e
7
+ data.tar.gz: 4920b321008e875fe86b939df83063f52d8b67bbb93dd4c7e1dd87b24c46616be1355a12964bf6aad9d93f9d3632e012e96869833bbaa29f20b17198cd6cd66e
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/LICENSE CHANGED
@@ -1,21 +1,21 @@
1
- MIT License
2
-
3
- Copyright (c) 2017 Mario Ruiz
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
1
+ MIT License
2
+
3
+ Copyright (c) 2017 Mario Ruiz
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md CHANGED
@@ -1,654 +1,654 @@
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 generate 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
- You can also parse and filter a json string very easily.
12
-
13
- To generate the strings following a pattern take a look at the documentation for string_pattern gem: https://github.com/MarioRuiz/string_pattern. We added support for generating strings from regular expressions but it is only working for the ´generate´ method, use it with caution since it is still on an early stage of development.
14
-
15
- To use nice_hash on Http connections take a look at nice_http gem: https://github.com/MarioRuiz/nice_http
16
-
17
- ## Installation
18
-
19
- Add this line to your application's Gemfile:
20
-
21
- ```ruby
22
- gem 'nice_hash'
23
- ```
24
-
25
- And then execute:
26
-
27
- $ bundle
28
-
29
- Or install it yourself as:
30
-
31
- $ gem install nice_hash
32
-
33
- ## Usage
34
-
35
- Remember!! To generate the strings following a pattern take a look at the documentation for string_pattern gem: https://github.com/MarioRuiz/string_pattern. We added support for generating strings from regular expressions but it is only working for the ´generate´ method, use it with caution since it is still on an early stage of development. All you have to do is to add to a key the value as a Regular expression, for example the key uuid in here will generate a random value like this: "E0BDE5B5-A738-49E6-83C1-9D1FFB313788"
36
-
37
- ´´´ruby
38
- my_hash = {
39
- uuid: /[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}/,
40
- key: "Wsdf88888",
41
- doomId: :"10:N"
42
- }
43
- ´´´
44
-
45
- This is the Hash we will be using on our examples:
46
-
47
- ```ruby
48
-
49
- require 'nice_hash'
50
-
51
- my_hash={
52
- loginame: :"5-10:/xn/",
53
- [:pwd1, :pwd2, :pwd3] => :"5-10:L/n/",
54
- name: :"10-20:T_/x/",
55
- draws: [
56
- {
57
- drawId: :"5:N",
58
- drawName: :"10:Ln",
59
- type: :"Weekely|Daily",
60
- owner: {
61
- default: 'admin',
62
- correct: :"20:L"
63
- }
64
- },
65
- {
66
- drawId: :"5:N",
67
- drawName: :"10:Ln",
68
- type: :"Weekely|Daily",
69
- owner: {
70
- default: 'admin',
71
- correct: :"20:L"
72
- }
73
- }
74
- ],
75
- zip: {default: '00000', correct: :'5:N'},
76
- address: "21 Doom Av",
77
- city: {
78
- default: "Madrid",
79
- correct: "London|Rome"
80
- },
81
- wagers: ['34AAB', 'dfffDD', '33499A'],
82
- country: {default: 'Spain', correct: ["Spain", "Iceland", "Serbia", "Denmark", "Canada", "Italy", "Austria"].join("|")}, #one of these values
83
- mobilePhone: {default: '(987)654321', correct: ['(', :'3:N', ')', :'6-8:N']},
84
- sex: :"male|female|other", #any of these values
85
- display: true
86
- }
87
- ```
88
-
89
- Explanations of the different fields:
90
-
91
- loginname: from 5 to 10 characters, mandatory to have lower letters and numbers
92
- pwd, pwd2, pwd3: will have the same value. The value from 5 to 10 chars, optional capital and lower letters, necessary to contain numbers
93
- name: from 10 to 20 chars. Optional national characters and space, necessary lower letters.
94
- drawId: 5 numbers
95
- drawName: 10 letters and/or numbers
96
- type: 'Weekely' or 'Daily'
97
- owner: correct: 20 letters
98
- zip: correct: 5 numbers
99
- city: correct: 'London' or 'Rome'
100
- country: correct: one of these values "Spain", "Iceland", "Serbia", "Denmark", "Canada", "Italy", "Austria"
101
- mobilePhone: correct: a sting pattern with one of the next: "(nnn) nnnnnn", "(nnn) nnnnnnn", "(nnn) nnnnnnnn"
102
- sex: 'male' or 'female' or 'other'
103
-
104
- 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/"
105
-
106
- You can also supply an array of strings and string patterns, like on mobilePhone.correct: ['(', :'3:N', ')', :'6-8:N']}
107
-
108
- 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"
109
-
110
- In case you want one pattern to be generated with unique values, so never repeat the same value for that particular pattern, use a symbol object pattern and add to the end of the pattern the symbol: &
111
-
112
- ```ruby
113
-
114
- loginame: :"5-10:/xn/&",
115
-
116
- ```
117
-
118
- Also if you have a JSON string you want to parse it and get the values of certain keys you can use the json method we added to nice_hash:
119
-
120
- ```ruby
121
- my_json_string="{\"id\":344,\"customer\":{\"name\":\"Peter Smith\",\"phone\":334334333},\"tickets\":[{\"idt\":345,\"name\":\"myFavor1\"},{\"idt\":3123},{\"idt\":3145,\"name\":\"Special ticket\"}]}"
122
- puts my_json_string.json(:idt)
123
- #> [345, 3123, 3145]
124
-
125
- puts my_json_string.json(:idt, :name)
126
- #> {:name=>["Peter Smith", ["myFavor1", "Special ticket"]], :idt=>[345, 3123, 3145]}
127
- ```
128
-
129
- ### How to access the different keys
130
-
131
- You can access the keys of the hash like always, but now we added to the Hash class the posibility of accessing it using:
132
-
133
- ```ruby
134
- puts my_hash[:address] # like usually is done
135
- puts my_hash.address
136
- my_hash.address = '99 Danish Street' #assignment
137
- puts my_hash.loginame
138
- puts my_hash.mobilePhone.correct
139
- puts my_hash.draws[1].owner.correct
140
- ```
141
- Also another way to access the different keys is by adding first underscore.
142
- 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...
143
-
144
- ```ruby
145
- puts my_hash._address
146
- my_hash._address = '99 Danish Street' #assignment
147
- my_hash._display = false #assignment
148
- puts my_hash._loginame
149
- puts my_hash._mobilePhone._correct
150
- puts my_hash._draws[1]._owner._correct
151
- puts my_hash._zip.correct #you can mix both also
152
- ```
153
-
154
- By using the string_pattern gem you can generate single strings following the specific pattern on the field:
155
-
156
- ```ruby
157
- puts my_hash.loginame.generate #>s93owuvkh
158
- puts my_hash.mobilePhone.correct.generate #>(039)5669558
159
- puts my_hash._zip._correct.gen # gen is an alias for generate method #>84584
160
- ```
161
-
162
- If you want to search for all the values of one or more keys use get_values method:
163
-
164
- ```ruby
165
- new_hash = my_hash.generate
166
- puts new_hash.get_values(:address) #> {:address=>"21 Doom Av"}
167
- puts new_hash.get_values(:address, :zip) #> {:zip=>{:default=>"00000", :correct=>"42782"}, :address=>"21 Doom Av"}
168
- puts new_hash.get_values(:drawId) #> {:drawId=>["84914", "21158"]}
169
- ```
170
-
171
- ### Filtering / Selecting an specific key on the hash and subhashes
172
-
173
- 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
174
-
175
- ```ruby
176
- #using NiceHash class
177
- new_hash = NiceHash.select_key(my_hash, :correct)
178
- #using select_key method on Hash class
179
- new_hash = my_hash.select_key(:correct)
180
- default_hash = my_hash.select_key(:default)
181
- ```
182
-
183
- On this example new_hash will contain:
184
-
185
- ```ruby
186
- {
187
- loginame: :"5-10:/xn/",
188
- [:pwd1, :pwd2, :pwd3] => :"5-10:L/n/",
189
- name: :"10-20:T_/x/",
190
- draws: [
191
- {
192
- drawId: :"5:N",
193
- drawName: :"10:Ln",
194
- type: :"Weekely|Daily",
195
- owner: :"20:L"
196
- },
197
- {
198
- drawId: :"5:N",
199
- drawName: :"10:Ln",
200
- type: :"Weekely|Daily",
201
- owner: :"20:L"
202
- }
203
- ],
204
- zip: :'5:N',
205
- address: "21 Doom Av",
206
- city: "London|Rome",
207
- wagers: ['34AAB', 'dfffDD', '33499A'],
208
- country: ["Spain", "Iceland", "Serbia", "Denmark", "Canada", "Italy", "Austria"].join("|"), #one of these values
209
- mobilePhone: ['(', :'3:N', ')', :'6-8:N'],
210
- sex: :"male|female|other", #any of these values
211
- display: true
212
- }
213
- ```
214
-
215
- ### How to generate the hash with the criteria we want
216
-
217
- You can use the 'generate' method and everytime will be generated a different hash with different values.
218
-
219
- Remember you can filter/select by a hash key
220
-
221
- Using the NiceHash class:
222
- ```ruby
223
- #without filtering
224
- new_hash = NiceHash.generate(my_hash)
225
- #filtering by a key passing the key on parameters
226
- new_hash = NiceHash.generate(my_hash, :correct)
227
- ```
228
-
229
- Using Hash class (you can use the alias 'gen' for 'generate'):
230
- ```ruby
231
- #without filtering
232
- new_hash = my_hash.generate
233
- #filtering by a key passing the key on parameters
234
- new_hash = my_hash.generate(:correct)
235
- #filtering by a key using select_key method
236
- new_hash = my_hash.select_key(:correct).generate
237
- ```
238
-
239
-
240
- In case of filtering by :correct new_hash would have a value like this for example:
241
-
242
- ```ruby
243
- {:loginame=>"s45x029o",
244
- :pwd1=>"E6hz9YS7",
245
- :pwd2=>"E6hz9YS7",
246
- :pwd3=>"E6hz9YS7",
247
- :name=>"OyTQNfEyPOzVYMxPym",
248
- :draws=>
249
- [{:drawId=>"54591",
250
- :drawName=>"cr5Q7pq4G8",
251
- :type=>"Weekely",
252
- :owner=>"nKEasYWInPGJxxElBZUB"},
253
- {:drawId=>"73307",
254
- :drawName=>"FnHPM4CsRC",
255
- :type=>"Weekely",
256
- :owner=>"cNGpHDhDLcxSFbOGqvNy"}],
257
- :zip=>"47537",
258
- :address=>"21 Doom Av",
259
- :city=>"London",
260
- :wagers=>["34AAB", "dfffDD", "33499A"],
261
- :country=>"Denmark",
262
- :mobilePhone=>"(707)8782080",
263
- :sex=>"male",
264
- :display=>true}
265
- ```
266
-
267
- In case no filtering you will get all the values for all keys
268
-
269
- ### How to generate the hash with wrong values for the string patterns specified on the hash
270
-
271
- We can generate wrong values passing the keyword argument: expected_errors (alias: errors)
272
-
273
- 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
274
-
275
- :length: wrong length, minimum or maximum
276
- :min_length: wrong minimum length
277
- :max_length: wrong maximum length
278
- :value: wrong resultant value
279
- :required_data: the output string won't include all necessary required data. It works only if required data supplied on the pattern.
280
- :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.
281
- :string_set_not_allowed: it will include one or more characters that are not supposed to be on the string.
282
-
283
- Examples:
284
-
285
- ```ruby
286
- wrong_values = my_hash.generate(:correct, expected_errors: [:value])
287
-
288
- wrong_max_length = my_hash.generate(:correct, errors: :max_length)
289
-
290
- wrong_min_length = my_hash.generate(:correct, expected_errors: :min_length)
291
-
292
- wrong_min_length = my_hash.select_key(:correct).generate(errors: :min_length)
293
-
294
- valid_values = my_hash.generate(:correct)
295
- ```
296
-
297
- On this example wrong_min_length will contain something like:
298
-
299
- ```ruby
300
- {:loginame=>"0u",
301
- :pwd1=>"4XDx",
302
- :pwd2=>"4XDx",
303
- :pwd3=>"4XDx",
304
- :name=>"bU",
305
- :draws=>
306
- [{:drawId=>"", :drawName=>"P03AgdMqV", :type=>"Dail", :owner=>"dYzLRMCnVc"},
307
- {:drawId=>"", :drawName=>"qw", :type=>"Dail", :owner=>"zkHhTEzM"}],
308
- :zip=>"7168",
309
- :address=>"21 Doom Av",
310
- :city=>"Rom",
311
- :wagers=>["34AAB", "dfffDD", "33499A"],
312
- :country=>"Spai",
313
- :mobilePhone=>"(237)17640431",
314
- :sex=>"mal",
315
- :display=>true}
316
- ```
317
-
318
- ### Return the select_fields or the pattern_fields
319
-
320
- 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
321
-
322
- It will return an array with all the fields found. On every entry of the array you will see keys to the field.
323
-
324
- ```ruby
325
- all_select_fields = my_hash.select_fields
326
- select_fields_on_correct = my_hash.select_fields(:correct)
327
-
328
- all_pattern_fields = my_hash.pattern_fields
329
- pattern_fields_on_correct = my_hash.pattern_fields(:correct)
330
- ```
331
-
332
- all_select_fields contains:
333
-
334
- ```ruby
335
- [[:draws, 0, :type],
336
- [:draws, 1, :type],
337
- [:city, :correct],
338
- [:country, :correct],
339
- [:sex]]
340
- ```
341
-
342
- select_fields_on_correct contains:
343
-
344
- ```ruby
345
- [[:draws, 0, :type],
346
- [:draws, 1, :type],
347
- [:city],
348
- [:country],
349
- [:sex]]
350
- ```
351
-
352
- all_pattern_fields contains:
353
-
354
- ```ruby
355
- [[:loginame],
356
- [[:pwd1, :pwd2, :pwd3]],
357
- [:name],
358
- [:draws, 0, :drawId],
359
- [:draws, 0, :drawName],
360
- [:draws, 0, :owner, :correct],
361
- [:draws, 1, :drawId],
362
- [:draws, 1, :drawName],
363
- [:draws, 1, :owner, :correct],
364
- [:zip, :correct],
365
- [:mobilePhone, :correct]]
366
- ```
367
-
368
- pattern_fields_on_correct contains:
369
-
370
- ```ruby
371
- [[:loginame],
372
- [[:pwd1, :pwd2, :pwd3]],
373
- [:name],
374
- [:draws, 0, :drawId],
375
- [:draws, 0, :drawName],
376
- [:draws, 0, :owner],
377
- [:draws, 1, :drawId],
378
- [:draws, 1, :drawName],
379
- [:draws, 1, :owner],
380
- [:zip],
381
- [:mobilePhone]]
382
- ```
383
-
384
-
385
- ### dig and bury Hash methods
386
- 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:
387
-
388
- ```ruby
389
- min_length_error = my_hash.generate :correct, errors: :min_length
390
-
391
- patterns = my_hash.pattern_fields :correct
392
-
393
- patterns.each{|key|
394
- if key[0].kind_of?(Array) # same values, like in pwd1, pwd2 and pwd3
395
- puts "#{key} same values"
396
- value = min_length_error.dig(key[0][0])
397
- else
398
- value = min_length_error.dig(*key)
399
- end
400
-
401
- pattern = my_hash.select_key(:correct).dig(*key)
402
- puts "the value: '#{value}' was generated from the key: #{key} with pattern: #{pattern}"
403
- }
404
- ```
405
-
406
- This returns something like:
407
-
408
- ```
409
- the value: '5z' was generated from the key: [:loginame] with pattern: 5-10:/xn/
410
- [[:pwd1, :pwd2, :pwd3]] same values
411
- the value: '5' was generated from the key: [[:pwd1, :pwd2, :pwd3]] with pattern: 5-10:L/n/
412
- the value: 'KshiYAmp' was generated from the key: [:name] with pattern: 10-20:T_/x/
413
- the value: '722' was generated from the key: [:draws, 0, :drawId] with pattern: 5:N
414
- the value: '4' was generated from the key: [:draws, 0, :drawName] with pattern: 10:Ln
415
- the value: 'jhVZkII' was generated from the key: [:draws, 0, :owner] with pattern: 20:L
416
- the value: '260' was generated from the key: [:draws, 1, :drawId] with pattern: 5:N
417
- the value: 'ssty8hlnJ' was generated from the key: [:draws, 1, :drawName] with pattern: 10:Ln
418
- the value: 'zPvcwOyyXvWSgNHsuv' was generated from the key: [:draws, 1, :owner] with pattern: 20:L
419
- the value: '242' was generated from the key: [:zip] with pattern: 5:N
420
- the value: '(91)7606' was generated from the key: [:mobilePhone] with pattern: ["(", :"3:N", ")", :"6-8:N"]
421
- ```
422
-
423
- 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.
424
-
425
- ```ruby
426
- default_values = my_hash.generate :default
427
-
428
- default_values.bury([:draws, 0, :drawName], "FirstDraw")
429
- ```
430
-
431
- After using the bury method default_values will contain:
432
-
433
- ```ruby
434
- {:loginame=>"i0v2jy",
435
- :pwd1=>"x33exx",
436
- :pwd2=>"x33exx",
437
- :pwd3=>"x33exx",
438
- :name=>"HdmsjLxlEgYIFY",
439
- :draws=>
440
- [{:drawId=>"12318",
441
- :drawName=>"FirstDraw",
442
- :type=>"Weekely",
443
- :owner=>"admin"},
444
- {:drawId=>"18947",
445
- :drawName=>"LPgf2ZQvkG",
446
- :type=>"Weekely",
447
- :owner=>"admin"}],
448
- :zip=>"00000",
449
- :address=>"21 Doom Av",
450
- :city=>"Madrid",
451
- :wagers=>["34AAB", "dfffDD", "33499A"],
452
- :country=>"Spain",
453
- :mobilePhone=>"(987)654321",
454
- :sex=>"male",
455
- :display=>true}
456
- ```
457
-
458
- ### Validating hashes
459
-
460
- 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.
461
-
462
- This is particulary useful to test REST APIs responses in JSON
463
-
464
- If we have a hash with these values:
465
-
466
- ```ruby
467
- {:loginame=>"rdewvqur",
468
- :pwd1=>"d3ulo",
469
- :pwd2=>"d3ulo",
470
- :pwd3=>"d3ulo",
471
- :name=>"LTqVKxxFCTqpkdjFkxU",
472
- :draws=>
473
- [{:drawId=>"54a43",
474
- :drawName=>"h3F24yjMWp",
475
- :type=>"Daily",
476
- :owner=>"abIZMRxTDsWjQcpdspZt"},
477
- {:drawId=>"13010",
478
- :drawName=>"NurCEAtE1M",
479
- :type=>"Daily",
480
- :owner=>"vSVoqtSzHkbvRNyJoYGz"}],
481
- :zip=>"30222",
482
- :address=>"21 Doom Av",
483
- :city=>"New York",
484
- :wagers=>["34AAB", "dfffDD", "33499A"],
485
- :country=>"Iceland",
486
- :mobilePhone=>"(441)97037845",
487
- :sex=>"male",
488
- :display=>true}
489
- ```
490
-
491
- To validate those values taking in consideration was is stated on my_hash:
492
-
493
- ```ruby
494
- results_all_fields = my_hash.validate :correct, values
495
-
496
- results_pattern_fields = my_hash.validate_patterns :correct, values
497
- ```
498
-
499
- results_all_fields will contain all the validation errors:
500
-
501
- ```ruby
502
- {:loginame=>[:value, :required_data],
503
- :draws=>[{:drawId=>[:value, :string_set_not_allowed]}],
504
- :city=>false}
505
- ```
506
-
507
- and results_pattern_fields will contain only the validation errors for the fields containing patterns:
508
-
509
- ```ruby
510
- {:loginame=>[:value, :required_data],
511
- :draws=>[{:drawId=>[:value, :string_set_not_allowed]}]}
512
- ```
513
-
514
- The possible validation values returned:
515
-
516
- :length: wrong length, minimum or maximum
517
- :min_length: wrong minimum length
518
- :max_length: wrong maximum length
519
- :value: wrong resultant value
520
- :required_data: the output string won't include all necessary required data. It works only if required data supplied on the pattern.
521
- :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.
522
- :string_set_not_allowed: it will include one or more characters that are not supposed to be on the string.
523
-
524
-
525
- ### Change only one value at a time and return an Array of Hashes
526
-
527
- 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.
528
-
529
- Then the best thing you can do is to use the method NiceHash.change_one_by_one.
530
-
531
-
532
- ```ruby
533
-
534
- wrong_min_length_hash = my_hash.generate(:correct, errors: :min_length)
535
-
536
- array_of_hashes = NiceHash.change_one_by_one([my_hash, :correct], wrong_min_length_hash)
537
-
538
- array_of_hashes.each {|hash_with_one_wrong_field|
539
- #Here your code to send through http the JSON data stored in hash_with_one_wrong_field
540
-
541
- #if you want to know which field is the one that is wrong:
542
- res = my_hash.validate(:correct, hash_with_one_wrong_field)
543
- }
544
- ```
545
-
546
- Take a look at a full example: https://gist.github.com/MarioRuiz/824d7a462b62fd85f02c1a09455deefb
547
-
548
- ### Adding other values on real time when calling `generate` method
549
-
550
- If you need a value to be supplied for your key on real time every time you call the `generate` method you can use `lambda`
551
-
552
- ```ruby
553
- my_hash = {
554
- loginname: :"10:Ln",
555
- datetime: lambda {
556
- Time.now.stamp
557
- },
558
- other: Time.now.stamp
559
- }
560
-
561
- pp my_hash.gen
562
- sleep 0.3
563
- pp my_hash.gen
564
-
565
- ```
566
-
567
- AS you can see in this example the value of the field `datetime` is different every time we generate the hash, but the value of the field `other` is generated the first time and it doesn't change later.
568
-
569
- This is the output:
570
-
571
- ```
572
- {:loginname=>"dQ1gwPvHHZ",
573
- :datetime=>"2019-01-02T13:41:05.536",
574
- :other=>"2019-01-02T13:41:05.536"}
575
-
576
- {:loginname=>"WUCnWJmm0o",
577
- :datetime=>"2019-01-02T13:41:05.836",
578
- :other=>"2019-01-02T13:41:05.536"}
579
- ```
580
-
581
- #### Accessing other values of the hash on real time
582
-
583
- If you need for example to access another value of the key to generate a value on real time you can use `NiceHash.values`
584
-
585
- Take a look at this example:
586
-
587
- ```ruby
588
-
589
- my_hash = {
590
- loginname: :"10:Ln",
591
- send_email: :"true|false",
592
- email: lambda {
593
- if NiceHash.values._send_email=='true'
594
- :"30-50:@".gen
595
- else
596
- ""
597
- end
598
- }
599
- }
600
-
601
- pp my_hash.gen
602
- pp my_hash.gen
603
- pp my_hash.gen
604
-
605
- ```
606
-
607
- This code will generate a hash where `send_email` can be `true` or `false`. In case it is `true` it will generate a value for the key `email` from 30 to 50 characters valid email, in case it is `false` it will contain empty string.
608
-
609
- This is a possible output of the previous code:
610
-
611
- ```ruby
612
- {:loginname=>"jnazA9iGN3",
613
- :send_email=>"true",
614
- :email=>"aRR4SsPaA.0ilh_RW0_y.sQL@goxrssgtkp4df.nkc"}
615
-
616
- {:loginname=>"2CjT9wLMxq", :send_email=>"false", :email=>""}
617
-
618
- {:loginname=>"XlMpgNPlLR", :send_email=>"false", :email=>""}
619
- ```
620
-
621
- ### Other useful methods
622
-
623
- In case you need the time stamp, we added the method `stamp` to the `Time` class
624
-
625
- ```ruby
626
- puts Time.now.stamp
627
- #> 2019-01-02T11:03:23.620
628
- ```
629
-
630
- In class `Date` we added a very handy `random` method you can use to generate random dates.
631
-
632
- ```ruby
633
- # random date from today to 60 days after
634
- puts Date.today.random(60)
635
-
636
- # random date from 01-09-2005 to 100 days later
637
- puts Date.strptime('01-09-2005', '%d-%m-%Y').random(100)
638
-
639
- # random date from 2003/10/31 to today
640
- puts Date.new(2003,10,31).random(Date.today)
641
- ```
642
-
643
-
644
-
645
- ## Contributing
646
-
647
- Bug reports and pull requests are welcome on GitHub at https://github.com/marioruiz/nice_hash.
648
-
649
-
650
- ## License
651
-
652
- The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
653
-
654
-
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 generate 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
+ You can also parse and filter a json string very easily.
12
+
13
+ To generate the strings following a pattern take a look at the documentation for string_pattern gem: https://github.com/MarioRuiz/string_pattern. We added support for generating strings from regular expressions but it is only working for the ´generate´ method, use it with caution since it is still on an early stage of development.
14
+
15
+ To use nice_hash on Http connections take a look at nice_http gem: https://github.com/MarioRuiz/nice_http
16
+
17
+ ## Installation
18
+
19
+ Add this line to your application's Gemfile:
20
+
21
+ ```ruby
22
+ gem 'nice_hash'
23
+ ```
24
+
25
+ And then execute:
26
+
27
+ $ bundle
28
+
29
+ Or install it yourself as:
30
+
31
+ $ gem install nice_hash
32
+
33
+ ## Usage
34
+
35
+ Remember!! To generate the strings following a pattern take a look at the documentation for string_pattern gem: https://github.com/MarioRuiz/string_pattern. We added support for generating strings from regular expressions but it is only working for the ´generate´ method, use it with caution since it is still on an early stage of development. All you have to do is to add to a key the value as a Regular expression, for example the key uuid in here will generate a random value like this: "E0BDE5B5-A738-49E6-83C1-9D1FFB313788"
36
+
37
+ ```ruby
38
+ my_hash = {
39
+ uuid: /[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}/,
40
+ key: "Wsdf88888",
41
+ doomId: :"10:N"
42
+ }
43
+ ```
44
+
45
+ This is the Hash we will be using on our examples:
46
+
47
+ ```ruby
48
+
49
+ require 'nice_hash'
50
+
51
+ my_hash={
52
+ loginame: :"5-10:/xn/",
53
+ [:pwd1, :pwd2, :pwd3] => :"5-10:L/n/",
54
+ name: :"10-20:T_/x/",
55
+ draws: [
56
+ {
57
+ drawId: :"5:N",
58
+ drawName: :"10:Ln",
59
+ type: :"Weekely|Daily",
60
+ owner: {
61
+ default: 'admin',
62
+ correct: :"20:L"
63
+ }
64
+ },
65
+ {
66
+ drawId: :"5:N",
67
+ drawName: :"10:Ln",
68
+ type: :"Weekely|Daily",
69
+ owner: {
70
+ default: 'admin',
71
+ correct: :"20:L"
72
+ }
73
+ }
74
+ ],
75
+ zip: {default: '00000', correct: :'5:N'},
76
+ address: "21 Doom Av",
77
+ city: {
78
+ default: "Madrid",
79
+ correct: "London|Rome"
80
+ },
81
+ wagers: ['34AAB', 'dfffDD', '33499A'],
82
+ country: {default: 'Spain', correct: ["Spain", "Iceland", "Serbia", "Denmark", "Canada", "Italy", "Austria"].join("|")}, #one of these values
83
+ mobilePhone: {default: '(987)654321', correct: ['(', :'3:N', ')', :'6-8:N']},
84
+ sex: :"male|female|other", #any of these values
85
+ display: true
86
+ }
87
+ ```
88
+
89
+ Explanations of the different fields:
90
+
91
+ loginname: from 5 to 10 characters, mandatory to have lower letters and numbers
92
+ pwd, pwd2, pwd3: will have the same value. The value from 5 to 10 chars, optional capital and lower letters, necessary to contain numbers
93
+ name: from 10 to 20 chars. Optional national characters and space, necessary lower letters.
94
+ drawId: 5 numbers
95
+ drawName: 10 letters and/or numbers
96
+ type: 'Weekely' or 'Daily'
97
+ owner: correct: 20 letters
98
+ zip: correct: 5 numbers
99
+ city: correct: 'London' or 'Rome'
100
+ country: correct: one of these values "Spain", "Iceland", "Serbia", "Denmark", "Canada", "Italy", "Austria"
101
+ mobilePhone: correct: a sting pattern with one of the next: "(nnn) nnnnnn", "(nnn) nnnnnnn", "(nnn) nnnnnnnn"
102
+ sex: 'male' or 'female' or 'other'
103
+
104
+ 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/"
105
+
106
+ You can also supply an array of strings and string patterns, like on mobilePhone.correct: ['(', :'3:N', ')', :'6-8:N']}
107
+
108
+ 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"
109
+
110
+ In case you want one pattern to be generated with unique values, so never repeat the same value for that particular pattern, use a symbol object pattern and add to the end of the pattern the symbol: &
111
+
112
+ ```ruby
113
+
114
+ loginame: :"5-10:/xn/&",
115
+
116
+ ```
117
+
118
+ Also if you have a JSON string you want to parse it and get the values of certain keys you can use the json method we added to nice_hash:
119
+
120
+ ```ruby
121
+ my_json_string="{\"id\":344,\"customer\":{\"name\":\"Peter Smith\",\"phone\":334334333},\"tickets\":[{\"idt\":345,\"name\":\"myFavor1\"},{\"idt\":3123},{\"idt\":3145,\"name\":\"Special ticket\"}]}"
122
+ puts my_json_string.json(:idt)
123
+ #> [345, 3123, 3145]
124
+
125
+ puts my_json_string.json(:idt, :name)
126
+ #> {:name=>["Peter Smith", ["myFavor1", "Special ticket"]], :idt=>[345, 3123, 3145]}
127
+ ```
128
+
129
+ ### How to access the different keys
130
+
131
+ You can access the keys of the hash like always, but now we added to the Hash class the posibility of accessing it using:
132
+
133
+ ```ruby
134
+ puts my_hash[:address] # like usually is done
135
+ puts my_hash.address
136
+ my_hash.address = '99 Danish Street' #assignment
137
+ puts my_hash.loginame
138
+ puts my_hash.mobilePhone.correct
139
+ puts my_hash.draws[1].owner.correct
140
+ ```
141
+ Also another way to access the different keys is by adding first underscore.
142
+ 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...
143
+
144
+ ```ruby
145
+ puts my_hash._address
146
+ my_hash._address = '99 Danish Street' #assignment
147
+ my_hash._display = false #assignment
148
+ puts my_hash._loginame
149
+ puts my_hash._mobilePhone._correct
150
+ puts my_hash._draws[1]._owner._correct
151
+ puts my_hash._zip.correct #you can mix both also
152
+ ```
153
+
154
+ By using the string_pattern gem you can generate single strings following the specific pattern on the field:
155
+
156
+ ```ruby
157
+ puts my_hash.loginame.generate #>s93owuvkh
158
+ puts my_hash.mobilePhone.correct.generate #>(039)5669558
159
+ puts my_hash._zip._correct.gen # gen is an alias for generate method #>84584
160
+ ```
161
+
162
+ If you want to search for all the values of one or more keys use get_values method:
163
+
164
+ ```ruby
165
+ new_hash = my_hash.generate
166
+ puts new_hash.get_values(:address) #> {:address=>"21 Doom Av"}
167
+ puts new_hash.get_values(:address, :zip) #> {:zip=>{:default=>"00000", :correct=>"42782"}, :address=>"21 Doom Av"}
168
+ puts new_hash.get_values(:drawId) #> {:drawId=>["84914", "21158"]}
169
+ ```
170
+
171
+ ### Filtering / Selecting an specific key on the hash and subhashes
172
+
173
+ 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
174
+
175
+ ```ruby
176
+ #using NiceHash class
177
+ new_hash = NiceHash.select_key(my_hash, :correct)
178
+ #using select_key method on Hash class
179
+ new_hash = my_hash.select_key(:correct)
180
+ default_hash = my_hash.select_key(:default)
181
+ ```
182
+
183
+ On this example new_hash will contain:
184
+
185
+ ```ruby
186
+ {
187
+ loginame: :"5-10:/xn/",
188
+ [:pwd1, :pwd2, :pwd3] => :"5-10:L/n/",
189
+ name: :"10-20:T_/x/",
190
+ draws: [
191
+ {
192
+ drawId: :"5:N",
193
+ drawName: :"10:Ln",
194
+ type: :"Weekely|Daily",
195
+ owner: :"20:L"
196
+ },
197
+ {
198
+ drawId: :"5:N",
199
+ drawName: :"10:Ln",
200
+ type: :"Weekely|Daily",
201
+ owner: :"20:L"
202
+ }
203
+ ],
204
+ zip: :'5:N',
205
+ address: "21 Doom Av",
206
+ city: "London|Rome",
207
+ wagers: ['34AAB', 'dfffDD', '33499A'],
208
+ country: ["Spain", "Iceland", "Serbia", "Denmark", "Canada", "Italy", "Austria"].join("|"), #one of these values
209
+ mobilePhone: ['(', :'3:N', ')', :'6-8:N'],
210
+ sex: :"male|female|other", #any of these values
211
+ display: true
212
+ }
213
+ ```
214
+
215
+ ### How to generate the hash with the criteria we want
216
+
217
+ You can use the 'generate' method and everytime will be generated a different hash with different values.
218
+
219
+ Remember you can filter/select by a hash key
220
+
221
+ Using the NiceHash class:
222
+ ```ruby
223
+ #without filtering
224
+ new_hash = NiceHash.generate(my_hash)
225
+ #filtering by a key passing the key on parameters
226
+ new_hash = NiceHash.generate(my_hash, :correct)
227
+ ```
228
+
229
+ Using Hash class (you can use the alias 'gen' for 'generate'):
230
+ ```ruby
231
+ #without filtering
232
+ new_hash = my_hash.generate
233
+ #filtering by a key passing the key on parameters
234
+ new_hash = my_hash.generate(:correct)
235
+ #filtering by a key using select_key method
236
+ new_hash = my_hash.select_key(:correct).generate
237
+ ```
238
+
239
+
240
+ In case of filtering by :correct new_hash would have a value like this for example:
241
+
242
+ ```ruby
243
+ {:loginame=>"s45x029o",
244
+ :pwd1=>"E6hz9YS7",
245
+ :pwd2=>"E6hz9YS7",
246
+ :pwd3=>"E6hz9YS7",
247
+ :name=>"OyTQNfEyPOzVYMxPym",
248
+ :draws=>
249
+ [{:drawId=>"54591",
250
+ :drawName=>"cr5Q7pq4G8",
251
+ :type=>"Weekely",
252
+ :owner=>"nKEasYWInPGJxxElBZUB"},
253
+ {:drawId=>"73307",
254
+ :drawName=>"FnHPM4CsRC",
255
+ :type=>"Weekely",
256
+ :owner=>"cNGpHDhDLcxSFbOGqvNy"}],
257
+ :zip=>"47537",
258
+ :address=>"21 Doom Av",
259
+ :city=>"London",
260
+ :wagers=>["34AAB", "dfffDD", "33499A"],
261
+ :country=>"Denmark",
262
+ :mobilePhone=>"(707)8782080",
263
+ :sex=>"male",
264
+ :display=>true}
265
+ ```
266
+
267
+ In case no filtering you will get all the values for all keys
268
+
269
+ ### How to generate the hash with wrong values for the string patterns specified on the hash
270
+
271
+ We can generate wrong values passing the keyword argument: expected_errors (alias: errors)
272
+
273
+ 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
274
+
275
+ :length: wrong length, minimum or maximum
276
+ :min_length: wrong minimum length
277
+ :max_length: wrong maximum length
278
+ :value: wrong resultant value
279
+ :required_data: the output string won't include all necessary required data. It works only if required data supplied on the pattern.
280
+ :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.
281
+ :string_set_not_allowed: it will include one or more characters that are not supposed to be on the string.
282
+
283
+ Examples:
284
+
285
+ ```ruby
286
+ wrong_values = my_hash.generate(:correct, expected_errors: [:value])
287
+
288
+ wrong_max_length = my_hash.generate(:correct, errors: :max_length)
289
+
290
+ wrong_min_length = my_hash.generate(:correct, expected_errors: :min_length)
291
+
292
+ wrong_min_length = my_hash.select_key(:correct).generate(errors: :min_length)
293
+
294
+ valid_values = my_hash.generate(:correct)
295
+ ```
296
+
297
+ On this example wrong_min_length will contain something like:
298
+
299
+ ```ruby
300
+ {:loginame=>"0u",
301
+ :pwd1=>"4XDx",
302
+ :pwd2=>"4XDx",
303
+ :pwd3=>"4XDx",
304
+ :name=>"bU",
305
+ :draws=>
306
+ [{:drawId=>"", :drawName=>"P03AgdMqV", :type=>"Dail", :owner=>"dYzLRMCnVc"},
307
+ {:drawId=>"", :drawName=>"qw", :type=>"Dail", :owner=>"zkHhTEzM"}],
308
+ :zip=>"7168",
309
+ :address=>"21 Doom Av",
310
+ :city=>"Rom",
311
+ :wagers=>["34AAB", "dfffDD", "33499A"],
312
+ :country=>"Spai",
313
+ :mobilePhone=>"(237)17640431",
314
+ :sex=>"mal",
315
+ :display=>true}
316
+ ```
317
+
318
+ ### Return the select_fields or the pattern_fields
319
+
320
+ 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
321
+
322
+ It will return an array with all the fields found. On every entry of the array you will see keys to the field.
323
+
324
+ ```ruby
325
+ all_select_fields = my_hash.select_fields
326
+ select_fields_on_correct = my_hash.select_fields(:correct)
327
+
328
+ all_pattern_fields = my_hash.pattern_fields
329
+ pattern_fields_on_correct = my_hash.pattern_fields(:correct)
330
+ ```
331
+
332
+ all_select_fields contains:
333
+
334
+ ```ruby
335
+ [[:draws, 0, :type],
336
+ [:draws, 1, :type],
337
+ [:city, :correct],
338
+ [:country, :correct],
339
+ [:sex]]
340
+ ```
341
+
342
+ select_fields_on_correct contains:
343
+
344
+ ```ruby
345
+ [[:draws, 0, :type],
346
+ [:draws, 1, :type],
347
+ [:city],
348
+ [:country],
349
+ [:sex]]
350
+ ```
351
+
352
+ all_pattern_fields contains:
353
+
354
+ ```ruby
355
+ [[:loginame],
356
+ [[:pwd1, :pwd2, :pwd3]],
357
+ [:name],
358
+ [:draws, 0, :drawId],
359
+ [:draws, 0, :drawName],
360
+ [:draws, 0, :owner, :correct],
361
+ [:draws, 1, :drawId],
362
+ [:draws, 1, :drawName],
363
+ [:draws, 1, :owner, :correct],
364
+ [:zip, :correct],
365
+ [:mobilePhone, :correct]]
366
+ ```
367
+
368
+ pattern_fields_on_correct contains:
369
+
370
+ ```ruby
371
+ [[:loginame],
372
+ [[:pwd1, :pwd2, :pwd3]],
373
+ [:name],
374
+ [:draws, 0, :drawId],
375
+ [:draws, 0, :drawName],
376
+ [:draws, 0, :owner],
377
+ [:draws, 1, :drawId],
378
+ [:draws, 1, :drawName],
379
+ [:draws, 1, :owner],
380
+ [:zip],
381
+ [:mobilePhone]]
382
+ ```
383
+
384
+
385
+ ### dig and bury Hash methods
386
+ 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:
387
+
388
+ ```ruby
389
+ min_length_error = my_hash.generate :correct, errors: :min_length
390
+
391
+ patterns = my_hash.pattern_fields :correct
392
+
393
+ patterns.each{|key|
394
+ if key[0].kind_of?(Array) # same values, like in pwd1, pwd2 and pwd3
395
+ puts "#{key} same values"
396
+ value = min_length_error.dig(key[0][0])
397
+ else
398
+ value = min_length_error.dig(*key)
399
+ end
400
+
401
+ pattern = my_hash.select_key(:correct).dig(*key)
402
+ puts "the value: '#{value}' was generated from the key: #{key} with pattern: #{pattern}"
403
+ }
404
+ ```
405
+
406
+ This returns something like:
407
+
408
+ ```
409
+ the value: '5z' was generated from the key: [:loginame] with pattern: 5-10:/xn/
410
+ [[:pwd1, :pwd2, :pwd3]] same values
411
+ the value: '5' was generated from the key: [[:pwd1, :pwd2, :pwd3]] with pattern: 5-10:L/n/
412
+ the value: 'KshiYAmp' was generated from the key: [:name] with pattern: 10-20:T_/x/
413
+ the value: '722' was generated from the key: [:draws, 0, :drawId] with pattern: 5:N
414
+ the value: '4' was generated from the key: [:draws, 0, :drawName] with pattern: 10:Ln
415
+ the value: 'jhVZkII' was generated from the key: [:draws, 0, :owner] with pattern: 20:L
416
+ the value: '260' was generated from the key: [:draws, 1, :drawId] with pattern: 5:N
417
+ the value: 'ssty8hlnJ' was generated from the key: [:draws, 1, :drawName] with pattern: 10:Ln
418
+ the value: 'zPvcwOyyXvWSgNHsuv' was generated from the key: [:draws, 1, :owner] with pattern: 20:L
419
+ the value: '242' was generated from the key: [:zip] with pattern: 5:N
420
+ the value: '(91)7606' was generated from the key: [:mobilePhone] with pattern: ["(", :"3:N", ")", :"6-8:N"]
421
+ ```
422
+
423
+ 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.
424
+
425
+ ```ruby
426
+ default_values = my_hash.generate :default
427
+
428
+ default_values.bury([:draws, 0, :drawName], "FirstDraw")
429
+ ```
430
+
431
+ After using the bury method default_values will contain:
432
+
433
+ ```ruby
434
+ {:loginame=>"i0v2jy",
435
+ :pwd1=>"x33exx",
436
+ :pwd2=>"x33exx",
437
+ :pwd3=>"x33exx",
438
+ :name=>"HdmsjLxlEgYIFY",
439
+ :draws=>
440
+ [{:drawId=>"12318",
441
+ :drawName=>"FirstDraw",
442
+ :type=>"Weekely",
443
+ :owner=>"admin"},
444
+ {:drawId=>"18947",
445
+ :drawName=>"LPgf2ZQvkG",
446
+ :type=>"Weekely",
447
+ :owner=>"admin"}],
448
+ :zip=>"00000",
449
+ :address=>"21 Doom Av",
450
+ :city=>"Madrid",
451
+ :wagers=>["34AAB", "dfffDD", "33499A"],
452
+ :country=>"Spain",
453
+ :mobilePhone=>"(987)654321",
454
+ :sex=>"male",
455
+ :display=>true}
456
+ ```
457
+
458
+ ### Validating hashes
459
+
460
+ 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.
461
+
462
+ This is particulary useful to test REST APIs responses in JSON
463
+
464
+ If we have a hash with these values:
465
+
466
+ ```ruby
467
+ {:loginame=>"rdewvqur",
468
+ :pwd1=>"d3ulo",
469
+ :pwd2=>"d3ulo",
470
+ :pwd3=>"d3ulo",
471
+ :name=>"LTqVKxxFCTqpkdjFkxU",
472
+ :draws=>
473
+ [{:drawId=>"54a43",
474
+ :drawName=>"h3F24yjMWp",
475
+ :type=>"Daily",
476
+ :owner=>"abIZMRxTDsWjQcpdspZt"},
477
+ {:drawId=>"13010",
478
+ :drawName=>"NurCEAtE1M",
479
+ :type=>"Daily",
480
+ :owner=>"vSVoqtSzHkbvRNyJoYGz"}],
481
+ :zip=>"30222",
482
+ :address=>"21 Doom Av",
483
+ :city=>"New York",
484
+ :wagers=>["34AAB", "dfffDD", "33499A"],
485
+ :country=>"Iceland",
486
+ :mobilePhone=>"(441)97037845",
487
+ :sex=>"male",
488
+ :display=>true}
489
+ ```
490
+
491
+ To validate those values taking in consideration was is stated on my_hash:
492
+
493
+ ```ruby
494
+ results_all_fields = my_hash.validate :correct, values
495
+
496
+ results_pattern_fields = my_hash.validate_patterns :correct, values
497
+ ```
498
+
499
+ results_all_fields will contain all the validation errors:
500
+
501
+ ```ruby
502
+ {:loginame=>[:value, :required_data],
503
+ :draws=>[{:drawId=>[:value, :string_set_not_allowed]}],
504
+ :city=>false}
505
+ ```
506
+
507
+ and results_pattern_fields will contain only the validation errors for the fields containing patterns:
508
+
509
+ ```ruby
510
+ {:loginame=>[:value, :required_data],
511
+ :draws=>[{:drawId=>[:value, :string_set_not_allowed]}]}
512
+ ```
513
+
514
+ The possible validation values returned:
515
+
516
+ :length: wrong length, minimum or maximum
517
+ :min_length: wrong minimum length
518
+ :max_length: wrong maximum length
519
+ :value: wrong resultant value
520
+ :required_data: the output string won't include all necessary required data. It works only if required data supplied on the pattern.
521
+ :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.
522
+ :string_set_not_allowed: it will include one or more characters that are not supposed to be on the string.
523
+
524
+
525
+ ### Change only one value at a time and return an Array of Hashes
526
+
527
+ 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.
528
+
529
+ Then the best thing you can do is to use the method NiceHash.change_one_by_one.
530
+
531
+
532
+ ```ruby
533
+
534
+ wrong_min_length_hash = my_hash.generate(:correct, errors: :min_length)
535
+
536
+ array_of_hashes = NiceHash.change_one_by_one([my_hash, :correct], wrong_min_length_hash)
537
+
538
+ array_of_hashes.each {|hash_with_one_wrong_field|
539
+ #Here your code to send through http the JSON data stored in hash_with_one_wrong_field
540
+
541
+ #if you want to know which field is the one that is wrong:
542
+ res = my_hash.validate(:correct, hash_with_one_wrong_field)
543
+ }
544
+ ```
545
+
546
+ Take a look at a full example: https://gist.github.com/MarioRuiz/824d7a462b62fd85f02c1a09455deefb
547
+
548
+ ### Adding other values on real time when calling `generate` method
549
+
550
+ If you need a value to be supplied for your key on real time every time you call the `generate` method you can use `lambda`
551
+
552
+ ```ruby
553
+ my_hash = {
554
+ loginname: :"10:Ln",
555
+ datetime: lambda {
556
+ Time.now.stamp
557
+ },
558
+ other: Time.now.stamp
559
+ }
560
+
561
+ pp my_hash.gen
562
+ sleep 0.3
563
+ pp my_hash.gen
564
+
565
+ ```
566
+
567
+ AS you can see in this example the value of the field `datetime` is different every time we generate the hash, but the value of the field `other` is generated the first time and it doesn't change later.
568
+
569
+ This is the output:
570
+
571
+ ```
572
+ {:loginname=>"dQ1gwPvHHZ",
573
+ :datetime=>"2019-01-02T13:41:05.536",
574
+ :other=>"2019-01-02T13:41:05.536"}
575
+
576
+ {:loginname=>"WUCnWJmm0o",
577
+ :datetime=>"2019-01-02T13:41:05.836",
578
+ :other=>"2019-01-02T13:41:05.536"}
579
+ ```
580
+
581
+ #### Accessing other values of the hash on real time
582
+
583
+ If you need for example to access another value of the key to generate a value on real time you can use `NiceHash.values`
584
+
585
+ Take a look at this example:
586
+
587
+ ```ruby
588
+
589
+ my_hash = {
590
+ loginname: :"10:Ln",
591
+ send_email: :"true|false",
592
+ email: lambda {
593
+ if NiceHash.values._send_email=='true'
594
+ :"30-50:@".gen
595
+ else
596
+ ""
597
+ end
598
+ }
599
+ }
600
+
601
+ pp my_hash.gen
602
+ pp my_hash.gen
603
+ pp my_hash.gen
604
+
605
+ ```
606
+
607
+ This code will generate a hash where `send_email` can be `true` or `false`. In case it is `true` it will generate a value for the key `email` from 30 to 50 characters valid email, in case it is `false` it will contain empty string.
608
+
609
+ This is a possible output of the previous code:
610
+
611
+ ```ruby
612
+ {:loginname=>"jnazA9iGN3",
613
+ :send_email=>"true",
614
+ :email=>"aRR4SsPaA.0ilh_RW0_y.sQL@goxrssgtkp4df.nkc"}
615
+
616
+ {:loginname=>"2CjT9wLMxq", :send_email=>"false", :email=>""}
617
+
618
+ {:loginname=>"XlMpgNPlLR", :send_email=>"false", :email=>""}
619
+ ```
620
+
621
+ ### Other useful methods
622
+
623
+ In case you need the time stamp, we added the method `stamp` to the `Time` class
624
+
625
+ ```ruby
626
+ puts Time.now.stamp
627
+ #> 2019-01-02T11:03:23.620Z
628
+ ```
629
+
630
+ In class `Date` we added a very handy `random` method you can use to generate random dates.
631
+
632
+ ```ruby
633
+ # random date from today to 60 days after
634
+ puts Date.today.random(60)
635
+
636
+ # random date from 01-09-2005 to 100 days later
637
+ puts Date.strptime('01-09-2005', '%d-%m-%Y').random(100)
638
+
639
+ # random date from 2003/10/31 to today
640
+ puts Date.new(2003,10,31).random(Date.today)
641
+ ```
642
+
643
+
644
+
645
+ ## Contributing
646
+
647
+ Bug reports and pull requests are welcome on GitHub at https://github.com/marioruiz/nice_hash.
648
+
649
+
650
+ ## License
651
+
652
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
653
+
654
+