[alfred] Update a bunch of workflows

pull/28/head
Alpha Chen 9 years ago
parent 730fd4ab95
commit 30af251bc9

@ -8,8 +8,8 @@
<array>
<string>features.websearch.duckduckgo.fallback</string>
<string>features.websearch.google.fallback</string>
<string>features.websearch.amazon.fallback</string>
<string>features.websearch.wiki.fallback</string>
<string>features.websearch.custom.491B807D-42B3-4CB4-861F-2ADF20727F53.fallback</string>
</array>
</dict>
</plist>

@ -64,6 +64,21 @@
<key>utf8</key>
<true/>
</dict>
<key>78F38D7E-7CF4-41FC-AD5F-C4017FFCA0AE</key>
<dict>
<key>enabled</key>
<true/>
<key>keyword</key>
<string>giphy</string>
<key>plusSpaces</key>
<false/>
<key>text</key>
<string>Search Giphy for '{query}'</string>
<key>url</key>
<string>http://giphy.com/search/?q={query}</string>
<key>utf8</key>
<true/>
</dict>
<key>A5E2DBA1-C7F6-4F89-8348-987E767FC291</key>
<dict>
<key>enabled</key>

@ -0,0 +1,6 @@
## Unreleased
## 1.0.0 - 2015.10.25
### Added
- Initial release of Faker.alfredworkflow!

@ -0,0 +1,10 @@
source "https://rubygems.org"
gem "alphred", "~> 1.0"
gem "faker", "~> 1.5"
group :development do
gem "minitest"
gem "rake"
gem "pry"
end

@ -0,0 +1,31 @@
GEM
remote: https://rubygems.org/
specs:
alphred (1.0.0)
builder (~> 3.2)
builder (3.2.2)
coderay (1.1.0)
faker (1.5.0)
i18n (~> 0.5)
i18n (0.7.0)
method_source (0.8.2)
minitest (5.8.2)
pry (0.10.3)
coderay (~> 1.1.0)
method_source (~> 0.8.1)
slop (~> 3.4)
rake (10.4.2)
slop (3.6.0)
PLATFORMS
ruby
DEPENDENCIES
alphred (~> 1.0)
faker (~> 1.5)
minitest
pry
rake
BUNDLED WITH
1.10.6

@ -0,0 +1,11 @@
# Faker.alfredworkflow
This [Alfred](https://www.alfredapp.com/) workflow generates fake data using
the [Faker](https://github.com/stympy/faker) Ruby gem. I use it mainly for
creating dummy answers for security questions required for creating accounts.
## Credits
- [Faker](https://github.com/stympy/faker)
- [eye mask icon by Creative Stall from the Noun
Project](https://thenounproject.com/term/eye-mask/178273/)

@ -0,0 +1,10 @@
require "rake/testtask"
require "alphred/tasks"
Rake::TestTask.new do |t|
t.test_files = FileList["test_*.rb"]
t.verbose = true
end
task default: :test

@ -0,0 +1,125 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>bundleid</key>
<string>com.arbitrarydefinitions.faker</string>
<key>category</key>
<string>Tools</string>
<key>connections</key>
<dict>
<key>6C68D0BB-A89A-4FDD-BB99-B5A5B460646E</key>
<array>
<dict>
<key>destinationuid</key>
<string>B5EB1D6A-BBD4-461B-AEBC-5A1CFBD844FA</string>
<key>modifiers</key>
<integer>0</integer>
<key>modifiersubtext</key>
<string></string>
</dict>
<dict>
<key>destinationuid</key>
<string>9DE3E4D9-4D72-4C53-9013-D1B1C4AE8776</string>
<key>modifiers</key>
<integer>0</integer>
<key>modifiersubtext</key>
<string></string>
</dict>
</array>
</dict>
<key>createdby</key>
<string>Alpha Chen</string>
<key>description</key>
<string>Creates fake data</string>
<key>disabled</key>
<false/>
<key>name</key>
<string>Faker</string>
<key>objects</key>
<array>
<dict>
<key>type</key>
<string>alfred.workflow.output.largetype</string>
<key>uid</key>
<string>B5EB1D6A-BBD4-461B-AEBC-5A1CFBD844FA</string>
<key>version</key>
<integer>0</integer>
</dict>
<dict>
<key>config</key>
<dict>
<key>argumenttype</key>
<integer>0</integer>
<key>escaping</key>
<integer>127</integer>
<key>keyword</key>
<string>faker</string>
<key>queuedelaycustom</key>
<integer>1</integer>
<key>queuedelayimmediatelyinitially</key>
<false/>
<key>queuedelaymode</key>
<integer>0</integer>
<key>queuemode</key>
<integer>1</integer>
<key>runningsubtext</key>
<string>Generating fake data...</string>
<key>script</key>
<string>ruby workflow.rb {query}</string>
<key>subtext</key>
<string>Generate fake data for "..."</string>
<key>title</key>
<string>Generate fake data</string>
<key>type</key>
<integer>0</integer>
<key>withspace</key>
<true/>
</dict>
<key>type</key>
<string>alfred.workflow.input.scriptfilter</string>
<key>uid</key>
<string>6C68D0BB-A89A-4FDD-BB99-B5A5B460646E</string>
<key>version</key>
<integer>0</integer>
</dict>
<dict>
<key>config</key>
<dict>
<key>autopaste</key>
<false/>
<key>clipboardtext</key>
<string>{query}</string>
</dict>
<key>type</key>
<string>alfred.workflow.output.clipboard</string>
<key>uid</key>
<string>9DE3E4D9-4D72-4C53-9013-D1B1C4AE8776</string>
<key>version</key>
<integer>0</integer>
</dict>
</array>
<key>readme</key>
<string></string>
<key>uidata</key>
<dict>
<key>6C68D0BB-A89A-4FDD-BB99-B5A5B460646E</key>
<dict>
<key>ypos</key>
<real>70</real>
</dict>
<key>9DE3E4D9-4D72-4C53-9013-D1B1C4AE8776</key>
<dict>
<key>ypos</key>
<real>130</real>
</dict>
<key>B5EB1D6A-BBD4-461B-AEBC-5A1CFBD844FA</key>
<dict>
<key>ypos</key>
<real>10</real>
</dict>
</dict>
<key>webaddress</key>
<string>https://github.com/kejadlen/faker</string>
</dict>
</plist>

@ -0,0 +1,10 @@
require "minitest/autorun"
require_relative "workflow"
class TestWorkflow < Minitest::Test
def test_i18n_failure
workflow = Workflow::Faker.new("a")
workflow.items.to_xml
end
end

@ -0,0 +1,9 @@
require 'rbconfig'
# ruby 1.8.7 doesn't define RUBY_ENGINE
ruby_engine = defined?(RUBY_ENGINE) ? RUBY_ENGINE : 'ruby'
ruby_version = RbConfig::CONFIG["ruby_version"]
path = File.expand_path('..', __FILE__)
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/builder-3.2.2/lib"
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/alphred-1.0.0/lib"
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/i18n-0.7.0/lib"
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/faker-1.5.0/lib"

@ -0,0 +1,9 @@
/.bundle/
/.yardoc
/Gemfile.lock
/_yardoc/
/coverage/
/doc/
/pkg/
/spec/reports/
/tmp/

@ -0,0 +1,13 @@
# Contributor Code of Conduct
As contributors and maintainers of this project, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities.
We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, or religion.
Examples of unacceptable behavior by participants include the use of sexual language or imagery, derogatory comments or personal attacks, trolling, public or private harassment, insults, or other unprofessional conduct.
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. Project maintainers who do not follow the Code of Conduct may be removed from the project team.
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers.
This Code of Conduct is adapted from the [Contributor Covenant](http://contributor-covenant.org), version 1.0.0, available at [http://contributor-covenant.org/version/1/0/0/](http://contributor-covenant.org/version/1/0/0/)

@ -0,0 +1,10 @@
source 'https://rubygems.org'
# Specify your gem's dependencies in alphred.gemspec
gemspec
group :development do
gem "guard"
gem "guard-minitest"
gem "pry"
end

@ -0,0 +1,5 @@
guard :minitest do
watch(%r{^test/(.*)\/?test_(.*)\.rb$})
watch(%r{^lib/(.*/)?([^/]+)\.rb$}) { |m| "test/#{m[1]}test_#{m[2]}.rb" }
watch(%r{^test/test_helper\.rb$}) { 'test' }
end

@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2015 Alpha Chen
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

@ -0,0 +1,123 @@
# Alphred
Alphred is a library for making Alfred workflows in Ruby. It's designed
specifically for how I work, so assumes that you manage dependencies with
[Bundler][bundler] and Rubies with [chruby][chruby].
[bundler]: http://bundler.io/
[chruby]: https://github.com/postmodern/chruby
## Usage
The [example script filter][scriptfilter] would look like this using Alphred:
[scriptfilter]: https://www.alfredapp.com/help/workflows/inputs/script-filter/
``` ruby
items = Alphred::Items.new(
Alphred::Item.new(uid: "desktop",
arg: "~/Desktop",
valid: true,
autocomplete: "Desktop",
type: :file,
title: "Desktop",
subtitle: "~/Desktop",
icon: { value: "~/Desktop", type: :fileicon }),
Alphred::Item.new(uid: "flickr",
valid: false,
autocomplete: "flickr",
title: "Flickr",
icon: "flickr.png"),
Alphred::Item.new(uid: "image",
autocomplete: "My holiday photo",
type: :file,
title: "My holiday photo",
subtitle: "~/Pictures/My holiday photo.jpg",
icon: { value: "public.jpeg", type: :filetype }),
Alphred::Item.new(uid: "home",
arg: "~/",
valid: true,
autocomplete: "Home",
type: :file,
title: "Home Folder",
subtitle: "Home folder ~/",
icon: { value: "~/", type: :fileicon },
mods: { shift: "Subtext when shift is pressed",
fn: "Subtext when fn is pressed",
ctrl: "Subtext when ctrl is pressed",
alt: "Subtext when alt is pressed",
cmd: "Subtext when cmd is pressed" },
text: { copy: "Text when copying",
largetype: "Text for LargeType" }))
items.to_xml
```
This produces the following XML:
``` xml
<?xml version="1.0" encoding="UTF-8"?>
<items>
<item uid="desktop" arg="~/Desktop" autocomplete="Desktop" type="file" valid="yes">
<title>Desktop</title>
<subtitle>~/Desktop</subtitle>
<icon type="fileicon">~/Desktop</icon>
</item>
<item uid="flickr" autocomplete="flickr" valid="no">
<title>Flickr</title>
<icon>flickr.png</icon>
</item>
<item uid="image" autocomplete="My holiday photo" type="file">
<title>My holiday photo</title>
<subtitle>~/Pictures/My holiday photo.jpg</subtitle>
<icon type="filetype">public.jpeg</icon>
</item>
<item uid="home" arg="~/" autocomplete="Home" type="file" valid="yes">
<title>Home Folder</title>
<subtitle>Home folder ~/</subtitle>
<icon type="fileicon">~/</icon>
<subtitle mod="shift">Subtext when shift is pressed</subtitle>
<subtitle mod="fn">Subtext when fn is pressed</subtitle>
<subtitle mod="ctrl">Subtext when ctrl is pressed</subtitle>
<subtitle mod="alt">Subtext when alt is pressed</subtitle>
<subtitle mod="cmd">Subtext when cmd is pressed</subtitle>
<text type="copy">Text when copying</text>
<text type="largetype">Text for LargeType</text>
</item>
</items>
```
### Releasing
Including `alphred/tasks` in your `Rakefile` will allow access to Alphred's
Rake tasks for releasing a workflow. `release` will tag the current commit with
the provided version and create a .alfredworkflow package with vendored gem
dependencies.
## TODO
- Make workflow configuration easier.
## Development
After checking out the repo, run `bundle install` to install dependencies.
Then, run `rake test` to run the tests. You can also run `rake console` for an
interactive prompt that will allow you to experiment.
To install this gem onto your local machine, run `bundle exec rake install`. To
release a new version, update the version number in `version.rb`, and then run
`bundle exec rake release`, which will create a git tag for the version, push
git commits and tags, and push the `.gem` file to
[rubygems.org](https://rubygems.org).
## Contributing
Bug reports and pull requests are welcome on GitHub at
https://github.com/kejadlen/alphred. This project is intended to be a safe,
welcoming space for collaboration, and contributors are expected to adhere to
the [Contributor Covenant](contributor-covenant.org) code of conduct.
## License
The gem is available as open source under the terms of the [MIT
License](http://opensource.org/licenses/MIT).

@ -0,0 +1,17 @@
require "bundler/gem_tasks"
require "rake/testtask"
Rake::TestTask.new(:test) do |t|
t.libs << "lib"
t.test_files = FileList['test/**/test_*.rb']
end
task :console do
require "bundler/setup"
require "alphred"
require "pry"
Pry.start
end
task :default => :test

@ -0,0 +1,26 @@
# coding: utf-8
lib = File.expand_path("../lib", __FILE__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require "alphred/version"
Gem::Specification.new do |spec|
spec.name = "alphred"
spec.version = Alphred::VERSION
spec.authors = ["Alpha Chen"]
spec.email = ["alpha.chen@gmail.com"]
spec.summary = %q{Helper utilities for making Alfred workflows.}
spec.homepage = "https://github.com/kejadlen/alph"
spec.license = "MIT"
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
spec.bindir = "bin"
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
spec.require_paths = ["lib"]
spec.add_dependency "builder", "~> 3.2"
spec.add_development_dependency "bundler", "~> 1.10"
spec.add_development_dependency "rake", "~> 10.0"
spec.add_development_dependency "minitest"
end

@ -0,0 +1,9 @@
require "builder"
require_relative "alphred/version"
require_relative "alphred/icon"
require_relative "alphred/item"
require_relative "alphred/items"
require_relative "alphred/mods"
require_relative "alphred/text"

@ -0,0 +1,39 @@
require "builder"
module Alphred
class Icon
VALID_TYPES = %i[ fileicon filetype ]
attr_accessor *%i[ value type ]
def initialize(**kwargs)
raise ArgumentError.new("missing keyword: value") unless kwargs.has_key?(:value)
@value = kwargs[:value]
self.type = kwargs[:type] if kwargs.has_key?(:type)
end
def type=(type)
raise ArgumentError.new("`type` must be one of #{VALID_TYPES}") unless type.nil? || VALID_TYPES.include?(type)
@type = type
end
def to_xml(xml=nil)
xml ||= Builder::XmlMarkup.new(indent: 2)
attrs = {}
attrs[:type] = self.type unless self.type.nil?
xml.icon self.value, attrs
end
end
end
module Kernel
def Icon(value)
case value
when Alphred::Icon then value
when String then Alphred::Icon.new(value: value)
when Hash then Alphred::Icon.new(**value)
end
end
end

@ -0,0 +1,59 @@
require "builder"
require_relative "mods"
require_relative "text"
module Alphred
class Item
VALID_TYPES = %i[ default file file_skipcheck ]
attr_accessor *%i[ uid arg valid autocomplete title subtitle mods icon text ]
def initialize(**kwargs)
raise ArgumentError.new("missing keyword: title") unless kwargs.has_key?(:title)
@title = kwargs[:title]
%i[ uid arg valid autocomplete subtitle ].each do |attr|
self.instance_variable_set("@#{attr}", kwargs[attr]) if kwargs.has_key?(attr)
end
@icon = Icon(kwargs[:icon]) if kwargs.has_key?(:icon)
@text = Text.new(kwargs[:text]) if kwargs.has_key?(:text)
@mods = Mods.new(kwargs[:mods]) if kwargs.has_key?(:mods)
self.type = kwargs[:type] if kwargs.has_key?(:type)
end
def type=(type)
raise ArgumentError.new("`type` must be one of #{VALID_TYPES}") unless type.nil? || VALID_TYPES.include?(type)
@type = type
end
def type
@type && @type.to_s.gsub(?_, ?:)
end
def to_xml(xml=nil)
xml ||= Builder::XmlMarkup.new(indent: 2)
xml.item self.attrs do
xml.title self.title
xml.subtitle self.subtitle unless self.subtitle.nil?
self.icon.to_xml(xml) unless self.icon.nil?
self.mods.to_xml(xml) unless self.mods.nil?
self.text.to_xml(xml) unless self.text.nil?
end
end
def attrs
attrs = {}
%i[ uid arg autocomplete type ].each do |attr|
value = self.send(attr)
attrs[attr] = value unless value.nil?
end
attrs[:valid] = (self.valid) ? "yes" : "no" unless self.valid.nil?
attrs
end
end
end

@ -0,0 +1,22 @@
require "builder"
module Alphred
class Items < DelegateClass(Array)
attr_reader :items
def initialize(*items)
@items = items
super(@items)
end
def to_xml
xml = Builder::XmlMarkup.new(indent: 2)
xml.instruct! :xml
xml.items do
self.items.each do |item|
item.to_xml(xml)
end
end
end
end
end

@ -0,0 +1,22 @@
require "builder"
module Alphred
class Mods
MODS = %i[ shift fn ctrl alt cmd ]
attr_accessor *MODS
def initialize(**kwargs)
MODS.each do |mod|
self.instance_variable_set("@#{mod}", kwargs[mod]) if kwargs.has_key?(mod)
end
end
def to_xml(xml)
MODS.each do |mod|
value = self.send(mod)
xml.subtitle value, mod: mod unless value.nil?
end
end
end
end

@ -0,0 +1,40 @@
require "rake"
namespace :alphred do
desc "Prepare a release, named after the directory"
task :release, [:version] => [:tag, :package]
desc "Tag the current commit in git with VERSION"
task :tag, [:version] do |t, args|
version = args[:version]
git_status = `git status --porcelain`
fail <<-FAIL unless git_status.empty?
Can't tag #{version}: dirty working directory.
FAIL
sh "git tag #{version}"
end
desc "Create an alfredworkflow package with vendored dependencies"
task :package do
restore_bundler_config do
cmd = "bundle install --standalone --path vendor/bundle --without development test"
sh "chruby-exec 2.0.0 -- #{cmd}"
end
sh "zip -r #{application_dir.pathmap("%n.alfredworkflow")} *"
rm_rf "vendor"
end
def application_dir
Rake.application.original_dir
end
def restore_bundler_config
path = File.join(application_dir, ".bundle", "config")
config = File.read(path)
yield
ensure
File.write(path, config, mode: ?w)
end
end

@ -0,0 +1,17 @@
require "builder"
module Alphred
class Text
attr_accessor *%i[ copy largetype ]
def initialize(copy: nil, largetype: nil)
@copy = copy
@largetype = largetype
end
def to_xml(xml)
xml.text copy, type: :copy unless self.copy.nil?
xml.text largetype, type: :largetype unless self.largetype.nil?
end
end
end

@ -0,0 +1,107 @@
= Change Log
== Version 3.2.0
* Ruby 2.0 compatibility changes.
* Allow single quoted attributes.
== Version 3.1.0
* Included the to_xs arity patch needed for weird Rails compatibility
issue.
* Escaping newlines in attributes now.
* Allow method caching
== Version 3.0.0
* Ruby 1.9 compatiblity issues.
== Version 2.2.0
* Applied patch from Thijs van der Vossen to allow UTF-8 encoded
output when the encoding is UTF-8 and $KCODE is UTF8.
== Version 2.1.2
* Fixed bug where private methods in kernel could leak through using
tag!(). Thanks to Hagen Overdick for finding and diagnosing this
bug.
== Version 2.1.1
* Fixed typo in XmlMarkup class docs (ident => indent). (from Martin
Fowler).
* Removed extra directory indirection from legacy CVS to SVN move.
* Removed some extraneous tabs from source.
* Fixed test on private methods in blankslate to differentiate between
targetted and untargetted private methods.
* Removed legacy capture of @self in XmlBase (@self was used back when
we used instance eval).
* Added additional tests for global functions (both direct and included).
== Version 2.1.0
* Fixed bug in BlankSlate where including a module into Object could
cause methods to leak into BlankSlate.
* Made BlankSlate available as its own gem. Currently the builder gem
still directly includes the BlankSlate code.
* Added reveal capability to BlankSlate.
== Version 2.0.0
* Added doc directory
* Added unit tests for XmlEvents.
* Added XChar module and used it in the _escape method.
* Attributes are now quoted by default when strings. Use Symbol
attribute values for unquoted behavior.
== Version 1.2.4
* Added a cdata! command to an XML Builder (from Josh Knowles).
== Version 1.2.3
The attributes in the <?xml ... ?> instruction will be ordered:
version, encoding, standalone.
== Version 1.2.2
Another fix for BlankSlate. The Kernal/Object traps added in 1.2.1
failed when a method was defined late more than once. Since the
method was already marked as removed, another attempt to undefine it
raised an error. The fix was to check the list of instance methods
before attempting the undef operation. Thanks to Florian Gross and
David Heinemeier Hansson for the patch.
== Version 1.2.1
BlankSlate now traps method definitions in Kernel and Object to avoid
late method definitions inadvertently becoming part of the definition
of BlankSlate as well.
== Version 1.2.0
Improved support for entity declarations by allowing nested
declarations and removal of the attribute processing.
Added namespace support.
== Version 1.1.0
Added support for comments, entity declarations and processing instructions.
== Version 1.0.0
Removed use of <tt>instace_eval</tt> making the use of XmlMarkup much
less prone to error.
== Version 0.1.1
Bug fix.
== Version 0.1.0
Initial version release.

@ -0,0 +1,20 @@
Copyright (c) 2003-2012 Jim Weirich (jim.weirich@gmail.com)
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

@ -0,0 +1,258 @@
# Project: Builder
## Goal
Provide a simple way to create XML markup and data structures.
## Classes
Builder::XmlMarkup:: Generate XML markup notation
Builder::XmlEvents:: Generate XML events (i.e. SAX-like)
**Notes:**
* An <tt>Builder::XmlTree</tt> class to generate XML tree
(i.e. DOM-like) structures is also planned, but not yet implemented.
Also, the events builder is currently lagging the markup builder in
features.
## Usage
```ruby
require 'rubygems'
require_gem 'builder', '~> 2.0'
builder = Builder::XmlMarkup.new
` xml = builder.person { |b| b.name("Jim"); b.phone("555-1234") }
xml #=> <person><name>Jim</name><phone>555-1234</phone></person>
```
or
```ruby
require 'rubygems'
require_gem 'builder'
builder = Builder::XmlMarkup.new(:target=>STDOUT, :indent=>2)
builder.person { |b| b.name("Jim"); b.phone("555-1234") }
#
# Prints:
# <person>
# <name>Jim</name>
# <phone>555-1234</phone>
# </person>
```
## Compatibility
### Version 2.0.0 Compatibility Changes
Version 2.0.0 introduces automatically escaped attribute values for
the first time. Versions prior to 2.0.0 did not insert escape
characters into attribute values in the XML markup. This allowed
attribute values to explicitly reference entities, which was
occasionally used by a small number of developers. Since strings
could always be explicitly escaped by hand, this was not a major
restriction in functionality.
However, it did surprise most users of builder. Since the body text is
normally escaped, everybody expected the attribute values to be
escaped as well. Escaped attribute values were the number one support
request on the 1.x Builder series.
Starting with Builder version 2.0.0, all attribute values expressed as
strings will be processed and the appropriate characters will be
escaped (e.g. "&" will be translated to "&amp;"). Attribute values
that are expressed as Symbol values will not be processed for escaped
characters and will be unchanged in output. (Yes, this probably counts
as Symbol abuse, but the convention is convenient and flexible).
Example:
```ruby
xml = Builder::XmlMarkup.new
xml.sample(:escaped=>"This&That", :unescaped=>:"Here&amp;There")
xml.target! =>
<sample escaped="This&amp;That" unescaped="Here&amp;There"/>
```
### Version 1.0.0 Compatibility Changes
Version 1.0.0 introduces some changes that are not backwards
compatible with earlier releases of builder. The main areas of
incompatibility are:
* Keyword based arguments to +new+ (rather than positional based). It
was found that a developer would often like to specify indentation
without providing an explicit target, or specify a target without
indentation. Keyword based arguments handle this situation nicely.
* Builder must now be an explicit target for markup tags. Instead of
writing
```ruby
xml_markup = Builder::XmlMarkup.new
xml_markup.div { strong("text") }
```
you need to write
```ruby
xml_markup = Builder::XmlMarkup.new
xml_markup.div { xml_markup.strong("text") }
```
* The builder object is passed as a parameter to all nested markup
blocks. This allows you to create a short alias for the builder
object that can be used within the block. For example, the previous
example can be written as:
```ruby
xml_markup = Builder::XmlMarkup.new
xml_markup.div { |xml| xml.strong("text") }
```
* If you have both a pre-1.0 and a post-1.0 gem of builder installed,
you can choose which version to use through the RubyGems
+require_gem+ facility.
```ruby
require_gem 'builder', "~> 0.0" # Gets the old version
require_gem 'builder', "~> 1.0" # Gets the new version
```
## Features
* XML Comments are supported ...
```ruby
xml_markup.comment! "This is a comment"
#=> <!-- This is a comment -->
```
* XML processing instructions are supported ...
```ruby
xml_markup.instruct! :xml, :version=>"1.0", :encoding=>"UTF-8"
#=> <?xml version="1.0" encoding="UTF-8"?>
```
If the processing instruction is omitted, it defaults to "xml".
When the processing instruction is "xml", the defaults attributes
are:
<b>version</b>: 1.0
<b>encoding</b>: "UTF-8"
(NOTE: if the encoding is set to "UTF-8" and $KCODE is set to
"UTF8", then Builder will emit UTF-8 encoded strings rather than
encoding non-ASCII characters as entities.)
* XML entity declarations are now supported to a small degree.
```ruby
xml_markup.declare! :DOCTYPE, :chapter, :SYSTEM, "../dtds/chapter.dtd"
#=> <!DOCTYPE chapter SYSTEM "../dtds/chapter.dtd">
```
The parameters to a declare! method must be either symbols or
strings. Symbols are inserted without quotes, and strings are
inserted with double quotes. Attribute-like arguments in hashes are
not allowed.
If you need to have an argument to declare! be inserted without
quotes, but the argument does not conform to the typical Ruby
syntax for symbols, then use the :"string" form to specify a symbol.
For example:
```ruby
xml_markup.declare! :ELEMENT, :chapter, :"(title,para+)"
#=> <!ELEMENT chapter (title,para+)>
```
Nested entity declarations are allowed. For example:
```ruby
@xml_markup.declare! :DOCTYPE, :chapter do |x|
x.declare! :ELEMENT, :chapter, :"(title,para+)"
x.declare! :ELEMENT, :title, :"(#PCDATA)"
x.declare! :ELEMENT, :para, :"(#PCDATA)"
end
#=>
<!DOCTYPE chapter [
<!ELEMENT chapter (title,para+)>
<!ELEMENT title (#PCDATA)>
<!ELEMENT para (#PCDATA)>
]>
```
* Some support for XML namespaces is now available. If the first
argument to a tag call is a symbol, it will be joined to the tag to
produce a namespace:tag combination. It is easier to show this than
describe it.
```ruby
xml.SOAP :Envelope do ... end
```
Just put a space before the colon in a namespace to produce the
right form for builder (e.g. "<tt>SOAP:Envelope</tt>" =>
"<tt>xml.SOAP :Envelope</tt>")
* String attribute values are <em>now</em> escaped by default by
Builder (<b>NOTE:</b> this is _new_ behavior as of version 2.0).
However, occasionally you need to use entities in attribute values.
Using a symbol (rather than a string) for an attribute value will
cause Builder to not run its quoting/escaping algorithm on that
particular value.
(<b>Note:</b> The +escape_attrs+ option for builder is now
obsolete).
Example:
```ruby
xml = Builder::XmlMarkup.new
xml.sample(:escaped=>"This&That", :unescaped=>:"Here&amp;There")
xml.target! =>
<sample escaped="This&amp;That" unescaped="Here&amp;There"/>
```
* UTF-8 Support
Builder correctly translates UTF-8 characters into valid XML. (New
in version 2.0.0). Thanks to Sam Ruby for the translation code.
You can get UTF-8 encoded output by making sure that the XML
encoding is set to "UTF-8" and that the $KCODE variable is set to
"UTF8".
```ruby
$KCODE = 'UTF8'
xml = Builder::Markup.new
xml.instruct!(:xml, :encoding => "UTF-8")
xml.sample("Iñtërnâtiônàl")
xml.target! =>
"<sample>Iñtërnâtiônàl</sample>"
```
## Links
| Description | Link |
| :----: | :----: |
| Documents | http://builder.rubyforge.org/ |
| Github Clone | git://github.com/jimweirich/builder.git |
| Issue / Bug Reports | https://github.com/jimweirich/builder/issues?state=open |
## Contact
| Description | Value |
| :----: | :----: |
| Author | Jim Weirich |
| Email | jim.weirich@gmail.com |
| Home Page | http://onestepback.org |
| License | MIT Licence (http://www.opensource.org/licenses/mit-license.html) |

@ -0,0 +1,195 @@
# Rakefile for rake -*- ruby -*-
# Copyright 2004, 2005, 2006 by Jim Weirich (jim@weirichhouse.org).
# All rights reserved.
# Permission is granted for use, copying, modification, distribution,
# and distribution of modified versions of this work as long as the
# above copyright notice is included.
require 'rake/clean'
require 'rake/testtask'
begin
require 'rubygems'
require 'rubygems/package_task'
require 'rdoc/task'
rescue Exception
nil
end
require './lib/builder/version'
# Determine the current version of the software
CLOBBER.include('pkg', 'html')
CLEAN.include('pkg/builder-*').include('pkg/blankslate-*').exclude('pkg/*.gem')
PKG_VERSION = Builder::VERSION
SRC_RB = FileList['lib/**/*.rb']
# The default task is run if rake is given no explicit arguments.
desc "Default Task"
task :default => :test_all
# Test Tasks ---------------------------------------------------------
desc "Run all tests"
task :test_all => [:test_units]
task :ta => [:test_all]
task :tu => [:test_units]
Rake::TestTask.new("test_units") do |t|
t.test_files = FileList['test/test*.rb']
t.libs << "."
t.verbose = false
end
# Create a task to build the RDOC documentation tree.
if defined?(RDoc)
rd = RDoc::Task.new("rdoc") { |rdoc|
rdoc.rdoc_dir = 'html'
rdoc.title = "Builder for Markup"
rdoc.options << '--line-numbers' << '--inline-source' << '--main' << 'README.rdoc'
rdoc.rdoc_files.include('lib/**/*.rb', '[A-Z]*', 'doc/**/*.rdoc').exclude("TAGS")
rdoc.template = 'doc/jamis.rb'
}
else
rd = Struct.new(:rdoc_files).new([])
end
# ====================================================================
# Create a task that will package the Rake software into distributable
# gem files.
PKG_FILES = FileList[
'[A-Z]*',
'doc/**/*',
'lib/**/*.rb',
'test/**/*.rb',
'rakelib/**/*'
]
PKG_FILES.exclude('test/test_cssbuilder.rb')
PKG_FILES.exclude('lib/builder/css.rb')
PKG_FILES.exclude('TAGS')
BLANKSLATE_FILES = FileList[
'lib/blankslate.rb',
'test/test_blankslate.rb'
]
if ! defined?(Gem)
puts "Package Target requires RubyGEMs"
else
spec = Gem::Specification.new do |s|
#### Basic information.
s.name = 'builder'
s.version = PKG_VERSION
s.summary = "Builders for MarkUp."
s.description = %{\
Builder provides a number of builder objects that make creating structured data
simple to do. Currently the following builder objects are supported:
* XML Markup
* XML Events
}
s.files = PKG_FILES.to_a
s.require_path = 'lib'
s.test_files = PKG_FILES.select { |fn| fn =~ /^test\/test/ }
s.has_rdoc = true
s.extra_rdoc_files = rd.rdoc_files.reject { |fn| fn =~ /\.rb$/ }.to_a
s.rdoc_options <<
'--title' << 'Builder -- Easy XML Building' <<
'--main' << 'README.rdoc' <<
'--line-numbers'
s.author = "Jim Weirich"
s.email = "jim.weirich@gmail.com"
s.homepage = "http://onestepback.org"
s.license = 'MIT'
end
blankslate_spec = Gem::Specification.new do |s|
#### Basic information.
s.name = 'blankslate'
s.version = PKG_VERSION
s.summary = "Blank Slate base class."
s.description = %{\
BlankSlate provides a base class where almost all of the methods from Object and
Kernel have been removed. This is useful when providing proxy object and other
classes that make heavy use of method_missing.
}
s.files = BLANKSLATE_FILES.to_a
s.require_path = 'lib'
s.test_files = PKG_FILES.select { |fn| fn =~ /^test\/test/ }
s.has_rdoc = true
s.extra_rdoc_files = rd.rdoc_files.reject { |fn| fn =~ /\.rb$/ }.to_a
s.rdoc_options <<
'--title' << 'BlankSlate -- Base Class for building proxies.' <<
'--main' << 'README.rdoc' <<
'--line-numbers'
s.author = "Jim Weirich"
s.email = "jim.weirich@gmail.com"
s.homepage = "http://onestepback.org"
s.license = 'MIT'
end
namespace 'builder' do
Gem::PackageTask.new(spec) do |t|
t.need_tar = false
end
end
namespace 'blankslate' do
Gem::PackageTask.new(blankslate_spec) do |t|
t.need_tar = false
end
end
task :package => [:remove_tags, 'builder:package', 'blankslate:package']
end
task :remove_tags do
rm "TAGS" rescue nil
end
# RCov ---------------------------------------------------------------
begin
require 'rcov/rcovtask'
Rcov::RcovTask.new do |t|
t.libs << "test"
t.rcov_opts = [
'-xRakefile', '--text-report'
]
t.test_files = FileList[
'test/test*.rb'
]
t.output_dir = 'coverage'
t.verbose = true
end
rescue LoadError
# No rcov available
end
desc "Install the jamis RDoc template"
task :install_jamis_template do
require 'rbconfig'
dest_dir = File.join(Config::CONFIG['rubylibdir'], "rdoc/generators/template/html")
fail "Unabled to write to #{dest_dir}" unless File.writable?(dest_dir)
install "doc/jamis.rb", dest_dir, :verbose => true
end

@ -0,0 +1,591 @@
module RDoc
module Page
FONTS = "\"Bitstream Vera Sans\", Verdana, Arial, Helvetica, sans-serif"
STYLE = <<CSS
a {
color: #00F;
text-decoration: none;
}
a:hover {
color: #77F;
text-decoration: underline;
}
body, td, p {
font-family: %fonts%;
background: #FFF;
color: #000;
margin: 0px;
font-size: small;
}
#content {
margin: 2em;
}
#description p {
margin-bottom: 0.5em;
}
.sectiontitle {
margin-top: 1em;
margin-bottom: 1em;
padding: 0.5em;
padding-left: 2em;
background: #005;
color: #FFF;
font-weight: bold;
border: 1px dotted black;
}
.attr-rw {
padding-left: 1em;
padding-right: 1em;
text-align: center;
color: #055;
}
.attr-name {
font-weight: bold;
}
.attr-desc {
}
.attr-value {
font-family: monospace;
}
.file-title-prefix {
font-size: large;
}
.file-title {
font-size: large;
font-weight: bold;
background: #005;
color: #FFF;
}
.banner {
background: #005;
color: #FFF;
border: 1px solid black;
padding: 1em;
}
.banner td {
background: transparent;
color: #FFF;
}
h1 a, h2 a, .sectiontitle a, .banner a {
color: #FF0;
}
h1 a:hover, h2 a:hover, .sectiontitle a:hover, .banner a:hover {
color: #FF7;
}
.dyn-source {
display: none;
background: #FFE;
color: #000;
border: 1px dotted black;
margin: 0.5em 2em 0.5em 2em;
padding: 0.5em;
}
.dyn-source .cmt {
color: #00F;
font-style: italic;
}
.dyn-source .kw {
color: #070;
font-weight: bold;
}
.method {
margin-left: 1em;
margin-right: 1em;
margin-bottom: 1em;
}
.description pre {
padding: 0.5em;
border: 1px dotted black;
background: #FFE;
}
.method .title {
font-family: monospace;
font-size: large;
border-bottom: 1px dashed black;
margin-bottom: 0.3em;
padding-bottom: 0.1em;
}
.method .description, .method .sourcecode {
margin-left: 1em;
}
.description p, .sourcecode p {
margin-bottom: 0.5em;
}
.method .sourcecode p.source-link {
text-indent: 0em;
margin-top: 0.5em;
}
.method .aka {
margin-top: 0.3em;
margin-left: 1em;
font-style: italic;
text-indent: 2em;
}
h1 {
padding: 1em;
border: 1px solid black;
font-size: x-large;
font-weight: bold;
color: #FFF;
background: #007;
}
h2 {
padding: 0.5em 1em 0.5em 1em;
border: 1px solid black;
font-size: large;
font-weight: bold;
color: #FFF;
background: #009;
}
h3, h4, h5, h6 {
padding: 0.2em 1em 0.2em 1em;
border: 1px dashed black;
color: #000;
background: #AAF;
}
.sourcecode > pre {
padding: 0.5em;
border: 1px dotted black;
background: #FFE;
}
CSS
XHTML_PREAMBLE = %{<?xml version="1.0" encoding="%charset%"?>
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
}
HEADER = XHTML_PREAMBLE + <<ENDHEADER
<html>
<head>
<title>%title%</title>
<meta http-equiv="Content-Type" content="text/html; charset=%charset%" />
<link rel="stylesheet" href="%style_url%" type="text/css" media="screen" />
<script language="JavaScript" type="text/javascript">
// <![CDATA[
function toggleSource( id )
{
var elem
var link
if( document.getElementById )
{
elem = document.getElementById( id )
link = document.getElementById( "l_" + id )
}
else if ( document.all )
{
elem = eval( "document.all." + id )
link = eval( "document.all.l_" + id )
}
else
return false;
if( elem.style.display == "block" )
{
elem.style.display = "none"
link.innerHTML = "show source"
}
else
{
elem.style.display = "block"
link.innerHTML = "hide source"
}
}
function openCode( url )
{
window.open( url, "SOURCE_CODE", "width=400,height=400,scrollbars=yes" )
}
// ]]>
</script>
</head>
<body>
ENDHEADER
FILE_PAGE = <<HTML
<table border='0' cellpadding='0' cellspacing='0' width="100%" class='banner'>
<tr><td>
<table width="100%" border='0' cellpadding='0' cellspacing='0'><tr>
<td class="file-title" colspan="2"><span class="file-title-prefix">File</span><br />%short_name%</td>
<td align="right">
<table border='0' cellspacing="0" cellpadding="2">
<tr>
<td>Path:</td>
<td>%full_path%
IF:cvsurl
&nbsp;(<a href="%cvsurl%">CVS</a>)
ENDIF:cvsurl
</td>
</tr>
<tr>
<td>Modified:</td>
<td>%dtm_modified%</td>
</tr>
</table>
</td></tr>
</table>
</td></tr>
</table><br>
HTML
###################################################################
CLASS_PAGE = <<HTML
<table width="100%" border='0' cellpadding='0' cellspacing='0' class='banner'><tr>
<td class="file-title"><span class="file-title-prefix">%classmod%</span><br />%full_name%</td>
<td align="right">
<table cellspacing=0 cellpadding=2>
<tr valign="top">
<td>In:</td>
<td>
START:infiles
HREF:full_path_url:full_path:
IF:cvsurl
&nbsp;(<a href="%cvsurl%">CVS</a>)
ENDIF:cvsurl
END:infiles
</td>
</tr>
IF:parent
<tr>
<td>Parent:</td>
<td>
IF:par_url
<a href="%par_url%">
ENDIF:par_url
%parent%
IF:par_url
</a>
ENDIF:par_url
</td>
</tr>
ENDIF:parent
</table>
</td>
</tr>
</table>
HTML
###################################################################
METHOD_LIST = <<HTML
<div id="content">
IF:diagram
<table cellpadding='0' cellspacing='0' border='0' width="100%"><tr><td align="center">
%diagram%
</td></tr></table>
ENDIF:diagram
IF:description
<div class="description">%description%</div>
ENDIF:description
IF:requires
<div class="sectiontitle">Required Files</div>
<ul>
START:requires
<li>HREF:aref:name:</li>
END:requires
</ul>
ENDIF:requires
IF:toc
<div class="sectiontitle">Contents</div>
<ul>
START:toc
<li><a href="#%href%">%secname%</a></li>
END:toc
</ul>
ENDIF:toc
IF:methods
<div class="sectiontitle">Methods</div>
<ul>
START:methods
<li>HREF:aref:name:</li>
END:methods
</ul>
ENDIF:methods
IF:includes
<div class="sectiontitle">Included Modules</div>
<ul>
START:includes
<li>HREF:aref:name:</li>
END:includes
</ul>
ENDIF:includes
START:sections
IF:sectitle
<div class="sectiontitle"><a nem="%secsequence%">%sectitle%</a></div>
IF:seccomment
<div class="description">
%seccomment%
</div>
ENDIF:seccomment
ENDIF:sectitle
IF:classlist
<div class="sectiontitle">Classes and Modules</div>
%classlist%
ENDIF:classlist
IF:constants
<div class="sectiontitle">Constants</div>
<table border='0' cellpadding='5'>
START:constants
<tr valign='top'>
<td class="attr-name">%name%</td>
<td>=</td>
<td class="attr-value">%value%</td>
</tr>
IF:desc
<tr valign='top'>
<td>&nbsp;</td>
<td colspan="2" class="attr-desc">%desc%</td>
</tr>
ENDIF:desc
END:constants
</table>
ENDIF:constants
IF:attributes
<div class="sectiontitle">Attributes</div>
<table border='0' cellpadding='5'>
START:attributes
<tr valign='top'>
<td class='attr-rw'>
IF:rw
[%rw%]
ENDIF:rw
</td>
<td class='attr-name'>%name%</td>
<td class='attr-desc'>%a_desc%</td>
</tr>
END:attributes
</table>
ENDIF:attributes
IF:method_list
START:method_list
IF:methods
<div class="sectiontitle">%type% %category% methods</div>
START:methods
<div class="method">
<div class="title">
IF:callseq
<a name="%aref%"></a><b>%callseq%</b>
ENDIF:callseq
IFNOT:callseq
<a name="%aref%"></a><b>%name%</b>%params%
ENDIF:callseq
IF:codeurl
[ <a href="javascript:openCode('%codeurl%')">source</a> ]
ENDIF:codeurl
</div>
IF:m_desc
<div class="description">
%m_desc%
</div>
ENDIF:m_desc
IF:aka
<div class="aka">
This method is also aliased as
START:aka
<a href="%aref%">%name%</a>
END:aka
</div>
ENDIF:aka
IF:sourcecode
<div class="sourcecode">
<p class="source-link">[ <a href="javascript:toggleSource('%aref%_source')" id="l_%aref%_source">show source</a> ]</p>
<div id="%aref%_source" class="dyn-source">
<pre>
%sourcecode%
</pre>
</div>
</div>
ENDIF:sourcecode
</div>
END:methods
ENDIF:methods
END:method_list
ENDIF:method_list
END:sections
</div>
HTML
FOOTER = <<ENDFOOTER
</body>
</html>
ENDFOOTER
BODY = HEADER + <<ENDBODY
!INCLUDE! <!-- banner header -->
<div id="bodyContent">
#{METHOD_LIST}
</div>
#{FOOTER}
ENDBODY
########################## Source code ##########################
SRC_PAGE = XHTML_PREAMBLE + <<HTML
<html>
<head><title>%title%</title>
<meta http-equiv="Content-Type" content="text/html; charset=%charset%">
<style>
.ruby-comment { color: green; font-style: italic }
.ruby-constant { color: #4433aa; font-weight: bold; }
.ruby-identifier { color: #222222; }
.ruby-ivar { color: #2233dd; }
.ruby-keyword { color: #3333FF; font-weight: bold }
.ruby-node { color: #777777; }
.ruby-operator { color: #111111; }
.ruby-regexp { color: #662222; }
.ruby-value { color: #662222; font-style: italic }
.kw { color: #3333FF; font-weight: bold }
.cmt { color: green; font-style: italic }
.str { color: #662222; font-style: italic }
.re { color: #662222; }
</style>
</head>
<body bgcolor="white">
<pre>%code%</pre>
</body>
</html>
HTML
########################## Index ################################
FR_INDEX_BODY = <<HTML
!INCLUDE!
HTML
FILE_INDEX = XHTML_PREAMBLE + <<HTML
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=%charset%">
<style>
<!--
body {
background-color: #EEE;
font-family: #{FONTS};
color: #000;
margin: 0px;
}
.banner {
background: #005;
color: #FFF;
padding: 0.2em;
font-size: small;
font-weight: bold;
text-align: center;
}
.entries {
margin: 0.25em 1em 0 1em;
font-size: x-small;
}
a {
color: #00F;
text-decoration: none;
white-space: nowrap;
}
a:hover {
color: #77F;
text-decoration: underline;
}
-->
</style>
<base target="docwin">
</head>
<body>
<div class="banner">%list_title%</div>
<div class="entries">
START:entries
<a href="%href%">%name%</a><br>
END:entries
</div>
</body></html>
HTML
CLASS_INDEX = FILE_INDEX
METHOD_INDEX = FILE_INDEX
INDEX = XHTML_PREAMBLE + <<HTML
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>%title%</title>
<meta http-equiv="Content-Type" content="text/html; charset=%charset%">
</head>
<frameset cols="20%,*">
<frameset rows="15%,35%,50%">
<frame src="fr_file_index.html" title="Files" name="Files" />
<frame src="fr_class_index.html" name="Classes" />
<frame src="fr_method_index.html" name="Methods" />
</frameset>
IF:inline_source
<frame src="%initial_page%" name="docwin">
ENDIF:inline_source
IFNOT:inline_source
<frameset rows="80%,20%">
<frame src="%initial_page%" name="docwin">
<frame src="blank.html" name="source">
</frameset>
ENDIF:inline_source
<noframes>
<body bgcolor="white">
Click <a href="html/index.html">here</a> for a non-frames
version of this page.
</body>
</noframes>
</frameset>
</html>
HTML
end
end

@ -0,0 +1,31 @@
= Builder 1.2.4 Released.
Added a "CDATA" method to the XML Markup builder (from Josh Knowles).
== What is Builder?
Builder::XmlMarkup allows easy programmatic creation of XML markup.
For example:
builder = Builder::XmlMarkup.new(:target=>STDOUT, :indent=>2)
builder.person { |b| b.name("Jim"); b.phone("555-1234") }
puts builder.target!
will generate:
<person>
<name>Jim</name>
<phone>555-1234</phone>
</person>
== Availability
The easiest way to get and install builder is via RubyGems ...
gem install builder (you may need root/admin privileges)
== Thanks
* Josh Knowles for the cdata! patch.
-- Jim Weirich

@ -0,0 +1,46 @@
= Builder 2.0.0 Released.
== Changes in 2.0.0
* UTF-8 characters in data are now correctly translated to their XML
equivalents. (Thanks to Sam Ruby)
* Attribute values are now escaped by default. See the README
file for details.
<b>NOTE:</b> The escaping attribute values by default is different
than in previous releases of Builder. This makes version 2.0.0
somewhat incompatible with the 1.x series of Builder. If you use "&",
"<", or ">" in attributes values, you may have to change your
code. (Essentially you remove the manual escaping. The new way is
easier, believe me).
== What is Builder?
Builder::XmlMarkup is a library that allows easy programmatic creation
of XML markup. For example:
builder = Builder::XmlMarkup.new(:target=>STDOUT, :indent=>2)
builder.person { |b| b.name("Jim"); b.phone("555-1234") }
will generate:
<person>
<name>Jim</name>
<phone>555-1234</phone>
</person>
== Availability
The easiest way to get and install builder is via RubyGems ...
gem install builder (you may need root/admin privileges)
== Thanks
* Sam Ruby for the XChar module and the related UTF-8 translation
tools.
* Also to Sam Ruby for gently persuading me to start quoting attribute
values.
-- Jim Weirich

@ -0,0 +1,58 @@
= Builder 2.1.1 Released.
Release 2.1.1 of Builder is mainly a bug fix release.
== Changes in 2.1.1
* Added <tt>reveal</tt> capability to BlankSlate.
* Fixed a bug in BlankSlate where including a module into Object could
cause methods to leak into BlankSlate.
* Fixed typo in XmlMarkup class docs (from Martin Fowler).
* Fixed test on private methods to differentiate between targetted and
untargetted private methods.
* Removed legacy capture of @self in XmlBase (@self was used back when
we used instance eval).
* Added additional tests for global functions (both direct and
included).
* Several misc internal cleanups, including rearranging the source
code tree.
<b>NOTE:</b> The escaping attribute values by default is different
than in previous releases of Builder. This makes version 2.0.x
somewhat incompatible with the 1.x series of Builder. If you use "&",
"<", or ">" in attributes values, you may have to change your
code. (Essentially you remove the manual escaping. The new way is
easier, believe me).
== What is Builder?
Builder::XmlMarkup is a library that allows easy programmatic creation
of XML markup. For example:
builder = Builder::XmlMarkup.new(:target=>STDOUT, :indent=>2)
builder.person { |b| b.name("Jim"); b.phone("555-1234") }
will generate:
<person>
<name>Jim</name>
<phone>555-1234</phone>
</person>
== Availability
The easiest way to get and install builder is via RubyGems ...
gem install builder (you may need root/admin privileges)
== Thanks
* Martin Fowler for spotting some typos in the documentation.
-- Jim Weirich

@ -0,0 +1,137 @@
#!/usr/bin/env ruby
#--
# Copyright 2004, 2006 by Jim Weirich (jim@weirichhouse.org).
# All rights reserved.
# Permission is granted for use, copying, modification, distribution,
# and distribution of modified versions of this work as long as the
# above copyright notice is included.
#++
class String
if instance_methods.first.is_a?(Symbol)
def _blankslate_as_name
to_sym
end
else
def _blankslate_as_name
self
end
end
end
class Symbol
if instance_methods.first.is_a?(Symbol)
def _blankslate_as_name
self
end
else
def _blankslate_as_name
to_s
end
end
end
######################################################################
# BlankSlate provides an abstract base class with no predefined
# methods (except for <tt>\_\_send__</tt> and <tt>\_\_id__</tt>).
# BlankSlate is useful as a base class when writing classes that
# depend upon <tt>method_missing</tt> (e.g. dynamic proxies).
#
class BlankSlate
class << self
# Hide the method named +name+ in the BlankSlate class. Don't
# hide +instance_eval+ or any method beginning with "__".
def hide(name)
warn_level = $VERBOSE
$VERBOSE = nil
if instance_methods.include?(name._blankslate_as_name) &&
name !~ /^(__|instance_eval$)/
@hidden_methods ||= {}
@hidden_methods[name.to_sym] = instance_method(name)
undef_method name
end
ensure
$VERBOSE = warn_level
end
def find_hidden_method(name)
@hidden_methods ||= {}
@hidden_methods[name] || superclass.find_hidden_method(name)
end
# Redefine a previously hidden method so that it may be called on a blank
# slate object.
def reveal(name)
hidden_method = find_hidden_method(name)
fail "Don't know how to reveal method '#{name}'" unless hidden_method
define_method(name, hidden_method)
end
end
instance_methods.each { |m| hide(m) }
end
######################################################################
# Since Ruby is very dynamic, methods added to the ancestors of
# BlankSlate <em>after BlankSlate is defined</em> will show up in the
# list of available BlankSlate methods. We handle this by defining a
# hook in the Object and Kernel classes that will hide any method
# defined after BlankSlate has been loaded.
#
module Kernel
class << self
alias_method :blank_slate_method_added, :method_added
# Detect method additions to Kernel and remove them in the
# BlankSlate class.
def method_added(name)
result = blank_slate_method_added(name)
return result if self != Kernel
BlankSlate.hide(name)
result
end
end
end
######################################################################
# Same as above, except in Object.
#
class Object
class << self
alias_method :blank_slate_method_added, :method_added
# Detect method additions to Object and remove them in the
# BlankSlate class.
def method_added(name)
result = blank_slate_method_added(name)
return result if self != Object
BlankSlate.hide(name)
result
end
def find_hidden_method(name)
nil
end
end
end
######################################################################
# Also, modules included into Object need to be scanned and have their
# instance methods removed from blank slate. In theory, modules
# included into Kernel would have to be removed as well, but a
# "feature" of Ruby prevents late includes into modules from being
# exposed in the first place.
#
class Module
alias blankslate_original_append_features append_features
def append_features(mod)
result = blankslate_original_append_features(mod)
return result if mod != Object
instance_methods.each do |name|
BlankSlate.hide(name)
end
result
end
end

@ -0,0 +1,13 @@
#!/usr/bin/env ruby
#--
# Copyright 2004 by Jim Weirich (jim@weirichhouse.org).
# All rights reserved.
# Permission is granted for use, copying, modification, distribution,
# and distribution of modified versions of this work as long as the
# above copyright notice is included.
#++
require 'builder/xmlmarkup'
require 'builder/xmlevents'

@ -0,0 +1,23 @@
#!/usr/bin/env ruby
#--
# Copyright 2004, 2006 by Jim Weirich (jim@weirichhouse.org).
# All rights reserved.
# Permission is granted for use, copying, modification, distribution,
# and distribution of modified versions of this work as long as the
# above copyright notice is included.
#++
######################################################################
# BlankSlate has been promoted to a top level name and is now
# available as a standalone gem. We make the name available in the
# Builder namespace for compatibility.
#
module Builder
if Object::const_defined?(:BasicObject)
BlankSlate = ::BasicObject
else
require 'blankslate'
BlankSlate = ::BlankSlate
end
end

@ -0,0 +1,8 @@
module Builder
VERSION_NUMBERS = [
VERSION_MAJOR = 3,
VERSION_MINOR = 2,
VERSION_BUILD = 2,
]
VERSION = VERSION_NUMBERS.join(".")
end

@ -0,0 +1,197 @@
#!/usr/bin/env ruby
# The XChar library is provided courtesy of Sam Ruby (See
# http://intertwingly.net/stories/2005/09/28/xchar.rb)
# --------------------------------------------------------------------
# If the Builder::XChar module is not currently defined, fail on any
# name clashes in standard library classes.
module Builder
def self.check_for_name_collision(klass, method_name, defined_constant=nil)
if klass.method_defined?(method_name.to_s)
fail RuntimeError,
"Name Collision: Method '#{method_name}' is already defined in #{klass}"
end
end
end
if ! defined?(Builder::XChar) and ! String.method_defined?(:encode)
Builder.check_for_name_collision(String, "to_xs")
Builder.check_for_name_collision(Fixnum, "xchr")
end
######################################################################
module Builder
####################################################################
# XML Character converter, from Sam Ruby:
# (see http://intertwingly.net/stories/2005/09/28/xchar.rb).
#
module XChar # :nodoc:
# See
# http://intertwingly.net/stories/2004/04/14/i18n.html#CleaningWindows
# for details.
CP1252 = { # :nodoc:
128 => 8364, # euro sign
130 => 8218, # single low-9 quotation mark
131 => 402, # latin small letter f with hook
132 => 8222, # double low-9 quotation mark
133 => 8230, # horizontal ellipsis
134 => 8224, # dagger
135 => 8225, # double dagger
136 => 710, # modifier letter circumflex accent
137 => 8240, # per mille sign
138 => 352, # latin capital letter s with caron
139 => 8249, # single left-pointing angle quotation mark
140 => 338, # latin capital ligature oe
142 => 381, # latin capital letter z with caron
145 => 8216, # left single quotation mark
146 => 8217, # right single quotation mark
147 => 8220, # left double quotation mark
148 => 8221, # right double quotation mark
149 => 8226, # bullet
150 => 8211, # en dash
151 => 8212, # em dash
152 => 732, # small tilde
153 => 8482, # trade mark sign
154 => 353, # latin small letter s with caron
155 => 8250, # single right-pointing angle quotation mark
156 => 339, # latin small ligature oe
158 => 382, # latin small letter z with caron
159 => 376, # latin capital letter y with diaeresis
}
# See http://www.w3.org/TR/REC-xml/#dt-chardata for details.
PREDEFINED = {
38 => '&amp;', # ampersand
60 => '&lt;', # left angle bracket
62 => '&gt;', # right angle bracket
}
# See http://www.w3.org/TR/REC-xml/#charsets for details.
VALID = [
0x9, 0xA, 0xD,
(0x20..0xD7FF),
(0xE000..0xFFFD),
(0x10000..0x10FFFF)
]
# http://www.fileformat.info/info/unicode/char/fffd/index.htm
REPLACEMENT_CHAR =
if String.method_defined?(:encode)
"\uFFFD"
elsif $KCODE == 'UTF8'
"\xEF\xBF\xBD"
else
'*'
end
end
end
if String.method_defined?(:encode)
module Builder
module XChar # :nodoc:
CP1252_DIFFERENCES, UNICODE_EQUIVALENT = Builder::XChar::CP1252.each.
inject([[],[]]) {|(domain,range),(key,value)|
[domain << key,range << value]
}.map {|seq| seq.pack('U*').force_encoding('utf-8')}
XML_PREDEFINED = Regexp.new('[' +
Builder::XChar::PREDEFINED.keys.pack('U*').force_encoding('utf-8') +
']')
INVALID_XML_CHAR = Regexp.new('[^'+
Builder::XChar::VALID.map { |item|
case item
when Fixnum
[item].pack('U').force_encoding('utf-8')
when Range
[item.first, '-'.ord, item.last].pack('UUU').force_encoding('utf-8')
end
}.join +
']')
ENCODING_BINARY = Encoding.find('BINARY')
ENCODING_UTF8 = Encoding.find('UTF-8')
ENCODING_ISO1 = Encoding.find('ISO-8859-1')
# convert a string to valid UTF-8, compensating for a number of
# common errors.
def XChar.unicode(string)
if string.encoding == ENCODING_BINARY
if string.ascii_only?
string
else
string = string.clone.force_encoding(ENCODING_UTF8)
if string.valid_encoding?
string
else
string.encode(ENCODING_UTF8, ENCODING_ISO1)
end
end
elsif string.encoding == ENCODING_UTF8
if string.valid_encoding?
string
else
string.encode(ENCODING_UTF8, ENCODING_ISO1)
end
else
string.encode(ENCODING_UTF8)
end
end
# encode a string per XML rules
def XChar.encode(string)
unicode(string).
tr(CP1252_DIFFERENCES, UNICODE_EQUIVALENT).
gsub(INVALID_XML_CHAR, REPLACEMENT_CHAR).
gsub(XML_PREDEFINED) {|c| PREDEFINED[c.ord]}
end
end
end
else
######################################################################
# Enhance the Fixnum class with a XML escaped character conversion.
#
class Fixnum
XChar = Builder::XChar if ! defined?(XChar)
# XML escaped version of chr. When <tt>escape</tt> is set to false
# the CP1252 fix is still applied but utf-8 characters are not
# converted to character entities.
def xchr(escape=true)
n = XChar::CP1252[self] || self
case n when *XChar::VALID
XChar::PREDEFINED[n] or
(n<128 ? n.chr : (escape ? "&##{n};" : [n].pack('U*')))
else
Builder::XChar::REPLACEMENT_CHAR
end
end
end
######################################################################
# Enhance the String class with a XML escaped character version of
# to_s.
#
class String
# XML escaped version of to_s. When <tt>escape</tt> is set to false
# the CP1252 fix is still applied but utf-8 characters are not
# converted to character entities.
def to_xs(escape=true)
unpack('U*').map {|n| n.xchr(escape)}.join # ASCII, UTF-8
rescue
unpack('C*').map {|n| n.xchr}.join # ISO-8859-1, WIN-1252
end
end
end

@ -0,0 +1,199 @@
#!/usr/bin/env ruby
require 'builder/blankslate'
module Builder
# Generic error for builder
class IllegalBlockError < RuntimeError; end
# XmlBase is a base class for building XML builders. See
# Builder::XmlMarkup and Builder::XmlEvents for examples.
class XmlBase < BlankSlate
class << self
attr_accessor :cache_method_calls
end
# Create an XML markup builder.
#
# out :: Object receiving the markup. +out+ must respond to
# <tt><<</tt>.
# indent :: Number of spaces used for indentation (0 implies no
# indentation and no line breaks).
# initial :: Level of initial indentation.
# encoding :: When <tt>encoding</tt> and $KCODE are set to 'utf-8'
# characters aren't converted to character entities in
# the output stream.
def initialize(indent=0, initial=0, encoding='utf-8')
@indent = indent
@level = initial
@encoding = encoding.downcase
end
def explicit_nil_handling?
@explicit_nil_handling
end
# Create a tag named +sym+. Other than the first argument which
# is the tag name, the arguments are the same as the tags
# implemented via <tt>method_missing</tt>.
def tag!(sym, *args, &block)
text = nil
attrs = nil
sym = "#{sym}:#{args.shift}" if args.first.kind_of?(::Symbol)
sym = sym.to_sym unless sym.class == ::Symbol
args.each do |arg|
case arg
when ::Hash
attrs ||= {}
attrs.merge!(arg)
when nil
attrs ||= {}
attrs.merge!({:nil => true}) if explicit_nil_handling?
else
text ||= ''
text << arg.to_s
end
end
if block
unless text.nil?
::Kernel::raise ::ArgumentError,
"XmlMarkup cannot mix a text argument with a block"
end
_indent
_start_tag(sym, attrs)
_newline
begin
_nested_structures(block)
ensure
_indent
_end_tag(sym)
_newline
end
elsif text.nil?
_indent
_start_tag(sym, attrs, true)
_newline
else
_indent
_start_tag(sym, attrs)
text! text
_end_tag(sym)
_newline
end
@target
end
# Create XML markup based on the name of the method. This method
# is never invoked directly, but is called for each markup method
# in the markup block that isn't cached.
def method_missing(sym, *args, &block)
cache_method_call(sym) if ::Builder::XmlBase.cache_method_calls
tag!(sym, *args, &block)
end
# Append text to the output target. Escape any markup. May be
# used within the markup brackets as:
#
# builder.p { |b| b.br; b.text! "HI" } #=> <p><br/>HI</p>
def text!(text)
_text(_escape(text))
end
# Append text to the output target without escaping any markup.
# May be used within the markup brackets as:
#
# builder.p { |x| x << "<br/>HI" } #=> <p><br/>HI</p>
#
# This is useful when using non-builder enabled software that
# generates strings. Just insert the string directly into the
# builder without changing the inserted markup.
#
# It is also useful for stacking builder objects. Builders only
# use <tt><<</tt> to append to the target, so by supporting this
# method/operation builders can use other builders as their
# targets.
def <<(text)
_text(text)
end
# For some reason, nil? is sent to the XmlMarkup object. If nil?
# is not defined and method_missing is invoked, some strange kind
# of recursion happens. Since nil? won't ever be an XML tag, it
# is pretty safe to define it here. (Note: this is an example of
# cargo cult programming,
# cf. http://fishbowl.pastiche.org/2004/10/13/cargo_cult_programming).
def nil?
false
end
private
require 'builder/xchar'
if ::String.method_defined?(:encode)
def _escape(text)
result = XChar.encode(text)
begin
encoding = ::Encoding::find(@encoding)
raise Exception if encoding.dummy?
result.encode(encoding)
rescue
# if the encoding can't be supported, use numeric character references
result.
gsub(/[^\u0000-\u007F]/) {|c| "&##{c.ord};"}.
force_encoding('ascii')
end
end
else
def _escape(text)
if (text.method(:to_xs).arity == 0)
text.to_xs
else
text.to_xs((@encoding != 'utf-8' or $KCODE != 'UTF8'))
end
end
end
def _escape_attribute(text)
_escape(text).gsub("\n", "&#10;").gsub("\r", "&#13;").
gsub(%r{"}, '&quot;') # " WART
end
def _newline
return if @indent == 0
text! "\n"
end
def _indent
return if @indent == 0 || @level == 0
text!(" " * (@level * @indent))
end
def _nested_structures(block)
@level += 1
block.call(self)
ensure
@level -= 1
end
# If XmlBase.cache_method_calls = true, we dynamicly create the method
# missed as an instance method on the XMLBase object. Because XML
# documents are usually very repetative in nature, the next node will
# be handled by the new method instead of method_missing. As
# method_missing is very slow, this speeds up document generation
# significantly.
def cache_method_call(sym)
class << self; self; end.class_eval do
unless method_defined?(sym)
define_method(sym) do |*args, &block|
tag!(sym, *args, &block)
end
end
end
end
end
XmlBase.cache_method_calls = true
end

@ -0,0 +1,63 @@
#!/usr/bin/env ruby
#--
# Copyright 2004 by Jim Weirich (jim@weirichhouse.org).
# All rights reserved.
# Permission is granted for use, copying, modification, distribution,
# and distribution of modified versions of this work as long as the
# above copyright notice is included.
#++
require 'builder/xmlmarkup'
module Builder
# Create a series of SAX-like XML events (e.g. start_tag, end_tag)
# from the markup code. XmlEvent objects are used in a way similar
# to XmlMarkup objects, except that a series of events are generated
# and passed to a handler rather than generating character-based
# markup.
#
# Usage:
# xe = Builder::XmlEvents.new(hander)
# xe.title("HI") # Sends start_tag/end_tag/text messages to the handler.
#
# Indentation may also be selected by providing value for the
# indentation size and initial indentation level.
#
# xe = Builder::XmlEvents.new(handler, indent_size, initial_indent_level)
#
# == XML Event Handler
#
# The handler object must expect the following events.
#
# [<tt>start_tag(tag, attrs)</tt>]
# Announces that a new tag has been found. +tag+ is the name of
# the tag and +attrs+ is a hash of attributes for the tag.
#
# [<tt>end_tag(tag)</tt>]
# Announces that an end tag for +tag+ has been found.
#
# [<tt>text(text)</tt>]
# Announces that a string of characters (+text+) has been found.
# A series of characters may be broken up into more than one
# +text+ call, so the client cannot assume that a single
# callback contains all the text data.
#
class XmlEvents < XmlMarkup
def text!(text)
@target.text(text)
end
def _start_tag(sym, attrs, end_too=false)
@target.start_tag(sym, attrs)
_end_tag(sym) if end_too
end
def _end_tag(sym)
@target.end_tag(sym)
end
end
end

@ -0,0 +1,339 @@
#!/usr/bin/env ruby
#--
# Copyright 2004, 2005 by Jim Weirich (jim@weirichhouse.org).
# All rights reserved.
# Permission is granted for use, copying, modification, distribution,
# and distribution of modified versions of this work as long as the
# above copyright notice is included.
#++
# Provide a flexible and easy to use Builder for creating XML markup.
# See XmlBuilder for usage details.
require 'builder/xmlbase'
module Builder
# Create XML markup easily. All (well, almost all) methods sent to
# an XmlMarkup object will be translated to the equivalent XML
# markup. Any method with a block will be treated as an XML markup
# tag with nested markup in the block.
#
# Examples will demonstrate this easier than words. In the
# following, +xm+ is an +XmlMarkup+ object.
#
# xm.em("emphasized") # => <em>emphasized</em>
# xm.em { xm.b("emp & bold") } # => <em><b>emph &amp; bold</b></em>
# xm.a("A Link", "href"=>"http://onestepback.org")
# # => <a href="http://onestepback.org">A Link</a>
# xm.div { xm.br } # => <div><br/></div>
# xm.target("name"=>"compile", "option"=>"fast")
# # => <target option="fast" name="compile"\>
# # NOTE: order of attributes is not specified.
#
# xm.instruct! # <?xml version="1.0" encoding="UTF-8"?>
# xm.html { # <html>
# xm.head { # <head>
# xm.title("History") # <title>History</title>
# } # </head>
# xm.body { # <body>
# xm.comment! "HI" # <!-- HI -->
# xm.h1("Header") # <h1>Header</h1>
# xm.p("paragraph") # <p>paragraph</p>
# } # </body>
# } # </html>
#
# == Notes:
#
# * The order that attributes are inserted in markup tags is
# undefined.
#
# * Sometimes you wish to insert text without enclosing tags. Use
# the <tt>text!</tt> method to accomplish this.
#
# Example:
#
# xm.div { # <div>
# xm.text! "line"; xm.br # line<br/>
# xm.text! "another line"; xmbr # another line<br/>
# } # </div>
#
# * The special XML characters <, >, and & are converted to &lt;,
# &gt; and &amp; automatically. Use the <tt><<</tt> operation to
# insert text without modification.
#
# * Sometimes tags use special characters not allowed in ruby
# identifiers. Use the <tt>tag!</tt> method to handle these
# cases.
#
# Example:
#
# xml.tag!("SOAP:Envelope") { ... }
#
# will produce ...
#
# <SOAP:Envelope> ... </SOAP:Envelope>"
#
# <tt>tag!</tt> will also take text and attribute arguments (after
# the tag name) like normal markup methods. (But see the next
# bullet item for a better way to handle XML namespaces).
#
# * Direct support for XML namespaces is now available. If the
# first argument to a tag call is a symbol, it will be joined to
# the tag to produce a namespace:tag combination. It is easier to
# show this than describe it.
#
# xml.SOAP :Envelope do ... end
#
# Just put a space before the colon in a namespace to produce the
# right form for builder (e.g. "<tt>SOAP:Envelope</tt>" =>
# "<tt>xml.SOAP :Envelope</tt>")
#
# * XmlMarkup builds the markup in any object (called a _target_)
# that accepts the <tt><<</tt> method. If no target is given,
# then XmlMarkup defaults to a string target.
#
# Examples:
#
# xm = Builder::XmlMarkup.new
# result = xm.title("yada")
# # result is a string containing the markup.
#
# buffer = ""
# xm = Builder::XmlMarkup.new(buffer)
# # The markup is appended to buffer (using <<)
#
# xm = Builder::XmlMarkup.new(STDOUT)
# # The markup is written to STDOUT (using <<)
#
# xm = Builder::XmlMarkup.new
# x2 = Builder::XmlMarkup.new(:target=>xm)
# # Markup written to +x2+ will be send to +xm+.
#
# * Indentation is enabled by providing the number of spaces to
# indent for each level as a second argument to XmlBuilder.new.
# Initial indentation may be specified using a third parameter.
#
# Example:
#
# xm = Builder.new(:indent=>2)
# # xm will produce nicely formatted and indented XML.
#
# xm = Builder.new(:indent=>2, :margin=>4)
# # xm will produce nicely formatted and indented XML with 2
# # spaces per indent and an over all indentation level of 4.
#
# builder = Builder::XmlMarkup.new(:target=>$stdout, :indent=>2)
# builder.name { |b| b.first("Jim"); b.last("Weirich) }
# # prints:
# # <name>
# # <first>Jim</first>
# # <last>Weirich</last>
# # </name>
#
# * The instance_eval implementation which forces self to refer to
# the message receiver as self is now obsolete. We now use normal
# block calls to execute the markup block. This means that all
# markup methods must now be explicitly send to the xml builder.
# For instance, instead of
#
# xml.div { strong("text") }
#
# you need to write:
#
# xml.div { xml.strong("text") }
#
# Although more verbose, the subtle change in semantics within the
# block was found to be prone to error. To make this change a
# little less cumbersome, the markup block now gets the markup
# object sent as an argument, allowing you to use a shorter alias
# within the block.
#
# For example:
#
# xml_builder = Builder::XmlMarkup.new
# xml_builder.div { |xml|
# xml.stong("text")
# }
#
class XmlMarkup < XmlBase
# Create an XML markup builder. Parameters are specified by an
# option hash.
#
# :target => <em>target_object</em>::
# Object receiving the markup. +target_object+ must respond to
# the <tt><<(<em>a_string</em>)</tt> operator and return
# itself. The default target is a plain string target.
#
# :indent => <em>indentation</em>::
# Number of spaces used for indentation. The default is no
# indentation and no line breaks.
#
# :margin => <em>initial_indentation_level</em>::
# Amount of initial indentation (specified in levels, not
# spaces).
#
# :quote => <em>:single</em>::
# Use single quotes for attributes rather than double quotes.
#
# :escape_attrs => <em>OBSOLETE</em>::
# The :escape_attrs option is no longer supported by builder
# (and will be quietly ignored). String attribute values are
# now automatically escaped. If you need unescaped attribute
# values (perhaps you are using entities in the attribute
# values), then give the value as a Symbol. This allows much
# finer control over escaping attribute values.
#
def initialize(options={})
indent = options[:indent] || 0
margin = options[:margin] || 0
@quote = (options[:quote] == :single) ? "'" : '"'
@explicit_nil_handling = options[:explicit_nil_handling]
super(indent, margin)
@target = options[:target] || ""
end
# Return the target of the builder.
def target!
@target
end
def comment!(comment_text)
_ensure_no_block ::Kernel::block_given?
_special("<!-- ", " -->", comment_text, nil)
end
# Insert an XML declaration into the XML markup.
#
# For example:
#
# xml.declare! :ELEMENT, :blah, "yada"
# # => <!ELEMENT blah "yada">
def declare!(inst, *args, &block)
_indent
@target << "<!#{inst}"
args.each do |arg|
case arg
when ::String
@target << %{ "#{arg}"} # " WART
when ::Symbol
@target << " #{arg}"
end
end
if ::Kernel::block_given?
@target << " ["
_newline
_nested_structures(block)
@target << "]"
end
@target << ">"
_newline
end
# Insert a processing instruction into the XML markup. E.g.
#
# For example:
#
# xml.instruct!
# #=> <?xml version="1.0" encoding="UTF-8"?>
# xml.instruct! :aaa, :bbb=>"ccc"
# #=> <?aaa bbb="ccc"?>
#
# Note: If the encoding is setup to "UTF-8" and the value of
# $KCODE is "UTF8", then builder will emit UTF-8 encoded strings
# rather than the entity encoding normally used.
def instruct!(directive_tag=:xml, attrs={})
_ensure_no_block ::Kernel::block_given?
if directive_tag == :xml
a = { :version=>"1.0", :encoding=>"UTF-8" }
attrs = a.merge attrs
@encoding = attrs[:encoding].downcase
end
_special(
"<?#{directive_tag}",
"?>",
nil,
attrs,
[:version, :encoding, :standalone])
end
# Insert a CDATA section into the XML markup.
#
# For example:
#
# xml.cdata!("text to be included in cdata")
# #=> <![CDATA[text to be included in cdata]]>
#
def cdata!(text)
_ensure_no_block ::Kernel::block_given?
_special("<![CDATA[", "]]>", text.gsub(']]>', ']]]]><![CDATA[>'), nil)
end
private
# NOTE: All private methods of a builder object are prefixed when
# a "_" character to avoid possible conflict with XML tag names.
# Insert text directly in to the builder's target.
def _text(text)
@target << text
end
# Insert special instruction.
def _special(open, close, data=nil, attrs=nil, order=[])
_indent
@target << open
@target << data if data
_insert_attributes(attrs, order) if attrs
@target << close
_newline
end
# Start an XML tag. If <tt>end_too</tt> is true, then the start
# tag is also the end tag (e.g. <br/>
def _start_tag(sym, attrs, end_too=false)
@target << "<#{sym}"
_insert_attributes(attrs)
@target << "/" if end_too
@target << ">"
end
# Insert an ending tag.
def _end_tag(sym)
@target << "</#{sym}>"
end
# Insert the attributes (given in the hash).
def _insert_attributes(attrs, order=[])
return if attrs.nil?
order.each do |k|
v = attrs[k]
@target << %{ #{k}=#{@quote}#{_attr_value(v)}#{@quote}} if v
end
attrs.each do |k, v|
@target << %{ #{k}=#{@quote}#{_attr_value(v)}#{@quote}} unless order.member?(k) # " WART
end
end
def _attr_value(value)
case value
when ::Symbol
value.to_s
else
_escape_attribute(value.to_s)
end
end
def _ensure_no_block(got_block)
if got_block
::Kernel::raise IllegalBlockError.new(
"Blocks are not allowed on XML instructions"
)
end
end
end
end

@ -0,0 +1,17 @@
# Optional publish task for Rake
require 'rake/contrib/sshpublisher'
require 'rake/contrib/rubyforgepublisher'
publisher = Rake::CompositePublisher.new
publisher.add Rake::RubyForgePublisher.new('builder', 'jimweirich')
publisher.add Rake::SshFilePublisher.new(
'linode',
'htdocs/software/builder',
'.',
'builder.blurb')
desc "Publish the Documentation to RubyForge."
task :publish => [:rdoc] do
publisher.upload
end

@ -0,0 +1,62 @@
#!/usr/bin/env ruby
module Tags
extend Rake::DSL if defined?(Rake::DSL)
PROG = ENV['TAGS'] || 'ctags'
RAKEFILES = FileList['Rakefile', '**/*.rake']
FILES = FileList['**/*.rb', '**/*.js'] + RAKEFILES
FILES.exclude('pkg', 'dist')
PROJECT_DIR = ['.']
RVM_GEMDIR = File.join(`rvm gemdir`.strip, "gems")
SYSTEM_DIRS = File.exists?(RVM_GEMDIR) ? RVM_GEMDIR : []
module_function
# Convert key_word to --key-word.
def keyword(key)
k = key.to_s.gsub(/_/, '-')
(k.length == 1) ? "-#{k}" : "--#{k}"
end
# Run ctags command
def run(*args)
opts = {
:e => true,
:totals => true,
:recurse => true,
}
opts = opts.merge(args.pop) if args.last.is_a?(Hash)
command_args = opts.map { |k, v|
(v == true) ? keyword(k) : "#{keyword(k)}=#{v}"
}.join(" ")
sh %{#{Tags::PROG} #{command_args} #{args.join(' ')}}
end
end
namespace "tags" do
desc "Generate an Emacs TAGS file"
task :emacs, [:all] => Tags::FILES do |t, args|
puts "Making Emacs TAGS file"
verbose(true) do
Tags.run(Tags::PROJECT_DIR)
Tags.run(Tags::RAKEFILES,
:language_force => "ruby",
:append => true)
if args.all
Tags::SYSTEM_DIRS.each do |dir|
Tags.run(dir,
:language_force => "ruby",
:append => true)
end
end
end
end
end
desc "Generate the TAGS file"
task :tags, [:all] => ["tags:emacs"]

@ -0,0 +1,41 @@
#!/usr/bin/env ruby
# encoding: iso-8859-1
#--
# Portions copyright 2004 by Jim Weirich (jim@weirichhouse.org).
# Portions copyright 2005 by Sam Ruby (rubys@intertwingly.net).
# All rights reserved.
# Permission is granted for use, copying, modification, distribution,
# and distribution of modified versions of this work as long as the
# above copyright notice is included.
#++
require 'builder/xmlmarkup'
require 'benchmark'
text = "This is a test of the new xml markup. I<>t<EFBFBD>rn<72>ti<74>n<EFBFBD>liz<69>ti<74>n\n" * 10000
include Benchmark # we need the CAPTION and FMTSTR constants
include Builder
n = 50
Benchmark.benchmark do |bm|
tf = bm.report("base") {
n.times do
x = XmlMarkup.new
x.text(text)
x.target!
end
}
def XmlMarkup._escape(text)
text.to_xs
end
tf = bm.report("to_xs") {
n.times do
x = XmlMarkup.new
x.text(text)
x.target!
end
}
end

@ -0,0 +1,39 @@
#!/usr/bin/env ruby
#--
# Portions copyright 2004 by Jim Weirich (jim@weirichhouse.org).
# Portions copyright 2005 by Sam Ruby (rubys@intertwingly.net).
# All rights reserved.
# Permission is granted for use, copying, modification, distribution,
# and distribution of modified versions of this work as long as the
# above copyright notice is included.
#++
# We are defining method_added in Kernel and Object so that when
# BlankSlate overrides them later, we can verify that it correctly
# calls the older hooks.
module Kernel
class << self
attr_reader :k_added_names
alias_method :preload_method_added, :method_added
def method_added(name)
preload_method_added(name)
@k_added_names ||= []
@k_added_names << name
end
end
end
class Object
class << self
attr_reader :o_added_names
alias_method :preload_method_added, :method_added
def method_added(name)
preload_method_added(name)
@o_added_names ||= []
@o_added_names << name
end
end
end

@ -0,0 +1,217 @@
#!/usr/bin/env ruby
#--
# Portions copyright 2004 by Jim Weirich (jim@weirichhouse.org).
# Portions copyright 2005 by Sam Ruby (rubys@intertwingly.net).
# All rights reserved.
# Permission is granted for use, copying, modification, distribution,
# and distribution of modified versions of this work as long as the
# above copyright notice is included.
#++
require 'test/unit'
require 'test/preload'
require 'blankslate'
require 'stringio'
# Methods to be introduced into the Object class late.
module LateObject
def late_object
33
end
def LateObject.included(mod)
# Modules defining an included method should not prevent blank
# slate erasure!
end
end
# Methods to be introduced into the Kernel module late.
module LateKernel
def late_kernel
44
end
def LateKernel.included(mod)
# Modules defining an included method should not prevent blank
# slate erasure!
end
end
# Introduce some late methods (both module and direct) into the Kernel
# module.
module Kernel
include LateKernel
def late_addition
1234
end
def double_late_addition
11
end
def double_late_addition
22
end
end
# Introduce some late methods (both module and direct) into the Object
# class.
class Object
include LateObject
def another_late_addition
4321
end
end
# Introduce some late methods by inclusion.
module GlobalModule
def global_inclusion
42
end
end
include GlobalModule
def direct_global
43
end
######################################################################
# Test case for blank slate.
#
class TestBlankSlate < Test::Unit::TestCase
def setup
@bs = BlankSlate.new
end
def test_undefined_methods_remain_undefined
assert_raise(NoMethodError) { @bs.no_such_method }
assert_raise(NoMethodError) { @bs.nil? }
end
# NOTE: NameError is acceptable because the lack of a '.' means that
# Ruby can't tell if it is a method or a local variable.
def test_undefined_methods_remain_undefined_during_instance_eval
assert_raise(NoMethodError, NameError) do
@bs.instance_eval do nil? end
end
assert_raise(NoMethodError, NameError) do
@bs.instance_eval do no_such_method end
end
end
def test_private_methods_are_undefined
assert_raise(NoMethodError) do
@bs.puts "HI"
end
end
def test_targetted_private_methods_are_undefined_during_instance_eval
assert_raise(NoMethodError, NameError) do
@bs.instance_eval do self.puts "HI" end
end
end
def test_untargetted_private_methods_are_defined_during_instance_eval
oldstdout = $stdout
$stdout = StringIO.new
@bs.instance_eval do
puts "HI"
end
ensure
$stdout = oldstdout
end
def test_methods_added_late_to_kernel_remain_undefined
assert_equal 1234, nil.late_addition
assert_raise(NoMethodError) { @bs.late_addition }
end
def test_methods_added_late_to_object_remain_undefined
assert_equal 4321, nil.another_late_addition
assert_raise(NoMethodError) { @bs.another_late_addition }
end
def test_methods_added_late_to_global_remain_undefined
assert_equal 42, global_inclusion
assert_raise(NoMethodError) { @bs.global_inclusion }
end
def test_preload_method_added
assert Kernel.k_added_names.include?(:late_addition)
assert Object.o_added_names.include?(:another_late_addition)
end
def test_method_defined_late_multiple_times_remain_undefined
assert_equal 22, nil.double_late_addition
assert_raise(NoMethodError) { @bs.double_late_addition }
end
def test_late_included_module_in_object_is_ok
assert_equal 33, 1.late_object
assert_raise(NoMethodError) { @bs.late_object }
end
def test_late_included_module_in_kernel_is_ok
assert_raise(NoMethodError) { @bs.late_kernel }
end
def test_revealing_previously_hidden_methods_are_callable
with_to_s = Class.new(BlankSlate) do
reveal :to_s
end
assert_match(/^#<.*>$/, with_to_s.new.to_s)
end
def test_revealing_previously_hidden_methods_are_callable_with_block
Object.class_eval <<-EOS
def given_block(&block)
block
end
EOS
with_given_block = Class.new(BlankSlate) do
reveal :given_block
end
assert_not_nil with_given_block.new.given_block {}
end
def test_revealing_a_hidden_method_twice_is_ok
with_to_s = Class.new(BlankSlate) do
reveal :to_s
reveal :to_s
end
assert_match(/^#<.*>$/, with_to_s.new.to_s)
end
def test_revealing_unknown_hidden_method_is_an_error
assert_raises(RuntimeError) do
Class.new(BlankSlate) do
reveal :xyz
end
end
end
def test_global_includes_still_work
assert_nothing_raised do
assert_equal 42, global_inclusion
assert_equal 42, Object.new.global_inclusion
assert_equal 42, "magic number".global_inclusion
assert_equal 43, direct_global
end
end
def test_reveal_should_not_bind_to_an_instance
with_object_id = Class.new(BlankSlate) do
reveal(:object_id)
end
obj1 = with_object_id.new
obj2 = with_object_id.new
assert obj1.object_id != obj2.object_id,
"Revealed methods should not be bound to a particular instance"
end
end

@ -0,0 +1,150 @@
#!/usr/bin/env ruby
#--
# Portions copyright 2004 by Jim Weirich (jim@weirichhouse.org).
# Portions copyright 2005 by Sam Ruby (rubys@intertwingly.net).
# All rights reserved.
# Permission is granted for use, copying, modification, distribution,
# and distribution of modified versions of this work as long as the
# above copyright notice is included.
#++
require 'test/unit'
require 'test/preload'
require 'builder'
require 'builder/xmlevents'
class TestEvents < Test::Unit::TestCase
class Target
attr_reader :events
def initialize
@events = []
end
def start_tag(tag, attrs)
@events << [:start_tag, tag, attrs]
end
def end_tag(tag)
@events << [:end_tag, tag]
end
def text(string)
@events << [:text, string]
end
end
def setup
@target = Target.new
@xml = Builder::XmlEvents.new(:target=>@target)
end
def test_simple
@xml.one
expect [:start_tag, :one, nil]
expect [:end_tag, :one]
expect_done
end
def test_nested
@xml.one { @xml.two }
expect [:start_tag, :one, nil]
expect [:start_tag, :two, nil]
expect [:end_tag, :two]
expect [:end_tag, :one]
expect_done
end
def test_text
@xml.one("a")
expect [:start_tag, :one, nil]
expect [:text, "a"]
expect [:end_tag, :one]
expect_done
end
def test_special_text
@xml.one("H&R")
expect [:start_tag, :one, nil]
expect [:text, "H&R"]
expect [:end_tag, :one]
expect_done
end
def test_text_with_entity
@xml.one("H&amp;R")
expect [:start_tag, :one, nil]
expect [:text, "H&amp;R"]
expect [:end_tag, :one]
expect_done
end
def test_attributes
@xml.a(:b=>"c", :x=>"y")
expect [:start_tag, :a, {:x => "y", :b => "c"}]
expect [:end_tag, :a]
expect_done
end
def test_moderately_complex
@xml.tag! "address-book" do |x|
x.entry :id=>"1" do
x.name {
x.first "Bill"
x.last "Smith"
}
x.address "Cincinnati"
end
x.entry :id=>"2" do
x.name {
x.first "John"
x.last "Doe"
}
x.address "Columbus"
end
end
expect [:start_tag, "address-book".intern, nil]
expect [:start_tag, :entry, {:id => "1"}]
expect [:start_tag, :name, nil]
expect [:start_tag, :first, nil]
expect [:text, "Bill"]
expect [:end_tag, :first]
expect [:start_tag, :last, nil]
expect [:text, "Smith"]
expect [:end_tag, :last]
expect [:end_tag, :name]
expect [:start_tag, :address, nil]
expect [:text, "Cincinnati"]
expect [:end_tag, :address]
expect [:end_tag, :entry]
expect [:start_tag, :entry, {:id => "2"}]
expect [:start_tag, :name, nil]
expect [:start_tag, :first, nil]
expect [:text, "John"]
expect [:end_tag, :first]
expect [:start_tag, :last, nil]
expect [:text, "Doe"]
expect [:end_tag, :last]
expect [:end_tag, :name]
expect [:start_tag, :address, nil]
expect [:text, "Columbus"]
expect [:end_tag, :address]
expect [:end_tag, :entry]
expect [:end_tag, "address-book".intern]
expect_done
end
def expect(value)
assert_equal value, @target.events.shift
end
def expect_done
assert_nil @target.events.shift
end
end

@ -0,0 +1,611 @@
#!/usr/bin/env ruby
#--
# Portions copyright 2004 by Jim Weirich (jim@weirichhouse.org).
# Portions copyright 2005 by Sam Ruby (rubys@intertwingly.net).
# All rights reserved.
# Permission is granted for use, copying, modification, distribution,
# and distribution of modified versions of this work as long as the
# above copyright notice is included.
#++
require 'test/unit'
require 'test/preload'
require 'builder'
require 'builder/xmlmarkup'
class TestMarkup < Test::Unit::TestCase
def setup
@xml = Builder::XmlMarkup.new
end
def test_create
assert_not_nil @xml
end
def test_simple
@xml.simple
assert_equal "<simple/>", @xml.target!
end
def test_value
@xml.value("hi")
assert_equal "<value>hi</value>", @xml.target!
end
def test_empty_value
@xml.value("")
assert_equal "<value></value>", @xml.target!
end
def test_nil_value
@xml.value(nil)
assert_equal "<value/>", @xml.target!
end
def test_no_value
@xml.value()
assert_equal "<value/>", @xml.target!
end
def test_nested
@xml.outer { |x| x.inner("x") }
assert_equal "<outer><inner>x</inner></outer>", @xml.target!
end
def test_attributes
@xml.ref(:id => 12)
assert_equal %{<ref id="12"/>}, @xml.target!
end
def test_single_quotes_for_attrs
@xml = Builder::XmlMarkup.new(:quote => :single)
@xml.ref(:id => 12)
assert_equal %{<ref id='12'/>}, @xml.target!
end
def test_mixed_quotes_for_attrs
@xml = Builder::XmlMarkup.new(:quote => :single)
x = Builder::XmlMarkup.new(:target=>@xml, :quote => :double)
@xml.ref(:id => 12) do
x.link(:id => 13)
end
assert_equal %{<ref id='12'><link id="13"/></ref>}, @xml.target!
end
def test_string_attributes_are_escaped_by_default
@xml.ref(:id => "H&R")
assert_equal %{<ref id="H&amp;R"/>}, @xml.target!
end
def test_symbol_attributes_are_unescaped_by_default
@xml.ref(:id => :"H&amp;R")
assert_equal %{<ref id="H&amp;R"/>}, @xml.target!
end
def test_attributes_escaping_can_be_turned_on
@xml = Builder::XmlMarkup.new
@xml.ref(:id => "<H&R \"block\">")
assert_equal %{<ref id="&lt;H&amp;R &quot;block&quot;&gt;"/>}, @xml.target!
end
def test_mixed_attribute_escaping_with_nested_builders
x = Builder::XmlMarkup.new(:target=>@xml)
@xml.ref(:id=>:"H&amp;R") {
x.element(:tag=>"Long&Short")
}
assert_equal "<ref id=\"H&amp;R\"><element tag=\"Long&amp;Short\"/></ref>",
@xml.target!
end
def test_multiple_attributes
@xml.ref(:id => 12, :name => "bill")
assert_match %r{^<ref( id="12"| name="bill"){2}/>$}, @xml.target!
end
def test_attributes_with_text
@xml.a("link", :href=>"http://onestepback.org")
assert_equal %{<a href="http://onestepback.org">link</a>}, @xml.target!
end
def test_attributes_with_newlines
@xml.abbr("W3C", :title=>"World\nWide\rWeb\r\nConsortium")
assert_equal %{<abbr title="World&#10;Wide&#13;Web&#13;&#10;Consortium">W3C</abbr>},
@xml.target!
end
def test_complex
@xml.body(:bg=>"#ffffff") { |x|
x.title("T", :style=>"red")
}
assert_equal %{<body bg="#ffffff"><title style="red">T</title></body>}, @xml.target!
end
def test_funky_symbol
@xml.tag!("non-ruby-token", :id=>1) { |x| x.ok }
assert_equal %{<non-ruby-token id="1"><ok/></non-ruby-token>}, @xml.target!
end
def test_tag_can_handle_private_method
@xml.tag!("loop", :id=>1) { |x| x.ok }
assert_equal %{<loop id="1"><ok/></loop>}, @xml.target!
end
def test_no_explicit_marker
@xml.p { |x| x.b("HI") }
assert_equal "<p><b>HI</b></p>", @xml.target!
end
def test_reference_local_vars
n = 3
@xml.ol { |x| n.times { x.li(n) } }
assert_equal "<ol><li>3</li><li>3</li><li>3</li></ol>", @xml.target!
end
def test_reference_methods
@xml.title { |x| x.a { x.b(name) } }
assert_equal "<title><a><b>bob</b></a></title>", @xml.target!
end
def test_append_text
@xml.p { |x| x.br; x.text! "HI" }
assert_equal "<p><br/>HI</p>", @xml.target!
end
def test_ambiguous_markup
ex = assert_raise(ArgumentError) {
@xml.h1("data1") { b }
}
assert_match(/\btext\b/, ex.message)
assert_match(/\bblock\b/, ex.message)
end
def test_capitalized_method
@xml.P { |x| x.B("hi"); x.BR(); x.EM { x.text! "world" } }
assert_equal "<P><B>hi</B><BR/><EM>world</EM></P>", @xml.target!
end
def test_escaping
@xml.div { |x| x.text! "<hi>"; x.em("H&R Block") }
assert_equal %{<div>&lt;hi&gt;<em>H&amp;R Block</em></div>}, @xml.target!
end
def test_nil
b = Builder::XmlMarkup.new
b.tag! "foo", nil
assert_equal %{<foo/>}, b.target!
end
def test_nil_without_explicit_nil_handling
b = Builder::XmlMarkup.new(:explicit_nil_handling => false)
b.tag! "foo", nil
assert_equal %{<foo/>}, b.target!
end
def test_nil_with_explicit_nil_handling
b = Builder::XmlMarkup.new(:explicit_nil_handling => true)
b.tag! "foo", nil
assert_equal %{<foo nil="true"/>}, b.target!
end
def test_non_escaping
@xml.div("ns:xml"=>:"&xml;") { |x| x << "<h&i>"; x.em("H&R Block") }
assert_equal %{<div ns:xml="&xml;"><h&i><em>H&amp;R Block</em></div>}, @xml.target!
end
def test_return_value
str = @xml.x("men")
assert_equal @xml.target!, str
end
def test_stacked_builders
b = Builder::XmlMarkup.new( :target => @xml )
b.div { @xml.span { @xml.a("text", :href=>"ref") } }
assert_equal "<div><span><a href=\"ref\">text</a></span></div>", @xml.target!
end
def name
"bob"
end
end
class TestAttributeEscaping < Test::Unit::TestCase
def setup
@xml = Builder::XmlMarkup.new
end
def test_element_gt
@xml.title('1<2')
assert_equal '<title>1&lt;2</title>', @xml.target!
end
def test_element_amp
@xml.title('AT&T')
assert_equal '<title>AT&amp;T</title>', @xml.target!
end
def test_element_amp2
@xml.title('&amp;')
assert_equal '<title>&amp;amp;</title>', @xml.target!
end
def test_attr_less
@xml.a(:title => '2>1')
assert_equal '<a title="2&gt;1"/>', @xml.target!
end
def test_attr_amp
@xml.a(:title => 'AT&T')
assert_equal '<a title="AT&amp;T"/>', @xml.target!
end
def test_attr_quot
@xml.a(:title => '"x"')
assert_equal '<a title="&quot;x&quot;"/>', @xml.target!
end
end
class TestNameSpaces < Test::Unit::TestCase
def setup
@xml = Builder::XmlMarkup.new(:indent=>2)
end
def test_simple_name_spaces
@xml.rdf :RDF
assert_equal "<rdf:RDF/>\n", @xml.target!
end
def test_long
xml = Builder::XmlMarkup.new(:indent=>2)
xml.instruct!
xml.rdf :RDF,
"xmlns:rdf" => :"&rdf;",
"xmlns:rdfs" => :"&rdfs;",
"xmlns:xsd" => :"&xsd;",
"xmlns:owl" => :"&owl;" do
xml.owl :Class, :'rdf:ID'=>'Bird' do
xml.rdfs :label, 'bird'
xml.rdfs :subClassOf do
xml.owl :Restriction do
xml.owl :onProperty, 'rdf:resource'=>'#wingspan'
xml.owl :maxCardinality,1,'rdf:datatype'=>'&xsd;nonNegativeInteger'
end
end
end
end
assert_match(/^<\?xml/, xml.target!)
assert_match(/\n<rdf:RDF/m, xml.target!)
assert_match(/xmlns:rdf="&rdf;"/m, xml.target!)
assert_match(/<owl:Restriction>/m, xml.target!)
end
def test_ensure
xml = Builder::XmlMarkup.new
xml.html do
xml.body do
begin
xml.p do
raise Exception.new('boom')
end
rescue Exception => e
xml.pre e
end
end
end
assert_match %r{<p>}, xml.target!
assert_match %r{</p>}, xml.target!
end
end
class TestDeclarations < Test::Unit::TestCase
def setup
@xml = Builder::XmlMarkup.new(:indent=>2)
end
def test_declare
@xml.declare! :element
assert_equal "<!element>\n", @xml.target!
end
def test_bare_arg
@xml.declare! :element, :arg
assert_equal"<!element arg>\n", @xml.target!
end
def test_string_arg
@xml.declare! :element, "string"
assert_equal"<!element \"string\">\n", @xml.target!
end
def test_mixed_args
@xml.declare! :element, :x, "y", :z, "-//OASIS//DTD DocBook XML//EN"
assert_equal "<!element x \"y\" z \"-//OASIS//DTD DocBook XML//EN\">\n", @xml.target!
end
def test_nested_declarations
@xml = Builder::XmlMarkup.new
@xml.declare! :DOCTYPE, :chapter do |x|
x.declare! :ELEMENT, :chapter, "(title,para+)".intern
end
assert_equal "<!DOCTYPE chapter [<!ELEMENT chapter (title,para+)>]>", @xml.target!
end
def test_nested_indented_declarations
@xml.declare! :DOCTYPE, :chapter do |x|
x.declare! :ELEMENT, :chapter, "(title,para+)".intern
end
assert_equal "<!DOCTYPE chapter [\n <!ELEMENT chapter (title,para+)>\n]>\n", @xml.target!
end
def test_complex_declaration
@xml.declare! :DOCTYPE, :chapter do |x|
x.declare! :ELEMENT, :chapter, "(title,para+)".intern
x.declare! :ELEMENT, :title, "(#PCDATA)".intern
x.declare! :ELEMENT, :para, "(#PCDATA)".intern
end
expected = %{<!DOCTYPE chapter [
<!ELEMENT chapter (title,para+)>
<!ELEMENT title (#PCDATA)>
<!ELEMENT para (#PCDATA)>
]>
}
assert_equal expected, @xml.target!
end
end
class TestSpecialMarkup < Test::Unit::TestCase
def setup
@xml = Builder::XmlMarkup.new(:indent=>2)
end
def test_comment
@xml.comment!("COMMENT")
assert_equal "<!-- COMMENT -->\n", @xml.target!
end
def test_indented_comment
@xml.p { @xml.comment! "OK" }
assert_equal "<p>\n <!-- OK -->\n</p>\n", @xml.target!
end
def test_instruct
@xml.instruct! :abc, :version=>"0.9"
assert_equal "<?abc version=\"0.9\"?>\n", @xml.target!
end
def test_indented_instruct
@xml.p { @xml.instruct! :xml }
assert_match %r{<p>\n <\?xml version="1.0" encoding="UTF-8"\?>\n</p>\n},
@xml.target!
end
def test_instruct_without_attributes
@xml.instruct! :zz
assert_equal "<?zz?>\n", @xml.target!
end
def test_xml_instruct
@xml.instruct!
assert_match(/^<\?xml version="1.0" encoding="UTF-8"\?>$/, @xml.target!)
end
def test_xml_instruct_with_overrides
@xml.instruct! :xml, :encoding=>"UCS-2"
assert_match(/^<\?xml version="1.0" encoding="UCS-2"\?>$/, @xml.target!)
end
def test_xml_instruct_with_standalong
@xml.instruct! :xml, :encoding=>"UCS-2", :standalone=>"yes"
assert_match(/^<\?xml version="1.0" encoding="UCS-2" standalone="yes"\?>$/, @xml.target!)
end
def test_no_blocks
assert_raise(Builder::IllegalBlockError) do
@xml.instruct! { |x| x.hi }
end
assert_raise(Builder::IllegalBlockError) do
@xml.comment!(:element) { |x| x.hi }
end
end
def test_cdata
@xml.cdata!("TEST")
assert_equal "<![CDATA[TEST]]>\n", @xml.target!
end
def test_cdata_with_ampersand
@xml.cdata!("TEST&CHECK")
assert_equal "<![CDATA[TEST&CHECK]]>\n", @xml.target!
end
def test_cdata_with_included_close
@xml.cdata!("TEST]]>CHECK")
assert_equal "<![CDATA[TEST]]]]><![CDATA[>CHECK]]>\n", @xml.target!
end
end
class TestIndentedXmlMarkup < Test::Unit::TestCase
def setup
@xml = Builder::XmlMarkup.new(:indent=>2)
end
def test_one_level
@xml.ol { |x| x.li "text" }
assert_equal "<ol>\n <li>text</li>\n</ol>\n", @xml.target!
end
def test_two_levels
@xml.p { |x|
x.ol { x.li "text" }
x.br
}
assert_equal "<p>\n <ol>\n <li>text</li>\n </ol>\n <br/>\n</p>\n", @xml.target!
end
def test_initial_level
@xml = Builder::XmlMarkup.new(:indent=>2, :margin=>4)
@xml.name { |x| x.first("Jim") }
assert_equal " <name>\n <first>Jim</first>\n </name>\n", @xml.target!
end
class TestUtfMarkup < Test::Unit::TestCase
if ! String.method_defined?(:encode)
def setup
@old_kcode = $KCODE
end
def teardown
$KCODE = @old_kcode
end
def test_use_entities_if_no_encoding_is_given_and_kcode_is_none
$KCODE = 'NONE'
xml = Builder::XmlMarkup.new
xml.p("\xE2\x80\x99")
assert_match(%r(<p>&#8217;</p>), xml.target!) #
end
def test_use_entities_if_encoding_is_utf_but_kcode_is_not
$KCODE = 'NONE'
xml = Builder::XmlMarkup.new
xml.instruct!(:xml, :encoding => 'UTF-8')
xml.p("\xE2\x80\x99")
assert_match(%r(<p>&#8217;</p>), xml.target!) #
end
else
# change in behavior. As there is no $KCODE anymore, the default
# moves from "does not understand utf-8" to "supports utf-8".
def test_use_entities_if_no_encoding_is_given_and_kcode_is_none
xml = Builder::XmlMarkup.new
xml.p("\xE2\x80\x99")
assert_match("<p>\u2019</p>", xml.target!) #
end
def test_use_entities_if_encoding_is_utf_but_kcode_is_not
xml = Builder::XmlMarkup.new
xml.instruct!(:xml, :encoding => 'UTF-8')
xml.p("\xE2\x80\x99")
assert_match("<p>\u2019</p>", xml.target!) #
end
end
def encode string, encoding
if !String.method_defined?(:encode)
$KCODE = encoding
string
elsif encoding == 'UTF8'
string.force_encoding('UTF-8')
else
string
end
end
def test_use_entities_if_kcode_is_utf_but_encoding_is_dummy_encoding
xml = Builder::XmlMarkup.new
xml.instruct!(:xml, :encoding => 'UTF-16')
xml.p(encode("\xE2\x80\x99", 'UTF8'))
assert_match(%r(<p>&#8217;</p>), xml.target!) #
end
def test_use_entities_if_kcode_is_utf_but_encoding_is_unsupported_encoding
xml = Builder::XmlMarkup.new
xml.instruct!(:xml, :encoding => 'UCS-2')
xml.p(encode("\xE2\x80\x99", 'UTF8'))
assert_match(%r(<p>&#8217;</p>), xml.target!) #
end
def test_use_utf8_if_encoding_defaults_and_kcode_is_utf8
xml = Builder::XmlMarkup.new
xml.p(encode("\xE2\x80\x99",'UTF8'))
assert_equal encode("<p>\xE2\x80\x99</p>",'UTF8'), xml.target!
end
def test_use_utf8_if_both_encoding_and_kcode_are_utf8
xml = Builder::XmlMarkup.new
xml.instruct!(:xml, :encoding => 'UTF-8')
xml.p(encode("\xE2\x80\x99",'UTF8'))
assert_match encode("<p>\xE2\x80\x99</p>",'UTF8'), xml.target!
end
def test_use_utf8_if_both_encoding_and_kcode_are_utf8_with_lowercase
xml = Builder::XmlMarkup.new
xml.instruct!(:xml, :encoding => 'utf-8')
xml.p(encode("\xE2\x80\x99",'UTF8'))
assert_match encode("<p>\xE2\x80\x99</p>",'UTF8'), xml.target!
end
end
class TestXmlEvents < Test::Unit::TestCase
def setup
@handler = EventHandler.new
@xe = Builder::XmlEvents.new(:target=>@handler)
end
def test_simple
@xe.p
assert_equal [:start, :p, nil], @handler.events.shift
assert_equal [:end, :p], @handler.events.shift
end
def test_text
@xe.p("HI")
assert_equal [:start, :p, nil], @handler.events.shift
assert_equal [:text, "HI"], @handler.events.shift
assert_equal [:end, :p], @handler.events.shift
end
def test_attributes
@xe.p("id"=>"2")
ev = @handler.events.shift
assert_equal [:start, :p], ev[0,2]
assert_equal "2", ev[2]['id']
assert_equal [:end, :p], @handler.events.shift
end
def test_indented
@xml = Builder::XmlEvents.new(:indent=>2, :target=>@handler)
@xml.p { |x| x.b("HI") }
assert_equal [:start, :p, nil], @handler.events.shift
assert_equal "\n ", pop_text
assert_equal [:start, :b, nil], @handler.events.shift
assert_equal "HI", pop_text
assert_equal [:end, :b], @handler.events.shift
assert_equal "\n", pop_text
assert_equal [:end, :p], @handler.events.shift
end
def pop_text
result = ''
while ! @handler.events.empty? && @handler.events[0][0] == :text
result << @handler.events[0][1]
@handler.events.shift
end
result
end
class EventHandler
attr_reader :events
def initialize
@events = []
end
def start_tag(sym, attrs)
@events << [:start, sym, attrs]
end
def end_tag(sym)
@events << [:end, sym]
end
def text(txt)
@events << [:text, txt]
end
end
end
end

@ -0,0 +1,62 @@
#!/usr/bin/env ruby
#--
# Portions copyright 2011 by Bart ten Brinke (info@retrosync.com).
# All rights reserved.
# Permission is granted for use, copying, modification, distribution,
# and distribution of modified versions of this work as long as the
# above copyright notice is included.
#++
require 'test/unit'
require 'test/preload'
require 'builder'
class TestMethodCaching < Test::Unit::TestCase
# We can directly ask if xml object responds to the cache_me or
# do_not_cache_me methods because xml is derived from BasicObject
# (and repond_to? is not defined in BasicObject).
#
# Instead we are going to stub out method_missing so that it throws
# an error, and then make sure that error is either thrown or not
# thrown as appropriate.
def teardown
super
Builder::XmlBase.cache_method_calls = true
end
def test_caching_does_not_break_weird_symbols
xml = Builder::XmlMarkup.new
xml.__send__("work-order", 1)
assert_equal "<work-order>1</work-order>", xml.target!
end
def test_method_call_caching
xml = Builder::XmlMarkup.new
xml.cache_me
def xml.method_missing(*args)
::Kernel.fail StandardError, "SHOULD NOT BE CALLED"
end
assert_nothing_raised do
xml.cache_me
end
end
def test_method_call_caching_disabled
Builder::XmlBase.cache_method_calls = false
xml = Builder::XmlMarkup.new
xml.do_not_cache_me
def xml.method_missing(*args)
::Kernel.fail StandardError, "SHOULD BE CALLED"
end
assert_raise(StandardError, "SHOULD BE CALLED") do
xml.do_not_cache_me
end
end
end

@ -0,0 +1,39 @@
#!/usr/bin/env ruby
#--
# Portions copyright 2004 by Jim Weirich (jim@weirichhouse.org).
# Portions copyright 2005 by Sam Ruby (rubys@intertwingly.net).
# All rights reserved.
# Permission is granted for use, copying, modification, distribution,
# and distribution of modified versions of this work as long as the
# above copyright notice is included.
#++
require 'test/unit'
require 'builder/xchar'
class TestNameCollisions < Test::Unit::TestCase
module Collide
def xchr
end
end
def test_no_collision
assert_nothing_raised do
Builder.check_for_name_collision(Collide, :not_defined)
end
end
def test_collision
assert_raise RuntimeError do
Builder.check_for_name_collision(Collide, "xchr")
end
end
def test_collision_with_symbol
assert_raise RuntimeError do
Builder.check_for_name_collision(Collide, :xchr)
end
end
end

@ -0,0 +1,78 @@
#!/usr/bin/env ruby
# encoding: us-ascii
#--
# Portions copyright 2004 by Jim Weirich (jim@weirichhouse.org).
# Portions copyright 2005 by Sam Ruby (rubys@intertwingly.net).
# All rights reserved.
# Permission is granted for use, copying, modification, distribution,
# and distribution of modified versions of this work as long as the
# above copyright notice is included.
#++
#!/usr/bin/env ruby
require 'test/unit'
require 'builder/xchar'
if String.method_defined?(:encode)
class String
ENCODING_BINARY = Encoding.find('BINARY')
# shim method for testing purposes
def to_xs(escape=true)
raise NameError.new('to_xs') unless caller[0].index(__FILE__)
result = Builder::XChar.encode(self)
if escape
result.gsub(/[^\u0000-\u007F]/) {|c| "&##{c.ord};"}
else
# really only useful for testing purposes
result.force_encoding(ENCODING_BINARY)
end
end
end
end
class TestXmlEscaping < Test::Unit::TestCase
REPLACEMENT_CHAR = Builder::XChar::REPLACEMENT_CHAR.to_xs
def test_ascii
assert_equal 'abc', 'abc'.to_xs
end
def test_predefined
assert_equal '&amp;', '&'.to_xs # ampersand
assert_equal '&lt;', '<'.to_xs # left angle bracket
assert_equal '&gt;', '>'.to_xs # right angle bracket
end
def test_invalid
assert_equal REPLACEMENT_CHAR, "\x00".to_xs # null
assert_equal REPLACEMENT_CHAR, "\x0C".to_xs # form feed
assert_equal REPLACEMENT_CHAR, "\xEF\xBF\xBF".to_xs # U+FFFF
end
def test_iso_8859_1
assert_equal '&#231;', "\xE7".to_xs # small c cedilla
assert_equal '&#169;', "\xA9".to_xs # copyright symbol
end
def test_win_1252
assert_equal '&#8217;', "\x92".to_xs # smart quote
assert_equal '&#8364;', "\x80".to_xs # euro
end
def test_utf8
assert_equal '&#8217;', "\xE2\x80\x99".to_xs # right single quote
assert_equal '&#169;', "\xC2\xA9".to_xs # copy
end
def test_utf8_verbatim
assert_equal "\xE2\x80\x99", "\xE2\x80\x99".to_xs(false) # right single quote
assert_equal "\xC2\xA9", "\xC2\xA9".to_xs(false) # copy
assert_equal "\xC2\xA9&amp;\xC2\xA9",
"\xC2\xA9&\xC2\xA9".to_xs(false) # copy with ampersand
end
end

@ -0,0 +1,139 @@
== 1.5.0 2015-08-17
* Added logos
* Added Slack Emoji
* Updated image generators
* Updated Dutch Locale
* Added support for generating RGB values, HSL colors, alpha channel, and HSLA colors
* Added locale for Uganda
* Added basic Ukrainian support
* Added university name generator
* Updated documentation
* Updated a variety of locales
* Various fixes
== 1.4.3 2014-08-15
* Updated Russian locale
* Added EIN generator
* Fixed Swedish locale
* Added birthday to Faker::Date
* Added Faker::App
== 1.4.2 2014-07-15
* Added Swedish locale
* README update
== 1.4.1 2014-07-04
* Bugfix and cleanup
== 1.4.0 2014-07-03
* Many enhancements and bugfixes
== 1.3.0 2014-03-08
* Many enhancements and few bugfixes
== 1.2.0 2013-07-27
* Many major and minor enhancements :)
== 1.1.2 2012-09-18
* 1 minor change:
* Fixed Ruby 1.8 compatibility
== 1.1.1 2012-09-17
* 1 minor change:
* Removed ja locale because of parse errors
== 1.1.0 2012-09-15
* 1 major change:
* Removed deprecated methods from Address: earth_country, us_state, us_state_abbr, uk_postcode, uk_county
* Many minor changes (please see github pull requests for credits)
* Added many localizations
* Added range and array support for Lorem
== 1.0.1 2011-09-27
* 1 minor enhancement
* Added safe_email method to get someaddress@example.com [Kazimierz Kiełkowicz]
* 1 bug fix:
* Use the locale fallback properly when parsing string formats
== 1.0.0 2011-09-08
* 2 major enhancements
* Moved all formats to locale files
* Stopped interfering with I18n's global settings for fallbacks
* 3 minor bug fixes:
* Ruby 1.9.2 fixes [eMxyzptlk]
* UTF8 fixes [maxmiliano]
* Updated IPv4 generator to return valid addresses [Sylvain Desbureaux]
* Many minor enhancements:
* Added bork locale for bork-ified lorem [johnbentcope]
* Added IPv6 address generator [jc00ke]
* Removed deprecation warnings for Array#rand [chrismarshall]
* Added German translation and I18n improvments [Matthias Kühnert]
* Added Dutch translation [moretea]
* Added Lat/Long generator [Andy Callaghan]
* Added buzzword-laden title generator [supercleanse]
* Added optional extended wordlist for lorem [chriskottom]
* Updated German translation [Jan Schwenzien]
* Locale improvements [suweller]
* Added limit to lorem generator [darrenterhune]
* Added Brazilian Portuguese translation [maxmiliano]
* Added Australian translation [madeindata]
* Added Canadian translation [igbanam]
* Added Norwegian translation [kytrinyx]
* Lots of translation-related cleanup [kytrinyx]
== 0.9.5 2011-01-27
* 1 minor bug fix:
* Fixed YAML [Aaron Patterson]
* 3 minor enhancements:
* Added default rake task to run all tests [Aaron Patterson]
* Removed shuffle method [Aaron Patterson]
* Use psych if present [Aaron Patterson]
== 0.9.4 2010-12-29
* 1 minor bug fix:
* Stopped getting in the way of Rails' late locale loading
== 0.9.3 2010-12-28
* 1 minor enhancement:
* Added a faker namespace for translations
== 0.9.2 2010-12-22
* 1 bug fix:
* Stopped stomping on I18n load path
== 0.9.1 2010-12-22
* 1 bug fix:
* Stopped setting I18n default locale
* 1 major enhancement:
* Added method_missing to Address to add methods based on data in locale files
* 1 minor enhancement:
* Added Swiss locale [Lukas Westermann]
== 0.9.0 2010-12-21
* 1 major enhancement:
* Moved strings and some formats to locale files
== 0.3.1 2008-04-03
* 1 minor enhancement:
* Added city to Address
== 0.3.0 2008-01-01
* 3 major enhancements:
* Added Lorem to generate fake Latin
* Added secondary_address to Address, and made inclusion of
secondary address in street_address optional (false by
default).
* Added UK address methods [Caius Durling]
== 0.2.1 2007-12-05
* 1 major enhancement:
* Dropped facets to avoid conflict with ActiveSupport
* 2 minor enhancements:
* Changed the output of user_name to randomly separate with a . or _
* Added a few tests
== 0.1.0 2007-11-22
* 1 major enhancement:
* Initial release

@ -0,0 +1,20 @@
Copyright (c) 2007-2010 Benjamin Curtis
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

@ -0,0 +1,550 @@
Faker
=====
This gem is a port of Perl's Data::Faker library that generates fake data.
It comes in very handy for taking screenshots (taking screenshots for my
project, [Catch the Best](http://catchthebest.com/) was the original impetus
for the creation of this gem), having real-looking test data, and having your
database populated with more than one or two records while you're doing
development.
NOTE: While Faker generates data at random, returned values are not guaranteed to be unique.
Installing
----------
```bash
gem install faker
```
##Usage
-----
```ruby
Faker::Name.name #=> "Christophe Bartell"
Faker::Internet.email #=> "kirsten.greenholt@corkeryfisher.info"
```
###Faker::Address
-----------------
```ruby
Faker::Address.city #=> "Imogeneborough"
Faker::Address.street_name #=> "Larkin Fork"
Faker::Address.street_address #=> "282 Kevin Brook"
Faker::Address.secondary_address #=> "Apt. 672"
Faker::Address.building_number #=> "7304"
Faker::Address.zip_code #=> "58517"
Faker::Address.zip #=> "58517"
Faker::Address.postcode #=> "58517"
Faker::Address.time_zone #=> "Asia/Yakutsk"
Faker::Address.street_suffix #=> "Street"
Faker::Address.city_suffix #=> "fort"
Faker::Address.city_prefix #=> "Lake"
Faker::Address.state #=> "California"
Faker::Address.state_abbr #=> "AP"
Faker::Address.country #=> "French Guiana"
Faker::Address.country_code #=> "IT"
Faker::Address.latitude #=> "-58.17256227443719"
Faker::Address.longitude #=> "-156.65548382095133"
```
###Faker::Bitcoin
-----------------
```ruby
Faker::Bitcoin.address #=> "1HUoGjmgChmnxxYhz87YytV4gVjfPaExmh"
Faker::Bitcoin.testnet_address #=> ""msHGunDvoEwmVFXvd2Bub1SNw5RP1YHJaf""
```
###Faker::Business
------------------
```ruby
Faker::Business.credit_card_number #=> "1228-1221-1221-1431"
Faker::Business.credit_card_expiry_date #=> <Date: 2015-11-11 ((2457338j,0s,0n),+0s,2299161j)>
Faker::Business.credit_card_type #=> "visa"
```
###Faker::Code
--------------
```ruby
Faker::Code.isbn #=> "759021701-8"
Faker::Code.ean #=> "4600051000057"
```
###Faker::Commerce
------------------
```ruby
Faker::Commerce.color #=> "lavender"
# Optional arguments max=3, fixed_amount=false
Faker::Commerce.department #=> "Grocery, Health & Beauty"
Faker::Commerce.department(5) #=> "Grocery, Books, Health & Beauty"
Faker::Commerce.department(2, true) #=> "Books & Tools"
Faker::Commerce.product_name #=> "Practical Granite Shirt"
Faker::Commerce.price #=> "44.6"
```
###Faker::Company
-----------------
```ruby
Faker::Company.name #=> "Hirthe-Ritchie"
Faker::Company.suffix #=> "Group"
# Generate a buzzword-laden catch phrase.
Faker::Company.catch_phrase #=> "Business-focused coherent parallelism"
Faker::Company.buzzword #=> "Business-focused"
# When a straight answer won't do, BS to the rescue!
Faker::Company.bs #=> "empower one-to-one web-readiness"
Faker::Company.ein #=> "34-8488813"
Faker::Company.duns_number #=> "08-341-3736"
# Get a random company logo url in PNG format.
Faker::Company.logo #=> "http://pigment.github.com/fake-logos/logos/medium/color/5.png"
Faker::Company.swedish_organisation_number #=> "7718797652"
```
###Faker::Date
---------------------
```ruby
# Random date between dates
Faker::Date.between(2.days.ago, Date.today) #=> "Wed, 24 Sep 2014"
# Random date in the future (up to maximum of N days)
Faker::Date.forward(23) # => "Fri, 03 Oct 2014"
# Random date in the past (up to maximum of N days)
Faker::Date.backward(14) #=> "Fri, 19 Sep 2014"
```
###Faker::Internet
---------------
```ruby
# Optional argument name=nil
Faker::Internet.email #=> "eliza@mann.net"
Faker::Internet.email('Nancy') #=> "nancy@terry.biz"
# Optional argument name=nil
Faker::Internet.free_email #=> "freddy@gmail.com"
Faker::Internet.free_email('Nancy') #=> "nancy@yahoo.com"
# Optional argument name=nil
Faker::Internet.safe_email #=> "christelle@example.org"
Faker::Internet.safe_email('Nancy') #=> "nancy@example.net"
# Optional arguments specifier=nil, separators=%w(. _)
Faker::Internet.user_name #=> "alexie"
Faker::Internet.user_name('Nancy') #=> "nancy"
Faker::Internet.user_name('Nancy Johnson', %w(. _ -)) #=> "johnson-nancy"
# Optional arguments: min_length=8, max_length=16
Faker::Internet.password #=> "vg5msvy1uerg7"
Faker::Internet.password(8) #=> "yfgjik0hgzdqs0"
Faker::Internet.password(10, 20) #=> "eoc9shwd1hwq4vbgfw"
Faker::Internet.domain_name #=> "effertz.info"
Faker::Internet.fix_umlauts('äöüß') #=> "aeoeuess"
Faker::Internet.domain_word #=> "haleyziemann"
Faker::Internet.domain_suffix #=> "info"
Faker::Internet.ip_v4_address #=> "24.29.18.175"
Faker::Internet.ip_v6_address #=> "ac5f:d696:3807:1d72:2eb5:4e81:7d2b:e1df"
# Optional argument prefix=''
Faker::Internet.mac_address #=> "e6:0d:00:11:ed:4f"
Faker::Internet.mac_address('55:44:33') #=> "55:44:33:02:1d:9b"
# Optional arguments: host=domain_name, path="/#{user_name}"
Faker::Internet.url #=> "http://thiel.com/chauncey_simonis"
Faker::Internet.url('example.com') #=> "http://example.com/clotilde.swift"
Faker::Internet.url('example.com', '/foobar.html') #=> "http://example.com/foobar.html"
# Optional arguments: words=nil, glue=nil
Faker::Internet.slug #=> "pariatur_laudantium"
Faker::Internet.slug('foo bar') #=> "foo.bar"
Faker::Internet.slug('foo bar', '-') #=> "foo-bar"
```
###Faker::Lorem
---------------
```ruby
Faker::Lorem.word #=> "repellendus"
# Optional arguments: num=3, supplemental=false
Faker::Lorem.words #=> ["dolores", "adipisci", "nesciunt"]
Faker::Lorem.words(4) #=> ["culpa", "recusandae", "aut", "omnis"]
Faker::Lorem.words(4, true) #=> ["colloco", "qui", "vergo", "deporto"]
# Optional arguments: char_count=255
Faker::Lorem.characters #=> "uw1ep04lhs0c4d931n1jmrspprf5wrj85fefue0y7y6m56b6omquh7br7dhqijwlawejpl765nb1716idmp3xnfo85v349pzy2o9rir23y2qhflwr71c1585fnynguiphkjm8p0vktwitcsm16lny7jzp9t4drwav3qmhz4yjq4k04x14gl6p148hulyqioo72tf8nwrxxcclfypz2lc58lsibgfe5w5p0xv95peafjjmm2frkhdc6duoky0aha"
Faker::Lorem.characters(10) #=> "ang9cbhoa8"
# Optional arguments: word_count=4, supplemental=false, random_words_to_add=6
Faker::Lorem.sentence #=> "Dolore illum animi et neque accusantium."
Faker::Lorem.sentence(3) #=> "Commodi qui minus deserunt sed vero quia."
Faker::Lorem.sentence(3, true) #=> "Inflammatio denego necessitatibus caelestis autus illum."
Faker::Lorem.sentence(3, false, 4) #=> "Aut voluptatem illum fugit ut sit."
Faker::Lorem.sentence(3, true, 4) #=> "Accusantium tantillus dolorem timor."
# Optional arguments: sentence_count=3, supplemental=false
Faker::Lorem.sentences #=> ["Vero earum commodi soluta.", "Quaerat fuga cumque et vero eveniet omnis ut.", "Cumque sit dolor ut est consequuntur."]
Faker::Lorem.sentences(1) #=> ["Ut perspiciatis explicabo possimus doloribus enim quia."]
Faker::Lorem.sentences(1, true) #=> ["Quis capillus curo ager veritatis voro et ipsum."]
# Optional arguments: sentence_count=3, supplemental=false, random_sentences_to_add=3
Faker::Lorem.paragraph #=> "Neque dicta enim quasi. Qui corrupti est quisquam. Facere animi quod aut. Qui nulla consequuntur consectetur sapiente."
Faker::Lorem.paragraph(2) #=> "Illo qui voluptas. Id sit quaerat enim aut cupiditate voluptates dolorum. Porro necessitatibus numquam dolor quia earum."
Faker::Lorem.paragraph(2, true) #=> "Cedo vero adipisci. Theatrum crustulum coaegresco tonsor crastinus stabilis. Aliqua crur consequatur amor una tolero sum."
Faker::Lorem.paragraph(2, false, 4) #=> "Neque aut et nemo aut incidunt voluptates. Dolore cum est sint est. Vitae assumenda porro odio dolores fugiat. Est voluptatum quia rerum."
Faker::Lorem.paragraph(2, true, 4) #=> "Vomito unde uxor annus. Et patior utilis sursum."
# Optional arguments: paragraph_count=3, supplemental=false
Faker::Lorem.paragraphs #=> ["Dolores quis quia ad quo voluptates. Maxime delectus totam numquam. Necessitatibus vel atque qui dolore.", "Id neque nemo. Dolores iusto facere est ad. Accusamus ipsa dolor ut.", "Et officiis ut hic. Sunt asperiores minus distinctio debitis ipsa dolor. Minima eos deleniti."]
Faker::Lorem.paragraphs(1) #=> ["Labore voluptas sequi. Ratione nulla eaque quia molestiae fugit. At quam laboriosam aut ut dignissimos."]
Faker::Lorem.paragraphs(1, true) #=> ["Depulso animi cunctatio amicitia adficio. Vester viduo qui despirmatio voluptas. Validus laudantium adopto ut agnitio venustas. Aer arcus odio esse."]
```
###Faker::Name
--------------
```ruby
Faker::Name.name #=> "Tyshawn Johns Sr."
Faker::Name.first_name #=> "Kaci"
Faker::Name.last_name #=> "Ernser"
Faker::Name.prefix #=> "Mr."
Faker::Name.suffix #=> "IV"
Faker::Name.title #=> "Legacy Creative Director"
```
###Faker::Avatar
----------------
```ruby
Faker::Avatar.image #=> "http://robohash.org/sitsequiquia.png?size=300x300"
Faker::Avatar.image("my-own-slug") #=> "http://robohash.org/my-own-slug.png?size=300x300"
Faker::Avatar.image("my-own-slug", "50x50") #=> "http://robohash.org/my-own-slug.png?size=50x50"
Faker::Avatar.image("my-own-slug", "50x50", "jpg") #=> "http://robohash.org/my-own-slug.jpg?size=50x50"
Faker::Avatar.image("my-own-slug", "50x50", "bmp") #=> "http://robohash.org/my-own-slug.bmp?size=50x50"
```
###Faker::Number
----------------
```ruby
# Required parameter: digits
Faker::Number.number(10) #=> "1968353479"
# Required parameter: l_digits
Faker::Number.decimal(2) #=> "11.88"
Faker::Number.decimal(2, 3) #=> "18.843"
# Required parameter: digits
Faker::Number.hexadecimal(3) #=> "e74"
Faker::Number.between(1, 10) #=> 7
Faker::Number.positive #=> 235.59238499107653
Faker::Number.negative #=> -4480.042585669558
Faker::Number.digit #=> "1"
```
###Faker::PhoneNumber
---------------------
Phone numbers may be in any of the following formats:
* 333-333-3333
* (333) 333-3333
* 1-333-333-3333
* 333.333.3333
* 333-333-3333
* 333-333-3333 x3333
* (333) 333-3333 x3333
* 1-333-333-3333 x3333
* 333.333.3333 x3333
(Don't let the example output below fool you - any format can be returned at random.)
```ruby
Faker::PhoneNumber.phone_number #=> "397.693.1309"
Faker::PhoneNumber.cell_phone #=> "(186)285-7925"
# NOTE NOTE NOTE NOTE
# For the 'US only' methods below, first you must do the following:
Faker::Config.locale = 'en-US'
# US only
Faker::PhoneNumber.area_code #=> "201"
# US only
Faker::PhoneNumber.exchange_code #=> "208"
# Optional parameter: length=4
Faker::PhoneNumber.subscriber_number #=> "3873"
Faker::PhoneNumber.subscriber_number(2) #=> "39"
Faker::PhoneNumber.extension #=> "3764"
```
###Faker::Time
---------------------
```ruby
# Random date between dates
Faker::Time.between(DateTime.now - 1, DateTime.now) #=> "2014-09-18 12:30:59 -0700"
# Random date between dates (within specified part of the day)
# You can install the active_support gem to facilitate time manipulation like 45.minutes + 2.hours
require "as-duration"
Faker::Time.between(2.days.ago, Time.now, :all) #=> "2014-09-19 07:03:30 -0700"
Faker::Time.between(2.days.ago, Time.now, :day) #=> "2014-09-18 16:28:13 -0700"
Faker::Time.between(2.days.ago, Time.now, :night) #=> "2014-09-20 19:39:38 -0700"
Faker::Time.between(2.days.ago, Time.now, :morning) #=> "2014-09-19 08:07:52 -0700"
Faker::Time.between(2.days.ago, Time.now, :afternoon) #=> "2014-09-18 12:10:34 -0700"
Faker::Time.between(2.days.ago, Time.now, :evening) #=> "2014-09-19 20:21:03 -0700"
Faker::Time.between(2.days.ago, Time.now, :midnight) #=> "2014-09-20 00:40:14 -0700"
# Random time in the future (up to maximum of N days)
Faker::Time.forward(23, :morning) # => "2014-09-26 06:54:47 -0700"
# Random time in the past (up to maximum of N days)
Faker::Time.backward(14, :evening) #=> "2014-09-17 19:56:33 -0700"
```
###Faker::Hacker
---------------------
Are you having trouble writing tech-savvy dialogue for your latest screenplay?
Worry not! Hollywood-grade technical talk is ready to fill out any form where you need to look smart.
```ruby
# Full Phrase
Faker::Hacker.say_something_smart #=> "Try to compress the SQL interface, maybe it will program the back-end hard drive!"
# Short technical abbreviations
Faker::Hacker.abbreviation #=> "RAM"
# Hacker centric adjectives
Faker::Hacker.adjective #=> "open-source"
# Only the best hacker related nouns
Faker::Hacker.noun #=> "bandwidth"
# Actions that hackers take
Faker::Hacker.verb #=> "bypass"
# Verbs that end in -ing
Faker::Hacker.ingverb #=> "synthesizing"
```
###Faker::App
-----------------
```ruby
Faker::App.name #=> "Treeflex"
Faker::App.version #=> "0.7.9"
Faker::App.author #=> "Daphne Swift"
```
###Faker::SlackEmoji
-----------------
```ruby
# Random Slack Emoji from people category
Faker::SlackEmoji.people #=> ":sleepy:"
# Random Slack Emoji from nature category
Faker::SlackEmoji.nature #=> ":chestnut:"
# Random Slack Emoji from food and drink category
Faker::SlackEmoji.food_and_drink #=> ":tangerine:"
# Random Slack Emoji from celebration category
Faker::SlackEmoji.celebration #=> ":ribbon:"
# Random Slack Emoji from activity category
Faker::SlackEmoji.activity #=> ":performing_arts:"
# Random Slack Emoji from travel and places category
Faker::SlackEmoji.travel_and_places #=> ":truck:"
# Random Slack Emoji from objects & symbols category
Faker::SlackEmoji.objects_and_symbols #=> ":alarm_clock:"
# Random Slack Emoji from custom category
Faker::SlackEmoji.custom #=> ":suspect:"
# Random Slack Emoji from any category
Faker::SlackEmoji.emoji #=> ":last_quarter_moon:"
```
###Faker::Team
-----------------
```ruby
# Random Team Creature
Faker::Team.creature #=> "gooses"
# Random Team Name created from random US State (Faker::Address.state) prepended to a random Team Creature
Faker::Team.name #=> "Oregon vixens"
# Random Team State
Faker::Team.state #=> "Oregon"
# Random Team Sport
Faker::Team.sport #=> "lacrosse"
```
###Faker::Book
------------------
```ruby
# Random Book Title
Faker::Book.title #=> "The Odd Sister"
# Random Author
Faker::Book.author #=> "Alysha Olsen"
# Random Publisher
Faker::Book.publisher #=> "Opus Reader"
```
###Faker::University
------------------
```ruby
# Random University Name
Faker::University.name #=> "South Texas College"
```
Customization
------------
Since you may want to make addresses and other types of data look different
depending on where in the world you are (US postal codes vs. UK postal codes,
for example), Faker uses the I18n gem to store strings (like state names) and
formats (US postal codes are NNNNN while UK postal codes are AAN NAA),
allowing you to get different formats by switching locales. Just set
Faker::Config.locale to the locale you want, and Faker will take care of the
rest.
If your locale doesn't already exist, create it in the \lib\locales\ directory
and you can then override or add elements to suit
```yaml
en-au-ocker:
faker:
name:
# Existing faker field, new data
first_name: [Charlotte, Ava, Chloe, Emily]
# New faker fields
ocker_first_name: [Bazza, Bluey, Davo, Johno, Shano, Shazza]
region: [South East Queensland, Wide Bay Burnett, Margaret River, Port Pirie, Gippsland, Elizabeth, Barossa]
```
Contributing
------------
See [CONTRIBUTING.md](https://github.com/stympy/faker/blob/master/CONTRIBUTING.md).
Contact
-------
Comments and feedback are welcome. Send an email to Benjamin Curtis via the [google group](http://groups.google.com/group/ruby-faker).
License
-------
This code is free to use under the terms of the MIT license.

@ -0,0 +1,22 @@
class Array
unless self.method_defined? :sample
def sample(n = nil)
#based on code from https://github.com/marcandre/backports
size = self.length
return self[Kernel.rand(size)] if n.nil?
n = n.to_int
raise ArgumentError, "negative array size" if n < 0
n = size if n > size
result = Array.new(self)
n.times do |i|
r = i + Kernel.rand(size - i)
result[i], result[r] = result[r], result[i]
end
result[n..size] = []
result
end
end
end

@ -0,0 +1,9 @@
# For Ruby 1.8
unless :symbol.respond_to?(:downcase)
Symbol.class_eval do
def downcase
to_s.downcase.intern
end
end
end

@ -0,0 +1,188 @@
# -*- coding: utf-8 -*-
mydir = File.expand_path(File.dirname(__FILE__))
begin
require 'psych'
rescue LoadError
end
require 'i18n'
require 'set' # Fixes a bug in i18n 0.6.11
if I18n.respond_to?(:enforce_available_locales=)
I18n.enforce_available_locales = true
end
I18n.load_path += Dir[File.join(mydir, 'locales', '*.yml')]
module Faker
class Config
@locale = nil
class << self
attr_writer :locale
def locale
@locale || I18n.locale
end
end
end
class Base
Numbers = Array(0..9)
ULetters = Array('A'..'Z')
Letters = ULetters + Array('a'..'z')
class << self
## make sure numerify results doesnt start with a zero
def numerify(number_string)
number_string.sub(/#/) { (rand(9)+1).to_s }.gsub(/#/) { rand(10).to_s }
end
def letterify(letter_string)
letter_string.gsub(/\?/) { ULetters.sample }
end
def bothify(string)
letterify(numerify(string))
end
# 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][A-HK-Y0-9][AEHMNPRTVXY0-9]?[ABEHMNPRVWXY0-9]? {1,2}[0-9][ABD-HJLN-UW-Z]{2}$/
#
# and generate a string like this:
#
# "U3V 3TP"
#
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
# Helper for the common approach of grabbing a translation
# with an array of values and selecting one of them.
def fetch(key)
fetched = translate("faker.#{key}")
fetched = fetched.sample if fetched.respond_to?(:sample)
if fetched.match(/^\//) and fetched.match(/\/$/) # A regex
regexify(fetched)
else
fetched
end
end
# 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}".
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
# Call I18n.translate with our configured locale if no
# locale is specified
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
# 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.merge(:locale => :en))))
end
def flexible(key)
@flexible_key = key
end
# 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
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
# Generates a random value between the interval
def rand_in_range(from, to)
from, to = to, from if to < from
Random.new.rand(from..to)
end
end
end
end
require 'faker/address'
require 'faker/code'
require 'faker/color'
require 'faker/company'
require 'faker/university'
require 'faker/finance'
require 'faker/internet'
require 'faker/lorem'
require 'faker/name'
require 'faker/team'
require 'faker/phone_number'
require 'faker/business'
require 'faker/commerce'
require 'faker/version'
require 'faker/number'
require 'faker/bitcoin'
require 'faker/avatar'
require 'faker/date'
require 'faker/time'
require 'faker/number'
require 'faker/hacker'
require 'faker/app'
require 'faker/slack_emoji'
require 'faker/book'
require 'extensions/array'
require 'extensions/symbol'
require 'helpers/char'

@ -0,0 +1,59 @@
module Faker
class Address < Base
flexible :address
class << self
def city
parse('address.city')
end
def street_name
parse('address.street_name')
end
def street_address(include_secondary = false)
numerify(parse('address.street_address') + (include_secondary ? ' ' + secondary_address : ''))
end
def secondary_address
numerify(fetch('address.secondary_address'))
end
def building_number
bothify(fetch('address.building_number'))
end
def zip_code(state_abbreviation = '')
return bothify(fetch('address.postcode')) if state_abbreviation === ''
# provide a zip code that is valid for the state provided
# see http://www.fincen.gov/forms/files/us_state_territory_zip_codes.pdf
bothify(fetch('address.postcode_by_state.' + state_abbreviation))
end
def time_zone
fetch('address.time_zone')
end
alias_method :zip, :zip_code
alias_method :postcode, :zip_code
def street_suffix; fetch('address.street_suffix'); end
def city_suffix; fetch('address.city_suffix'); end
def city_prefix; fetch('address.city_prefix'); end
def state_abbr; fetch('address.state_abbr'); end
def state; fetch('address.state'); end
def country; fetch('address.country'); end
def country_code; fetch('address.country_code'); end
def latitude
((rand * 180) - 90).to_s
end
def longitude
((rand * 360) - 180).to_s
end
end
end
end

@ -0,0 +1,22 @@
module Faker
class App < Base
class << self
def name
fetch('app.name')
end
def version
if parse('app.version') == ""
numerify(fetch('app.version'))
else
parse('app.version')
end
end
def author
parse('app.author')
end
end
end
end

@ -0,0 +1,14 @@
module Faker
class Avatar < Base
class << self
SUPPORTED_FORMATS = %w(png jpg bmp)
def image(slug = nil, size = '300x300', format = 'png', set = 'set1')
raise ArgumentError, "Size should be specified in format 300x300" unless size.match(/^[0-9]+x[0-9]+$/)
raise ArgumentError, "Supported formats are #{SUPPORTED_FORMATS.join(', ')}" unless SUPPORTED_FORMATS.include?(format)
slug ||= Faker::Lorem.words.join
"http://robohash.org/#{slug}.#{format}?size=#{size}&set=#{set}"
end
end
end
end

@ -0,0 +1,49 @@
require 'digest'
require 'securerandom'
module Faker
class Bitcoin < Base
class << self
PROTOCOL_VERSIONS = {
main: 0,
testnet: 111
}
def address
address_for(:main)
end
def testnet_address
address_for(:testnet)
end
protected
def base58(str)
alphabet = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
base = alphabet.size
lv = 0
str.split('').reverse.each_with_index { |v,i| lv += v.unpack('C')[0] * 256**i }
ret = ''
while lv > 0 do
lv, mod = lv.divmod(base)
ret << alphabet[mod]
end
npad = str.match(/^#{0.chr}*/)[0].to_s.size
'1'*npad + ret.reverse
end
def address_for(network)
version = PROTOCOL_VERSIONS.fetch(network)
hash = SecureRandom.hex(20)
packed = version.chr + [hash].pack("H*")
checksum = Digest::SHA2.digest(Digest::SHA2.digest(packed))[0..3]
base58(packed + checksum)
end
end
end
end

@ -0,0 +1,19 @@
module Faker
class Book < Base
flexible :book
class << self
def title
fetch('book.title')
end
def author
fetch('book.author')
end
def publisher
fetch('book.publisher')
end
end
end
end

@ -0,0 +1,22 @@
require 'date'
module Faker
class Business < Base
flexible :business
class << self
def credit_card_number
fetch('business.credit_card_numbers')
end
def credit_card_expiry_date
::Date.today + (365 * (rand(4) + 1))
end
def credit_card_type
fetch('business.credit_card_types')
end
end
end
end

@ -0,0 +1,70 @@
module Faker
class Code < Base
class << self
# Generates a 10 digit NPI (National Provider Identifier
# issued to health care providers in the United States)
def npi
Random.new.rand(10 ** 10).to_s.rjust(10, '0')
end
# By default generates 10 sign isbn code in format 123456789-X
# You can pass 13 to generate new 13 sign code
def isbn(base = 10)
base == 13 ? generate_base13_isbn : generate_base10_isbn
end
# By default generates 13 sign ean code in format 1234567890123
# You can pass 8 to generate ean8 code
def ean(base = 13)
base == 8 ? generate_base8_ean : generate_base13_ean
end
def rut
value = Number.number(8)
vd = rut_verificator_digit(value)
value << "-#{vd}"
end
private
def generate_base10_isbn
values = regexify(/\d{9}/)
remainder = sum(values) { |value, index| (index + 1) * value.to_i } % 11
values << "-#{remainder == 10 ? 'X' : remainder}"
end
def generate_base13_isbn
values = regexify(/\d{12}/)
remainder = sum(values) { |value, index| index.even? ? value.to_i : value.to_i * 3 } % 10
values << "-#{((10 - remainder) % 10)}"
end
def sum(values, &block)
values.split(//).each_with_index.inject(0) do |sum, (value, index)|
sum + block.call(value, index)
end
end
def generate_base8_ean
values = regexify(/\d{7}/)
check_digit = 10 - values.split(//).each_with_index.inject(0){ |s, (v, i)| s + v.to_i * EAN_CHECK_DIGIT8[i] } % 10
values << (check_digit == 10 ? 0 : check_digit).to_s
end
def generate_base13_ean
values = regexify(/\d{12}/)
check_digit = 10 - values.split(//).each_with_index.inject(0){ |s, (v, i)| s + v.to_i * EAN_CHECK_DIGIT13[i] } % 10
values << (check_digit == 10 ? 0 : check_digit).to_s
end
EAN_CHECK_DIGIT8 = [3, 1, 3, 1, 3, 1, 3]
EAN_CHECK_DIGIT13 = [1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3]
def rut_verificator_digit(rut)
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(:+)
(11 - total % 11).to_s.gsub(/10/, 'k').gsub(/11/, '0')
end
end
end
end

@ -0,0 +1,49 @@
module Faker
class Color < Base
class << self
def hex_color
@hex_color = "#%06x" % (rand * 0xffffff)
end
def single_rgb_color
@single_rgb_color = (0..255).to_a.sample
@single_rgb_color
end
def rgb_color
@rgb_colors = []
3.times do
@rgb_colors.push single_rgb_color
end
@rgb_colors
end
def single_hsl_color
@single_hsla_color = Faker::Base::rand_in_range(0.0, 360.00).round(2)
@single_hsla_color
end
def alpha_channel
@alpha_channel = rand
@alpha_channel
end
def hsl_color
@hsl_colors = []
3.times do
@hsl_colors.push single_hsl_color
end
@hsl_colors
end
def hsla_color
@hsla_colors = []
3.times do
@hsla_colors.push single_hsl_color
end
@hsla_colors.push alpha_channel
@hsla_colors
end
end
end
end

@ -0,0 +1,55 @@
module Faker
class Commerce < Base
class << self
def color
fetch('commerce.color')
end
def department(max = 3, fixed_amount = false)
num = max if fixed_amount
num ||= 1 + rand(max)
categories = categories(num)
if num > 1
merge_categories(categories)
else
categories[0]
end
end
def product_name
fetch('commerce.product_name.adjective') + ' ' + fetch('commerce.product_name.material') + ' ' + fetch('commerce.product_name.product')
end
def material
fetch('commerce.product_name.material')
end
def price
random = Random.new
(random.rand(0..100.0) * 100).floor/100.0
end
private
def categories(num)
categories = []
while categories.length < num do
category = fetch('commerce.department')
categories << category unless categories.include?(category)
end
categories
end
def merge_categories(categories)
separator = fetch('separator')
comma_separated = categories.slice!(0...-1).join(', ')
[comma_separated, categories[0]].join(separator)
end
end
end
end

@ -0,0 +1,78 @@
module Faker
class Company < Base
flexible :company
class << self
def name
parse('company.name')
end
def suffix
fetch('company.suffix')
end
# Generate a buzzword-laden catch phrase.
def catch_phrase
translate('faker.company.buzzwords').collect {|list| list.sample }.join(' ')
end
def buzzword
translate('faker.company.buzzwords').flatten.sample
end
# When a straight answer won't do, BS to the rescue!
def bs
translate('faker.company.bs').collect {|list| list.sample }.join(' ')
end
def ein
('%09d' % rand(10 ** 9)).gsub(/(\d\d)(\d\d\d\d\d\d\d)/, '\\1-\\2')
end
def duns_number
('%09d' % rand(10 ** 9)).gsub(/(\d\d)(\d\d\d)(\d\d\d\d)/, '\\1-\\2-\\3')
end
# Get a random company logo url in PNG format.
def logo
rand_num = Random.rand(13) + 1
"http://pigment.github.io/fake-logos/logos/medium/color/#{rand_num}.png"
end
def swedish_organisation_number
base = ('%09d' % rand(10 ** 9))
base + luhn_algorithm(base).to_s
end
private
def luhn_algorithm(number)
multiplications = []
number.split(//).each_with_index do |digit, i|
if i % 2 == 0
multiplications << digit.to_i * 2
else
multiplications << digit.to_i
end
end
sum = 0
multiplications.each do |num|
num.to_s.each_byte do |character|
sum += character.chr.to_i
end
end
if sum % 10 == 0
control_digit = 0
else
control_digit = (sum / 10 + 1) * 10 - sum
end
control_digit
end
end
end
end

@ -0,0 +1,42 @@
module Faker
class Date < Base
class << self
def between(from, to)
from = get_date_object(from)
to = get_date_object(to)
Faker::Base::rand_in_range(from, to)
end
def forward(days = 365)
from = ::Date.today + 1
to = ::Date.today + days
between(from, to).to_date
end
def backward(days = 365)
from = ::Date.today - days
to = ::Date.today - 1
between(from, to).to_date
end
def birthday(min_age = 18, max_age = 65)
t = ::Date.today
from = ::Date.new(t.year - min_age, t.month, t.day)
to = ::Date.new(t.year - max_age, t.month, t.day)
between(from, to).to_date
end
private
def get_date_object(date)
date = ::Date.parse(date) if date.is_a?(String)
date = date.to_date if date.respond_to?(:to_date)
date
end
end
end
end

@ -0,0 +1,26 @@
module Faker
class Finance < Base
CREDIT_CARD_TYPES = [ :visa, :mastercard, :discover, :american_express, :diners_club, :jcb, :switch, :solo, :dankort, :maestro, :forbrugsforeningen, :laser ]
class << self
def credit_card(*types)
types = CREDIT_CARD_TYPES if types.empty?
type = types.sample
template = numerify(fetch("credit_card.#{type}"))
# calculate the luhn checksum digit
multiplier = 1
luhn_sum = template.gsub(/[^0-9]/, '').split('').reverse.map(&:to_i).inject(0) do |sum, digit|
multiplier = (multiplier == 2 ? 1 : 2)
sum + (digit * multiplier).to_s.split('').map(&:to_i).inject(0) { |digit_sum, cur| digit_sum + cur }
end
# the sum plus whatever the last digit is must be a multiple of 10. So, the
# last digit must be 10 - the last digit of the sum.
luhn_digit = (10 - (luhn_sum % 10)) % 10
template.gsub! 'L', luhn_digit.to_s
template
end
end
end
end

@ -0,0 +1,31 @@
#Port of http://shinytoylabs.com/jargon/
module Faker
class Hacker < Base
flexible :hacker
class << self
def say_something_smart
phrases.sample
end
def abbreviation; fetch('hacker.abbreviation'); end
def adjective; fetch('hacker.adjective'); end
def noun; fetch('hacker.noun'); end
def verb; fetch('hacker.verb'); end
def ingverb; fetch('hacker.ingverb'); end
def phrases
[ "If we #{verb} the #{noun}, we can get to the #{abbreviation} #{noun} through the #{adjective} #{abbreviation} #{noun}!",
"We need to #{verb} the #{adjective} #{abbreviation} #{noun}!",
"Try to #{verb} the #{abbreviation} #{noun}, maybe it will #{verb} the #{adjective} #{noun}!",
"You can't #{verb} the #{noun} without #{ingverb} the #{adjective} #{abbreviation} #{noun}!",
"Use the #{adjective} #{abbreviation} #{noun}, then you can #{verb} the #{adjective} #{noun}!",
"The #{abbreviation} #{noun} is down, #{verb} the #{adjective} #{noun} so we can #{verb} the #{abbreviation} #{noun}!",
"#{ingverb} the #{noun} won't do anything, we need to #{verb} the #{adjective} #{abbreviation} #{noun}!",
"I'll #{verb} the #{adjective} #{abbreviation} #{noun}, that should #{noun} the #{abbreviation} #{noun}!"
]
end
end
end
end

@ -0,0 +1,111 @@
# encoding: utf-8
module Faker
class Internet < Base
class << self
def email(name = nil)
[user_name(name), domain_name].join('@')
end
def free_email(name = nil)
[user_name(name), fetch('internet.free_email')].join('@')
end
def safe_email(name = nil)
[user_name(name), 'example.'+ %w[org com net].shuffle.first].join('@')
end
def user_name(specifier = nil, separators = %w(. _))
if specifier.kind_of? String
return specifier.scan(/\w+/).shuffle.join(separators.sample).downcase
elsif specifier.kind_of? Integer
tries = 0 # Don't try forever in case we get something like 1_000_000.
begin
result = user_name nil, separators
tries += 1
end while result.length < specifier and tries < 7
until result.length >= specifier
result = result * 2
end
return result
elsif specifier.kind_of? Range
tries = 0
begin
result = user_name specifier.min, separators
tries += 1
end while not specifier.include? result.length and tries < 7
return result[0...specifier.max]
end
[
Char.prepare(Name.first_name),
[Name.first_name, Name.last_name].map{ |name|
Char.prepare name
}.join(separators.sample)
].sample
end
def password(min_length = 8, max_length = 16)
temp = Lorem.characters(min_length)
diff_length = max_length - min_length
if diff_length > 0
diff_rand = rand(diff_length + 1)
temp += Lorem.characters(diff_rand)
end
temp = temp[0..min_length] if min_length > 0
return temp
end
def domain_name
[Char.prepare(domain_word), domain_suffix].join('.')
end
def fix_umlauts(string)
Char.fix_umlauts string
end
def domain_word
if %w(uk).include? Config.locale
return Char.prepare Company.name.split(' ')[1]
end
Char.prepare Company.name.split(' ').first
end
def domain_suffix
fetch('internet.domain_suffix')
end
def mac_address(prefix='')
prefix_digits = prefix.split(':').map{ |d| d.to_i(16) }
address_digits = (6 - prefix_digits.size).times.map{ rand(256) }
(prefix_digits + address_digits).map{ |d| '%02x' % d }.join(':')
end
def ip_v4_address
ary = (2..254).to_a
[ary.sample,
ary.sample,
ary.sample,
ary.sample].join('.')
end
def ip_v6_address
@@ip_v6_space ||= (0..65535).to_a
container = (1..8).map{ |_| @@ip_v6_space.sample }
container.map{ |n| n.to_s(16) }.join(':')
end
def url(host = domain_name, path = "/#{user_name}")
"http://#{host}#{path}"
end
def slug(words = nil, glue = nil)
glue ||= %w[- _ .].sample
(words || Faker::Lorem::words(2).join(' ')).gsub(' ', glue).downcase
end
def device_token
rand(16 ** 64).to_s(16).rjust(64, '0').chars.to_a.shuffle.join
end
end
end
end

@ -0,0 +1,66 @@
module Faker
# Based on Perl's Text::Lorem
class Lorem < Base
class << self
def word
translate('faker.lorem.words').sample
end
def words(num = 3, supplemental = false)
resolved_num = resolve(num)
word_list = (
translate('faker.lorem.words') +
(supplemental ? translate('faker.lorem.supplemental') : [])
)
word_list = word_list * ((resolved_num / word_list.length) + 1)
word_list.shuffle[0, resolved_num]
end
def character
characters(1)
end
def characters(char_count = 255)
return '' if char_count.respond_to?(:to_i) && char_count.to_i < 1
char_count = resolve(char_count)
rand(36**char_count).to_s(36).rjust(char_count, '0').chars.to_a.shuffle.join
end
def sentence(word_count = 4, supplemental = false, random_words_to_add = 6)
words(word_count + rand(random_words_to_add.to_i).to_i, supplemental).join(' ').capitalize + '.'
end
def sentences(sentence_count = 3, supplemental = false)
[].tap do |sentences|
1.upto(resolve(sentence_count)) do
sentences << sentence(3, supplemental)
end
end
end
def paragraph(sentence_count = 3, supplemental = false, random_sentences_to_add = 3)
sentences(resolve(sentence_count) + rand(random_sentences_to_add.to_i).to_i, supplemental).join(' ')
end
def paragraphs(paragraph_count = 3, supplemental = false)
[].tap do |paragraphs|
1.upto(resolve(paragraph_count)) do
paragraphs << paragraph(3, supplemental)
end
end
end
private
# If an array or range is passed, a random value will be selected.
# All other values are simply returned.
def resolve(value)
case value
when Array then value[rand(value.size)]
when Range then rand((value.last+1) - value.first) + value.first
else value
end
end
end
end
end

@ -0,0 +1,22 @@
module Faker
class Name < Base
flexible :name
class << self
def name
parse('name.name')
end
def first_name; fetch('name.first_name'); end
def last_name; fetch('name.last_name'); end
def prefix; fetch('name.prefix'); end
def suffix; fetch('name.suffix'); end
# Generate a buzzword-laden job title
# Wordlist from http://www.bullshitjob.com/title/
def title; fetch('name.title.descriptor') + ' ' + fetch('name.title.level') + ' ' + fetch('name.title.job'); end
end
end
end

@ -0,0 +1,57 @@
module Faker
class Number < Base
class << self
def number(digits)
(1..digits).collect {digit}.join
end
def decimal(l_digits, r_digits = 2)
l_d = self.number(l_digits)
r_d = self.number(r_digits)
"#{l_d}.#{r_d}"
end
def digit
(rand() * 9).round.to_s
end
def hexadecimal(digits)
hex = ""
digits.times { hex += rand(15).to_s(16) }
hex
end
def between(from = 1.00, to = 5000.00)
Faker::Base::rand_in_range(from, to)
end
def positive(from = 1.00, to = 5000.00)
random_number = between(from, to)
greater_than_zero(random_number)
end
def negative(from = -5000.00, to = -1.00)
random_number = between(from, to)
less_than_zero(random_number)
end
private
def greater_than_zero(number)
should_be(number, :>)
end
def less_than_zero(number)
should_be(number, :<)
end
def should_be(number, method_to_compare)
if number.send(method_to_compare, 0)
number
else
number * -1
end
end
end
end
end

@ -0,0 +1,52 @@
module Faker
class PhoneNumber < Base
class << self
def phone_number
if parse('phone_number.formats') == ""
numerify(fetch('phone_number.formats'))
else
parse('phone_number.formats')
end
end
def cell_phone
if parse('cell_phone.formats') == ""
numerify(fetch('cell_phone.formats'))
else
parse('cell_phone.formats')
end
end
# US only
def area_code
begin
fetch('phone_number.area_code')
rescue I18n::MissingTranslationData
nil
end
end
# US only
def exchange_code
begin
fetch('phone_number.exchange_code')
rescue I18n::MissingTranslationData
nil
end
end
# US only
# Can be used for both extensions and last four digits of phone number.
# Since extensions can be of variable length, this method taks a length parameter
def subscriber_number(length = 4)
begin
rand.to_s[2..(1 + length)]
rescue I18n::MissingTranslationData
nil
end
end
alias_method :extension, :subscriber_number
end
end
end

@ -0,0 +1,43 @@
module Faker
class SlackEmoji < Base
class << self
def people
fetch('slack_emoji.people')
end
def nature
fetch('slack_emoji.nature')
end
def food_and_drink
fetch('slack_emoji.food_and_drink')
end
def celebration
fetch('slack_emoji.celebration')
end
def activity
fetch('slack_emoji.activity')
end
def travel_and_places
fetch('slack_emoji.travel_and_places')
end
def objects_and_symbols
fetch('slack_emoji.objects_and_symbols')
end
def custom
fetch('slack_emoji.custom')
end
def emoji
parse('slack_emoji.emoji')
end
end
end
end

@ -0,0 +1,20 @@
module Faker
class Team < Base
flexible :team
class << self
def name
parse('team.name')
end
def creature
fetch('team.creature')
end
def state
fetch('address.state')
end
end
end
end

@ -0,0 +1,48 @@
module Faker
class Time < Date
TIME_RANGES = {
:all => (0..23),
:day => (9..17),
:night => (18..23),
:morning => (6..11),
:afternoon => (12..17),
:evening => (17..21),
:midnight => (0..4)
}
class << self
def between(from, to, period = :all)
super(from, to).to_time + random_time(period)
end
def forward(days = 365, period = :all)
super(days).to_time + random_time(period)
end
def backward(days = 365, period = :all)
super(days).to_time + random_time(period)
end
private
def random_time(period)
hours(period) + minutes + seconds
end
def hours(period)
raise ArgumentError, 'invalid period' unless TIME_RANGES.has_key? period
hour_at_period = TIME_RANGES[period].to_a.sample
(60 * 60 * hour_at_period)
end
def minutes
60 * seconds
end
def seconds
(0..59).to_a.sample
end
end
end
end

@ -0,0 +1,20 @@
module Faker
class University < Base
flexible :university
class << self
def name
parse('university.name')
end
def prefix
fetch('university.prefix')
end
def suffix
fetch('university.suffix')
end
end
end
end

@ -0,0 +1,44 @@
# coding: utf-8
module Faker
module Char
def self.prepare(string)
result = romanize_cyrillic string
result = fix_umlauts result
result.gsub(/\W/, '').downcase
end
def self.fix_umlauts(string)
string.gsub(/[äöüß]/i) do |match|
case match.downcase
when "ä" 'ae'
when "ö" 'oe'
when "ü" 'ue'
when "ß" 'ss'
end
end
end
def self.romanize_cyrillic(string)
if Faker::Config.locale == "uk"
# Based on conventions abopted by BGN/PCGN for Ukrainian
uk_chars = {
'а' => 'a', 'б' => 'b', 'в' => 'v', 'г' => 'h', 'ґ' => 'g', 'д' => 'd',
'е' => 'e', 'є' => 'ye', 'ж' => 'zh', 'з' => 'z', 'и' => 'y', 'і' => 'i',
'ї' => 'yi', 'й' => 'y', 'к' => 'k', 'л' => 'l', 'м' => 'm', 'н' => 'n',
'о' => 'o', 'п' => 'p', 'р' => 'r', 'с' => 's', 'т' => 't', 'у' => 'u',
'ф' => 'f', 'х' => 'kh', 'ц' => 'ts', 'ч' => 'ch', 'ш' => 'sh', 'щ' => 'shch',
'ю' => 'yu', 'я' => 'ya',
'А' => 'a', 'Б' => 'b', 'В' => 'v', 'Г' => 'h', 'Ґ' => 'g', 'Д' => 'd',
'Е' => 'e', 'Є' => 'ye', 'Ж' => 'zh', 'З' => 'z', 'И' => 'y', 'І' => 'i',
'Ї' => 'yi', 'Й' => 'y', 'К' => 'k', 'Л' => 'l', 'М' => 'm', 'Н' => 'n',
'О' => 'o', 'П' => 'p', 'Р' => 'r', 'С' => 's', 'Т' => 't', 'У' => 'u',
'Ф' => 'f', 'Х' => 'kh', 'Ц' => 'ts', 'Ч' => 'ch', 'Ш' => 'sh', 'Щ' => 'shch',
'Ю' => 'yu', 'Я' => 'ya',
'ь' => '' # Ignore symbol, because its standard presentation is not allowed in URLs
}
return string.gsub(/[а-яА-ЯіїєґІЇЄҐ]/, uk_chars)
end
string
end
end
end

@ -0,0 +1,19 @@
de-CH:
faker:
address:
country_code: [CH, CH, CH, DE, AT, US, LI, US, HK, VN]
postcode: ['1###', '2###', '3###', '4###', '5###', '6###', '7###', '8###', '9###']
default_country: [Schweiz]
company:
suffix: [AG, GmbH, und Söhne, und Partner, "& Co.", Gruppe, LLC, Inc.]
name:
- "#{Name.last_name} #{suffix}"
- "#{Name.last_name}-#{Name.last_name}"
- "#{Name.last_name}, #{Name.last_name} und #{Name.last_name}"
internet:
domain_suffix: [com, net, biz, ch, de, li, at, ch, ch]
phone_number:
formats: ['0800 ### ###', '0800 ## ## ##', '0## ### ## ##', '0## ### ## ##', '+41 ## ### ## ##', '0900 ### ###', '076 ### ## ##', '+4178 ### ## ##', '0041 79 ### ## ##']

@ -0,0 +1,24 @@
# Australia formatted data types
# Using Top 200 Australian baby names of 2010
# 286 Surnames familiar to Australian population
en-AU:
faker:
name:
first_name: [William, Jack, Oliver, Joshua, Thomas, Lachlan, Cooper, Noah, Ethan, Lucas, James, Samuel, Jacob, Liam, Alexander, Benjamin, Max, Isaac, Daniel, Riley, Ryan, Charlie, Tyler, Jake, Matthew, Xavier, Harry, Jayden, Nicholas, Harrison, Levi, Luke, Adam, Henry, Aiden, Dylan, Oscar, Michael, Jackson, Logan, Joseph, Blake, Nathan, Connor, Elijah, Nate, Archie, Bailey, Marcus, Cameron, Jordan, Zachary, Caleb, Hunter, Ashton, Toby, Aidan, Hayden, Mason, Hamish, Edward, Angus, Eli, Sebastian, Christian, Patrick, Andrew, Anthony, Luca, Kai, Beau, Alex, George, Callum, Finn, Zac, Mitchell, Jett, Jesse, Gabriel, Leo, Declan, Charles, Jasper, Jonathan, Aaron, Hugo, David, Christopher, Chase, Owen, Justin, Ali, Darcy, Lincoln, Cody, Phoenix, Sam, John, Joel, Isabella, Ruby, Chloe, Olivia, Charlotte, Mia, Lily, Emily, Ella, Sienna, Sophie, Amelia, Grace, Ava, Zoe, Emma, Sophia, Matilda, Hannah, Jessica, Lucy, Georgia, Sarah, Abigail, Zara, Eva, Scarlett, Jasmine, Chelsea, Lilly, Ivy, Isla, Evie, Isabelle, Maddison, Layla, Summer, Annabelle, Alexis, Elizabeth, Bella, Holly, Lara, Madison, Alyssa, Maya, Tahlia, Claire, Hayley, Imogen, Jade, Ellie, Sofia, Addison, Molly, Phoebe, Alice, Savannah, Gabriella, Kayla, Mikayla, Abbey, Eliza, Willow, Alexandra, Poppy, Samantha, Stella, Amy, Amelie, Anna, Piper, Gemma, Isabel, Victoria, Stephanie, Caitlin, Heidi, Paige, Rose, Amber, Audrey, Claudia, Taylor, Madeline, Angelina, Natalie, Charli, Lauren, Ashley, Violet, Mackenzie, Abby, Skye, Lillian, Alana, Lola, Leah, Eve, Kiara]
last_name: [Smith, Jones, Williams, Brown, Wilson, Taylor, Johnson, White, Martin, Anderson, Thompson, Nguyen, Thomas, Walker, Harris, Lee, Ryan, Robinson, Kelly, King, Davis, Wright, Evans, Roberts, Green, Hall, Wood, Jackson, Clarke, Patel, Khan, Lewis, James, Phillips, Mason, Mitchell, Rose, Davies, Rodriguez, Cox, Alexander, Garden, Campbell, Johnston, Moore, Smyth, O'neill, Doherty, Stewart, Quinn, Murphy, Graham, Mclaughlin, Hamilton, Murray, Hughes, Robertson, Thomson, Scott, Macdonald, Reid, Clark, Ross, Young, Watson, Paterson, Morrison, Morgan, Griffiths, Edwards, Rees, Jenkins, Owen, Price, Moss, Richards, Abbott, Adams, Armstrong, Bahringer, Bailey, Barrows, Bartell, Bartoletti, Barton, Bauch, Baumbach, Bayer, Beahan, Beatty, Becker, Beier, Berge, Bergstrom, Bode, Bogan, Borer, Bosco, Botsford, Boyer, Boyle, Braun, Bruen, Carroll, Carter, Cartwright, Casper, Cassin, Champlin, Christiansen, Cole, Collier, Collins, Connelly, Conroy, Corkery, Cormier, Corwin, Cronin, Crooks, Cruickshank, Cummings, D'amore, Daniel, Dare, Daugherty, Dickens, Dickinson, Dietrich, Donnelly, Dooley, Douglas, Doyle, Durgan, Ebert, Emard, Emmerich, Erdman, Ernser, Fadel, Fahey, Farrell, Fay, Feeney, Feil, Ferry, Fisher, Flatley, Gibson, Gleason, Glover, Goldner, Goodwin, Grady, Grant, Greenfelder, Greenholt, Grimes, Gutmann, Hackett, Hahn, Haley, Hammes, Hand, Hane, Hansen, Harber, Hartmann, Harvey, Hayes, Heaney, Heathcote, Heller, Hermann, Hermiston, Hessel, Hettinger, Hickle, Hill, Hills, Hoppe, Howe, Howell, Hudson, Huel, Hyatt, Jacobi, Jacobs, Jacobson, Jerde, Johns, Keeling, Kemmer, Kessler, Kiehn, Kirlin, Klein, Koch, Koelpin, Kohler, Koss, Kovacek, Kreiger, Kris, Kuhlman, Kuhn, Kulas, Kunde, Kutch, Lakin, Lang, Langworth, Larkin, Larson, Leannon, Leffler, Little, Lockman, Lowe, Lynch, Mann, Marks, Marvin, Mayer, Mccullough, Mcdermott, Mckenzie, Miller, Mills, Monahan, Morissette, Mueller, Muller, Nader, Nicolas, Nolan, O'connell, O'conner, O'hara, O'keefe, Olson, O'reilly, Parisian, Parker, Quigley, Reilly, Reynolds, Rice, Ritchie, Rohan, Rolfson, Rowe, Russel, Rutherford, Sanford, Sauer, Schmidt, Schmitt, Schneider, Schroeder, Schultz, Shields, Smitham, Spencer, Stanton, Stark, Stokes, Swift, Tillman, Towne, Tremblay, Tromp, Turcotte, Turner, Walsh, Walter, Ward, Waters, Weber, Welch, West, Wilderman, Wilkinson, Williamson, Windler, Wolf]
company:
suffix: [Pty Ltd, and Sons, Corp, Group, Brothers, Partners]
internet:
domain_suffix: [com.au, com, net.au, net, org.au, org]
address:
state_abbr: [NSW, QLD, NT, SA, WA, TAS, ACT, VIC]
state: [New South Wales, Queensland, Northern Territory, South Australia, Western Australia, Tasmania, Australian Capital Territory, Victoria]
postcode: ['0###', '2###', '3###', '4###', '5###', '6###', '7###']
building_number: ['####', '###', '##']
street_suffix: [Avenue, Boulevard, Circle, Circuit, Court, Crescent, Crest, Drive, Estate Dr, Grove, Hill, Island, Junction, Knoll, Lane, Loop, Mall, Manor, Meadow, Mews, Parade, Parkway, Pass, Place, Plaza, Ridge, Road, Run, Square, Station St, Street, Summit, Terrace, Track, Trail, View Rd, Way]
default_country: [Australia]
phone_number:
formats: ['0# #### ####', '+61 # #### ####', '04## ### ###', '+61 4## ### ###'] #iOS AUS phone formats
team:
sport: ['basketball', 'football', 'footy', 'netball', 'rugby']

@ -0,0 +1,4 @@
en-BORK:
faker:
lorem:
words: [Boot, I, Nu, Nur, Tu, Um, a, becoose-a, boot, bork, burn, chuuses, cumplete-a, cun, cunseqooences, curcoomstunces, dee, deeslikes, denuoonceeng, desures, du, eccuoont, ectooel, edfuntege-a, efueeds, egeeen, ell, ere-a, feend, foolt, frum, geefe-a, gesh, greet, heem, heppeeness, hes, hoo, hoomun, idea, ifer, in, incuoonter, injuy, itselff, ixcept, ixemple-a, ixerceese-a, ixpleeen, ixplurer, ixpuoond, ixtremely, knoo, lebureeuoos, lufes, meestekee, mester-booeelder, moost, mun, nu, nut, oobteeen, oocceseeunelly, ooccoor, ooff, oone-a, oor, peeen, peeenffool, physeecel, pleesoore-a, poorsooe-a, poorsooes, preeesing, prucoore-a, prudooces, reeght, reshunelly, resooltunt, sume-a, teecheengs, teke-a, thees, thet, thuse-a, treefiel, troot, tu, tueel, und, undertekes, unnuyeeng, uny, unyune-a, us, veell, veet, ves, vheech, vhu, yuoo, zee, zeere-a]

@ -0,0 +1,14 @@
en-CA:
faker:
address:
postcode: /[A-CEJ-NPR-TVXY][0-9][A-CEJ-NPR-TV-Z] ?[0-9][A-CEJ-NPR-TV-Z][0-9]/
state: [Alberta, British Columbia, Manitoba, New Brunswick, Newfoundland and Labrador, Nova Scotia, Northwest Territories, Nunavut, Ontario, Prince Edward Island, Quebec, Saskatchewan, Yukon]
state_abbr: ["AB", "BC", "MB", "NB", "NL", "NS", "NU", "NT", "ON", "PE", "QC", "SK", "YT"]
default_country: [Canada]
internet:
free_email: [gmail.com, yahoo.ca, hotmail.com]
domain_suffix: [ca, com, biz, info, name, net, org]
phone_number:
formats: ['###-###-####', '(###)###-####', '###.###.####', '1-###-###-####', '###-###-#### x###', '(###)###-#### x###', '1-###-###-#### x###', '###.###.#### x###', '###-###-#### x####', '(###)###-#### x####', '1-###-###-#### x####', '###.###.#### x####', '###-###-#### x#####', '(###)###-#### x#####', '1-###-###-#### x#####', '###.###.#### x#####']

@ -0,0 +1,13 @@
en-GB:
faker:
address:
postcode: /[A-PR-UWYZ][A-HK-Y]?[0-9][ABEHMNPRVWXY0-9]? [0-9][ABD-HJLN-UW-Z]{2}/
county: [Avon, Bedfordshire, Berkshire, Borders, Buckinghamshire, Cambridgeshire, Central, Cheshire, Cleveland, Clwyd, Cornwall, County Antrim, County Armagh, County Down, County Fermanagh, County Londonderry, County Tyrone, Cumbria, Derbyshire, Devon, Dorset, Dumfries and Galloway, Durham, Dyfed, East Sussex, Essex, Fife, Gloucestershire, Grampian, Greater Manchester, Gwent, Gwynedd County, Hampshire, Herefordshire, Hertfordshire, Highlands and Islands, Humberside, Isle of Wight, Kent, Lancashire, Leicestershire, Lincolnshire, Lothian, Merseyside, Mid Glamorgan, Norfolk, North Yorkshire, Northamptonshire, Northumberland, Nottinghamshire, Oxfordshire, Powys, Rutland, Shropshire, Somerset, South Glamorgan, South Yorkshire, Staffordshire, Strathclyde, Suffolk, Surrey, Tayside, Tyne and Wear, Warwickshire, West Glamorgan, West Midlands, West Sussex, West Yorkshire, Wiltshire, Worcestershire]
uk_country: [England, Scotland, Wales, Northern Ireland]
default_country: [England, Scotland, Wales, Northern Ireland]
internet:
domain_suffix: [co.uk, com, biz, info, name]
phone_number:
formats: ['01#### #####', '01### ######', '01#1 ### ####', '011# ### ####', '02# #### ####', '03## ### ####', '055 #### ####', '056 #### ####', '0800 ### ####', '08## ### ####', '09## ### ####', '016977 ####', '01### #####', '0500 ######', '0800 ######']
cell_phone:
formats: ['074## ######', '075## ######', '076## ######', '077## ######', '078## ######', '079## ######']

@ -0,0 +1,39 @@
# Country => Nepal
# This file is formatted for Nepal.
nep:
faker:
name:
first_name: [
"Aarav", "Ajita", "Amit", "Amita", "Amrit", "Arijit", "Ashmi", "Asmita", "Bibek", "Bijay", "Bikash", "Bina", "Bishal",
"Bishnu", "Buddha", "Deepika", "Dipendra", "Gagan", "Ganesh", "Khem", "Krishna", "Laxmi", "Manisha", "Nabin", "Nikita",
"Niraj", "Nischal", "Padam", "Pooja", "Prabin", "Prakash", "Prashant", "Prem", "Purna", "Rajendra", "Rajina", "Raju",
"Rakesh", "Ranjan", "Ratna", "Sagar", "Sandeep", "Sanjay", "Santosh", "Sarita", "Shilpa", "Shirisha", "Shristi",
"Siddhartha", "Subash", "Sumeet", "Sunita", "Suraj", "Susan", "Sushant"
]
last_name: [
"Adhikari", "Aryal", "Baral", "Basnet", "Bastola", "Basynat", "Bhandari", "Bhattarai", "Chettri", "Devkota", "Dhakal",
"Dongol", "Ghale", "Gurung", "Gyawali", "Hamal", "Jung", "KC", "Kafle", "Karki", "Khadka", "Koirala", "Lama", "Limbu",
"Magar", "Maharjan", "Niroula", "Pandey", "Pradhan", "Rana", "Raut", "Sai", "Shai", "Shakya", "Sherpa", "Shrestha",
"Subedi", "Tamang", "Thapa"
]
address:
postcode: [0000]
state: [
"Baglung", "Banke", "Bara", "Bardiya", "Bhaktapur", "Bhojupu", "Chitwan", "Dailekh", "Dang", "Dhading", "Dhankuta", "Dhanusa", "Dolakha",
"Dolpha", "Gorkha", "Gulmi", "Humla", "Ilam", "Jajarkot", "Jhapa", "Jumla", "Kabhrepalanchok", "Kalikot", "Kapilvastu", "Kaski", "Kathmandu",
"Lalitpur", "Lamjung", "Manang", "Mohottari", "Morang", "Mugu", "Mustang", "Myagdi", "Nawalparasi", "Nuwakot", "Palpa", "Parbat", "Parsa",
"Ramechhap", "Rauswa", "Rautahat", "Rolpa", "Rupandehi", "Sankhuwasabha", "Sarlahi", "Sindhuli", "Sindhupalchok", "Sunsari", "Surket",
"Syangja", "Tanahu", "Terhathum"
]
city: ["Bhaktapur", "Biratnagar", "Birendranagar", "Birgunj", "Butwal", "Damak", "Dharan", "Gaur", "Gorkha", "Hetauda", "Itahari", "Janakpur", "Kathmandu", "Lahan", "Nepalgunj", "Pokhara"]
default_country: ["Nepal"]
internet:
free_email: ['worldlink.com.np', 'gmail.com', 'yahoo.com', 'hotmail.com']
domain_suffix: ['np', 'com', 'info', 'net', 'org']
company:
suffix: ['Pvt Ltd', 'Group', 'Ltd', 'Limited']
phone_number:
formats: ['##-#######', '+977-#-#######', '+977########']

@ -0,0 +1,128 @@
en-UG:
faker:
internet:
domain_suffix: [ug, com, org, co.ug, org.ug, net]
address:
default_country: [Uganda, The Republic of Uganda, UG]
# city names from http://en.wikipedia.org/wiki/List_of_cities_and_towns_in_Uganda
city_names: [
Alebtong, Abim, Adjumani, Amolatar, Amuria, Amuru, Apac, Arua,
Bombo, Budaka, Bugembe, Bugiri, Bukedea, Bulisa, Buikwe, Bundibugyo,
Busembatya, Bushenyi, Busia, Busolwe, Butaleja,Buwenge,
Dokolo,
Entebbe,
Fort Portal,
Gulu,
Hima,Hoima,
Ibanda, Iganga, Isingiro,
Jinja,
Kaabong, Kabale, Kaberamaido, Kabwohe, Kagadi, Kakinga, Kakiri, Kalangala, Kaliro,
Kalisizo, Kalongo, Kalungu, Kampala, Kamuli, Kanoni, Kamwenge, Kanungu, Kapchorwa,
Kasese, Katakwi, Kayunga, Kibaale, Kiboga, Kihiihi, Kiira, Kiruhura, Kiryandongo,
Kisoro, Kitgum, Koboko, Kotido, Kumi, Kyenjojo, Kyotera,
Lira, Lugazi, Lukaya, Luwero, Lwakhakha, Lwengo, Lyantonde,
Malaba, Manafwa, Masaka, Masindi, Masindi Port, Matugga, Mayuge, Mbale,Mbarara,
Mitooma, Mityana, Mpigi, Mpondwe, Moroto, Moyo, Mubende, Mukono, Mutukula,
Nagongera, Nakaseke, Nakasongola, Nakapiripirit, Namutumba, Nansana, Nebbi, Ngora,
Njeru, Nkokonjeru, Ntungamo,
Oyam,
Pader, Paidha, Pakwach, Pallisa,
Rakai, Rukungiri,
Sembabule, Sironko, Soroti,
Tororo,
Wakiso, Wobulenzi,
Yumbe
]
# district names from http://en.wikipedia.org/wiki/Category:Districts_of_Uganda
district_names: [
Abim, Adjumani, Agago, Alebtong, Amolatar, Amudat, Amuria, Amuru, Apac, Arua,
Budaka, Bududa, Bugiri, Buhweju, Buikwe, Bukedea, Bukomansimbi, Bukwo, Bulambuli,
Buliisa, Bundibugyo, Bushenyi, Busia, Butaleja, Butambala, Buvuma, Buyende,
Dokolo,
Gomba, Gulu,
Hoima,
Ibanda, Iganga, Isingiro,
Jinja,
Kaabong, Kabale, Kabarole, Kaberamaido, Kalangala, Kaliro, Kalungu, Kampala, Kamuli,
Kamwenge, Kanungu, Kapchorwa, Kasese, Katakwi, Kayunga, Kibaale, Kiboga, Kibuku,
Kigezi, Kiruhura, Kiryandongo, Kisoro, Kitgum, Koboko, Kole, Kotido, Kumi, Kween,
Kyankwanzi, Kyegegwa, Kyenjojo,
Lamwo, Lira, Luuka, Luweero, Lwengo, Lyantonde,
Manafwa, Maracha, Maracha-Terego, Masaka, Masindi, Mayuge, Mbale, Mbarara, Mitooma,
Mityana, Moroto, Moyo, Mpigi, Mubende, Mukono,
Nakapiripirit, Nakaseke, Nakasongola, Namayingo, Namutumba, Napak, Nebbi, Ngora,
Ntoroko, Ntungamo, Nwoya,
Otuke, Oyam,
Pader, Pallisa,
Rakai, Rubirizi, Rukungiri,
Sembabule, Serere, Sheema, Sironko, Soroti,
Tororo,
Wakiso,
Yumbe,
Zombo
]
regions: [Central, East, North, West]
city:
- "#{city_names}"
district:
- "#{district_names}"
region:
- "#{regions}"
phone_number:
formats:
# carrier mtn landline
- "256 39# ### ###"
- "+256 39# ### ###"
- "039# ### ###"
# carrier utl landline
- "256 41# ### ###"
- "+256 41# ### ###"
- "041# ### ###"
cell_phone:
formats:
# africell
- "+256 79# ### ###"
- "256 79# ### ###"
- "0 79# ### ###"
# airtel
- "+256 70# ### ###"
- "256 70# ### ###"
- "0 70# ### ###"
- "+256 75# ### ###"
- "256 75# ### ###"
- "0 75# ### ###"
# mtn
- "+256 77# ### ###"
- "256 77# ### ###"
- "0 77# ### ###"
- "+256 78# ### ###"
- "256 78# ### ###"
- "0 78# ### ###"
# smart
- "+256 74# ### ###"
- "256 74# ### ###"
- "0 74# ### ###"
# utl
- "+256 71# ### ###"
- "256 71# ### ###"
- "0 71# ### ###"
# vodafone
- "+256 72# ### ###"
- "256 72# ### ###"
- "0 72# ### ###"
name:
last_name: [
Abayisenga, Agaba, Ahebwe, Aisu, Akankunda, Akankwasa, Akashaba, Akashabe, Ampumuza, Ankunda, Asasira, Asiimwe, Atuhe, Atuhire, Atukunda, Atukwase, Atwine, Aurishaba,
Badru, Baguma, Bakabulindi, Bamwiine, Barigye, Bbosa, Bisheko, Biyinzika, Bugala, Bukenya, Buyinza, Bwana, Byanyima, Byaruhanga,
Ddamulira,
Gamwera,
Ijaga, Isyagi,
Kaaya, Kabanda, Kabuubi, Kabuye, Kafeero, Kagambira, Kakooza, Kalumba, Kanshabe, Kansiime, Kanyesigye, Kareiga, Kasekende, Kasumba, Kateregga, Katusiime, Kawooya, Kawuki, Kayemba, Kazibwe, Kibirige, Kiconco, Kiganda, Kijjoba, Kirabira, Kirabo, Kirigwajjo, Kisitu, Kitovu, Kityamuwesi, Kivumbi, Kiwanuka, Kyambadde,
Lunyoro,
Mbabazi, Migisha, Mugisa, Mugisha, Muhwezi, Mukalazi, Mulalira, Munyagwa, Murungi, Mushabe, Musinguzi, Mutabuza, Muyambi, Mwesige, Mwesigye,
Nabasa, Nabimanya, Nankunda, Natukunda, Nayebare, Nimukunda, Ninsiima, Nkoojo, Nkurunungi, Nuwagaba, Nuwamanya, Nyeko,
Obol, Odeke, Okumu, Okumuringa, Opega, Orishaba, Osiki, Ouma,
Rubalema, Rusiimwa, Rwabyoma,
Tamale, Tendo, Tizikara, Tuhame, Tumusiime, Tumwebaze, Tumwesigye, Tumwiine, Turyasingura, Tusiime, Twasiima, Twesigomwe,
Wasswa, Wavamuno, Were
]

@ -0,0 +1,83 @@
en-US:
faker:
internet:
domain_suffix: [com, us, biz, info, name, net, org, io, co]
address:
default_country: [United States, United States of America, USA]
postcode_by_state:
AL: '350##'
AK: '995##'
AS: '967##'
AZ: '850##'
AR: '717##'
CA: '900##'
CO: '800##'
CT: '061##'
DC: '204##'
DE: '198##'
FL: '322##'
GA: '301##'
HI: '967##'
ID: '832##'
IL: '600##'
IN: '463##'
IA: '510##'
KS: '666##'
KY: '404##'
LA: '701##'
ME: '042##'
MD: '210##'
MA: '026##'
MI: '480##'
MN: '555##'
MS: '387##'
MO: '650##'
MT: '590##'
NE: '688##'
NV: '898##'
NH: '036##'
NJ: '076##'
NM: '880##'
NY: '122##'
NC: '288##'
ND: '586##'
OH: '444##'
OK: '730##'
OR: '979##'
PA: '186##'
RI: '029##'
SC: '299##'
SD: '577##'
TN: '383##'
TX: '798##'
UT: '847##'
VT: '050##'
VA: '222##'
WA: '990##'
WV: '247##'
WI: '549##'
WY: '831##'
phone_number:
area_code: ["201", "202", "203", "205", "206", "207", "208", "209", "210", "212", "213", "214", "215", "216", "217", "218", "219", "224", "225", "227", "228", "229", "231", "234", "239", "240", "248", "251", "252", "253", "254", "256", "260", "262", "267", "269", "270", "276", "281", "283", "301", "302", "303", "304", "305", "307", "308", "309", "310", "312", "313", "314", "315", "316", "317", "318", "319", "320", "321", "323", "330", "331", "334", "336", "337", "339", "347", "351", "352", "360", "361", "386", "401", "402", "404", "405", "406", "407", "408", "409", "410", "412", "413", "414", "415", "417", "419", "423", "424", "425", "434", "435", "440", "443", "445", "464", "469", "470", "475", "478", "479", "480", "484", "501", "502", "503", "504", "505", "507", "508", "509", "510", "512", "513", "515", "516", "517", "518", "520", "530", "540", "541", "551", "557", "559", "561", "562", "563", "564", "567", "570", "571", "573", "574", "580", "585", "586", "601", "602", "603", "605", "606", "607", "608", "609", "610", "612", "614", "615", "616", "617", "618", "619", "620", "623", "626", "630", "631", "636", "641", "646", "650", "651", "660", "661", "662", "667", "678", "682", "701", "702", "703", "704", "706", "707", "708", "712", "713", "714", "715", "716", "717", "718", "719", "720", "724", "727", "731", "732", "734", "737", "740", "754", "757", "760", "763", "765", "770", "772", "773", "774", "775", "781", "785", "786", "801", "802", "803", "804", "805", "806", "808", "810", "812", "813", "814", "815", "816", "817", "818", "828", "830", "831", "832", "835", "843", "845", "847", "848", "850", "856", "857", "858", "859", "860", "862", "863", "864", "865", "870", "872", "878", "901", "903", "904", "906", "907", "908", "909", "910", "912", "913", "914", "915", "916", "917", "918", "919", "920", "925", "928", "931", "936", "937", "940", "941", "947", "949", "952", "954", "956", "959", "970", "971", "972", "973", "975", "978", "979", "980", "984", "985", "989"]
exchange_code: ["201", "202", "203", "205", "206", "207", "208", "209", "210", "212", "213", "214", "215", "216", "217", "218", "219", "224", "225", "227", "228", "229", "231", "234", "239", "240", "248", "251", "252", "253", "254", "256", "260", "262", "267", "269", "270", "276", "281", "283", "301", "302", "303", "304", "305", "307", "308", "309", "310", "312", "313", "314", "315", "316", "317", "318", "319", "320", "321", "323", "330", "331", "334", "336", "337", "339", "347", "351", "352", "360", "361", "386", "401", "402", "404", "405", "406", "407", "408", "409", "410", "412", "413", "414", "415", "417", "419", "423", "424", "425", "434", "435", "440", "443", "445", "464", "469", "470", "475", "478", "479", "480", "484", "501", "502", "503", "504", "505", "507", "508", "509", "510", "512", "513", "515", "516", "517", "518", "520", "530", "540", "541", "551", "557", "559", "561", "562", "563", "564", "567", "570", "571", "573", "574", "580", "585", "586", "601", "602", "603", "605", "606", "607", "608", "609", "610", "612", "614", "615", "616", "617", "618", "619", "620", "623", "626", "630", "631", "636", "641", "646", "650", "651", "660", "661", "662", "667", "678", "682", "701", "702", "703", "704", "706", "707", "708", "712", "713", "714", "715", "716", "717", "718", "719", "720", "724", "727", "731", "732", "734", "737", "740", "754", "757", "760", "763", "765", "770", "772", "773", "774", "775", "781", "785", "786", "801", "802", "803", "804", "805", "806", "808", "810", "812", "813", "814", "815", "816", "817", "818", "828", "830", "831", "832", "835", "843", "845", "847", "848", "850", "856", "857", "858", "859", "860", "862", "863", "864", "865", "870", "872", "878", "901", "903", "904", "906", "907", "908", "909", "910", "912", "913", "914", "915", "916", "917", "918", "919", "920", "925", "928", "931", "936", "937", "940", "941", "947", "949", "952", "954", "956", "959", "970", "971", "972", "973", "975", "978", "979", "980", "984", "985", "989"]
formats:
- "#{PhoneNumber.area_code}-#{PhoneNumber.exchange_code}-#{PhoneNumber.subscriber_number}"
- "(#{PhoneNumber.area_code}) #{PhoneNumber.exchange_code}-#{PhoneNumber.subscriber_number}"
- "1-#{PhoneNumber.area_code}-#{PhoneNumber.exchange_code}-#{PhoneNumber.subscriber_number}"
- "#{PhoneNumber.area_code}.#{PhoneNumber.exchange_code}.#{PhoneNumber.subscriber_number}"
- "#{PhoneNumber.area_code}-#{PhoneNumber.exchange_code}-#{PhoneNumber.subscriber_number}"
- "(#{PhoneNumber.area_code}) #{PhoneNumber.exchange_code}-#{PhoneNumber.subscriber_number}"
- "1-#{PhoneNumber.area_code}-#{PhoneNumber.exchange_code}-#{PhoneNumber.subscriber_number}"
- "#{PhoneNumber.area_code}.#{PhoneNumber.exchange_code}.#{PhoneNumber.subscriber_number}"
- "#{PhoneNumber.area_code}-#{PhoneNumber.exchange_code}-#{PhoneNumber.subscriber_number} x#{PhoneNumber.extension}"
- "(#{PhoneNumber.area_code}) #{PhoneNumber.exchange_code}-#{PhoneNumber.subscriber_number} x#{PhoneNumber.extension}"
- "1-#{PhoneNumber.area_code}-#{PhoneNumber.exchange_code}-#{PhoneNumber.subscriber_number} x#{PhoneNumber.extension}"
- "#{PhoneNumber.area_code}.#{PhoneNumber.exchange_code}.#{PhoneNumber.subscriber_number} x#{PhoneNumber.extension}"
- "#{PhoneNumber.area_code}-#{PhoneNumber.exchange_code}-#{PhoneNumber.subscriber_number} x#{PhoneNumber.extension}"
- "(#{PhoneNumber.area_code}) #{PhoneNumber.exchange_code}-#{PhoneNumber.subscriber_number} x#{PhoneNumber.extension}"
- "1-#{PhoneNumber.area_code}-#{PhoneNumber.exchange_code}-#{PhoneNumber.subscriber_number} x#{PhoneNumber.extension}"
- "#{PhoneNumber.area_code}.#{PhoneNumber.exchange_code}.#{PhoneNumber.subscriber_number} x#{PhoneNumber.extension}"
- "#{PhoneNumber.area_code}-#{PhoneNumber.exchange_code}-#{PhoneNumber.subscriber_number} x#{PhoneNumber.extension}"
- "(#{PhoneNumber.area_code}) #{PhoneNumber.exchange_code}-#{PhoneNumber.subscriber_number} x#{PhoneNumber.extension}"
- "1-#{PhoneNumber.area_code}-#{PhoneNumber.exchange_code}-#{PhoneNumber.subscriber_number} x#{PhoneNumber.extension}"
- "#{PhoneNumber.area_code}.#{PhoneNumber.exchange_code}.#{PhoneNumber.subscriber_number} x#{PhoneNumber.extension}"

@ -0,0 +1,31 @@
# Australian Slang, and ocker names for a bit of fun, as well as
# Aussie specific terms and references
# Took the lead of previous contributors of en-au as a baseline
# regular names are top 50 names from 2013
en-au-ocker:
faker:
name:
first_name: [Charlotte, Ava, Chloe, Emily, Olivia, Zoe, Lily, Sophie, Amelia, Sofia, Ella, Isabella, Ruby, Sienna, Mia+3, Grace, Emma, Ivy, Layla, Abigail, Isla, Hannah, Zara, Lucy, Evie, Annabelle, Madison, Alice, Georgia, Maya, Madeline, Audrey, Scarlett, Isabelle, Chelsea, Mila, Holly, Indiana, Poppy, Harper, Sarah, Alyssa, Jasmine, Imogen, Hayley, Pheobe, Eva, Evelyn, Mackenzie, Ayla, Oliver, Jack, Jackson, William, Ethan, Charlie, Lucas, Cooper, Lachlan, Noah, Liam, Alexander, Max, Isaac, Thomas, Xavier, Oscar, Benjamin, Aiden, Mason, Samuel, James, Levi, Riley, Harrison, Ryan, Henry, Jacob, Joshua, Leo, Zach, Harry, Hunter, Flynn, Archie, Tyler, Elijah, Hayden, Jayden, Blake, Archer, Ashton, Sebastian, Zachery, Lincoln, Mitchell, Luca, Nathan, Kai, Connor, Tom, Nigel, Matt, Sean]
last_name: [Smith, Jones, Williams, Brown, Wilson, Taylor, Morton, White, Martin, Anderson, Thompson, Nguyen, Thomas, Walker, Harris, Lee, Ryan, Robinson, Kelly, King, Rausch, Ridge, Connolly, LeQuesne]
ocker_first_name: [Bazza, Bluey, Davo, Johno, Shano, Shazza]
company:
suffix: [Pty Ltd, and Sons, Corp, Group, Brothers, Partners]
internet:
domain_suffix: [com.au, com, net.au, net, org.au, org]
address:
street_root: [Ramsay Street, Bonnie Doon, Cavill Avenue, Queen Street]
street_name:
- "#{street_root}"
city_prefix: [Bondi, Burleigh Heads, Carlton, Fitzroy, Fremantle, Glenelg, Manly, Noosa, Stones Corner, St Kilda, Surry Hills, Yarra Valley]
city:
- "#{city_prefix}"
state_abbr: [NSW, QLD, NT, SA, WA, TAS, ACT, VIC]
region: [South East Queensland, Wide Bay Burnett, Margaret River, Port Pirie, Gippsland, Elizabeth, Barossa]
state: [New South Wales, Queensland, Northern Territory, South Australia, Western Australia, Tasmania, Australian Capital Territory, Victoria]
postcode: ['0###', '2###', '3###', '4###', '5###', '6###', '7###']
building_number: ['####', '###', '##']
street_suffix: [Avenue, Boulevard, Circle, Circuit, Court, Crescent, Crest, Drive, Estate Dr, Grove, Hill, Island, Junction, Knoll, Lane, Loop, Mall, Manor, Meadow, Mews, Parade, Parkway, Pass, Place, Plaza, Ridge, Road, Run, Square, Station St, Street, Summit, Terrace, Track, Trail, View Rd, Way]
default_country: [Australia]
phone_number:
formats: ['0# #### ####', '+61 # #### ####', '04## ### ###', '+61 4## ### ###'] #iOS AUS phone formats

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save