factory-helper 1.5.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.
- checksums.yaml +7 -0
- data/History.txt +126 -0
- data/License.txt +20 -0
- data/README.md +445 -0
- data/lib/extensions/array.rb +22 -0
- data/lib/extensions/symbol.rb +9 -0
- data/lib/factory-helper.rb +182 -0
- data/lib/factory-helper/address.rb +59 -0
- data/lib/factory-helper/app.rb +22 -0
- data/lib/factory-helper/avatar.rb +14 -0
- data/lib/factory-helper/bitcoin.rb +49 -0
- data/lib/factory-helper/business.rb +22 -0
- data/lib/factory-helper/code.rb +63 -0
- data/lib/factory-helper/commerce.rb +51 -0
- data/lib/factory-helper/company.rb +40 -0
- data/lib/factory-helper/date.rb +42 -0
- data/lib/factory-helper/finance.rb +26 -0
- data/lib/factory-helper/hacker.rb +31 -0
- data/lib/factory-helper/internet.rb +116 -0
- data/lib/factory-helper/lorem.rb +66 -0
- data/lib/factory-helper/name.rb +22 -0
- data/lib/factory-helper/number.rb +57 -0
- data/lib/factory-helper/phone_number.rb +52 -0
- data/lib/factory-helper/team.rb +20 -0
- data/lib/factory-helper/time.rb +48 -0
- data/lib/factory-helper/version.rb +3 -0
- data/lib/locales/de-AT.yml +49 -0
- data/lib/locales/de-CH.yml +19 -0
- data/lib/locales/de.yml +57 -0
- data/lib/locales/en-AU.yml +22 -0
- data/lib/locales/en-BORK.yml +4 -0
- data/lib/locales/en-CA.yml +14 -0
- data/lib/locales/en-GB.yml +13 -0
- data/lib/locales/en-IND.yml +20 -0
- data/lib/locales/en-NEP.yml +39 -0
- data/lib/locales/en-US.yml +83 -0
- data/lib/locales/en-au-ocker.yml +31 -0
- data/lib/locales/en.yml +155 -0
- data/lib/locales/es.yml +62 -0
- data/lib/locales/fa.yml +6 -0
- data/lib/locales/fr.yml +55 -0
- data/lib/locales/it.yml +59 -0
- data/lib/locales/ja.yml +25 -0
- data/lib/locales/ko.yml +37 -0
- data/lib/locales/nb-NO.yml +52 -0
- data/lib/locales/nl.yml +77 -0
- data/lib/locales/pl.yml +66 -0
- data/lib/locales/pt-BR.yml +57 -0
- data/lib/locales/ru.yml +65 -0
- data/lib/locales/sk.yml +72 -0
- data/lib/locales/sv.yml +76 -0
- data/lib/locales/vi.yml +63 -0
- data/lib/locales/zh-CN.yml +27 -0
- data/lib/locales/zh-TW.yml +27 -0
- metadata +140 -0
@@ -0,0 +1,22 @@
|
|
1
|
+
class Array
|
2
|
+
unless self.method_defined? :sample
|
3
|
+
def sample(n = nil)
|
4
|
+
#based on code from https://github.com/marcandre/backports
|
5
|
+
size = self.length
|
6
|
+
return self[Kernel.rand(size)] if n.nil?
|
7
|
+
|
8
|
+
n = n.to_int
|
9
|
+
raise ArgumentError, "negative array size" if n < 0
|
10
|
+
|
11
|
+
n = size if n > size
|
12
|
+
|
13
|
+
result = Array.new(self)
|
14
|
+
n.times do |i|
|
15
|
+
r = i + Kernel.rand(size - i)
|
16
|
+
result[i], result[r] = result[r], result[i]
|
17
|
+
end
|
18
|
+
result[n..size] = []
|
19
|
+
result
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,182 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
mydir = File.expand_path(File.dirname(__FILE__))
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'psych'
|
6
|
+
rescue LoadError
|
7
|
+
end
|
8
|
+
|
9
|
+
require 'i18n'
|
10
|
+
require 'set' # Fixes a bug in i18n 0.6.11
|
11
|
+
|
12
|
+
if I18n.respond_to?(:enforce_available_locales=)
|
13
|
+
I18n.enforce_available_locales = true
|
14
|
+
end
|
15
|
+
I18n.load_path += Dir[File.join(mydir, 'locales', '*.yml')]
|
16
|
+
|
17
|
+
|
18
|
+
module Faker
|
19
|
+
class Config
|
20
|
+
@locale = nil
|
21
|
+
|
22
|
+
class << self
|
23
|
+
attr_writer :locale
|
24
|
+
def locale
|
25
|
+
@locale || I18n.locale
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
class Base
|
31
|
+
Numbers = Array(0..9)
|
32
|
+
ULetters = Array('A'..'Z')
|
33
|
+
Letters = ULetters + Array('a'..'z')
|
34
|
+
|
35
|
+
class << self
|
36
|
+
## make sure numerify results doesn’t start with a zero
|
37
|
+
def numerify(number_string)
|
38
|
+
number_string.sub(/#/) { (rand(9)+1).to_s }.gsub(/#/) { rand(10).to_s }
|
39
|
+
end
|
40
|
+
|
41
|
+
def letterify(letter_string)
|
42
|
+
letter_string.gsub(/\?/) { ULetters.sample }
|
43
|
+
end
|
44
|
+
|
45
|
+
def bothify(string)
|
46
|
+
letterify(numerify(string))
|
47
|
+
end
|
48
|
+
|
49
|
+
# Given a regular expression, attempt to generate a string
|
50
|
+
# that would match it. This is a rather simple implementation,
|
51
|
+
# so don't be shocked if it blows up on you in a spectacular fashion.
|
52
|
+
#
|
53
|
+
# It does not handle ., *, unbounded ranges such as {1,},
|
54
|
+
# extensions such as (?=), character classes, some abbreviations
|
55
|
+
# for character classes, and nested parentheses.
|
56
|
+
#
|
57
|
+
# I told you it was simple. :) It's also probably dog-slow,
|
58
|
+
# so you shouldn't use it.
|
59
|
+
#
|
60
|
+
# It will take a regex like this:
|
61
|
+
#
|
62
|
+
# /^[A-PR-UWYZ0-9][A-HK-Y0-9][AEHMNPRTVXY0-9]?[ABEHMNPRVWXY0-9]? {1,2}[0-9][ABD-HJLN-UW-Z]{2}$/
|
63
|
+
#
|
64
|
+
# and generate a string like this:
|
65
|
+
#
|
66
|
+
# "U3V 3TP"
|
67
|
+
#
|
68
|
+
def regexify(re)
|
69
|
+
re = re.source if re.respond_to?(:source) # Handle either a Regexp or a String that looks like a Regexp
|
70
|
+
re.
|
71
|
+
gsub(/^\/?\^?/, '').gsub(/\$?\/?$/, ''). # Ditch the anchors
|
72
|
+
gsub(/\{(\d+)\}/, '{\1,\1}').gsub(/\?/, '{0,1}'). # All {2} become {2,2} and ? become {0,1}
|
73
|
+
gsub(/(\[[^\]]+\])\{(\d+),(\d+)\}/) {|match| $1 * Array(Range.new($2.to_i, $3.to_i)).sample }. # [12]{1,2} becomes [12] or [12][12]
|
74
|
+
gsub(/(\([^\)]+\))\{(\d+),(\d+)\}/) {|match| $1 * Array(Range.new($2.to_i, $3.to_i)).sample }. # (12|34){1,2} becomes (12|34) or (12|34)(12|34)
|
75
|
+
gsub(/(\\?.)\{(\d+),(\d+)\}/) {|match| $1 * Array(Range.new($2.to_i, $3.to_i)).sample }. # A{1,2} becomes A or AA or \d{3} becomes \d\d\d
|
76
|
+
gsub(/\((.*?)\)/) {|match| match.gsub(/[\(\)]/, '').split('|').sample }. # (this|that) becomes 'this' or 'that'
|
77
|
+
gsub(/\[([^\]]+)\]/) {|match| match.gsub(/(\w\-\w)/) {|range| Array(Range.new(*range.split('-'))).sample } }. # All A-Z inside of [] become C (or X, or whatever)
|
78
|
+
gsub(/\[([^\]]+)\]/) {|match| $1.split('').sample }. # All [ABC] become B (or A or C)
|
79
|
+
gsub('\d') {|match| Numbers.sample }.
|
80
|
+
gsub('\w') {|match| Letters.sample }
|
81
|
+
end
|
82
|
+
|
83
|
+
# Helper for the common approach of grabbing a translation
|
84
|
+
# with an array of values and selecting one of them.
|
85
|
+
def fetch(key)
|
86
|
+
fetched = translate("faker.#{key}")
|
87
|
+
fetched = fetched.sample if fetched.respond_to?(:sample)
|
88
|
+
if fetched.match(/^\//) and fetched.match(/\/$/) # A regex
|
89
|
+
regexify(fetched)
|
90
|
+
else
|
91
|
+
fetched
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
# Load formatted strings from the locale, "parsing" them
|
96
|
+
# into method calls that can be used to generate a
|
97
|
+
# formatted translation: e.g., "#{first_name} #{last_name}".
|
98
|
+
def parse(key)
|
99
|
+
fetch(key).scan(/(\(?)#\{([A-Za-z]+\.)?([^\}]+)\}([^#]+)?/).map {|prefix, kls, meth, etc|
|
100
|
+
# If the token had a class Prefix (e.g., Name.first_name)
|
101
|
+
# grab the constant, otherwise use self
|
102
|
+
cls = kls ? Faker.const_get(kls.chop) : self
|
103
|
+
|
104
|
+
# If an optional leading parentheses is not present, prefix.should == "", otherwise prefix.should == "("
|
105
|
+
# In either case the information will be retained for reconstruction of the string.
|
106
|
+
text = prefix
|
107
|
+
|
108
|
+
# If the class has the method, call it, otherwise
|
109
|
+
# fetch the transation (i.e., faker.name.first_name)
|
110
|
+
text += cls.respond_to?(meth) ? cls.send(meth) : fetch("#{(kls || self).to_s.split('::').last.downcase}.#{meth.downcase}")
|
111
|
+
|
112
|
+
# And tack on spaces, commas, etc. left over in the string
|
113
|
+
text += etc.to_s
|
114
|
+
}.join
|
115
|
+
end
|
116
|
+
|
117
|
+
# Call I18n.translate with our configured locale if no
|
118
|
+
# locale is specified
|
119
|
+
def translate(*args)
|
120
|
+
opts = args.last.is_a?(Hash) ? args.pop : {}
|
121
|
+
opts[:locale] ||= Faker::Config.locale
|
122
|
+
opts[:raise] = true
|
123
|
+
I18n.translate(*(args.push(opts)))
|
124
|
+
rescue I18n::MissingTranslationData
|
125
|
+
# Super-simple fallback -- fallback to en if the
|
126
|
+
# translation was missing. If the translation isn't
|
127
|
+
# in en either, then it will raise again.
|
128
|
+
I18n.translate(*(args.push(opts.merge(:locale => :en))))
|
129
|
+
end
|
130
|
+
|
131
|
+
def flexible(key)
|
132
|
+
@flexible_key = key
|
133
|
+
end
|
134
|
+
|
135
|
+
# You can add whatever you want to the locale file, and it will get caught here.
|
136
|
+
# E.g., in your locale file, create a
|
137
|
+
# name:
|
138
|
+
# girls_name: ["Alice", "Cheryl", "Tatiana"]
|
139
|
+
# Then you can call Faker::Name.girls_name and it will act like #first_name
|
140
|
+
def method_missing(m, *args, &block)
|
141
|
+
super unless @flexible_key
|
142
|
+
|
143
|
+
# Use the alternate form of translate to get a nil rather than a "missing translation" string
|
144
|
+
if translation = translate(:faker)[@flexible_key][m]
|
145
|
+
translation.respond_to?(:sample) ? translation.sample : translation
|
146
|
+
else
|
147
|
+
super
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
# Generates a random value between the interval
|
152
|
+
def rand_in_range(from, to)
|
153
|
+
from, to = to, from if to < from
|
154
|
+
Random.new.rand(from..to)
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
require_relative 'factory-helper/address'
|
161
|
+
require_relative 'factory-helper/code'
|
162
|
+
require_relative 'factory-helper/company'
|
163
|
+
require_relative 'factory-helper/finance'
|
164
|
+
require_relative 'factory-helper/internet'
|
165
|
+
require_relative 'factory-helper/lorem'
|
166
|
+
require_relative 'factory-helper/name'
|
167
|
+
require_relative 'factory-helper/team'
|
168
|
+
require_relative 'factory-helper/phone_number'
|
169
|
+
require_relative 'factory-helper/business'
|
170
|
+
require_relative 'factory-helper/commerce'
|
171
|
+
require_relative 'factory-helper/version'
|
172
|
+
require_relative 'factory-helper/number'
|
173
|
+
require_relative 'factory-helper/bitcoin'
|
174
|
+
require_relative 'factory-helper/avatar'
|
175
|
+
require_relative 'factory-helper/date'
|
176
|
+
require_relative 'factory-helper/time'
|
177
|
+
require_relative 'factory-helper/number'
|
178
|
+
require_relative 'factory-helper/hacker'
|
179
|
+
require_relative 'factory-helper/app'
|
180
|
+
|
181
|
+
require_relative 'extensions/array'
|
182
|
+
require_relative 'extensions/symbol'
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module Faker
|
2
|
+
class Address < Base
|
3
|
+
flexible :address
|
4
|
+
|
5
|
+
class << self
|
6
|
+
def city
|
7
|
+
parse('address.city')
|
8
|
+
end
|
9
|
+
|
10
|
+
def street_name
|
11
|
+
parse('address.street_name')
|
12
|
+
end
|
13
|
+
|
14
|
+
def street_address(include_secondary = false)
|
15
|
+
numerify(parse('address.street_address') + (include_secondary ? ' ' + secondary_address : ''))
|
16
|
+
end
|
17
|
+
|
18
|
+
def secondary_address
|
19
|
+
numerify(fetch('address.secondary_address'))
|
20
|
+
end
|
21
|
+
|
22
|
+
def building_number
|
23
|
+
bothify(fetch('address.building_number'))
|
24
|
+
end
|
25
|
+
|
26
|
+
def zip_code(state_abbreviation = '')
|
27
|
+
return bothify(fetch('address.postcode')) if state_abbreviation === ''
|
28
|
+
|
29
|
+
# provide a zip code that is valid for the state provided
|
30
|
+
# see http://www.fincen.gov/forms/files/us_state_territory_zip_codes.pdf
|
31
|
+
bothify(fetch('address.postcode_by_state.' + state_abbreviation))
|
32
|
+
end
|
33
|
+
|
34
|
+
def time_zone
|
35
|
+
fetch('address.time_zone')
|
36
|
+
end
|
37
|
+
|
38
|
+
alias_method :zip, :zip_code
|
39
|
+
alias_method :postcode, :zip_code
|
40
|
+
|
41
|
+
def street_suffix; fetch('address.street_suffix'); end
|
42
|
+
def city_suffix; fetch('address.city_suffix'); end
|
43
|
+
def city_prefix; fetch('address.city_prefix'); end
|
44
|
+
def state_abbr; fetch('address.state_abbr'); end
|
45
|
+
def state; fetch('address.state'); end
|
46
|
+
def country; fetch('address.country'); end
|
47
|
+
def country_code; fetch('address.country_code'); end
|
48
|
+
|
49
|
+
def latitude
|
50
|
+
((rand * 180) - 90).to_s
|
51
|
+
end
|
52
|
+
|
53
|
+
def longitude
|
54
|
+
((rand * 360) - 180).to_s
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Faker
|
2
|
+
class App < Base
|
3
|
+
class << self
|
4
|
+
|
5
|
+
def name
|
6
|
+
fetch('app.name')
|
7
|
+
end
|
8
|
+
|
9
|
+
def version
|
10
|
+
if parse('app.version') == ""
|
11
|
+
numerify(fetch('app.version'))
|
12
|
+
else
|
13
|
+
parse('app.version')
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def author
|
18
|
+
parse('app.author')
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Faker
|
2
|
+
class Avatar < Base
|
3
|
+
class << self
|
4
|
+
SUPPORTED_FORMATS = %w(png jpg bmp)
|
5
|
+
|
6
|
+
def image(slug = nil, size = '300x300', format = 'png')
|
7
|
+
raise ArgumentError, "Size should be specified in format 300x300" unless size.match(/^[0-9]+x[0-9]+$/)
|
8
|
+
raise ArgumentError, "Supported formats are #{SUPPORTED_FORMATS.join(', ')}" unless SUPPORTED_FORMATS.include?(format)
|
9
|
+
slug ||= Faker::Lorem.words.join
|
10
|
+
"http://robohash.org/#{slug}.#{format}?size=#{size}"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'digest'
|
2
|
+
require 'securerandom'
|
3
|
+
|
4
|
+
module Faker
|
5
|
+
class Bitcoin < Base
|
6
|
+
class << self
|
7
|
+
|
8
|
+
PROTOCOL_VERSIONS = {
|
9
|
+
main: 0,
|
10
|
+
testnet: 111
|
11
|
+
}
|
12
|
+
|
13
|
+
def address
|
14
|
+
address_for(:main)
|
15
|
+
end
|
16
|
+
|
17
|
+
def testnet_address
|
18
|
+
address_for(:testnet)
|
19
|
+
end
|
20
|
+
|
21
|
+
protected
|
22
|
+
|
23
|
+
def base58(str)
|
24
|
+
alphabet = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
|
25
|
+
base = alphabet.size
|
26
|
+
|
27
|
+
lv = 0
|
28
|
+
str.split('').reverse.each_with_index { |v,i| lv += v.unpack('C')[0] * 256**i }
|
29
|
+
|
30
|
+
ret = ''
|
31
|
+
while lv > 0 do
|
32
|
+
lv, mod = lv.divmod(base)
|
33
|
+
ret << alphabet[mod]
|
34
|
+
end
|
35
|
+
|
36
|
+
npad = str.match(/^#{0.chr}*/)[0].to_s.size
|
37
|
+
'1'*npad + ret.reverse
|
38
|
+
end
|
39
|
+
|
40
|
+
def address_for(network)
|
41
|
+
version = PROTOCOL_VERSIONS.fetch(network)
|
42
|
+
hash = SecureRandom.hex(20)
|
43
|
+
packed = version.chr + [hash].pack("H*")
|
44
|
+
checksum = Digest::SHA2.digest(Digest::SHA2.digest(packed))[0..3]
|
45
|
+
base58(packed + checksum)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'date'
|
2
|
+
|
3
|
+
module Faker
|
4
|
+
class Business < Base
|
5
|
+
flexible :business
|
6
|
+
|
7
|
+
class << self
|
8
|
+
def credit_card_number
|
9
|
+
fetch('business.credit_card_numbers')
|
10
|
+
end
|
11
|
+
|
12
|
+
def credit_card_expiry_date
|
13
|
+
::Date.parse(fetch('business.credit_card_expiry_dates'))
|
14
|
+
end
|
15
|
+
|
16
|
+
def credit_card_type
|
17
|
+
fetch('business.credit_card_types')
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
module Faker
|
2
|
+
class Code < Base
|
3
|
+
class << self
|
4
|
+
# By default generates 10 sign isbn code in format 123456789-X
|
5
|
+
# You can pass 13 to generate new 13 sign code
|
6
|
+
def isbn(base = 10)
|
7
|
+
base == 13 ? generate_base13_isbn : generate_base10_isbn
|
8
|
+
end
|
9
|
+
|
10
|
+
# By default generates 13 sign ean code in format 1234567890123
|
11
|
+
# You can pass 8 to generate ean8 code
|
12
|
+
def ean(base = 13)
|
13
|
+
base == 8 ? generate_base8_ean : generate_base13_ean
|
14
|
+
end
|
15
|
+
|
16
|
+
def rut
|
17
|
+
value = Number.number(8)
|
18
|
+
vd = rut_verificator_digit(value)
|
19
|
+
value << "-#{vd}"
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def generate_base10_isbn
|
25
|
+
values = regexify(/\d{9}/)
|
26
|
+
remainder = sum(values) { |value, index| (index + 1) * value.to_i } % 11
|
27
|
+
values << "-#{remainder == 10 ? 'X' : remainder}"
|
28
|
+
end
|
29
|
+
|
30
|
+
def generate_base13_isbn
|
31
|
+
values = regexify(/\d{12}/)
|
32
|
+
remainder = sum(values) { |value, index| index.even? ? value.to_i : value.to_i * 3 } % 10
|
33
|
+
values << "-#{((10 - remainder) % 10)}"
|
34
|
+
end
|
35
|
+
|
36
|
+
def sum(values, &block)
|
37
|
+
values.split(//).each_with_index.inject(0) do |sum, (value, index)|
|
38
|
+
sum + block.call(value, index)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def generate_base8_ean
|
43
|
+
values = regexify(/\d{7}/)
|
44
|
+
check_digit = 10 - values.split(//).each_with_index.inject(0){ |s, (v, i)| s + v.to_i * EAN_CHECK_DIGIT8[i] } % 10
|
45
|
+
values << (check_digit == 10 ? 0 : check_digit).to_s
|
46
|
+
end
|
47
|
+
|
48
|
+
def generate_base13_ean
|
49
|
+
values = regexify(/\d{12}/)
|
50
|
+
check_digit = 10 - values.split(//).each_with_index.inject(0){ |s, (v, i)| s + v.to_i * EAN_CHECK_DIGIT13[i] } % 10
|
51
|
+
values << (check_digit == 10 ? 0 : check_digit).to_s
|
52
|
+
end
|
53
|
+
|
54
|
+
EAN_CHECK_DIGIT8 = [3, 1, 3, 1, 3, 1, 3]
|
55
|
+
EAN_CHECK_DIGIT13 = [1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3]
|
56
|
+
|
57
|
+
def rut_verificator_digit(rut)
|
58
|
+
total = rut.to_s.rjust(8, '0').split(//).zip(%w(3 2 7 6 5 4 3 2)).collect{|a, b| a.to_i * b.to_i}.inject(:+)
|
59
|
+
(11 - total % 11).to_s.gsub(/10/, 'k').gsub(/11/, '0')
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|