Skip to content

Commit

Permalink
Add Faker::Json (#1156)
Browse files Browse the repository at this point in the history
* Add Faker::Json with tests and documentation

* Fix rubo cop erros

add expetions to rubocop.yml

* Fix rubocop erros in test_faker_json.rb

* Update json.md

* Update json.rb

* Update test_faker_json.rb

* Update test_faker_json.rb

* Update json.rb

* Update .rubocop.yml
  • Loading branch information
the-wendell authored and vbrazo committed Sep 18, 2018
1 parent 644321d commit f01ae29
Show file tree
Hide file tree
Showing 4 changed files with 172 additions and 0 deletions.
11 changes: 11 additions & 0 deletions .rubocop.yml
Expand Up @@ -25,7 +25,18 @@ Style/DateTime:
Enabled: false
Style/Documentation:
Enabled: false
Style/EvalWithLocation:
Exclude:
- 'lib/faker/json.rb'
Style/FrozenStringLiteralComment:
Exclude:
- 'lib/faker/json.rb'
- 'test/test_faker_json.rb'
Style/For:
Enabled: false
Style/RegexpLiteral:
Enabled: false

Security/Eval:
Exclude:
- 'lib/faker/json.rb'
64 changes: 64 additions & 0 deletions doc/json.md
@@ -0,0 +1,64 @@
# Faker::Json

**shallow_json(width_int, options_hash)** -> JSON formated string

Takes a width_int and options_hash where the number of key value pairs in the
returned JSON string is equal to the width_int.

`options_hash = {key: Class.method, value: Class.method}` where Class is
any class in the Faker gem. For example if you want random names for keys
and random Star Wars quotes for values you would write the options_hash as follows
```ruby
options_hash = { key: 'Name.first_name', value: 'StarWars.quote' }
```

It is important to note that you do not need to append your Faker Gem Class calls
with `Faker::`

```ruby
Faker::Json.shallow_json(3, key: 'RockBand.name', value: 'Seinfeld.quote')
# =>
{"Parliament Funkadelic":"They're real, and they're spectacular.",
"Fleetwood Mac":"I'm not a lesbian. I hate men, but I'm not a lesbian.",
"The Roots":"It became very clear to me sitting out there today that every decision
I've made in my entire life has been wrong. My life is the complete opposite of everything
I want it to be. Every instinct I have, in every aspect of life, be it something to wear,
something to eat - it's all been wrong."}
```

**add_depth_to_json(JSON, width_int, options_hash)** -> JSON

Functions exactly as `Json#shallow_json()` except it takes in a JSON as an
additional argument and returns that JSON with new generated nested JSONs in
place of the lowest nested values. It is important to note that the JSON must
be a JSON and not a hash.

```ruby
json = Faker::Json.shallow_json(3, key: 'Name.first_name', value: 'Name.last_name')
puts json # =>
{"Alisha":"Olson","Everardo":"DuBuque","Bridgette":"Turner"}

json2 = Faker::Json.add_depth_to_json(json, 2, key: 'Name.first_name', value: 'Name.last_name')
puts json2 # =>
{"Alisha":{"Daisy":"Trantow","Oda":"Haag"},
"Everardo":{"Javier":"Marvin","Eliseo":"Schuppe"},
"Bridgette":{"Jorge":"Kertzmann","Lelah":"MacGyver"}}

json3 = Faker::Json.add_depth_to_json(json2, 4, key: 'Name.first_name', value: 'Name.last_name')
puts json3 # =>
{"Alisha":
{"Daisy":
{"Bulah":"Wunsch","Cristian":"Champlin","Lester":"Bartoletti","Greg":"Jacobson"},
"Oda":
{"Salvatore":"Kuhlman","Aubree":"Okuneva","Larry":"Schmitt","Velva":"Gibson"}},
"Everardo":
{"Javier":
{"Eduardo":"Orn","Laila":"Kub","Thad":"Legros","Dion":"Wilderman"},
"Eliseo":
{"Olin":"Hilpert","Marisa":"Greenfelder","Karlee":"Schmitt","Judd":"Larkin"}},
"Bridgette":
{"Jorge":
{"Eloy":"Pfeffer","Kody":"Hansen","Paxton":"Lubowitz","Abe":"Lesch"},
"Lelah":
{"Rick":"Wiza","Bonita":"Bayer","Gardner":"Auer","Felicity":"Abbott"}}}
```
70 changes: 70 additions & 0 deletions lib/faker/json.rb
@@ -0,0 +1,70 @@
module Faker
class Json < Base
require 'json'

class << self
def shallow_json(width = 3, options = { key: 'Name.first_name', value: 'Name.first_name' })
options[:key] = options[:key].prepend('Faker::')
options[:value] = options[:value].prepend('Faker::')

hash = build_shallow_hash(width, options)
JSON.generate(hash)
end

def add_depth_to_json(json = shallow_json, width = 3, options = { key: 'Name.first_name', value: 'Name.first_name' })
options[:key] = options[:key].prepend('Faker::')
options[:value] = options[:value].prepend('Faker::')

hash = JSON.parse(json)
hash.each do |key, _|
add_hash_to_bottom(hash, [key], width, options)
end
JSON.generate(hash)
end

private

def build_shallow_hash(width, options)
key = options[:key]
value = options[:value]

hash = {}
width.times do
hash[eval(key)] = eval(value)
end
hash
end

def add_hash_to_bottom(hash, key_array, width, options)
key_string = build_keys_from_array(key_array)
if eval("hash#{key_string}").is_a?(::Hash)
eval("hash#{key_string}").each do |key, _|
key_array << key
add_hash_to_bottom(hash, key_array, width, options)
end
else
add_hash(key_array, hash, width, options)
key_array.pop
end
end

def add_hash(key_array, hash, width, options)
string_to_eval = 'hash'
key_array.length.times do |index|
string_to_eval << "['#{key_array[index]}']"
end
string_to_eval << " = #{build_shallow_hash(width, options)}"
eval(string_to_eval)
hash
end

def build_keys_from_array(key_array)
key_string = ''
key_array.each do |value|
key_string << "['#{value}']"
end
key_string
end
end
end
end
27 changes: 27 additions & 0 deletions test/test_faker_json.rb
@@ -0,0 +1,27 @@
require File.expand_path(File.dirname(__FILE__) + '/test_helper.rb')

class TestFakerJson < Test::Unit::TestCase
require 'json'

def setup
@tester = Faker::Json
end

def test_shallow_json
json = Faker::Json.shallow_json(3, key: 'Name.first_name', value: 'Name.first_name')
assert JSON.parse(json).flatten.length.equal?(6)
end

def test_add_depth_to_json
json = Faker::Json.shallow_json(3, key: 'Name.first_name', value: 'Name.first_name')
json = Faker::Json.add_depth_to_json(json, 3, key: 'Name.first_name', value: 'Name.first_name')
assert JSON.parse(json).flatten[1].flatten.length.equal?(6)
assert JSON.parse(json).flatten[3].flatten.length.equal?(6)
assert JSON.parse(json).flatten[5].flatten.length.equal?(6)

json = Faker::Json.add_depth_to_json(json, 3, key: 'Name.first_name', value: 'Name.first_name')
assert JSON.parse(json).flatten[1].flatten[1].flatten.length.equal?(6)
assert JSON.parse(json).flatten[3].flatten[3].flatten.length.equal?(6)
assert JSON.parse(json).flatten[5].flatten[5].flatten.length.equal?(6)
end
end

0 comments on commit f01ae29

Please sign in to comment.