nice_hash 1.3.0 → 1.4.0

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 +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
+