Skip to content

Commit

Permalink
Merge pull request #7 from rickychilcott/feature/unique
Browse files Browse the repository at this point in the history
Generate unique address
  • Loading branch information
askn authored Jun 26, 2019
2 parents 5b53bf1 + 06ad8f0 commit 83c9388
Show file tree
Hide file tree
Showing 19 changed files with 208 additions and 17 deletions.
5 changes: 5 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
language: crystal
crystal:
- latest
- nightly
script:
- crystal spec
- crystal run examples/test.cr
- crystal run examples/test2.cr
35 changes: 32 additions & 3 deletions examples/test.cr
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,15 @@ puts Faker::Address.longitude
puts "\n### Faker::Commerce\n\n"

puts Faker::Commerce.color
puts Faker::Commerce.unique_color
puts Faker::Commerce.department
puts Faker::Commerce.unique_department
puts Faker::Commerce.unique_department(2)
puts Faker::Commerce.unique_department(2, true)
puts Faker::Commerce.product_name
puts Faker::Commerce.price
puts Faker::Commerce.unique_price
puts Faker::Commerce.unique_price(0.0..10_000.00)

puts "\n### Faker::Company\n\n"

Expand All @@ -38,10 +44,16 @@ puts "\n\t### Faker::Internet\n\n"

puts Faker::Internet.email
puts Faker::Internet.email("Nancy")
puts Faker::Internet.unique_email("Nancy")
puts Faker::Internet.unique_email("Nancy")
puts Faker::Internet.free_email
puts Faker::Internet.unique_free_email
puts Faker::Internet.free_email("Nancy")
puts Faker::Internet.unique_free_email("Nancy")
puts Faker::Internet.safe_email
puts Faker::Internet.unique_safe_email
puts Faker::Internet.safe_email("Nancy")
puts Faker::Internet.unique_safe_email("Nancy")

puts Faker::Internet.user_name
puts Faker::Internet.user_name("Nancy")
Expand Down Expand Up @@ -88,19 +100,36 @@ puts Faker::Name.prefix
puts Faker::Name.suffix
puts Faker::Name.title

puts "\n\t### Faker::Avatar\n\n"

puts Faker::Avatar.image
puts Faker::Avatar.image("borp")
puts Faker::Avatar.unique_image("borp")
puts Faker::Avatar.unique_image("borp")

puts "\n\t### Faker::Number\n\n"

puts Faker::Number.number(10)
# puts Faker::Number.unique_number(10)
# puts Faker::Number.unique_number(10)
# puts Faker::Number.unique_number(10)
puts Faker::Number.decimal(2)
puts Faker::Number.decimal(2, 3)
puts Faker::Number.unique_decimal(2)
# puts Faker::Number.unique_decimal(2, 3)
puts Faker::Number.digit
puts Faker::Number.unique_digit

puts "\n\t### Faker::PhoneNumber\n\n"

puts Faker::PhoneNumber.phone_number

puts "\n\t### Faker::Business\n\n"

p Faker::Business.credit_card_number
p Faker::Business.credit_card_expiry_date
p Faker::Business.credit_card_type
puts Faker::Business.credit_card_number
puts Faker::Business.credit_card_expiry_date
puts Faker::Business.credit_card_type

puts Faker::Business.unique_credit_card_number
puts Faker::Business.unique_credit_card_expiry_date
puts Faker::Business.unique_credit_card_type
11 changes: 11 additions & 0 deletions spec/address_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,15 @@ describe Faker::Address do
Faker::Address.latitude.should eq "-23.850993082533705"
Faker::Address.longitude.should eq "-4.488135572134695"
end

it "should generate unique result" do
Faker.seed 123456
vals = Array(String).new

10_000.times do |t|
vals << Faker::Address.unique_city
end

vals.size.should eq vals.uniq.size
end
end
2 changes: 1 addition & 1 deletion spec/internet_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ describe Faker::Internet do
it "password_max_with_integer_arg" do
(1..32).to_a.each do |min_length|
max_length = min_length + 4
(Faker::Internet.password(min_length, max_length).size <= max_length).should be_true
(Faker::Internet.password(min_length, max_length).size <= max_length).should be_true
end
end

Expand Down
1 change: 1 addition & 0 deletions src/faker.cr
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
require "./data.cr"
require "./faker/base"
require "./faker/*"

module Faker
Expand Down
23 changes: 22 additions & 1 deletion src/faker/address.cr
Original file line number Diff line number Diff line change
@@ -1,26 +1,33 @@
module Faker
class Address
class Address < Base
def self.zip_code
Faker.numerify(["#####", "#####-####"].sample(Faker.rng))
end

uniquify_builder(zip_code)

{% for data_type in %w(state state_abbr city_suffix city_prefix country street_suffix country_code) %}
def self.{{data_type.id}}
Faker.fetch(Data["address"]["{{data_type.id}}"])
end
uniquify_builder({{data_type.id}})
{% end %}

def self.city
Faker.fetch(Data["address"]["city"])
end

uniquify_builder(city)

def self.street_name
[
->{ [Name.last_name, street_suffix].join(" ") },
->{ [Name.first_name, street_suffix].join(" ") },
].sample(Faker.rng).call
end

uniquify_builder(street_name)

def self.street_address
Faker.numerify([
->{ "##### %s" % street_name },
Expand All @@ -32,31 +39,45 @@ module Faker
].sample(Faker.rng).call)
end

uniquify_builder(street_address)

def self.secondary_address
Faker.numerify(Faker.fetch(Data["address"]["secondary_address"]))
end

uniquify_builder(street_address)

def self.building_number
Faker.bothify(Faker.fetch(Data["address"]["building_number"]))
end

uniquify_builder(building_number)

def self.postcode
Faker.bothify([
->{ "??# #??" },
->{ "??## #??" },
].sample(Faker.rng).call)
end

uniquify_builder(postcode)

def self.latitude
((Faker.rng.rand * 180) - 90).to_s
end

uniquify_builder(latitude)

def self.longitude
((Faker.rng.rand * 360) - 180).to_s
end

uniquify_builder(longitude)

def self.time_zone
Faker.fetch(Data["address"]["time_zone"])
end

uniquify_builder(time_zone)
end
end
4 changes: 3 additions & 1 deletion src/faker/avatar.cr
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
module Faker
class Avatar
class Avatar < Base
def self.image(slug = nil)
slug ||= Faker::Lorem.word
"http://robohash.org/#{slug}"
end

uniquify_builder(image, slug = nil)
end
end
25 changes: 25 additions & 0 deletions src/faker/base.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
module Faker
class NonUniqueValue < Exception
end

class Base
alias Any = String | Int32 | Float64 | Time

macro uniquify_builder(attribute_name, *modified_method_attributes)
@@__unique_vals_for_{{attribute_name}} = Array(Any).new

def self.unique_{{attribute_name}}({% if !modified_method_attributes.empty? %}{{*modified_method_attributes}},{% end %} max_retries = 10_0000)
max_retries.times do |t|
val = self.{{attribute_name}}({{*modified_method_attributes}})

if !@@__unique_vals_for_{{attribute_name}}.includes?(val)
@@__unique_vals_for_{{attribute_name}} << val
return val
end
end

raise NonUniqueValue.new("Unable to generate unique value for {{attribute_name}}")
end
end
end
end
8 changes: 7 additions & 1 deletion src/faker/business.cr
Original file line number Diff line number Diff line change
@@ -1,16 +1,22 @@
module Faker
class Business
class Business < Base
def self.credit_card_number
Faker.fetch(Data["business"]["credit_card_numbers"])
end

uniquify_builder(credit_card_number)

def self.credit_card_expiry_date
credit_card_expiry_date = Faker.fetch(Data["business"]["credit_card_expiry_dates"]).as String
Time.parse_local(credit_card_expiry_date, "%Y-%m-%d")
end

uniquify_builder(credit_card_expiry_date)

def self.credit_card_type
Faker.fetch(Data["business"]["credit_card_types"])
end

uniquify_builder(credit_card_type)
end
end
12 changes: 11 additions & 1 deletion src/faker/commerce.cr
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
module Faker
class Commerce
class Commerce < Base
def self.color
Faker.fetch(Data["color"]["name"])
end

uniquify_builder(color)

def self.department(max = 3, fixed_amount = false)
num = max if fixed_amount
num ||= 1 + Faker.rng.rand(max)
Expand All @@ -17,20 +19,28 @@ module Faker
end
end

uniquify_builder(department, max = 3, fixed_amount = false)

def self.material
product_name = Data["commerce"]["product_name"].as Hash
Faker.fetch(product_name["material"])
end

uniquify_builder(material)

def self.product_name
product_name = Data["commerce"]["product_name"].as Hash
Faker.fetch(product_name["adjective"]) + " " + Faker.fetch(product_name["material"]) + " " + Faker.fetch(product_name["product"])
end

uniquify_builder(product_name)

def self.price(range = 0.0..100.0)
(Faker.rng.rand(range) * 100).floor/100.0
end

uniquify_builder(price, range = 0.0..100.0)

private def self.categories(num)
categories = [] of String
while categories.size < num
Expand Down
12 changes: 11 additions & 1 deletion src/faker/company.cr
Original file line number Diff line number Diff line change
@@ -1,26 +1,36 @@
module Faker
class Company
class Company < Base
def self.name
Faker.fetch(Data["company"]["name"])
end

uniquify_builder(name)

def self.suffix
Faker.fetch(Data["company"]["suffix"])
end

uniquify_builder(suffix)

def self.catch_phrase
data = Data["company"]["buzzwords"].as Array(Array(String))
Faker.fetch(data.flatten)
end

uniquify_builder(catch_phrase)

def self.bs
data = Data["company"]["bs"].as Array(Array(String))
Faker.fetch(data.flatten)
end

uniquify_builder(bs)

def self.logo
rand_num = Faker.rng.rand(13) + 1
"https://pigment.github.io/fake-logos/logos/medium/color/#{rand_num}.png"
end

uniquify_builder(logo)
end
end
3 changes: 2 additions & 1 deletion src/faker/finance.cr
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
module Faker
class Finance
class Finance < Base
CREDIT_CARD_TYPES = (Data["credit_card"].as(Hash)).keys

def self.credit_card(types : Array = [] of Array(String))
Expand All @@ -21,5 +21,6 @@ module Faker
template = template.gsub "L", luhn_digit.to_s
template
end
# TODO: uniquify_builder(credit_card, types : Array = [] of Array(String))
end
end
5 changes: 4 additions & 1 deletion src/faker/hacker.cr
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
# Port of http://shinytoylabs.com/jargon/
module Faker
class Hacker
class Hacker < Base
def self.say_something_smart
phrases.sample(Faker.rng)
end

uniquify_builder(say_something_smart)

{% for data_type in %w(abbreviation adjective noun verb ingverb) %}
def self.{{data_type.id}}
Faker.fetch(Data["hacker"]["{{data_type.id}}"])
end
uniquify_builder({{data_type.id}})
{% end %}

def self.phrases
Expand Down
Loading

0 comments on commit 83c9388

Please sign in to comment.