NiceHash

NiceHash creates hashes following certain patterns so your testing will be much easier.

You can easily generate all the hashes you want following the criteria you specify.

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.

require'nice_hash'my_hash={loginame::"5-10:/xn/",[:pwd1,:pwd2,:pwd3]=>:"5-10:L/n/",name::"10-20:T_/x/",draws:[{drawId::"5:N",drawName::"10:Ln",type::"Weekely|Daily",owner:{default:'admin',correct::"20:L"}},{drawId::"5:N",drawName::"10:Ln",type::"Weekely|Daily",owner:{default:'admin',correct::"20:L"}}],zip:{default:'00000',correct::'5:N'},address:"21 Doom Av",city:{default:"Madrid",correct:"London|Rome"},wagers:['34AAB','dfffDD','33499A'],country:{default:'Spain',correct:["Spain","Iceland","Serbia","Denmark","Canada","Italy","Austria"].join("|")},#one of these values
mobilePhone:{default:'(987)654321',correct:['(',:'3:N',')',:'6-8:N']},sex::"male|female|other",#any of these values
display:true}

How to access the different keys

You can access the keys of the hash like always, but now we added to the Hash class the posibility of accessing it using:

putsmy_hash[:address]# like usually is done
putsmy_hash.addressmy_hash.address='99 Danish Street'#assignment
putsmy_hash.loginameputsmy_hash.mobilePhone.correctputsmy_hash.draws[1].owner.correct

Also another way to access the different keys is by adding first underscore.
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...

putsmy_hash._addressmy_hash._address='99 Danish Street'#assignment
my_hash._display=false#assignment
putsmy_hash._loginameputsmy_hash._mobilePhone._correctputsmy_hash._draws[1]._owner._correctputsmy_hash._zip.correct#you can mix both also

By using the string_pattern gem you can generate single strings following the specific pattern on the field:

{loginame::"5-10:/xn/",[:pwd1,:pwd2,:pwd3]=>:"5-10:L/n/",name::"10-20:T_/x/",draws:[{drawId::"5:N",drawName::"10:Ln",type::"Weekely|Daily",owner::"20:L"},{drawId::"5:N",drawName::"10:Ln",type::"Weekely|Daily",owner::"20:L"}],zip::'5:N',address:"21 Doom Av",city:"London|Rome",wagers:['34AAB','dfffDD','33499A'],country:["Spain","Iceland","Serbia","Denmark","Canada","Italy","Austria"].join("|"),#one of these values
mobilePhone:['(',:'3:N',')',:'6-8:N'],sex::"male|female|other",#any of these values
display:true}

How to generate the hash with the criteria we want

You can use the 'generate' method and everytime will be generated a different hash with different values.

#without filtering
new_hash=my_hash.generate#filtering by a key passing the key on parameters
new_hash=my_hash.generate(:correct)#filtering by a key using select_key method
new_hash=my_hash.select_key(:correct).generate

In case of filtering by :correct new_hash would have a value like this for example:

How to generate the hash with wrong values for the string patterns specified on the hash

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

:length: wrong length, minimum or maximum
:min_length: wrong minimum length
:max_length: wrong maximum length
:value: wrong resultant value
:required_data: the output string won't include all necessary required data. It works only if required data supplied on the pattern.
: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.
:string_set_not_allowed: it will include one or more characters that are not supposed to be on the string.

dig and bury Hash methods

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:

min_length_error=my_hash.generate:correct,errors::min_lengthpatterns=my_hash.pattern_fields:correctpatterns.each{|key|ifkey[0].kind_of?(Array)# same values, like in pwd1, pwd2 and pwd3
puts"#{key} same values"value=min_length_error.dig(key[0][0])elsevalue=min_length_error.dig(*key)endpattern=my_hash.select_key(:correct).dig(*key)puts"the value: '#{value}' was generated from the key: #{key} with pattern: #{pattern}"}

This returns something like:

the value: '5z' was generated from the key: [:loginame] with pattern: 5-10:/xn/
[[:pwd1, :pwd2, :pwd3]] same values
the value: '5' was generated from the key: [[:pwd1, :pwd2, :pwd3]] with pattern: 5-10:L/n/
the value: 'KshiYAmp' was generated from the key: [:name] with pattern: 10-20:T_/x/
the value: '722' was generated from the key: [:draws, 0, :drawId] with pattern: 5:N
the value: '4' was generated from the key: [:draws, 0, :drawName] with pattern: 10:Ln
the value: 'jhVZkII' was generated from the key: [:draws, 0, :owner] with pattern: 20:L
the value: '260' was generated from the key: [:draws, 1, :drawId] with pattern: 5:N
the value: 'ssty8hlnJ' was generated from the key: [:draws, 1, :drawName] with pattern: 10:Ln
the value: 'zPvcwOyyXvWSgNHsuv' was generated from the key: [:draws, 1, :owner] with pattern: 20:L
the value: '242' was generated from the key: [:zip] with pattern: 5:N
the value: '(91)7606' was generated from the key: [:mobilePhone] with pattern: ["(", :"3:N", ")", :"6-8:N"]

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.

:length: wrong length, minimum or maximum
:min_length: wrong minimum length
:max_length: wrong maximum length
:value: wrong resultant value
:required_data: the output string won't include all necessary required data. It works only if required data supplied on the pattern.
: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.
:string_set_not_allowed: it will include one or more characters that are not supposed to be on the string.

Change only one value at a time and return an Array of Hashes

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.

Then the best thing you can do is to use the method NiceHash.change_one_by_one.

wrong_min_length_hash=my_hash.generate(:correct,errors::min_length)array_of_hashes=NiceHash.change_one_by_one([my_hash,:correct],wrong_min_length_hash)array_of_hashes.each{|hash_with_one_wrong_field|#Here your code to send through http the JSON data stored in hash_with_one_wrong_field
#if you want to know which field is the one that is wrong:
res=my_hash.validate(:correct,hash_with_one_wrong_field)}

Other useful methods

In class Date we added a very handy random method you can use to generate random dates.

# random date from today to 60 days after
putsDate.today.random(60)# random date from 01-09-2005 to 100 days later
putsDate.strptime('01-09-2005','%d-%m-%Y').random(100)# random date from 2003/10/31 to today
putsDate.new(2003,10,31).random(Date.today)