Class: Faker::Base

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

Direct Known Subclasses

Address, Alphanumeric, Ancient, App, Appliance, Artist, Avatar, Bank, Beer, Faker::Blockchain::Bitcoin, Faker::Blockchain::Ethereum, Faker::Blockchain::Tezos, Book, Faker::Books::CultureSeries, Faker::Books::Dune, Faker::Books::Lovecraft, Boolean, BossaNova, Business, Cannabis, ChileRut, ChuckNorris, Code, Coffee, Coin, Color, Commerce, Company, Compass, Construction, Cosmere, Creature::Animal, Creature::Cat, Creature::Dog, Creature::Horse, Crypto, CryptoCoin, Currency, Date, DcComics, Demographic, Dessert, Device, DrivingLicence, Educator, ElectricalComponents, Esport, File, Fillmurray, Finance, Food, FunnyName, Game, Games::Dota, Games::ElderScrolls, Games::Fallout, Games::HalfLife, Games::Heroes, Games::HeroesOfTheStorm, Games::LeagueOfLegends, Games::Myst, Games::Overwatch, Games::Pokemon, Games::SonicTheHedgehog, Games::SuperSmashBros, Games::Witcher, Games::WorldOfWarcraft, Games::Zelda, Gender, GreekPhilosophers, Hacker, Hipster, House, IDNumber, IndustrySegments, Internet, Invoice, JapaneseMedia::DragonBall, JapaneseMedia::OnePiece, JapaneseMedia::SwordArtOnline, Job, Json, Kpop, Lorem, LoremFlickr, LoremPixel, Markdown, Marketing, Measurement, Military, Movie, Movies::BackToTheFuture, Movies::Ghostbusters, Movies::HarryPotter, Movies::HitchhikersGuideToTheGalaxy, Movies::Hobbit, Movies::Lebowski, Movies::LordOfTheRings, Movies::PrincessBride, Movies::StarWars, Movies::VForVendetta, Music, Music::GratefulDead, Music::Opera, Music::Phish, Music::RockBand, Music::UmphreysMcgee, Name, Nation, NationalHealthService, NatoPhoneticAlphabet, Number, Omniauth, PhoneNumber, Placeholdit, ProgrammingLanguage, Quote, Quotes::Shakespeare, Relationship, Restaurant, Science, SlackEmoji, Source, SouthAfrica, Space, Sports::Basketball, Sports::Football, String, Stripe, Subscription, Superhero, Team, Time, TvShows::AquaTeenHungerForce, TvShows::BojackHorseman, TvShows::BreakingBad, TvShows::Buffy, TvShows::Community, TvShows::DrWho, TvShows::DumbAndDumber, TvShows::FamilyGuy, TvShows::Friends, TvShows::GameOfThrones, TvShows::HeyArnold, TvShows::HowIMetYourMother, TvShows::MichaelScott, TvShows::NewGirl, TvShows::ParksAndRec, TvShows::RickAndMorty, TvShows::RuPaul, TvShows::Seinfeld, TvShows::SiliconValley, TvShows::Simpsons, TvShows::SouthPark, TvShows::StarTrek, TvShows::Stargate, TvShows::StrangerThings, TvShows::TheExpanse, TvShows::TheFreshPrinceOfBelAir, TvShows::TheITCrowd, TvShows::TheThickOfIt, TvShows::TwinPeaks, TvShows::VentureBros, Twitter, Types, University, Vehicle, Verb, WorldCup

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


57
58
59
# File 'lib/faker.rb', line 57

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

.disable_enforce_available_localesObject


241
242
243
244
245
246
247
# File 'lib/faker.rb', line 241

def disable_enforce_available_locales
  old_enforce_available_locales = I18n.enforce_available_locales
  I18n.enforce_available_locales = false
  yield
ensure
  I18n.enforce_available_locales = old_enforce_available_locales
end

.fetch(key) ⇒ Object

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


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

def fetch(key)
  fetched = sample(translate("faker.#{key}"))
  if 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.


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

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


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

def flexible(key)
  @flexible_key = key
end

.letterify(letter_string) ⇒ Object


53
54
55
# File 'lib/faker.rb', line 53

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


189
190
191
192
193
194
195
196
197
# File 'lib/faker.rb', line 189

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


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

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”.


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
146
147
# File 'lib/faker.rb', line 121

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


231
232
233
234
235
236
237
238
239
# File 'lib/faker.rb', line 231

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

.rand_in_range(from, to) ⇒ Object

Generates a random value between the interval


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

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”


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

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

.resolve(value) ⇒ Object

If an array or range is passed, a random value will be selected. All other values are simply returned.


211
212
213
214
215
216
217
# File 'lib/faker.rb', line 211

def resolve(value)
  case value
  when Array then sample(value)
  when Range then rand value
  else value
  end
end

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

Returns:


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

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

.sample(list) ⇒ Object


223
224
225
# File 'lib/faker.rb', line 223

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

.shuffle(list) ⇒ Object


227
228
229
# File 'lib/faker.rb', line 227

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


151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
# File 'lib/faker.rb', line 151

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.
  disable_enforce_available_locales do
    I18n.translate(*args.push(opts))
  end
end

.unique(max_retries = 10_000) ⇒ Object


219
220
221
# File 'lib/faker.rb', line 219

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.


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

def with_locale(tmp_locale = nil)
  current_locale = Faker::Config.own_locale
  Faker::Config.locale = tmp_locale

  disable_enforce_available_locales do
    I18n.with_locale(tmp_locale) { yield }
  end
ensure
  Faker::Config.locale = current_locale
end