parent
730fd4ab95
commit
30af251bc9
@ -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
|
After Width: | Height: | Size: 24 KiB |
@ -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"
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,9 @@
|
||||
/.bundle/
|
||||
/.yardoc
|
||||
/Gemfile.lock
|
||||
/_yardoc/
|
||||
/coverage/
|
||||
/doc/
|
||||
/pkg/
|
||||
/spec/reports/
|
||||
/tmp/
|
@ -0,0 +1,4 @@
|
||||
language: ruby
|
||||
rvm:
|
||||
- 2.2.2
|
||||
before_install: gem install bundler -v 1.10.6
|
@ -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,3 @@
|
||||
module Alphred
|
||||
VERSION = "1.0.0"
|
||||
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 "&"). 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&There")
|
||||
xml.target! =>
|
||||
<sample escaped="This&That" unescaped="Here&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&There")
|
||||
xml.target! =>
|
||||
<sample escaped="This&That" unescaped="Here&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
|
||||
(<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
|
||||
(<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> </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 => '&', # ampersand
|
||||
60 => '<', # left angle bracket
|
||||
62 => '>', # 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", " ").gsub("\r", " ").
|
||||
gsub(%r{"}, '"') # " 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 & 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 <,
|
||||
# > and & 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,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&R")
|
||||
expect [:start_tag, :one, nil]
|
||||
expect [:text, "H&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&R"/>}, @xml.target!
|
||||
end
|
||||
|
||||
def test_symbol_attributes_are_unescaped_by_default
|
||||
@xml.ref(:id => :"H&R")
|
||||
assert_equal %{<ref id="H&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="<H&R "block">"/>}, @xml.target!
|
||||
end
|
||||
|
||||
def test_mixed_attribute_escaping_with_nested_builders
|
||||
x = Builder::XmlMarkup.new(:target=>@xml)
|
||||
@xml.ref(:id=>:"H&R") {
|
||||
x.element(:tag=>"Long&Short")
|
||||
}
|
||||
assert_equal "<ref id=\"H&R\"><element tag=\"Long&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 Wide Web 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><hi><em>H&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&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<2</title>', @xml.target!
|
||||
end
|
||||
|
||||
def test_element_amp
|
||||
@xml.title('AT&T')
|
||||
assert_equal '<title>AT&T</title>', @xml.target!
|
||||
end
|
||||
|
||||
def test_element_amp2
|
||||
@xml.title('&')
|
||||
assert_equal '<title>&amp;</title>', @xml.target!
|
||||
end
|
||||
|
||||
def test_attr_less
|
||||
@xml.a(:title => '2>1')
|
||||
assert_equal '<a title="2>1"/>', @xml.target!
|
||||
end
|
||||
|
||||
def test_attr_amp
|
||||
@xml.a(:title => 'AT&T')
|
||||
assert_equal '<a title="AT&T"/>', @xml.target!
|
||||
end
|
||||
|
||||
def test_attr_quot
|
||||
@xml.a(:title => '"x"')
|
||||
assert_equal '<a title=""x""/>', @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>’</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>’</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>’</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>’</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 '&', '&'.to_xs # ampersand
|
||||
assert_equal '<', '<'.to_xs # left angle bracket
|
||||
assert_equal '>', '>'.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 'ç', "\xE7".to_xs # small c cedilla
|
||||
assert_equal '©', "\xA9".to_xs # copyright symbol
|
||||
end
|
||||
|
||||
def test_win_1252
|
||||
assert_equal '’', "\x92".to_xs # smart quote
|
||||
assert_equal '€', "\x80".to_xs # euro
|
||||
end
|
||||
|
||||
def test_utf8
|
||||
assert_equal '’', "\xE2\x80\x99".to_xs # right single quote
|
||||
assert_equal '©', "\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&\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,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,3 @@
|
||||
module Faker #:nodoc:
|
||||
VERSION = "1.5.0"
|
||||
end
|
File diff suppressed because one or more lines are too long
@ -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 ### ## ##']
|
File diff suppressed because one or more lines are too long
@ -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## ######']
|
File diff suppressed because one or more lines are too long
@ -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…
Reference in new issue