nice_hash 1.3.0 → 1.4.0

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