faker 0.9.5 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,3 +1,30 @@
1
+ == 1.0.0 2011-09-05
2
+ * 2 major enhancements
3
+ * Moved all formats to locale files
4
+ * Stopped interfering with I18n's global settings for fallbacks
5
+ * 3 minor bug fixes:
6
+ * Ruby 1.9.2 fixes [eMxyzptlk]
7
+ * UTF8 fixes [maxmiliano]
8
+ * Updated IPv4 generator to return valid addresses [Sylvain Desbureaux]
9
+ * Many minor enhancements:
10
+ * Added bork locale for bork-ified lorem [johnbentcope]
11
+ * Added IPv6 address generator [jc00ke]
12
+ * Removed deprecation warnings for Array#rand [chrismarshall]
13
+ * Added German translation and I18n improvments [Matthias Kühnert]
14
+ * Added Dutch translation [moretea]
15
+ * Added Lat/Long generator [Andy Callaghan]
16
+ * Added buzzword-laden title generator [supercleanse]
17
+ * Added optional extended wordlist for lorem [chriskottom]
18
+ * Updated German translation [Jan Schwenzien]
19
+ * Locale improvements [suweller]
20
+ * Added limit to lorem generator [darrenterhune]
21
+ * Added Brazilian Portuguese translation [maxmiliano]
22
+ * Added Australian translation [madeindata]
23
+ * Added Canadian translation [igbanam]
24
+ * Added Norwegian translation [kytrinyx]
25
+ * Lots of translation-related cleanup [kytrinyx]
26
+
27
+
1
28
  == 0.9.5 2011-01-27
2
29
  * 1 minor bug fix:
3
30
  * Fixed YAML [Aaron Patterson]
data/README.md CHANGED
@@ -13,19 +13,6 @@ Usage
13
13
  * Faker::Name.name => "Christophe Bartell"
14
14
  * Faker::Internet.email => "kirsten.greenholt@corkeryfisher.info"
15
15
 
16
- Usage with Rails
17
- ----------------
18
-
19
- If you want to change your locale with Rails from the default of :en, change
20
- config/application.rb, setting config.i18n.locale to whatever locale you
21
- want. Change locale rather than default_locale (as suggested by the comments
22
- in that file) so that I18n's fallbacks will work properly and Faker can use
23
- the formats and data in en.yml (if there is no Faker localization for your
24
- locale). If you'd prefer to set default_locale rather than locale, then
25
- you'll also need to add config.i18n.fallbacks.defaults = [:en] to your
26
- configuration to make the fallbacks work for Faker.
27
-
28
-
29
16
  Customization
30
17
  ------------
31
18
  Since you may want to make addresses and other types of data look different
@@ -1,5 +1,7 @@
1
1
  class Array
2
- def rand
3
- self[Kernel.rand(length)]
2
+ unless self.method_defined? :sample
3
+ def sample
4
+ choice
5
+ end
4
6
  end
5
- end
7
+ end
@@ -1,4 +1,4 @@
1
- mydir = File.dirname(__FILE__)
1
+ mydir = File.expand_path(File.dirname(__FILE__))
2
2
 
3
3
  begin
4
4
  require 'psych'
@@ -6,36 +6,82 @@ rescue LoadError
6
6
  end
7
7
 
8
8
  require 'i18n'
9
- I18n::Backend::Simple.send(:include, I18n::Backend::Fallbacks)
10
9
  I18n.load_path += Dir[File.join(mydir, 'locales', '*.yml')]
10
+ I18n.reload!
11
11
 
12
12
 
13
13
  module Faker
14
14
  class Config
15
- def self.locale=(locale)
16
- I18n.locale = locale
15
+ @locale = nil
16
+
17
+ class << self
18
+ attr_writer :locale
19
+ def locale
20
+ @locale || I18n.locale
21
+ end
17
22
  end
18
23
  end
19
24
 
20
25
  class Base
21
26
  class << self
27
+ ## make sure numerify results doesn’t start with a zero
22
28
  def numerify(number_string)
23
- number_string.gsub(/#/) { rand(10).to_s }
29
+ number_string.sub(/#/) { (rand(9)+1).to_s }.gsub(/#/) { rand(10).to_s }
24
30
  end
25
31
 
26
32
  def letterify(letter_string)
27
- letter_string.gsub(/\?/) { ('a'..'z').to_a.rand }
33
+ letter_string.gsub(/\?/) { ('A'..'Z').to_a.sample }
28
34
  end
29
35
 
30
36
  def bothify(string)
31
37
  letterify(numerify(string))
32
38
  end
33
39
 
34
- # Helper for the common approach of grabbing a translation with an array
35
- # of values and selecting one of them
40
+ # Helper for the common approach of grabbing a translation
41
+ # with an array of values and selecting one of them.
36
42
  def fetch(key)
37
- I18n.translate("faker.#{key}").rand
43
+ translate("faker.#{key}").sample
44
+ end
45
+
46
+ # Load formatted strings from the locale, "parsing" them
47
+ # into method calls that can be used to generate a
48
+ # formatted translation: e.g., "#{first_name} #{last_name}".
49
+ def parse(key)
50
+ fetch(key).scan(/#\{([A-Za-z]+\.)?([^\}]+)\}([^#]+)?/).map {|kls, meth, etc| (kls ? Faker.const_get(kls.chop) : self).send(meth) + etc.to_s }.join
51
+ end
52
+
53
+ # Call I18n.translate with our configured locale if no
54
+ # locale is specified
55
+ def translate(*args)
56
+ opts = args.last.is_a?(Hash) ? args.pop : {}
57
+ opts[:locale] ||= Faker::Config.locale
58
+ opts[:throw] = true
59
+ I18n.translate(*(args.push(opts)))
60
+ rescue
61
+ # Super-simple fallback -- fallback to en if the
62
+ # translation was missing. If the translation isn't
63
+ # in en either, then it will raise again.
64
+ I18n.translate(*(args.push(opts.merge(:locale => :en))))
65
+ end
66
+
67
+ def flexible(key)
68
+ @flexible_key = key
38
69
  end
70
+
71
+ # You can add whatever you want to the locale file, and it will get caught here.
72
+ # E.g., in your locale file, create a
73
+ # name:
74
+ # girls_name: ["Alice", "Cheryl", "Tatiana"]
75
+ # Then you can call Faker::Name.girls_name and it will act like #first_name
76
+ def method_missing(m, *args, &block)
77
+ # Use the alternate form of translate to get a nil rather than a "missing translation" string
78
+ if translation = translate(:faker)[@flexible_key][m]
79
+ translation.respond_to?(:sample) ? translation.sample : translation
80
+ else
81
+ super
82
+ end
83
+ end
84
+
39
85
  end
40
86
  end
41
87
  end
@@ -1,24 +1,18 @@
1
1
  module Faker
2
2
  class Address < Base
3
+ flexible :address
4
+
3
5
  class << self
4
6
  def city
5
- [
6
- '%s %s%s' % [city_prefix, Name.first_name, city_suffix],
7
- '%s %s' % [city_prefix, Name.first_name],
8
- '%s%s' % [Name.first_name, city_suffix],
9
- '%s%s' % [Name.last_name, city_suffix],
10
- ].rand
7
+ parse('address.city')
11
8
  end
12
9
 
13
10
  def street_name
14
- [
15
- Proc.new { [Name.last_name, street_suffix].join(' ') },
16
- Proc.new { [Name.first_name, street_suffix].join(' ') }
17
- ].rand.call
11
+ parse('address.street_name')
18
12
  end
19
13
 
20
14
  def street_address(include_secondary = false)
21
- numerify("#{fetch('address.street_address')} #{street_name}#{' ' + secondary_address if include_secondary}")
15
+ numerify(parse('address.street_address') + (include_secondary ? ' ' + secondary_address : ''))
22
16
  end
23
17
 
24
18
  def secondary_address
@@ -26,7 +20,7 @@ module Faker
26
20
  end
27
21
 
28
22
  def zip_code
29
- bothify(fetch('address.postcode')).upcase
23
+ bothify(fetch('address.postcode'))
30
24
  end
31
25
  alias_method :zip, :zip_code
32
26
  alias_method :postcode, :zip_code
@@ -38,18 +32,14 @@ module Faker
38
32
  def state; fetch('address.state'); end
39
33
  def country; fetch('address.country'); end
40
34
 
41
- # You can add whatever you want to the locale file, and it will get
42
- # caught here... e.g., create a country_code array in your locale,
43
- # then you can call #country_code and it will act like #country
44
- def method_missing(m, *args, &block)
45
- # Use the alternate form of translate to get a nil rather than a "missing translation" string
46
- if translation = I18n.translate(:faker)[:address][m]
47
- translation.respond_to?(:rand) ? translation.rand : translation
48
- else
49
- super
50
- end
35
+ def latitude
36
+ ((rand * 180) - 90).to_s
51
37
  end
52
-
38
+
39
+ def longitude
40
+ ((rand * 360) - 180).to_s
41
+ end
42
+
53
43
  # Deprecated
54
44
  alias_method :earth_country, :country
55
45
  alias_method :us_state, :state
@@ -59,4 +49,4 @@ module Faker
59
49
 
60
50
  end
61
51
  end
62
- end
52
+ end
@@ -1,8 +1,10 @@
1
1
  module Faker
2
2
  class Company < Base
3
+ flexible :company
4
+
3
5
  class << self
4
6
  def name
5
- Formats.rand.call
7
+ parse('company.name')
6
8
  end
7
9
 
8
10
  def suffix
@@ -10,30 +12,15 @@ module Faker
10
12
  end
11
13
 
12
14
  # Generate a buzzword-laden catch phrase.
13
- # Wordlist from http://www.1728.com/buzzword.htm
14
15
  def catch_phrase
15
- [
16
- ["Adaptive", "Advanced", "Ameliorated", "Assimilated", "Automated", "Balanced", "Business-focused", "Centralized", "Cloned", "Compatible", "Configurable", "Cross-group", "Cross-platform", "Customer-focused", "Customizable", "Decentralized", "De-engineered", "Devolved", "Digitized", "Distributed", "Diverse", "Down-sized", "Enhanced", "Enterprise-wide", "Ergonomic", "Exclusive", "Expanded", "Extended", "Face to face", "Focused", "Front-line", "Fully-configurable", "Function-based", "Fundamental", "Future-proofed", "Grass-roots", "Horizontal", "Implemented", "Innovative", "Integrated", "Intuitive", "Inverse", "Managed", "Mandatory", "Monitored", "Multi-channelled", "Multi-lateral", "Multi-layered", "Multi-tiered", "Networked", "Object-based", "Open-architected", "Open-source", "Operative", "Optimized", "Optional", "Organic", "Organized", "Persevering", "Persistent", "Phased", "Polarised", "Pre-emptive", "Proactive", "Profit-focused", "Profound", "Programmable", "Progressive", "Public-key", "Quality-focused", "Reactive", "Realigned", "Re-contextualized", "Re-engineered", "Reduced", "Reverse-engineered", "Right-sized", "Robust", "Seamless", "Secured", "Self-enabling", "Sharable", "Stand-alone", "Streamlined", "Switchable", "Synchronised", "Synergistic", "Synergized", "Team-oriented", "Total", "Triple-buffered", "Universal", "Up-sized", "Upgradable", "User-centric", "User-friendly", "Versatile", "Virtual", "Visionary", "Vision-oriented"].rand,
17
- ["24 hour", "24/7", "3rd generation", "4th generation", "5th generation", "6th generation", "actuating", "analyzing", "assymetric", "asynchronous", "attitude-oriented", "background", "bandwidth-monitored", "bi-directional", "bifurcated", "bottom-line", "clear-thinking", "client-driven", "client-server", "coherent", "cohesive", "composite", "context-sensitive", "contextually-based", "content-based", "dedicated", "demand-driven", "didactic", "directional", "discrete", "disintermediate", "dynamic", "eco-centric", "empowering", "encompassing", "even-keeled", "executive", "explicit", "exuding", "fault-tolerant", "foreground", "fresh-thinking", "full-range", "global", "grid-enabled", "heuristic", "high-level", "holistic", "homogeneous", "human-resource", "hybrid", "impactful", "incremental", "intangible", "interactive", "intermediate", "leading edge", "local", "logistical", "maximized", "methodical", "mission-critical", "mobile", "modular", "motivating", "multimedia", "multi-state", "multi-tasking", "national", "needs-based", "neutral", "next generation", "non-volatile", "object-oriented", "optimal", "optimizing", "radical", "real-time", "reciprocal", "regional", "responsive", "scalable", "secondary", "solution-oriented", "stable", "static", "systematic", "systemic", "system-worthy", "tangible", "tertiary", "transitional", "uniform", "upward-trending", "user-facing", "value-added", "web-enabled", "well-modulated", "zero administration", "zero defect", "zero tolerance"].rand,
18
- ["ability", "access", "adapter", "algorithm", "alliance", "analyzer", "application", "approach", "architecture", "archive", "artificial intelligence", "array", "attitude", "benchmark", "budgetary management", "capability", "capacity", "challenge", "circuit", "collaboration", "complexity", "concept", "conglomeration", "contingency", "core", "customer loyalty", "database", "data-warehouse", "definition", "emulation", "encoding", "encryption", "extranet", "firmware", "flexibility", "focus group", "forecast", "frame", "framework", "function", "functionalities", "Graphic Interface", "groupware", "Graphical User Interface", "hardware", "help-desk", "hierarchy", "hub", "implementation", "info-mediaries", "infrastructure", "initiative", "installation", "instruction set", "interface", "internet solution", "intranet", "knowledge user", "knowledge base", "local area network", "leverage", "matrices", "matrix", "methodology", "middleware", "migration", "model", "moderator", "monitoring", "moratorium", "neural-net", "open architecture", "open system", "orchestration", "paradigm", "parallelism", "policy", "portal", "pricing structure", "process improvement", "product", "productivity", "project", "projection", "protocol", "secured line", "service-desk", "software", "solution", "standardization", "strategy", "structure", "success", "superstructure", "support", "synergy", "system engine", "task-force", "throughput", "time-frame", "toolset", "utilisation", "website", "workforce"].rand
19
- ].join(' ')
16
+ translate('faker.company.buzzwords').collect {|list| list.sample }.join(' ')
20
17
  end
21
18
 
22
19
  # When a straight answer won't do, BS to the rescue!
23
- # Wordlist from http://dack.com/web/bullshit.html
24
20
  def bs
25
- [
26
- ["implement", "utilize", "integrate", "streamline", "optimize", "evolve", "transform", "embrace", "enable", "orchestrate", "leverage", "reinvent", "aggregate", "architect", "enhance", "incentivize", "morph", "empower", "envisioneer", "monetize", "harness", "facilitate", "seize", "disintermediate", "synergize", "strategize", "deploy", "brand", "grow", "target", "syndicate", "synthesize", "deliver", "mesh", "incubate", "engage", "maximize", "benchmark", "expedite", "reintermediate", "whiteboard", "visualize", "repurpose", "innovate", "scale", "unleash", "drive", "extend", "engineer", "revolutionize", "generate", "exploit", "transition", "e-enable", "iterate", "cultivate", "matrix", "productize", "redefine", "recontextualize"].rand,
27
- ["clicks-and-mortar", "value-added", "vertical", "proactive", "robust", "revolutionary", "scalable", "leading-edge", "innovative", "intuitive", "strategic", "e-business", "mission-critical", "sticky", "one-to-one", "24/7", "end-to-end", "global", "B2B", "B2C", "granular", "frictionless", "virtual", "viral", "dynamic", "24/365", "best-of-breed", "killer", "magnetic", "bleeding-edge", "web-enabled", "interactive", "dot-com", "sexy", "back-end", "real-time", "efficient", "front-end", "distributed", "seamless", "extensible", "turn-key", "world-class", "open-source", "cross-platform", "cross-media", "synergistic", "bricks-and-clicks", "out-of-the-box", "enterprise", "integrated", "impactful", "wireless", "transparent", "next-generation", "cutting-edge", "user-centric", "visionary", "customized", "ubiquitous", "plug-and-play", "collaborative", "compelling", "holistic", "rich"].rand,
28
- ["synergies", "web-readiness", "paradigms", "markets", "partnerships", "infrastructures", "platforms", "initiatives", "channels", "eyeballs", "communities", "ROI", "solutions", "e-tailers", "e-services", "action-items", "portals", "niches", "technologies", "content", "vortals", "supply-chains", "convergence", "relationships", "architectures", "interfaces", "e-markets", "e-commerce", "systems", "bandwidth", "infomediaries", "models", "mindshare", "deliverables", "users", "schemas", "networks", "applications", "metrics", "e-business", "functionalities", "experiences", "web services", "methodologies"].rand
29
- ].join(' ')
21
+ translate('faker.company.bs').collect {|list| list.sample }.join(' ')
30
22
  end
31
23
  end
32
24
 
33
- Formats = [
34
- Proc.new { [ Name.last_name, suffix ].join(' ') },
35
- Proc.new { [ Name.last_name, Name.last_name ].join('-') },
36
- Proc.new { "%s, %s and %s" % [ Name.last_name, Name.last_name, Name.last_name ] }
37
- ]
38
25
  end
39
- end
26
+ end
@@ -1,3 +1,4 @@
1
+ # encoding: utf-8
1
2
  module Faker
2
3
  class Internet < Base
3
4
  class << self
@@ -10,19 +11,30 @@ module Faker
10
11
  end
11
12
 
12
13
  def user_name(name = nil)
13
- return name.scan(/\w+/).shuffle.join(%w(. _).rand).downcase if name
14
+ return name.scan(/\w+/).shuffle.join(%w(. _).sample).downcase if name
14
15
 
15
- [
16
+ fix_umlauts([
16
17
  Proc.new { Name.first_name.gsub(/\W/, '').downcase },
17
18
  Proc.new {
18
19
  [ Name.first_name, Name.last_name ].map {|n|
19
20
  n.gsub(/\W/, '')
20
- }.join(%w(. _).rand).downcase }
21
- ].rand.call
21
+ }.join(%w(. _).sample).downcase }
22
+ ].sample.call)
22
23
  end
23
24
 
24
25
  def domain_name
25
- [ domain_word, domain_suffix ].join('.')
26
+ [ fix_umlauts(domain_word), domain_suffix ].join('.')
27
+ end
28
+
29
+ def fix_umlauts(string)
30
+ string.gsub(/[äöüß]/i) do |match|
31
+ case match.downcase
32
+ when "ä" 'ae'
33
+ when "ö" 'oe'
34
+ when "ü" 'ue'
35
+ when "ß" 'ss'
36
+ end
37
+ end
26
38
  end
27
39
 
28
40
  def domain_word
@@ -34,11 +46,22 @@ module Faker
34
46
  end
35
47
 
36
48
  def ip_v4_address
37
- [(0..255).to_a.rand,
38
- (0..255).to_a.rand,
39
- (0..255).to_a.rand,
40
- (0..255).to_a.rand].join('.')
49
+ ary = (2..254).to_a
50
+ [ary.sample,
51
+ ary.sample,
52
+ ary.sample,
53
+ ary.sample].join('.')
54
+ end
55
+
56
+ def ip_v6_address
57
+ @@ip_v6_space ||= (0..65535).to_a
58
+ container = (1..8).map{ |_| @@ip_v6_space.sample }
59
+ container.map{ |n| n.to_s(16) }.join(':')
60
+ end
61
+
62
+ def url
63
+ "http://#{domain_name}/#{user_name}"
41
64
  end
42
65
  end
43
66
  end
44
- end
67
+ end
@@ -1,32 +1,39 @@
1
1
  module Faker
2
2
  # Based on Perl's Text::Lorem
3
3
  class Lorem < Base
4
- def self.words(num = 3)
5
- I18n.translate('faker.lorem.words').shuffle[0, num]
4
+ def self.words(num = 3, supplemental = false)
5
+ (
6
+ translate('faker.lorem.words') +
7
+ (supplemental ? translate('faker.lorem.supplemental') : [])
8
+ ).shuffle[0, num]
9
+ end
10
+
11
+ def self.characters(char_count = 255)
12
+ rand(36**char_count).to_s(36)
6
13
  end
7
14
 
8
- def self.sentence(word_count = 4)
9
- words(word_count + rand(6)).join(' ').capitalize + '.'
15
+ def self.sentence(word_count = 4, supplemental = false)
16
+ words(word_count + rand(6), supplemental).join(' ').capitalize + '.'
10
17
  end
11
18
 
12
- def self.sentences(sentence_count = 3)
19
+ def self.sentences(sentence_count = 3, supplemental = false)
13
20
  [].tap do |sentences|
14
21
  1.upto(sentence_count) do
15
- sentences << sentence
22
+ sentences << sentence(3, supplemental)
16
23
  end
17
24
  end
18
25
  end
19
26
 
20
- def self.paragraph(sentence_count = 3)
21
- sentences(sentence_count + rand(3)).join(' ')
27
+ def self.paragraph(sentence_count = 3, supplemental = false)
28
+ sentences(sentence_count + rand(3), supplemental).join(' ')
22
29
  end
23
30
 
24
- def self.paragraphs(paragraph_count = 3)
31
+ def self.paragraphs(paragraph_count = 3, supplemental = false)
25
32
  [].tap do |paragraphs|
26
33
  1.upto(paragraph_count) do
27
- paragraphs << paragraph
34
+ paragraphs << paragraph(3, supplemental)
28
35
  end
29
36
  end
30
37
  end
31
38
  end
32
- end
39
+ end
@@ -1,9 +1,11 @@
1
1
  module Faker
2
2
  class Name < Base
3
+ flexible :name
4
+
3
5
  class << self
4
6
 
5
7
  def name
6
- fetch('name.formats').collect {|meth| self.send(meth) }.join(' ')
8
+ parse('name.name')
7
9
  end
8
10
 
9
11
  def first_name; fetch('name.first_name'); end
@@ -11,6 +13,10 @@ module Faker
11
13
  def prefix; fetch('name.prefix'); end
12
14
  def suffix; fetch('name.suffix'); end
13
15
 
16
+ # Generate a buzzword-laden job title
17
+ # Wordlist from http://www.bullshitjob.com/title/
18
+ def title; fetch('name.title.descriptor') + ' ' + fetch('name.title.level') + ' ' + fetch('name.title.job'); end
19
+
14
20
  end
15
21
  end
16
- end
22
+ end
@@ -4,6 +4,14 @@ module Faker
4
4
  def phone_number
5
5
  numerify(fetch('phone_number.formats'))
6
6
  end
7
+
8
+ def cell_phone
9
+ if (translation = translate(:faker)[:cell_phone]).is_a? Hash
10
+ numerify(translation[:formats].sample)
11
+ else
12
+ numerify(fetch('phone_number.formats'))
13
+ end
14
+ end
7
15
  end
8
16
  end
9
- end
17
+ end
@@ -1,3 +1,3 @@
1
1
  module Faker #:nodoc:
2
- VERSION = "0.9.5"
2
+ VERSION = "1.0.0"
3
3
  end
@@ -3,9 +3,16 @@ de-ch:
3
3
  address:
4
4
  country_code: [CH, CH, CH, DE, AT, US, LI, US, HK, VN]
5
5
  postcode: ['1###', '2###', '3###', '4###', '5###', '6###', '7###', '8###', '9###']
6
+
6
7
  company:
7
8
  suffix: [AG, GmbH, und Söhne, und Partner, "& Co.", Gruppe, LLC, Inc.]
9
+ name:
10
+ - "#{Name.last_name} #{suffix}"
11
+ - "#{Name.last_name}-#{Name.last_name}"
12
+ - "#{Name.last_name}, #{Name.last_name} und #{Name.last_name}"
13
+
8
14
  internet:
9
15
  domain_suffix: [com, net, biz, ch, de, li, at, ch, ch]
16
+
10
17
  phone_number:
11
18
  formats: ['0800 ### ###', '0800 ## ## ##', '0## ### ## ##', '0## ### ## ##', '+41 ## ### ## ##', '0900 ### ###', '076 ### ## ##', '+4178 ### ## ##', '0041 79 ### ## ##']