Class: Faker::Base

Inherits:
Object
  • Object
show all
Defined in:
lib/faker.rb

Constant Summary collapse

Numbers =
Array(0..9)
ULetters =
Array('A'..'Z')
Letters =
ULetters + Array('a'..'z')

Class Method Summary collapse

Class Method Details

.bothify(string) ⇒ Object



50
51
52
# File 'lib/faker.rb', line 50

def bothify(string)
  letterify(numerify(string))
end

.fetch(key) ⇒ Object

Helper for the common approach of grabbing a translation with an array of values and selecting one of them.



90
91
92
93
94
95
96
97
98
# File 'lib/faker.rb', line 90

def fetch(key)
  fetched = translate("faker.#{key}")
  fetched = fetched.sample if fetched.respond_to?(:sample)
  if fetched && fetched.match(/^\//) and fetched.match(/\/$/) # A regex
    regexify(fetched)
  else
    fetched
  end
end

.fetch_all(key) ⇒ Object

Helper for the common approach of grabbing a translation with an array of values and returning all of them.



102
103
104
105
106
107
108
109
110
# File 'lib/faker.rb', line 102

def fetch_all(key)
  fetched = translate("faker.#{key}")
  fetched = fetched.last if fetched.size <= 1
  if !fetched.respond_to?(:sample) && fetched.match(/^\//) and fetched.match(/\/$/) # A regex
    regexify(fetched)
  else
    fetched
  end
end

.flexible(key) ⇒ Object



160
161
162
# File 'lib/faker.rb', line 160

def flexible(key)
  @flexible_key = key
end

.letterify(letter_string) ⇒ Object



46
47
48
# File 'lib/faker.rb', line 46

def letterify(letter_string)
  letter_string.gsub(/\?/) { ULetters.sample }
end

.method_missing(m, *args, &block) ⇒ Object

You can add whatever you want to the locale file, and it will get caught here. E.g., in your locale file, create a

name:
  girls_name: ["Alice", "Cheryl", "Tatiana"]

Then you can call Faker::Name.girls_name and it will act like #first_name



169
170
171
172
173
174
175
176
177
178
# File 'lib/faker.rb', line 169

def method_missing(m, *args, &block)
  super unless @flexible_key

  # Use the alternate form of translate to get a nil rather than a "missing translation" string
  if translation = translate(:faker)[@flexible_key][m]
    translation.respond_to?(:sample) ? translation.sample : translation
  else
    super
  end
end

.numerify(number_string) ⇒ Object

make sure numerify results doesn’t start with a zero



42
43
44
# File 'lib/faker.rb', line 42

def numerify(number_string)
  number_string.sub(/#/) { (rand(9)+1).to_s }.gsub(/#/) { rand(10).to_s }
end

.parse(key) ⇒ Object

Load formatted strings from the locale, “parsing” them into method calls that can be used to generate a formatted translation: e.g., “#first_name #last_name”.



115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
# File 'lib/faker.rb', line 115

def parse(key)
  fetch(key).scan(/(\(?)#\{([A-Za-z]+\.)?([^\}]+)\}([^#]+)?/).map {|prefix, kls, meth, etc|
    # If the token had a class Prefix (e.g., Name.first_name)
    # grab the constant, otherwise use self
    cls = kls ? Faker.const_get(kls.chop) : self

    # If an optional leading parentheses is not present, prefix.should == "", otherwise prefix.should == "("
    # In either case the information will be retained for reconstruction of the string.
    text = prefix

    # If the class has the method, call it, otherwise
    # fetch the transation (i.e., faker.name.first_name)
    text += cls.respond_to?(meth) ? cls.send(meth) : fetch("#{(kls || self).to_s.split('::').last.downcase}.#{meth.downcase}")

    # And tack on spaces, commas, etc. left over in the string
    text += etc.to_s
  }.join
end

.rand_in_range(from, to) ⇒ Object

Generates a random value between the interval



181
182
183
184
# File 'lib/faker.rb', line 181

def rand_in_range(from, to)
  from, to = to, from if to < from
  rand(from..to)
end

.regexify(re) ⇒ Object

Given a regular expression, attempt to generate a string that would match it. This is a rather simple implementation, so don’t be shocked if it blows up on you in a spectacular fashion.

It does not handle ., *, unbounded ranges such as 1,, extensions such as (?=), character classes, some abbreviations for character classes, and nested parentheses.

I told you it was simple. :) It’s also probably dog-slow, so you shouldn’t use it.

It will take a regex like this:

/^[A-PR-UWYZ0-9][AEHMNPRTVXY0-9]?? 1,2[ABD-HJLN-UW-Z]2$/

and generate a string like this:

“U3V 3TP”



73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/faker.rb', line 73

def regexify(re)
  re = re.source if re.respond_to?(:source) # Handle either a Regexp or a String that looks like a Regexp
  re.
    gsub(/^\/?\^?/, '').gsub(/\$?\/?$/, '').                                                                      # Ditch the anchors
    gsub(/\{(\d+)\}/, '{\1,\1}').gsub(/\?/, '{0,1}').                                                             # All {2} become {2,2} and ? become {0,1}
    gsub(/(\[[^\]]+\])\{(\d+),(\d+)\}/) {|match| $1 * Array(Range.new($2.to_i, $3.to_i)).sample }.                # [12]{1,2} becomes [12] or [12][12]
    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)
    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
    gsub(/\((.*?)\)/) {|match| match.gsub(/[\(\)]/, '').split('|').sample }.                                      # (this|that) becomes 'this' or 'that'
    gsub(/\[([^\]]+)\]/) {|match| match.gsub(/(\w\-\w)/) {|range| Array(Range.new(*range.split('-'))).sample } }. # All A-Z inside of [] become C (or X, or whatever)
    gsub(/\[([^\]]+)\]/) {|match| $1.split('').sample }.                                                          # All [ABC] become B (or A or C)
    gsub('\d') {|match| Numbers.sample }.
    gsub('\w') {|match| Letters.sample }
end

.translate(*args) ⇒ Object

Call I18n.translate with our configured locale if no locale is specified



136
137
138
139
140
141
142
143
144
145
146
147
148
149
# File 'lib/faker.rb', line 136

def translate(*args)
  opts = args.last.is_a?(Hash) ? args.pop : {}
  opts[:locale] ||= Faker::Config.locale
  opts[:raise] = true
  I18n.translate(*(args.push(opts)))
rescue I18n::MissingTranslationData
  opts = args.last.is_a?(Hash) ? args.pop : {}
  opts[:locale] = :en

  # Super-simple fallback -- fallback to en if the
  # translation was missing.  If the translation isn't
  # in en either, then it will raise again.
  I18n.translate(*(args.push(opts)))
end

.unique(max_retries = 10_000) ⇒ Object



186
187
188
# File 'lib/faker.rb', line 186

def unique(max_retries = 10_000)
  @unique_generator ||= UniqueGenerator.new(self, max_retries)
end

.with_locale(tmp_locale = nil) ⇒ Object

Executes block with given locale set.



152
153
154
155
156
157
158
# File 'lib/faker.rb', line 152

def with_locale(tmp_locale = nil)
  current_locale = Faker::Config.own_locale
  Faker::Config.locale = tmp_locale
  I18n.with_locale(tmp_locale) { yield }
ensure
  Faker::Config.locale = current_locale
end