factory-helper 1.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. checksums.yaml +7 -0
  2. data/History.txt +126 -0
  3. data/License.txt +20 -0
  4. data/README.md +445 -0
  5. data/lib/extensions/array.rb +22 -0
  6. data/lib/extensions/symbol.rb +9 -0
  7. data/lib/factory-helper.rb +182 -0
  8. data/lib/factory-helper/address.rb +59 -0
  9. data/lib/factory-helper/app.rb +22 -0
  10. data/lib/factory-helper/avatar.rb +14 -0
  11. data/lib/factory-helper/bitcoin.rb +49 -0
  12. data/lib/factory-helper/business.rb +22 -0
  13. data/lib/factory-helper/code.rb +63 -0
  14. data/lib/factory-helper/commerce.rb +51 -0
  15. data/lib/factory-helper/company.rb +40 -0
  16. data/lib/factory-helper/date.rb +42 -0
  17. data/lib/factory-helper/finance.rb +26 -0
  18. data/lib/factory-helper/hacker.rb +31 -0
  19. data/lib/factory-helper/internet.rb +116 -0
  20. data/lib/factory-helper/lorem.rb +66 -0
  21. data/lib/factory-helper/name.rb +22 -0
  22. data/lib/factory-helper/number.rb +57 -0
  23. data/lib/factory-helper/phone_number.rb +52 -0
  24. data/lib/factory-helper/team.rb +20 -0
  25. data/lib/factory-helper/time.rb +48 -0
  26. data/lib/factory-helper/version.rb +3 -0
  27. data/lib/locales/de-AT.yml +49 -0
  28. data/lib/locales/de-CH.yml +19 -0
  29. data/lib/locales/de.yml +57 -0
  30. data/lib/locales/en-AU.yml +22 -0
  31. data/lib/locales/en-BORK.yml +4 -0
  32. data/lib/locales/en-CA.yml +14 -0
  33. data/lib/locales/en-GB.yml +13 -0
  34. data/lib/locales/en-IND.yml +20 -0
  35. data/lib/locales/en-NEP.yml +39 -0
  36. data/lib/locales/en-US.yml +83 -0
  37. data/lib/locales/en-au-ocker.yml +31 -0
  38. data/lib/locales/en.yml +155 -0
  39. data/lib/locales/es.yml +62 -0
  40. data/lib/locales/fa.yml +6 -0
  41. data/lib/locales/fr.yml +55 -0
  42. data/lib/locales/it.yml +59 -0
  43. data/lib/locales/ja.yml +25 -0
  44. data/lib/locales/ko.yml +37 -0
  45. data/lib/locales/nb-NO.yml +52 -0
  46. data/lib/locales/nl.yml +77 -0
  47. data/lib/locales/pl.yml +66 -0
  48. data/lib/locales/pt-BR.yml +57 -0
  49. data/lib/locales/ru.yml +65 -0
  50. data/lib/locales/sk.yml +72 -0
  51. data/lib/locales/sv.yml +76 -0
  52. data/lib/locales/vi.yml +63 -0
  53. data/lib/locales/zh-CN.yml +27 -0
  54. data/lib/locales/zh-TW.yml +27 -0
  55. 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,9 @@
1
+ # For Ruby 1.8
2
+ unless :symbol.respond_to?(:downcase)
3
+ Symbol.class_eval do
4
+ def downcase
5
+ to_s.downcase.intern
6
+ end
7
+ end
8
+ end
9
+
@@ -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