Class: Faker::Base

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

Direct Known Subclasses

Address, Ancient, App, Appliance, AquaTeenHungerForce, Artist, Avatar, BackToTheFuture, Bank, Beer, Bitcoin, BojackHorseman, Book, Boolean, BossaNova, BreakingBad, Business, Cannabis, Cat, ChuckNorris, Code, Coffee, Color, Commerce, Community, Company, Compass, Crypto, Currency, Date, Demographic, Dessert, Device, Dog, Dota, DrWho, DragonBall, DumbAndDumber, Dune, Educator, ElderScrolls, ElectricalComponents, Esport, Ethereum, Fallout, FamilyGuy, FamousLastWords, File, Fillmurray, Finance, Food, Football, Friends, FunnyName, GameOfThrones, Gender, GreekPhilosophers, Hacker, HarryPotter, HeyArnold, Hipster, HitchhikersGuideToTheGalaxy, Hobbit, HowIMetYourMother, IDNumber, Internet, Invoice, Job, Kpop, LeagueOfLegends, Lebowski, LordOfTheRings, Lorem, LoremFlickr, LoremPixel, Lovecraft, Markdown, Matz, Measurement, MichaelScott, Military, MostInterestingManInTheWorld, Movie, Music, Myst, Name, Nation, NatoPhoneticAlphabet, NewGirl, Number, Omniauth, OnePiece, Overwatch, ParksAndRec, PhoneNumber, Placeholdit, Pokemon, PrincessBride, ProgrammingLanguage, RickAndMorty, Robin, RockBand, RuPaul, Science, Seinfeld, Shakespeare, SiliconValley, Simpsons, SingularSiegler, SlackEmoji, Source, Space, StarTrek, StarWars, Stargate, StrangerThings, String, Stripe, Superhero, SwordArtOnline, Team, TheFreshPrinceOfBelAir, TheITCrowd, TheThickOfIt, TwinPeaks, Twitter, Types, UmphreysMcgee, University, VForVendetta, Vehicle, VentureBros, Verb, Witcher, WorldCup, WorldOfWarcraft, Yoda, Zelda

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



55
56
57
# File 'lib/faker.rb', line 55

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.



95
96
97
98
99
100
101
102
# File 'lib/faker.rb', line 95

def fetch(key)
  fetched = sample(translate("faker.#{key}"))
  if fetched && fetched.match(%r{^\/}) && fetched.match(%r{\/$}) # 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.



106
107
108
109
110
111
112
113
114
# File 'lib/faker.rb', line 106

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

.flexible(key) ⇒ Object



173
174
175
# File 'lib/faker.rb', line 173

def flexible(key)
  @flexible_key = key
end

.letterify(letter_string) ⇒ Object



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

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

.method_missing(mth, *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



182
183
184
185
186
187
188
189
190
# File 'lib/faker.rb', line 182

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

  if (translation = translate("faker.#{@flexible_key}.#{mth}"))
    sample(translation)
  else
    super
  end
end

.numerify(number_string, leading_zero: false) ⇒ Object

by default numerify results do not start with a zero



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

def numerify(number_string, leading_zero: false)
  return number_string.gsub(/#/) { rand(10).to_s } if leading_zero
  number_string.sub(/#/) { rand(1..9).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”.



119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
# File 'lib/faker.rb', line 119

def parse(key)
  fetched = fetch(key)
  parts = fetched.scan(/(\(?)#\{([A-Za-z]+\.)?([^\}]+)\}([^#]+)?/).map do |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
    # (e.g., faker.phone_number.area_code)
    text += if cls.respond_to?(meth)
              cls.send(meth)
            else
              # Do just enough snake casing to convert PhoneNumber to phone_number
              key_path = cls.to_s.split('::').last.gsub(/([a-z\d])([A-Z])/, '\1_\2').downcase
              fetch("#{key_path}.#{meth.downcase}")
            end

    # And tack on spaces, commas, etc. left over in the string
    text + etc.to_s
  end
  # If the fetched key couldn't be parsed, then fallback to numerify
  parts.any? ? parts.join : numerify(fetched)
end

.rand(max = nil) ⇒ Object



214
215
216
217
218
219
220
221
222
# File 'lib/faker.rb', line 214

def rand(max = nil)
  if max.nil?
    Faker::Config.random.rand
  elsif max.is_a?(Range) || max.to_i > 0
    Faker::Config.random.rand(max)
  else
    0
  end
end

.rand_in_range(from, to) ⇒ Object

Generates a random value between the interval



197
198
199
200
# File 'lib/faker.rb', line 197

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

.regexify(reg) ⇒ 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”



78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/faker.rb', line 78

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

.respond_to_missing?(method_name, include_private = false) ⇒ Boolean

Returns:



192
193
194
# File 'lib/faker.rb', line 192

def respond_to_missing?(method_name, include_private = false)
  super
end

.sample(list) ⇒ Object



206
207
208
# File 'lib/faker.rb', line 206

def sample(list)
  list.respond_to?(:sample) ? list.sample(random: Faker::Config.random) : list
end

.shuffle(list) ⇒ Object



210
211
212
# File 'lib/faker.rb', line 210

def shuffle(list)
  list.shuffle(random: Faker::Config.random)
end

.translate(*args) ⇒ Object

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



149
150
151
152
153
154
155
156
157
158
159
160
161
162
# File 'lib/faker.rb', line 149

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



202
203
204
# File 'lib/faker.rb', line 202

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

.with_locale(tmp_locale = nil) ⇒ Object

Executes block with given locale set.



165
166
167
168
169
170
171
# File 'lib/faker.rb', line 165

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