diff --git a/Gemfile b/Gemfile index 96c32f5..b088ce1 100644 --- a/Gemfile +++ b/Gemfile @@ -1,10 +1,16 @@ -source :gemcutter +source :rubygems -gem 'rake' -gem 'heroku' -gem 'sauce' -gem 'launchy' -gem 'httparty', :path => 'vendor/httparty' +# This group is for vendoring changes for a "release" +group :vendor do + gem 'httparty' +end + +group :development do + gem 'rake' + gem 'heroku' + gem 'sauce' + gem 'launchy' +end group :test do gem 'rspec' diff --git a/Gemfile.deploy b/Gemfile.deploy new file mode 100644 index 0000000..153a310 --- /dev/null +++ b/Gemfile.deploy @@ -0,0 +1,8 @@ +source :rubygems + +# This group is for vendoring changes for a "release" +group :vendor do + gem 'httparty' +end + +# vim: ft=ruby diff --git a/Gemfile.deploy.lock b/Gemfile.deploy.lock new file mode 100644 index 0000000..7c94879 --- /dev/null +++ b/Gemfile.deploy.lock @@ -0,0 +1,14 @@ +GEM + remote: http://rubygems.org/ + specs: + httparty (0.9.0) + multi_json (~> 1.0) + multi_xml + multi_json (1.4.0) + multi_xml (0.5.1) + +PLATFORMS + ruby + +DEPENDENCIES + httparty diff --git a/Rakefile b/Rakefile index f4f2317..0016d29 100644 --- a/Rakefile +++ b/Rakefile @@ -7,3 +7,25 @@ RSpec::Core::RakeTask.new('spec') do |t| end Cucumber::Rake::Task.new('cucumber') + + +BUNDLER_VARS = %w(BUNDLE_GEMFILE RUBYOPT GEM_HOME) + def with_clean_env + begin + bundled_env = ENV.to_hash + BUNDLER_VARS.each{ |var| ENV.delete(var) } + yield + ensure + ENV.replace(bundled_env.to_hash) + end + end + +namespace :gems do + desc 'Vendor the gems in Gemfile.deploy' + task :vendor do + with_clean_env do + sh 'bundle install --deployment --standalone=vendor --gemfile=Gemfile.deploy --path=vendor' + sh 'bundle install --no-deployment' + end + end +end diff --git a/init.rb b/init.rb index 28a188c..db05daf 100644 --- a/init.rb +++ b/init.rb @@ -1 +1,2 @@ +require File.expand_path(File.dirname(__FILE__) + '/vendor/bundler/setup.rb') require 'sauce/heroku/cli' diff --git a/lib/sauce/heroku/cli.rb b/lib/sauce/heroku/cli.rb index 6edffd9..1411739 100644 --- a/lib/sauce/heroku/cli.rb +++ b/lib/sauce/heroku/cli.rb @@ -1,7 +1,8 @@ require 'heroku' require 'heroku/command/base' require 'httparty' -require 'sauce' +require 'json' +#require 'sauce' require 'yaml' module Heroku diff --git a/vendor/bundler/setup.rb b/vendor/bundler/setup.rb new file mode 100644 index 0000000..829184f --- /dev/null +++ b/vendor/bundler/setup.rb @@ -0,0 +1,4 @@ +path = File.expand_path('..', __FILE__) +$:.unshift File.expand_path("#{path}/../ruby/1.9.1/gems/multi_json-1.4.0/lib") +$:.unshift File.expand_path("#{path}/../ruby/1.9.1/gems/multi_xml-0.5.1/lib") +$:.unshift File.expand_path("#{path}/../ruby/1.9.1/gems/httparty-0.9.0/lib") diff --git a/vendor/ruby/1.9.1/bin/httparty b/vendor/ruby/1.9.1/bin/httparty new file mode 100755 index 0000000..7c671f5 --- /dev/null +++ b/vendor/ruby/1.9.1/bin/httparty @@ -0,0 +1,19 @@ +#!/usr/bin/env ruby +# +# This file was generated by RubyGems. +# +# The application 'httparty' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require 'rubygems' + +version = ">= 0" + +if ARGV.first =~ /^_(.*)_$/ and Gem::Version.correct? $1 then + version = $1 + ARGV.shift +end + +gem 'httparty', version +load Gem.bin_path('httparty', 'httparty', version) diff --git a/vendor/ruby/1.9.1/cache/httparty-0.9.0.gem b/vendor/ruby/1.9.1/cache/httparty-0.9.0.gem new file mode 100644 index 0000000..62f851d Binary files /dev/null and b/vendor/ruby/1.9.1/cache/httparty-0.9.0.gem differ diff --git a/vendor/ruby/1.9.1/cache/multi_json-1.4.0.gem b/vendor/ruby/1.9.1/cache/multi_json-1.4.0.gem new file mode 100644 index 0000000..b5709ff Binary files /dev/null and b/vendor/ruby/1.9.1/cache/multi_json-1.4.0.gem differ diff --git a/vendor/ruby/1.9.1/cache/multi_xml-0.5.1.gem b/vendor/ruby/1.9.1/cache/multi_xml-0.5.1.gem new file mode 100644 index 0000000..27d7aa8 Binary files /dev/null and b/vendor/ruby/1.9.1/cache/multi_xml-0.5.1.gem differ diff --git a/vendor/ruby/1.9.1/gems/httparty-0.9.0/.gitignore b/vendor/ruby/1.9.1/gems/httparty-0.9.0/.gitignore new file mode 100644 index 0000000..24953a8 --- /dev/null +++ b/vendor/ruby/1.9.1/gems/httparty-0.9.0/.gitignore @@ -0,0 +1,10 @@ +Gemfile.lock +.DS_Store +.yardoc/ +doc/ +tmp/ +log/ +pkg/ +*.swp +/.bundle +.rvmrc diff --git a/vendor/ruby/1.9.1/gems/httparty-0.9.0/.travis.yml b/vendor/ruby/1.9.1/gems/httparty-0.9.0/.travis.yml new file mode 100644 index 0000000..5d2b2c2 --- /dev/null +++ b/vendor/ruby/1.9.1/gems/httparty-0.9.0/.travis.yml @@ -0,0 +1,8 @@ +language: ruby +rvm: + - 1.8.7 + - ree + - 1.9.3 +notifications: + email: false +bundler_args: --without development diff --git a/vendor/ruby/1.9.1/gems/httparty-0.9.0/Gemfile b/vendor/ruby/1.9.1/gems/httparty-0.9.0/Gemfile new file mode 100644 index 0000000..0918e93 --- /dev/null +++ b/vendor/ruby/1.9.1/gems/httparty-0.9.0/Gemfile @@ -0,0 +1,15 @@ +source :rubygems +gemspec + +gem 'rake' +gem 'cucumber', '~> 0.7' +gem 'fakeweb', '~> 1.2' +gem 'rspec', '~> 1.3' +gem 'mongrel', '1.2.0.pre2' +gem 'multi_json', '~> 1.3' + +group :development do + gem 'guard' + gem 'guard-rspec' + gem 'guard-bundler' +end diff --git a/vendor/ruby/1.9.1/gems/httparty-0.9.0/Guardfile b/vendor/ruby/1.9.1/gems/httparty-0.9.0/Guardfile new file mode 100644 index 0000000..fdb6013 --- /dev/null +++ b/vendor/ruby/1.9.1/gems/httparty-0.9.0/Guardfile @@ -0,0 +1,16 @@ +rspec_options = { + :version => 1, + :all_after_pass => false, + :all_on_start => false, +} + +guard 'rspec', rspec_options do + watch(%r{^spec/.+_spec\.rb$}) + watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" } + watch('spec/spec_helper.rb') { "spec" } +end + +guard 'bundler' do + watch('Gemfile') + watch(/^.+\.gemspec/) +end diff --git a/vendor/ruby/1.9.1/gems/httparty-0.9.0/History b/vendor/ruby/1.9.1/gems/httparty-0.9.0/History new file mode 100644 index 0000000..09c2049 --- /dev/null +++ b/vendor/ruby/1.9.1/gems/httparty-0.9.0/History @@ -0,0 +1,293 @@ +== 0.9.0 2012-09-07 +* new + * [support for connection adapters](https://github.com/jnunemaker/httparty/pull/157) + * [allow ssl_version on ruby 1.9](https://github.com/jnunemaker/httparty/pull/159) + +* bug fixes + * [don't treat port 4430 as ssl](https://github.com/jnunemaker/httparty/commit/a296b1c97f83d7dcc6ef85720a43664c265685ac) + * [deep clone default options](https://github.com/jnunemaker/httparty/commit/f74227d30f9389b4b23a888c9af49fb9b8248e1f) + * a few net digest auth fixes + +== 0.8.3 2012-04-21 +* new + * [lazy parsing of responses](https://github.com/jnunemaker/httparty/commit/9fd5259c8dab00e426082b66af44ede2c9068f45) + * [add support for PATCH requests](https://github.com/jnunemaker/httparty/commit/7ab6641e37a9e31517e46f6124f38c615395d38a) +* bug fixes + * [subclasses no longer override superclass options](https://github.com/jnunemaker/httparty/commit/682af8fbf672e7b3009e650da776c85cdfe78d39) + +== 0.8.2 2012-04-12 +* new + * add -r to make CLI return failure code if status >= 400 + * allow blank username from CLI +* bug fixes + * return nil for null body + * automatically deflate responses with a Content-Encoding: x-gzip header + * Do not HEAD on POST request with digest authentication + * add support for proxy authentication + * fix posting data with CLI + * require rexml/document if xml format from CLI + * support for fragmented responses + +== 0.8.1 2011-10-05 +* bug fixes + * content-encoding header should be removed when automatically inflating the body + +== 0.8.0 2011-09-13 +* new + * switch to multi json/xml for parsing by default +* bug fixes + * fix redirects to relative uri's + +== 0.7.8 2011-06-06 +* bug fix + * Make response honor respond to + * net http timeout can also be a float + +== 0.7.7 2011-04-16 +* bug fix + * Fix NoMethodError when using the NON_RAILS_QUERY_STRING_NORMALIZER with a hash whose key is a symbol and value is nil + +== 0.7.5 2011-04-16 +* bug fix + * caused issue with latest rubygems + +== 0.7.4 2011-02-13 +* bug fixes + * Set VERIFY_NONE when using https. Ruby 1.9.2 no longer sets this for us. gh-67 + +== 0.7.3 2011-01-20 +* bug fixes + * Fix digest auth for unspecified quality of protection (bjoernalbers, mtrudel, dwo) + +== 0.7.2 2011-01-20 +* bug fixes + * Fix gem dependencies + +== 0.7.1 2011-01-19 +* bug fixes + * Fix uninitialized constant HTTParty::Response::Net in 1.9.2 (cap10morgan) + * Other fixes for 1.9.2, full suite still fails (cap10morgan) + +== 0.7.0 2011-01-18 +* minor enhancements + * Added query methods for HTTP status codes, i.e. response.success? + response.created? (thanks citizenparker) + * Added support for ssl_ca_file and ssl_ca_path (dlitz) + * Allow custom query string normalization. gh-8 + * Unlock private keys with password (freerange) + * Added high level request documentation (phildarnowsky) + * Added basic post example (pbuckley) + * Response object has access to its corresponding request object + * Added example of siginin into tripit.com + * Added option to follow redirects (rkj). gh-56 +* bug fixes + * Fixed superclass mismatch exception while running tests + (thanks dlitz http://github.com/dlitz/httparty/commit/48224f0615b32133afcff4718ad426df7a4b401b) + +== 0.6.1 2010-07-07 +* minor enhancements + * updated to crack 0.1.8 +* bug fixes + * subclasses always merge into the parent's default_options and + default_cookies (l4rk). + * subclasses play nicely with grand parents. gh-49 + +== 0.6.0 2010-06-13 +* major enhancements + * Digest Auth (bartiaco, sbecker, gilles, and aaronrussell) + * Maintain HTTP method across redirects (bartiaco and sbecker) + * HTTParty::Response#response returns the Net::HTTPResponse object + * HTTParty::Response#headers returns a HTTParty::Response::Headers object + which quacks like a Hash + Net::HTTPHeader. The #headers method continues + to be backwards-compatible with the old Hash return value but may become + deprecated in the future. + +* minor enhancements + * Update crack requirement to version 0.1.7 + You may still get a warning because Crack's version constant is out of date + * Timeout option can be set for all requests using HTTParty.default_timeout (taazza) + * Closed #38 "headers hash should downcase keys so canonical header name can be used" + * Closed #40 "Gzip response" wherein gziped and deflated responses are + automatically inflated. (carsonmcdonald) + +== 0.5.2 2010-01-31 +* minor enhancements + * Update crack requirement to version 0.1.6 + +== 0.5.1 2010-01-30 +* bug fixes + * Handle 304 response correctly by returning the HTTParty::Response object instead of redirecting (seth and hellvinz) + * Only redirect 300 responses if the header contains a Location + * Don't append empty query strings to the uri. Closes #31 + * When no_follow is enabled, only raise the RedirectionTooDeep exception when a response tries redirecting. Closes #28 + +* major enhancements + * Removed rubygems dependency. I suggest adding rubygems to RUBYOPT if this causes problems for you. + $ export RUBYOPT='rubygems' + * HTTParty#debug_output prints debugging information for the current request (iwarshak) + * HTTParty#no_follow now available as a class-level option. Sets whether or not to follow redirects. + +* minor enhancements + * HTTParty::VERSION now available + * Update crack requirement to version 0.1.5 + +== 0.5.0 2009-12-07 +* bug fixes + * inheritable attributes no longer mutable by subclasses (yyyc514) + * namespace BasicObject within HTTParty to avoid class name collisions (eric) + +* major enhancements + * Custom Parsers via class or proc + * Deprecation warning on HTTParty::AllowedFormats + moved to HTTParty::Parser::SupportedFormats + +* minor enhancements + * Curl inspired output when using the binary in verbose mode (alexvollmer) + * raise UnsupportedURIScheme when scheme is not HTTP or HTTPS (djspinmonkey) + * Allow SSL for ports other than 443 when scheme is HTTPS (stefankroes) + * Accept PEM certificates via HTTParty#pem (chrislo) + * Support HEAD and OPTION verbs (grempe) + * Verify SSL certificates when providing a PEM file (collectiveidea/danielmorrison) + +== 0.4.5 2009-09-12 +* bug fixes + * Fixed class-level headers overwritten by cookie management code. Closes #19 + * Fixed "superclass mismatch for class BlankSlate" error. Closes #20 + * Fixed reading files as post data from the command line (vesan) + +* minor enhancements + * Timeout option added; will raise a Timeout::Error after the timeout has elapsed (attack). Closes #17 + HTTParty.get "http://github.com", :timeout => 1 + * Building gem with Jeweler + +== 0.4.4 2009-07-19 +* 2 minor update + * :query no longer sets form data. Use body and set content type to application/x-www-form-urlencoded if you need it. :query was wrong for that. + * Fixed a bug in the cookies class method that caused cookies to be forgotten after the first request. + * Also, some general cleanup of tests and such. + +== 0.4.3 2009-04-23 +* 1 minor update + * added message to the response object + +== 0.4.2 2009-03-30 +* 2 minor changes + * response code now returns an integer instead of a string (jqr) + * rubyforge project setup for crack so i'm now depending on that instead of jnunemaker-crack + +== 0.4.1 2009-03-29 +* 1 minor fix + * gem 'jnunemaker-crack' instead of gem 'crack' + +== 0.4.0 2009-03-29 +* 1 minor change + * Switched xml and json parsing to crack (same code as before just moved to gem for easier reuse in other projects) + +== 0.3.1 2009-02-10 +* 1 minor fix, 1 minor enhancement + * Fixed unescaping umlauts (siebertm) + * Added yaml response parsing (Miha Filej) + +== 0.3.0 2009-01-31 +* 1 major enhancement, 1 bug fix + * JSON gem no longer a requirement. It was conflicting with rails json stuff so I just stole ActiveSupport's json decoding and bundled it with HTTParty. + * Fixed bug where query strings were being duplicated on redirects + * Added a bunch of specs and moved some code around. + +== 0.2.10 2009-01-29 +* 1 minor enhancement + * Made encoding on query parameters treat everything except URI::PATTERN::UNRESERVED as UNSAFE to force encoding of '+' character (Julian Russell) + +== 0.2.9 2009-01-29 +* 3 minor enhancements + * Added a 'headers' accessor to the response with a hash of any HTTP headers. (Don Peterson) + * Add support for a ":cookies" option to be used at the class level, or as an option on any individual call. It should be passed a hash, which will be converted to the proper format and added to the request headers when the call is made. (Don Peterson) + * Refactored several specs and added a full suite of cucumber features (Don Peterson) + +== 0.2.8 2009-01-28 +* 1 major fix + * fixed major bug with response where it wouldn't iterate or really work at all with parsed responses + +== 0.2.7 2009-01-28 +* 2 minor fixes, 2 minor enhancements, 2 major enhancements + * fixed undefined method add_node for nil class error that occasionally happened (juliocesar) + * Handle nil or unexpected values better when typecasting. (Brian Landau) + * More robust handling of mime types (Alex Vollmer) + * Fixed support for specifying headers and added support for basic auth to CLI. (Alex Vollmer) + * Added first class response object that includes original body and status code (Alex Vollmer) + * Now parsing all response types as some non-200 responses provide important information, this means no more exception raising (Alex Vollmer) + +== 0.2.6 2009-01-05 +* 1 minor bug fix + * added explicit require of time as Time#parse failed outside of rails (willcodeforfoo) + +== 0.2.5 2009-01-05 +* 1 major enhancement + * Add command line interface to HTTParty (Alex Vollmer) + +== 0.2.4 2008-12-23 +* 1 bug fix + * Fixed that mimetype detection was failing if no mimetype was returned from service (skippy) +== 0.2.3 2008-12-23 +* 1 bug fix + * Fixed typecasting class variable naming issue + +== 0.2.2 2008-12-08 +* 1 bug fix + * Added the missing core extension hash method to_xml_attributes + +== 0.2.1 2008-12-08 +* 1 bug fix + * Fixed that HTTParty was borking ActiveSupport and as such Rails (thanks to Rob Sanheim) + +== 0.2.0 2008-12-07 +* 1 major enhancement + * Removed ActiveSupport as a dependency. Now requires json gem for json deserialization and uses an included class to do the xml parsing. + +== 0.1.8 2008-11-30 +* 3 major enhancements + * Moved base_uri normalization into request class and out of httparty module, fixing + the problem where base_uri was not always being normalized. + * Stupid simple support for HTTParty.get/post/put/delete. (jqr) + * Switched gem management to Echoe from newgem. + +== 0.1.7 2008-11-30 +* 1 major enhancement + * fixed multiple class definitions overriding each others options + +== 0.1.6 2008-11-26 +* 1 major enhancement + * now passing :query to set_form_data if post request to avoid content length errors + +== 0.1.5 2008-11-14 +* 2 major enhancements + * Refactored send request method out into its own object. + * Added :html format if you just want to do that. + +== 0.1.4 2008-11-08 +* 3 major enhancements: + * Removed some cruft + * Added ability to follow redirects automatically and turn that off (Alex Vollmer) + +== 0.1.3 2008-08-22 + +* 3 major enhancements: + * Added http_proxy key for setting proxy server and port (francxk@gmail.com) + * Now raises exception when http error occurs (francxk@gmail.com) + * Changed auto format detection from file extension to response content type (Jay Pignata) + +== 0.1.2 2008-08-09 + +* 1 major enhancement: + * default_params were not being appended to query string if option[:query] was blank + +== 0.1.1 2008-07-30 + +* 2 major enhancement: + * Added :basic_auth key for options when making a request + * :query and :body both now work with query string or hash + +== 0.1.0 2008-07-27 + +* 1 major enhancement: + * Initial release diff --git a/vendor/ruby/1.9.1/gems/httparty-0.9.0/MIT-LICENSE b/vendor/ruby/1.9.1/gems/httparty-0.9.0/MIT-LICENSE new file mode 100644 index 0000000..ea4d340 --- /dev/null +++ b/vendor/ruby/1.9.1/gems/httparty-0.9.0/MIT-LICENSE @@ -0,0 +1,20 @@ +Copyright (c) 2008 John Nunemaker + +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. \ No newline at end of file diff --git a/vendor/ruby/1.9.1/gems/httparty-0.9.0/README.md b/vendor/ruby/1.9.1/gems/httparty-0.9.0/README.md new file mode 100644 index 0000000..3a0fb71 --- /dev/null +++ b/vendor/ruby/1.9.1/gems/httparty-0.9.0/README.md @@ -0,0 +1,79 @@ +# httparty + +Makes http fun again! + +## Install + +``` +gem install httparty +``` + +## Requirements + +* multi_json and multi_xml +* You like to party! + +## Examples + +```ruby +# Use the class methods to get down to business quickly +response = HTTParty.get('http://twitter.com/statuses/public_timeline.json') +puts response.body, response.code, response.message, response.headers.inspect + +response.each do |item| + puts item['user']['screen_name'] +end + +# Or wrap things up in your own class +class Twitter + include HTTParty + base_uri 'twitter.com' + + def initialize(u, p) + @auth = {:username => u, :password => p} + end + + # which can be :friends, :user or :public + # options[:query] can be things like since, since_id, count, etc. + def timeline(which=:friends, options={}) + options.merge!({:basic_auth => @auth}) + self.class.get("/statuses/#{which}_timeline.json", options) + end + + def post(text) + options = { :body => {:status => text}, :basic_auth => @auth } + self.class.post('/statuses/update.json', options) + end +end + +twitter = Twitter.new(config['email'], config['password']) +pp twitter.timeline +``` + +See the [examples directory](http://github.com/jnunemaker/httparty/tree/master/examples) for even more goodies. + +## Command Line Interface + +httparty also includes the executable `httparty` which can be +used to query web services and examine the resulting output. By default +it will output the response as a pretty-printed Ruby object (useful for +grokking the structure of output). This can also be overridden to output +formatted XML or JSON. Execute `httparty --help` for all the +options. Below is an example of how easy it is. + +``` +httparty "http://twitter.com/statuses/public_timeline.json" +``` + +## Help and Docs + +* https://groups.google.com/forum/#!forum/httparty-gem +* http://rdoc.info/projects/jnunemaker/httparty + +## Contributing + +* Fork the project. +* Make your feature addition or bug fix. +* Add tests for it. This is important so I don't break it in a future version unintentionally. +* Commit, do not mess with rakefile, version, or history. (if you want to have your own version, that is fine but bump version in a commit by itself in another branch so I can ignore when I pull) +* Send me a pull request. Bonus points for topic branches. diff --git a/vendor/ruby/1.9.1/gems/httparty-0.9.0/Rakefile b/vendor/ruby/1.9.1/gems/httparty-0.9.0/Rakefile new file mode 100644 index 0000000..1cf504b --- /dev/null +++ b/vendor/ruby/1.9.1/gems/httparty-0.9.0/Rakefile @@ -0,0 +1,15 @@ +require 'bundler' +Bundler::GemHelper.install_tasks + +require 'spec/rake/spectask' +Spec::Rake::SpecTask.new(:spec) do |spec| + spec.ruby_opts << '-rubygems' + spec.libs << 'lib' << 'spec' + spec.spec_files = FileList['spec/**/*_spec.rb'] + spec.spec_opts = ['--options', 'spec/spec.opts'] +end + +require 'cucumber/rake/task' +Cucumber::Rake::Task.new(:features) + +task :default => [:spec, :features] \ No newline at end of file diff --git a/vendor/ruby/1.9.1/gems/httparty-0.9.0/bin/httparty b/vendor/ruby/1.9.1/gems/httparty-0.9.0/bin/httparty new file mode 100755 index 0000000..dbbfd0a --- /dev/null +++ b/vendor/ruby/1.9.1/gems/httparty-0.9.0/bin/httparty @@ -0,0 +1,114 @@ +#!/usr/bin/env ruby + +require "optparse" +require "pp" + +$:.unshift(File.join(File.dirname(__FILE__), "/../lib")) +require "httparty" + +opts = { + :action => :get, + :headers => {}, + :verbose => false +} + +OptionParser.new do |o| + o.banner = "USAGE: #{$0} [options] [url]" + + o.on("-f", + "--format [FORMAT]", + "Output format to use instead of pretty-print ruby: " + + "plain, json or xml") do |f| + opts[:output_format] = f.downcase.to_sym + end + + o.on("-a", + "--action [ACTION]", + "HTTP action: get (default), post, put, delete, head, or options") do |a| + opts[:action] = a.downcase.to_sym + end + + o.on("-d", + "--data [BODY]", + "Data to put in request body (prefix with '@' for file)") do |d| + if d =~ /^@/ + opts[:body] = open(d[1..-1]).read + else + opts[:body] = d + end + end + + o.on("-H", "--header [NAME:VALUE]", "Additional HTTP headers in NAME:VALUE form") do |h| + abort "Invalid header specification, should be Name:Value" unless h =~ /.+:.+/ + name, value = h.split(':') + opts[:headers][name.strip] = value.strip + end + + o.on("-v", "--verbose", "If set, print verbose output") do |v| + opts[:verbose] = true + end + + o.on("-u", "--user [CREDS]", "Use basic authentication. Value should be user:password") do |u| + abort "Invalid credentials format. Must be user:password" unless u =~ /.*:.+/ + user, password = u.split(':') + opts[:basic_auth] = { :username => user, :password => password } + end + + o.on("-r", "--response-code", "Command fails if response code >= 400") do + opts[:response_code] = true + end + + o.on("-h", "--help", "Show help documentation") do |h| + puts o + exit + end +end.parse! + + +if ARGV.empty? + STDERR.puts "You need to provide a URL" + STDERR.puts "USAGE: #{$0} [options] [url]" +end + +def dump_headers(response) + resp_type = Net::HTTPResponse::CODE_TO_OBJ[response.code.to_s] + puts "#{response.code} #{resp_type.to_s.sub(/^Net::HTTP/, '')}" + response.headers.each do |n,v| + puts "#{n}: #{v}" + end + puts +end + +if opts[:verbose] + puts "#{opts[:action].to_s.upcase} #{ARGV.first}" + opts[:headers].each do |n,v| + puts "#{n}: #{v}" + end + puts +end + +response = HTTParty.send(opts[:action], ARGV.first, opts) +if opts[:output_format].nil? + dump_headers(response) if opts[:verbose] + pp response +else + print_format = opts[:output_format] + dump_headers(response) if opts[:verbose] + + case opts[:output_format] + when :json + begin + require 'json' + puts JSON.pretty_generate(response.delegate) + rescue LoadError + puts YAML.dump(response.delegate) + end + when :xml + require 'rexml/document' + REXML::Document.new(response.body).write(STDOUT, 2) + puts + else + puts response + end +end +exit false if opts[:response_code] && response.code >= 400 diff --git a/vendor/ruby/1.9.1/gems/httparty-0.9.0/cucumber.yml b/vendor/ruby/1.9.1/gems/httparty-0.9.0/cucumber.yml new file mode 100644 index 0000000..80df8ac --- /dev/null +++ b/vendor/ruby/1.9.1/gems/httparty-0.9.0/cucumber.yml @@ -0,0 +1 @@ +default: features --format progress diff --git a/vendor/ruby/1.9.1/gems/httparty-0.9.0/examples/aaws.rb b/vendor/ruby/1.9.1/gems/httparty-0.9.0/examples/aaws.rb new file mode 100644 index 0000000..a1f4fb2 --- /dev/null +++ b/vendor/ruby/1.9.1/gems/httparty-0.9.0/examples/aaws.rb @@ -0,0 +1,32 @@ +require 'rubygems' +require 'active_support' + +dir = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib')) +require File.join(dir, 'httparty') +require 'pp' +config = YAML::load(File.read(File.join(ENV['HOME'], '.aaws'))) + +module AAWS + class Book + include HTTParty + base_uri 'http://ecs.amazonaws.com' + default_params :Service => 'AWSECommerceService', :Operation => 'ItemSearch', :SearchIndex => 'Books' + + def initialize(key) + self.class.default_params :AWSAccessKeyId => key + end + + def search(options={}) + raise ArgumentError, 'You must search for something' if options[:query].blank? + + # amazon uses nasty camelized query params + options[:query] = options[:query].inject({}) { |h, q| h[q[0].to_s.camelize] = q[1]; h } + + # make a request and return the items (NOTE: this doesn't handle errors at this point) + self.class.get('/onca/xml', options)['ItemSearchResponse']['Items'] + end + end +end + +aaws = AAWS::Book.new(config[:access_key]) +pp aaws.search(:query => {:title => 'Ruby On Rails'}) diff --git a/vendor/ruby/1.9.1/gems/httparty-0.9.0/examples/basic.rb b/vendor/ruby/1.9.1/gems/httparty-0.9.0/examples/basic.rb new file mode 100644 index 0000000..d813795 --- /dev/null +++ b/vendor/ruby/1.9.1/gems/httparty-0.9.0/examples/basic.rb @@ -0,0 +1,32 @@ +dir = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib')) +require File.join(dir, 'httparty') +require 'pp' + +# You can also use post, put, delete, head, options in the same fashion +response = HTTParty.get('http://twitter.com/statuses/public_timeline.json') +puts response.body, response.code, response.message, response.headers.inspect + +response.each do |item| + puts item['user']['screen_name'] +end + +# An example post to a minimal rails app in the development environment +# Note that "skip_before_filter :verify_authenticity_token" must be set in the +# "pears" controller for this example + +class Partay + include HTTParty + base_uri 'http://localhost:3000' +end + +options = { + :body => { + :pear => { # your resource + :foo => '123', # your columns/data + :bar => 'second', + :baz => 'last thing' + } + } +} + +pp Partay.post('/pears.xml', options) diff --git a/vendor/ruby/1.9.1/gems/httparty-0.9.0/examples/crack.rb b/vendor/ruby/1.9.1/gems/httparty-0.9.0/examples/crack.rb new file mode 100644 index 0000000..63a2aaf --- /dev/null +++ b/vendor/ruby/1.9.1/gems/httparty-0.9.0/examples/crack.rb @@ -0,0 +1,19 @@ +require 'rubygems' +require 'crack' + +dir = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib')) +require File.join(dir, 'httparty') +require 'pp' + +class Rep + include HTTParty + + parser( + Proc.new do |body, format| + Crack::XML.parse(body) + end + ) +end + +pp Rep.get('http://whoismyrepresentative.com/whoismyrep.php?zip=46544') +pp Rep.get('http://whoismyrepresentative.com/whoismyrep.php', :query => {:zip => 46544}) diff --git a/vendor/ruby/1.9.1/gems/httparty-0.9.0/examples/custom_parsers.rb b/vendor/ruby/1.9.1/gems/httparty-0.9.0/examples/custom_parsers.rb new file mode 100644 index 0000000..3a91813 --- /dev/null +++ b/vendor/ruby/1.9.1/gems/httparty-0.9.0/examples/custom_parsers.rb @@ -0,0 +1,67 @@ +class ParseAtom + include HTTParty + + # Support Atom along with the default parsers: xml, json, yaml, etc. + class Parser::Atom < HTTParty::Parser + SupportedFormats.merge!({"application/atom+xml" => :atom}) + + protected + + # perform atom parsing on body + def atom + body.to_atom + end + end + + parser Parser::Atom +end + + +class OnlyParseAtom + include HTTParty + + # Only support Atom + class Parser::OnlyAtom < HTTParty::Parser + SupportedFormats = {"application/atom+xml" => :atom} + + protected + + # perform atom parsing on body + def atom + body.to_atom + end + end + + parser Parser::OnlyAtom +end + + +class SkipParsing + include HTTParty + + # Parse the response body however you like + class Parser::Simple < HTTParty::Parser + def parse + body + end + end + + parser Parser::Simple +end + + +class AdHocParsing + include HTTParty + parser( + Proc.new do |body, format| + case format + when :json + body.to_json + when :xml + body.to_xml + else + body + end + end + ) +end diff --git a/vendor/ruby/1.9.1/gems/httparty-0.9.0/examples/delicious.rb b/vendor/ruby/1.9.1/gems/httparty-0.9.0/examples/delicious.rb new file mode 100644 index 0000000..e6d6243 --- /dev/null +++ b/vendor/ruby/1.9.1/gems/httparty-0.9.0/examples/delicious.rb @@ -0,0 +1,37 @@ +dir = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib')) +require File.join(dir, 'httparty') +require 'pp' +config = YAML::load(File.read(File.join(ENV['HOME'], '.delicious'))) + +class Delicious + include HTTParty + base_uri 'https://api.del.icio.us/v1' + + def initialize(u, p) + @auth = {:username => u, :password => p} + end + + # query params that filter the posts are: + # tag (optional). Filter by this tag. + # dt (optional). Filter by this date (CCYY-MM-DDThh:mm:ssZ). + # url (optional). Filter by this url. + # ie: posts(:query => {:tag => 'ruby'}) + def posts(options={}) + options.merge!({:basic_auth => @auth}) + self.class.get('/posts/get', options) + end + + # query params that filter the posts are: + # tag (optional). Filter by this tag. + # count (optional). Number of items to retrieve (Default:15, Maximum:100). + def recent(options={}) + options.merge!({:basic_auth => @auth}) + self.class.get('/posts/recent', options) + end +end + +delicious = Delicious.new(config['username'], config['password']) +pp delicious.posts(:query => {:tag => 'ruby'}) +pp delicious.recent + +delicious.recent['posts']['post'].each { |post| puts post['href'] } \ No newline at end of file diff --git a/vendor/ruby/1.9.1/gems/httparty-0.9.0/examples/google.rb b/vendor/ruby/1.9.1/gems/httparty-0.9.0/examples/google.rb new file mode 100644 index 0000000..f629b4d --- /dev/null +++ b/vendor/ruby/1.9.1/gems/httparty-0.9.0/examples/google.rb @@ -0,0 +1,16 @@ +dir = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib')) +require File.join(dir, 'httparty') +require 'pp' + +class Google + include HTTParty + format :html +end + +# google.com redirects to www.google.com so this is live test for redirection +pp Google.get('http://google.com') + +puts '', '*'*70, '' + +# check that ssl is requesting right +pp Google.get('https://www.google.com') \ No newline at end of file diff --git a/vendor/ruby/1.9.1/gems/httparty-0.9.0/examples/headers_and_user_agents.rb b/vendor/ruby/1.9.1/gems/httparty-0.9.0/examples/headers_and_user_agents.rb new file mode 100644 index 0000000..8e55aff --- /dev/null +++ b/vendor/ruby/1.9.1/gems/httparty-0.9.0/examples/headers_and_user_agents.rb @@ -0,0 +1,6 @@ +# To send custom user agents to identify your application to a web service (or mask as a specific browser for testing), send "User-Agent" as a hash to headers as shown below. + +require 'httparty' + +APPLICATION_NAME = "Httparty" +response = HTTParty.get('http://example.com', :headers => {"User-Agent" => APPLICATION_NAME}) diff --git a/vendor/ruby/1.9.1/gems/httparty-0.9.0/examples/nokogiri_html_parser.rb b/vendor/ruby/1.9.1/gems/httparty-0.9.0/examples/nokogiri_html_parser.rb new file mode 100644 index 0000000..b45a2b8 --- /dev/null +++ b/vendor/ruby/1.9.1/gems/httparty-0.9.0/examples/nokogiri_html_parser.rb @@ -0,0 +1,22 @@ +require 'rubygems' +require 'nokogiri' + + +dir = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib')) +require File.join(dir, 'httparty') +require 'pp' + +class HtmlParserIncluded < HTTParty::Parser + SupportedFormats.merge!('text/html' => :html) + + def html + Nokogiri::HTML(body) + end +end + +class Page + include HTTParty + parser HtmlParserIncluded +end + +pp Page.get('http://www.google.com') diff --git a/vendor/ruby/1.9.1/gems/httparty-0.9.0/examples/rubyurl.rb b/vendor/ruby/1.9.1/gems/httparty-0.9.0/examples/rubyurl.rb new file mode 100644 index 0000000..65808fb --- /dev/null +++ b/vendor/ruby/1.9.1/gems/httparty-0.9.0/examples/rubyurl.rb @@ -0,0 +1,14 @@ +dir = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib')) +require File.join(dir, 'httparty') +require 'pp' + +class Rubyurl + include HTTParty + base_uri 'rubyurl.com' + + def self.shorten( website_url ) + post( '/api/links.json', :query => { :link => { :website_url => website_url } } ) + end +end + +pp Rubyurl.shorten( 'http://istwitterdown.com/') \ No newline at end of file diff --git a/vendor/ruby/1.9.1/gems/httparty-0.9.0/examples/tripit_sign_in.rb b/vendor/ruby/1.9.1/gems/httparty-0.9.0/examples/tripit_sign_in.rb new file mode 100644 index 0000000..f06617d --- /dev/null +++ b/vendor/ruby/1.9.1/gems/httparty-0.9.0/examples/tripit_sign_in.rb @@ -0,0 +1,33 @@ +dir = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib')) +require File.join(dir, 'httparty') + +class TripIt + include HTTParty + base_uri 'http://www.tripit.com' + debug_output + + def initialize(email, password) + @email = email + response = self.class.get('/account/login') + response = self.class.post( + '/account/login', + :body => { + :login_email_address => email, + :login_password => password + }, + :headers => {'Cookie' => response.headers['Set-Cookie']} + ) + @cookie = response.request.options[:headers]['Cookie'] + end + + def account_settings + self.class.get('/account/edit', :headers => {'Cookie' => @cookie}) + end + + def logged_in? + account_settings.include? "You're logged in as #{@email}" + end +end + +tripit = TripIt.new('email', 'password') +puts "Logged in: #{tripit.logged_in?}" diff --git a/vendor/ruby/1.9.1/gems/httparty-0.9.0/examples/twitter.rb b/vendor/ruby/1.9.1/gems/httparty-0.9.0/examples/twitter.rb new file mode 100644 index 0000000..c7794fa --- /dev/null +++ b/vendor/ruby/1.9.1/gems/httparty-0.9.0/examples/twitter.rb @@ -0,0 +1,31 @@ +dir = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib')) +require File.join(dir, 'httparty') +require 'pp' +config = YAML::load(File.read(File.join(ENV['HOME'], '.twitter'))) + +class Twitter + include HTTParty + base_uri 'twitter.com' + + def initialize(u, p) + @auth = {:username => u, :password => p} + end + + # which can be :friends, :user or :public + # options[:query] can be things like since, since_id, count, etc. + def timeline(which=:friends, options={}) + options.merge!({:basic_auth => @auth}) + self.class.get("/statuses/#{which}_timeline.json", options) + end + + def post(text) + options = { :query => {:status => text}, :basic_auth => @auth } + self.class.post('/statuses/update.json', options) + end +end + +twitter = Twitter.new(config['email'], config['password']) +pp twitter.timeline +# pp twitter.timeline(:friends, :query => {:since_id => 868482746}) +# pp twitter.timeline(:friends, :query => 'since_id=868482746') +# pp twitter.post('this is a test of 0.2.0') \ No newline at end of file diff --git a/vendor/ruby/1.9.1/gems/httparty-0.9.0/examples/whoismyrep.rb b/vendor/ruby/1.9.1/gems/httparty-0.9.0/examples/whoismyrep.rb new file mode 100644 index 0000000..b59473c --- /dev/null +++ b/vendor/ruby/1.9.1/gems/httparty-0.9.0/examples/whoismyrep.rb @@ -0,0 +1,10 @@ +dir = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib')) +require File.join(dir, 'httparty') +require 'pp' + +class Rep + include HTTParty +end + +pp Rep.get('http://whoismyrepresentative.com/whoismyrep.php?zip=46544') +pp Rep.get('http://whoismyrepresentative.com/whoismyrep.php', :query => {:zip => 46544}) \ No newline at end of file diff --git a/vendor/ruby/1.9.1/gems/httparty-0.9.0/features/basic_authentication.feature b/vendor/ruby/1.9.1/gems/httparty-0.9.0/features/basic_authentication.feature new file mode 100644 index 0000000..b467237 --- /dev/null +++ b/vendor/ruby/1.9.1/gems/httparty-0.9.0/features/basic_authentication.feature @@ -0,0 +1,20 @@ +Feature: Basic Authentication + + As a developer + I want to be able to use a service that requires Basic Authentication + Because that is not an uncommon requirement + + Scenario: Passing no credentials to a page requiring Basic Authentication + Given a restricted page at '/basic_auth.html' + When I call HTTParty#get with '/basic_auth.html' + Then it should return a response with a 401 response code + + Scenario: Passing proper credentials to a page requiring Basic Authentication + Given a remote service that returns 'Authenticated Page' + And that service is accessed at the path '/basic_auth.html' + And that service is protected by Basic Authentication + And that service requires the username 'jcash' with the password 'maninblack' + When I call HTTParty#get with '/basic_auth.html' and a basic_auth hash: + | username | password | + | jcash | maninblack | + Then the return value should match 'Authenticated Page' diff --git a/vendor/ruby/1.9.1/gems/httparty-0.9.0/features/command_line.feature b/vendor/ruby/1.9.1/gems/httparty-0.9.0/features/command_line.feature new file mode 100644 index 0000000..951e236 --- /dev/null +++ b/vendor/ruby/1.9.1/gems/httparty-0.9.0/features/command_line.feature @@ -0,0 +1,7 @@ +Feature: Command Line + + As a developer + I want to be able to harness the power of HTTParty from the command line + Because that would make quick testing and debugging easy + And 'easy' is my middle name + And I'm kidding it's actually 'Danger'! diff --git a/vendor/ruby/1.9.1/gems/httparty-0.9.0/features/deals_with_http_error_codes.feature b/vendor/ruby/1.9.1/gems/httparty-0.9.0/features/deals_with_http_error_codes.feature new file mode 100644 index 0000000..bd6dd85 --- /dev/null +++ b/vendor/ruby/1.9.1/gems/httparty-0.9.0/features/deals_with_http_error_codes.feature @@ -0,0 +1,26 @@ +Feature: Deals with HTTP error codes + + As a developer + I want to be informed of non-successful responses + Because sometimes thing explode + And I should probably know what happened + + Scenario: A response of '404 - Not Found' + Given a remote service that returns a 404 status code + And that service is accessed at the path '/404_service.html' + When I call HTTParty#get with '/404_service.html' + Then it should return a response with a 404 response code + + Scenario: A response of '500 - Internal Server Error' + Given a remote service that returns a 500 status code + And that service is accessed at the path '/500_service.html' + When I call HTTParty#get with '/500_service.html' + Then it should return a response with a 500 response code + + Scenario: A non-successful response where I need the body + Given a remote service that returns a 400 status code + And the response from the service has a body of 'Bad response' + And that service is accessed at the path '/400_service.html' + When I call HTTParty#get with '/400_service.html' + Then it should return a response with a 400 response code + And the return value should match 'Bad response' diff --git a/vendor/ruby/1.9.1/gems/httparty-0.9.0/features/digest_authentication.feature b/vendor/ruby/1.9.1/gems/httparty-0.9.0/features/digest_authentication.feature new file mode 100644 index 0000000..456a0a7 --- /dev/null +++ b/vendor/ruby/1.9.1/gems/httparty-0.9.0/features/digest_authentication.feature @@ -0,0 +1,20 @@ +Feature: Digest Authentication + + As a developer + I want to be able to use a service that requires Digest Authentication + Because that is not an uncommon requirement + + Scenario: Passing no credentials to a page requiring Digest Authentication + Given a restricted page at '/digest_auth.html' + When I call HTTParty#get with '/digest_auth.html' + Then it should return a response with a 401 response code + + Scenario: Passing proper credentials to a page requiring Digest Authentication + Given a remote service that returns 'Digest Authenticated Page' + And that service is accessed at the path '/digest_auth.html' + And that service is protected by Digest Authentication + And that service requires the username 'jcash' with the password 'maninblack' + When I call HTTParty#get with '/digest_auth.html' and a digest_auth hash: + | username | password | + | jcash | maninblack | + Then the return value should match 'Digest Authenticated Page' diff --git a/vendor/ruby/1.9.1/gems/httparty-0.9.0/features/handles_compressed_responses.feature b/vendor/ruby/1.9.1/gems/httparty-0.9.0/features/handles_compressed_responses.feature new file mode 100644 index 0000000..b20bba2 --- /dev/null +++ b/vendor/ruby/1.9.1/gems/httparty-0.9.0/features/handles_compressed_responses.feature @@ -0,0 +1,19 @@ +Feature: Handles Compressed Responses + + In order to save bandwidth + As a developer + I want to uncompress compressed responses + + Scenario: Supports deflate encoding + Given a remote deflate service + And the response from the service has a body of '

Some HTML

' + And that service is accessed at the path '/deflate_service.html' + When I call HTTParty#get with '/deflate_service.html' + Then the return value should match '

Some HTML

' + + Scenario: Supports gzip encoding + Given a remote gzip service + And the response from the service has a body of '

Some HTML

' + And that service is accessed at the path '/gzip_service.html' + When I call HTTParty#get with '/gzip_service.html' + Then the return value should match '

Some HTML

' diff --git a/vendor/ruby/1.9.1/gems/httparty-0.9.0/features/handles_multiple_formats.feature b/vendor/ruby/1.9.1/gems/httparty-0.9.0/features/handles_multiple_formats.feature new file mode 100644 index 0000000..438a6ba --- /dev/null +++ b/vendor/ruby/1.9.1/gems/httparty-0.9.0/features/handles_multiple_formats.feature @@ -0,0 +1,34 @@ +Feature: Handles Multiple Formats + + As a developer + I want to be able to consume remote services of many different formats + And I want those formats to be automatically detected and handled + Because web services take many forms + And I don't want to have to do any extra work + + Scenario: An HTML service + Given a remote service that returns '

Some HTML

' + And that service is accessed at the path '/html_service.html' + And the response from the service has a Content-Type of 'text/html' + When I call HTTParty#get with '/html_service.html' + Then it should return a String + And the return value should match '

Some HTML

' + + Scenario: A JSON service + Given a remote service that returns '{ "jennings": "waylon", "cash": "johnny" }' + And that service is accessed at the path '/service.json' + And the response from the service has a Content-Type of 'application/json' + When I call HTTParty#get with '/service.json' + Then it should return a Hash equaling: + | key | value | + | jennings | waylon | + | cash | johnny | + + Scenario: An XML Service + Given a remote service that returns 'waylon jennings' + And that service is accessed at the path '/service.xml' + And the response from the service has a Content-Type of 'text/xml' + When I call HTTParty#get with '/service.xml' + Then it should return a Hash equaling: + | key | value | + | singer | waylon jennings | diff --git a/vendor/ruby/1.9.1/gems/httparty-0.9.0/features/steps/env.rb b/vendor/ruby/1.9.1/gems/httparty-0.9.0/features/steps/env.rb new file mode 100644 index 0000000..8bf4bb3 --- /dev/null +++ b/vendor/ruby/1.9.1/gems/httparty-0.9.0/features/steps/env.rb @@ -0,0 +1,22 @@ +require 'mongrel' +require './lib/httparty' +require 'spec/expectations' + +Before do + def new_port + server = TCPServer.new('0.0.0.0', nil) + port = server.addr[1] + ensure + server.close + end + + port = ENV["HTTPARTY_PORT"] || new_port + @host_and_port = "0.0.0.0:#{port}" + @server = Mongrel::HttpServer.new("0.0.0.0", port) + @server.run + @request_options = {} +end + +After do + @server.stop +end diff --git a/vendor/ruby/1.9.1/gems/httparty-0.9.0/features/steps/httparty_response_steps.rb b/vendor/ruby/1.9.1/gems/httparty-0.9.0/features/steps/httparty_response_steps.rb new file mode 100644 index 0000000..bf535da --- /dev/null +++ b/vendor/ruby/1.9.1/gems/httparty-0.9.0/features/steps/httparty_response_steps.rb @@ -0,0 +1,26 @@ +Then /it should return an? (\w+)$/ do |class_string| + @response_from_httparty.should be_an_instance_of(class_string.class) +end + +Then /the return value should match '(.*)'/ do |expected_text| + @response_from_httparty.should eql(expected_text) +end + +Then /it should return a Hash equaling:/ do |hash_table| + @response_from_httparty.should be_an_instance_of(Hash) + @response_from_httparty.keys.length.should eql(hash_table.rows.length) + hash_table.hashes.each do |pair| + key, value = pair["key"], pair["value"] + @response_from_httparty.keys.should include(key) + @response_from_httparty[key].should eql(value) + end +end + +Then /it should return a response with a (\d+) response code/ do |code| + @response_from_httparty.code.should eql(code.to_i) +end + +Then /it should raise (?:an|a) ([\w:]+) exception/ do |exception| + @exception_from_httparty.should_not be_nil + @exception_from_httparty.class.name.should eql(exception) +end diff --git a/vendor/ruby/1.9.1/gems/httparty-0.9.0/features/steps/httparty_steps.rb b/vendor/ruby/1.9.1/gems/httparty-0.9.0/features/steps/httparty_steps.rb new file mode 100644 index 0000000..b9bd268 --- /dev/null +++ b/vendor/ruby/1.9.1/gems/httparty-0.9.0/features/steps/httparty_steps.rb @@ -0,0 +1,27 @@ +When /^I set my HTTParty timeout option to (\d+)$/ do |timeout| + @request_options[:timeout] = timeout.to_i +end + +When /I call HTTParty#get with '(.*)'$/ do |url| + begin + @response_from_httparty = HTTParty.get("http://#{@host_and_port}#{url}", @request_options) + rescue HTTParty::RedirectionTooDeep, Timeout::Error => e + @exception_from_httparty = e + end +end + +When /I call HTTParty#get with '(.*)' and a basic_auth hash:/ do |url, auth_table| + h = auth_table.hashes.first + @response_from_httparty = HTTParty.get( + "http://#{@host_and_port}#{url}", + :basic_auth => { :username => h["username"], :password => h["password"] } + ) +end + +When /I call HTTParty#get with '(.*)' and a digest_auth hash:/ do |url, auth_table| + h = auth_table.hashes.first + @response_from_httparty = HTTParty.get( + "http://#{@host_and_port}#{url}", + :digest_auth => { :username => h["username"], :password => h["password"] } + ) +end \ No newline at end of file diff --git a/vendor/ruby/1.9.1/gems/httparty-0.9.0/features/steps/mongrel_helper.rb b/vendor/ruby/1.9.1/gems/httparty-0.9.0/features/steps/mongrel_helper.rb new file mode 100644 index 0000000..8841c8e --- /dev/null +++ b/vendor/ruby/1.9.1/gems/httparty-0.9.0/features/steps/mongrel_helper.rb @@ -0,0 +1,94 @@ +require 'base64' +class BasicMongrelHandler < Mongrel::HttpHandler + attr_accessor :content_type, :custom_headers, :response_body, :response_code, :preprocessor, :username, :password + + def initialize + @content_type = "text/html" + @response_body = "" + @response_code = 200 + @custom_headers = {} + end + + def process(request, response) + instance_eval &preprocessor if preprocessor + reply_with(response, response_code, response_body) + end + + def reply_with(response, code, response_body) + response.start(code) do |head, body| + head["Content-Type"] = content_type + custom_headers.each { |k,v| head[k] = v } + body.write(response_body) + end + end +end + +class DeflateHandler < BasicMongrelHandler + def process(request, response) + response.start do |head, body| + head['Content-Encoding'] = 'deflate' + body.write Zlib::Deflate.deflate(response_body) + end + end +end + +class GzipHandler < BasicMongrelHandler + def process(request, response) + response.start do |head, body| + head['Content-Encoding'] = 'gzip' + body.write gzip(response_body) + end + end + + protected + + def gzip(string) + sio = StringIO.new('', 'r+') + gz = Zlib::GzipWriter.new sio + gz.write string + gz.finish + sio.rewind + sio.read + end +end + +module BasicAuthentication + def self.extended(base) + base.custom_headers["WWW-Authenticate"] = 'Basic Realm="Super Secret Page"' + end + + def process(request, response) + if authorized?(request) + super + else + reply_with(response, 401, "Incorrect. You have 20 seconds to comply.") + end + end + + def authorized?(request) + request.params["HTTP_AUTHORIZATION"] == "Basic " + Base64.encode64("#{@username}:#{@password}").strip + end +end + +module DigestAuthentication + def self.extended(base) + base.custom_headers["WWW-Authenticate"] = 'Digest realm="testrealm@host.com",qop="auth,auth-int",nonce="nonce",opaque="opaque"' + end + + def process(request, response) + if authorized?(request) + super + else + reply_with(response, 401, "Incorrect. You have 20 seconds to comply.") + end + end + + def authorized?(request) + request.params["HTTP_AUTHORIZATION"] =~ /Digest.*uri=/ + end +end + +def new_mongrel_redirector(target_url, relative_path = false) + target_url = "http://#{@host_and_port}#{target_url}" unless relative_path + Mongrel::RedirectHandler.new(target_url) +end diff --git a/vendor/ruby/1.9.1/gems/httparty-0.9.0/features/steps/remote_service_steps.rb b/vendor/ruby/1.9.1/gems/httparty-0.9.0/features/steps/remote_service_steps.rb new file mode 100644 index 0000000..da0aee2 --- /dev/null +++ b/vendor/ruby/1.9.1/gems/httparty-0.9.0/features/steps/remote_service_steps.rb @@ -0,0 +1,69 @@ +Given /a remote service that returns '(.*)'/ do |response_body| + @handler = BasicMongrelHandler.new + Given "the response from the service has a body of '#{response_body}'" +end + +Given /a remote service that returns a (\d+) status code/ do |code| + @handler = BasicMongrelHandler.new + @handler.response_code = code +end + +Given /that service is accessed at the path '(.*)'/ do |path| + @server.register(path, @handler) +end + +Given /^that service takes (\d+) seconds to generate a response$/ do |time| + @server_response_time = time.to_i + @handler.preprocessor = Proc.new { sleep time.to_i } +end + +Given /^a remote deflate service$/ do + @handler = DeflateHandler.new +end + +Given /^a remote gzip service$/ do + @handler = GzipHandler.new +end + +Given /the response from the service has a Content-Type of '(.*)'/ do |content_type| + @handler.content_type = content_type +end + +Given /the response from the service has a body of '(.*)'/ do |response_body| + @handler.response_body = response_body +end + +Given /the url '(.*)' redirects to '(.*)'/ do |redirection_url, target_url| + @server.register redirection_url, new_mongrel_redirector(target_url) +end + +Given /that service is protected by Basic Authentication/ do + @handler.extend BasicAuthentication +end + +Given /that service is protected by Digest Authentication/ do + @handler.extend DigestAuthentication +end + +Given /that service requires the username '(.*)' with the password '(.*)'/ do |username, password| + @handler.username = username + @handler.password = password +end + +Given /a restricted page at '(.*)'/ do |url| + Given "a remote service that returns 'A response I will never see'" + And "that service is accessed at the path '#{url}'" + And "that service is protected by Basic Authentication" + And "that service requires the username 'something' with the password 'secret'" +end + +# This joins the server thread, and halts cucumber, so you can actually hit the +# server with a browser. Runs until you kill it with Ctrl-c +Given /I want to hit this in a browser/ do + @server.acceptor.join +end + +Then /I wait for the server to recover/ do + timeout = @request_options[:timeout] || 0 + sleep @server_response_time - timeout +end diff --git a/vendor/ruby/1.9.1/gems/httparty-0.9.0/features/supports_redirection.feature b/vendor/ruby/1.9.1/gems/httparty-0.9.0/features/supports_redirection.feature new file mode 100644 index 0000000..debc7b8 --- /dev/null +++ b/vendor/ruby/1.9.1/gems/httparty-0.9.0/features/supports_redirection.feature @@ -0,0 +1,22 @@ +Feature: Supports Redirection + + As a developer + I want to work with services that may redirect me + And I want it to follow a reasonable number of redirects + Because sometimes web services do that + + Scenario: A service that redirects once + Given a remote service that returns 'Service Response' + And that service is accessed at the path '/landing_service.html' + And the url '/redirector.html' redirects to '/landing_service.html' + When I call HTTParty#get with '/redirector.html' + Then the return value should match 'Service Response' + + # TODO: Look in to why this actually fails... + Scenario: A service that redirects to a relative URL + + Scenario: A service that redirects infinitely + Given the url '/first.html' redirects to '/second.html' + And the url '/second.html' redirects to '/first.html' + When I call HTTParty#get with '/first.html' + Then it should raise an HTTParty::RedirectionTooDeep exception diff --git a/vendor/ruby/1.9.1/gems/httparty-0.9.0/features/supports_timeout_option.feature b/vendor/ruby/1.9.1/gems/httparty-0.9.0/features/supports_timeout_option.feature new file mode 100644 index 0000000..db56463 --- /dev/null +++ b/vendor/ruby/1.9.1/gems/httparty-0.9.0/features/supports_timeout_option.feature @@ -0,0 +1,13 @@ +Feature: Supports the timeout option + In order to handle inappropriately slow response times + As a developer + I want my request to raise an exception after my specified timeout as elapsed + + Scenario: A long running response + Given a remote service that returns '

Some HTML

' + And that service is accessed at the path '/long_running_service.html' + And that service takes 2 seconds to generate a response + When I set my HTTParty timeout option to 1 + And I call HTTParty#get with '/long_running_service.html' + Then it should raise a Timeout::Error exception + And I wait for the server to recover diff --git a/vendor/ruby/1.9.1/gems/httparty-0.9.0/httparty.gemspec b/vendor/ruby/1.9.1/gems/httparty-0.9.0/httparty.gemspec new file mode 100644 index 0000000..d9fe866 --- /dev/null +++ b/vendor/ruby/1.9.1/gems/httparty-0.9.0/httparty.gemspec @@ -0,0 +1,24 @@ +# -*- encoding: utf-8 -*- +$:.push File.expand_path("../lib", __FILE__) +require "httparty/version" + +Gem::Specification.new do |s| + s.name = "httparty" + s.version = HTTParty::VERSION + s.platform = Gem::Platform::RUBY + s.authors = ["John Nunemaker", "Sandro Turriate"] + s.email = ["nunemaker@gmail.com"] + s.homepage = "http://jnunemaker.github.com/httparty" + s.summary = %q{Makes http fun! Also, makes consuming restful web services dead easy.} + s.description = %q{Makes http fun! Also, makes consuming restful web services dead easy.} + + s.add_dependency 'multi_json', "~> 1.0" + s.add_dependency 'multi_xml' + + s.post_install_message = "When you HTTParty, you must party hard!" + + s.files = `git ls-files`.split("\n") + s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n") + s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) } + s.require_paths = ["lib"] +end diff --git a/vendor/ruby/1.9.1/gems/httparty-0.9.0/lib/httparty.rb b/vendor/ruby/1.9.1/gems/httparty-0.9.0/lib/httparty.rb new file mode 100644 index 0000000..9885e58 --- /dev/null +++ b/vendor/ruby/1.9.1/gems/httparty-0.9.0/lib/httparty.rb @@ -0,0 +1,503 @@ +require 'pathname' +require 'net/http' +require 'net/https' +require 'uri' +require 'zlib' +require 'multi_xml' +require 'multi_json' + +require 'httparty/module_inheritable_attributes' +require 'httparty/cookie_hash' +require 'httparty/net_digest_auth' +require 'httparty/version' +require 'httparty/connection_adapter' + +# @see HTTParty::ClassMethods +module HTTParty + module AllowedFormatsDeprecation + def const_missing(const) + if const.to_s =~ /AllowedFormats$/ + Kernel.warn("Deprecated: Use HTTParty::Parser::SupportedFormats") + HTTParty::Parser::SupportedFormats + else + super + end + end + end + + extend AllowedFormatsDeprecation + + def self.included(base) + base.extend ClassMethods + base.send :include, HTTParty::ModuleInheritableAttributes + base.send(:mattr_inheritable, :default_options) + base.send(:mattr_inheritable, :default_cookies) + base.instance_variable_set("@default_options", {}) + base.instance_variable_set("@default_cookies", CookieHash.new) + end + + # == Common Request Options + # Request methods (get, post, patch, put, delete, head, options) all take a common set of options. These are: + # + # [:+body+:] Body of the request. If passed a Hash, will try to normalize it first, by default passing it to ActiveSupport::to_params. Any other kind of object will get used as-is. + # [:+http_proxyaddr+:] Address of proxy server to use. + # [:+http_proxyport+:] Port of proxy server to use. + # [:+http_proxyuser+:] User for proxy server authentication. + # [:+http_proxypass+:] Password for proxy server authentication. + # [:+limit+:] Maximum number of redirects to follow. Takes precedences over :+no_follow+. + # [:+query+:] Query string, or a Hash representing it. Normalized according to the same rules as :+body+. If you specify this on a POST, you must use a Hash. See also HTTParty::ClassMethods.default_params. + # [:+timeout+:] Timeout for opening connection and reading data. + # + # There are also another set of options with names corresponding to various class methods. The methods in question are those that let you set a class-wide default, and the options override the defaults on a request-by-request basis. Those options are: + # * :+base_uri+: see HTTParty::ClassMethods.base_uri. + # * :+basic_auth+: see HTTParty::ClassMethods.basic_auth. Only one of :+basic_auth+ and :+digest_auth+ can be used at a time; if you try using both, you'll get an ArgumentError. + # * :+debug_output+: see HTTParty::ClassMethods.debug_output. + # * :+digest_auth+: see HTTParty::ClassMethods.digest_auth. Only one of :+basic_auth+ and :+digest_auth+ can be used at a time; if you try using both, you'll get an ArgumentError. + # * :+format+: see HTTParty::ClassMethods.format. + # * :+headers+: see HTTParty::ClassMethods.headers. Must be a Hash. + # * :+maintain_method_across_redirects+: see HTTParty::ClassMethods.maintain_method_across_redirects. + # * :+no_follow+: see HTTParty::ClassMethods.no_follow. + # * :+parser+: see HTTParty::ClassMethods.parser. + # * :+connection_adapter+: see HTTParty::ClassMethods.connection_adapter. + # * :+pem+: see HTTParty::ClassMethods.pem. + # * :+query_string_normalizer+: see HTTParty::ClassMethods.query_string_normalizer + # * :+ssl_ca_file+: see HTTParty::ClassMethods.ssl_ca_file. + # * :+ssl_ca_path+: see HTTParty::ClassMethods.ssl_ca_path. + + module ClassMethods + + extend AllowedFormatsDeprecation + + # Allows setting http proxy information to be used + # + # class Foo + # include HTTParty + # http_proxy 'http://foo.com', 80, 'user', 'pass' + # end + def http_proxy(addr=nil, port=nil, user=nil, pass=nil) + default_options[:http_proxyaddr] = addr + default_options[:http_proxyport] = port + default_options[:http_proxyuser] = user + default_options[:http_proxypass] = pass + end + + # Allows setting a base uri to be used for each request. + # Will normalize uri to include http, etc. + # + # class Foo + # include HTTParty + # base_uri 'twitter.com' + # end + def base_uri(uri=nil) + return default_options[:base_uri] unless uri + default_options[:base_uri] = HTTParty.normalize_base_uri(uri) + end + + # Allows setting basic authentication username and password. + # + # class Foo + # include HTTParty + # basic_auth 'username', 'password' + # end + def basic_auth(u, p) + default_options[:basic_auth] = {:username => u, :password => p} + end + + # Allows setting digest authentication username and password. + # + # class Foo + # include HTTParty + # digest_auth 'username', 'password' + # end + def digest_auth(u, p) + default_options[:digest_auth] = {:username => u, :password => p} + end + + # Do not send rails style query strings. + # Specically, don't use bracket notation when sending an array + # + # For a query: + # get '/', :query => {:selected_ids => [1,2,3]} + # + # The default query string looks like this: + # /?selected_ids[]=1&selected_ids[]=2&selected_ids[]=3 + # + # Call `disable_rails_query_string_format` to transform the query string + # into: + # /?selected_ids=1&selected_ids=2&selected_ids=3 + # + # @example + # class Foo + # include HTTParty + # disable_rails_query_string_format + # end + def disable_rails_query_string_format + query_string_normalizer Request::NON_RAILS_QUERY_STRING_NORMALIZER + end + + # Allows setting default parameters to be appended to each request. + # Great for api keys and such. + # + # class Foo + # include HTTParty + # default_params :api_key => 'secret', :another => 'foo' + # end + def default_params(h={}) + raise ArgumentError, 'Default params must be a hash' unless h.is_a?(Hash) + default_options[:default_params] ||= {} + default_options[:default_params].merge!(h) + end + + # Allows setting a default timeout for all HTTP calls + # Timeout is specified in seconds. + # + # class Foo + # include HTTParty + # default_timeout 10 + # end + def default_timeout(t) + raise ArgumentError, 'Timeout must be an integer or float' unless t && (t.is_a?(Integer) || t.is_a?(Float)) + default_options[:timeout] = t + end + + # Set an output stream for debugging, defaults to $stderr. + # The output stream is passed on to Net::HTTP#set_debug_output. + # + # class Foo + # include HTTParty + # debug_output $stderr + # end + def debug_output(stream = $stderr) + default_options[:debug_output] = stream + end + + # Allows setting HTTP headers to be used for each request. + # + # class Foo + # include HTTParty + # headers 'Accept' => 'text/html' + # end + def headers(h={}) + raise ArgumentError, 'Headers must be a hash' unless h.is_a?(Hash) + default_options[:headers] ||= {} + default_options[:headers].merge!(h) + end + + def cookies(h={}) + raise ArgumentError, 'Cookies must be a hash' unless h.is_a?(Hash) + default_cookies.add_cookies(h) + end + + # Proceed to the location header when an HTTP response dictates a redirect. + # Redirects are always followed by default. + # + # @example + # class Foo + # include HTTParty + # base_uri 'http://google.com' + # follow_redirects true + # end + def follow_redirects(value = true) + default_options[:follow_redirects] = value + end + + # Allows setting the format with which to parse. + # Must be one of the allowed formats ie: json, xml + # + # class Foo + # include HTTParty + # format :json + # end + def format(f = nil) + if f.nil? + default_options[:format] + else + parser(Parser) if parser.nil? + default_options[:format] = f + validate_format + end + end + + # Declare whether or not to follow redirects. When true, an + # {HTTParty::RedirectionTooDeep} error will raise upon encountering a + # redirect. You can then gain access to the response object via + # HTTParty::RedirectionTooDeep#response. + # + # @see HTTParty::ResponseError#response + # + # @example + # class Foo + # include HTTParty + # base_uri 'http://google.com' + # no_follow true + # end + # + # begin + # Foo.get('/') + # rescue HTTParty::RedirectionTooDeep => e + # puts e.response.body + # end + def no_follow(value = false) + default_options[:no_follow] = value + end + + # Declare that you wish to maintain the chosen HTTP method across redirects. + # The default behavior is to follow redirects via the GET method. + # If you wish to maintain the original method, you can set this option to true. + # + # @example + # class Foo + # include HTTParty + # base_uri 'http://google.com' + # maintain_method_across_redirects true + # end + + def maintain_method_across_redirects(value = true) + default_options[:maintain_method_across_redirects] = value + end + + # Allows setting a PEM file to be used + # + # class Foo + # include HTTParty + # pem File.read('/home/user/my.pem'), "optional password" + # end + def pem(pem_contents, password=nil) + default_options[:pem] = pem_contents + default_options[:pem_password] = password + end + + # Override the way query strings are normalized. + # Helpful for overriding the default rails normalization of Array queries. + # + # For a query: + # get '/', :query => {:selected_ids => [1,2,3]} + # + # The default query string normalizer returns: + # /?selected_ids[]=1&selected_ids[]=2&selected_ids[]=3 + # + # Let's change it to this: + # /?selected_ids=1&selected_ids=2&selected_ids=3 + # + # Pass a Proc to the query normalizer which accepts the yielded query. + # + # @example Modifying Array query strings + # class ServiceWrapper + # include HTTParty + # + # query_string_normalizer proc { |query| + # query.map do |key, value| + # value.map {|v| "#{key}=#{v}"} + # end.join('&') + # } + # end + # + # @param [Proc] normalizer custom query string normalizer. + # @yield [Hash, String] query string + # @yieldreturn [Array] an array that will later be joined with '&' + def query_string_normalizer(normalizer) + default_options[:query_string_normalizer] = normalizer + end + + # Allows setting of SSL version to use. This only works in Ruby 1.9. + # You can get a list of valid versions from OpenSSL::SSL::SSLContext::METHODS. + # + # class Foo + # include HTTParty + # ssl_version :SSLv3 + # end + def ssl_version(version) + default_options[:ssl_version] = version + end + + # Allows setting an OpenSSL certificate authority file + # + # class Foo + # include HTTParty + # ssl_ca_file '/etc/ssl/certs/ca-certificates.crt' + # end + def ssl_ca_file(path) + default_options[:ssl_ca_file] = path + end + + # Allows setting an OpenSSL certificate authority path (directory) + # + # class Foo + # include HTTParty + # ssl_ca_path '/etc/ssl/certs/' + # end + def ssl_ca_path(path) + default_options[:ssl_ca_path] = path + end + + # Allows setting a custom parser for the response. + # + # class Foo + # include HTTParty + # parser Proc.new {|data| ...} + # end + def parser(custom_parser = nil) + if custom_parser.nil? + default_options[:parser] + else + default_options[:parser] = custom_parser + validate_format + end + end + + # Allows setting a custom connection_adapter for the http connections + # + # @example + # class Foo + # include HTTParty + # connection_adapter Proc.new {|uri, options| ... } + # end + # + # @example provide optional configuration for your connection_adapter + # class Foo + # include HTTParty + # connection_adapter Proc.new {|uri, options| ... }, {:foo => :bar} + # end + # + # @see HTTParty::ConnectionAdapter + def connection_adapter(custom_adapter = nil, options = nil) + if custom_adapter.nil? + default_options[:connection_adapter] + else + default_options[:connection_adapter] = custom_adapter + default_options[:connection_adapter_options] = options + end + end + + # Allows making a get request to a url. + # + # class Foo + # include HTTParty + # end + # + # # Simple get with full url + # Foo.get('http://foo.com/resource.json') + # + # # Simple get with full url and query parameters + # # ie: http://foo.com/resource.json?limit=10 + # Foo.get('http://foo.com/resource.json', :query => {:limit => 10}) + def get(path, options={}, &block) + perform_request Net::HTTP::Get, path, options, &block + end + + # Allows making a post request to a url. + # + # class Foo + # include HTTParty + # end + # + # # Simple post with full url and setting the body + # Foo.post('http://foo.com/resources', :body => {:bar => 'baz'}) + # + # # Simple post with full url using :query option, + # # which gets set as form data on the request. + # Foo.post('http://foo.com/resources', :query => {:bar => 'baz'}) + def post(path, options={}, &block) + perform_request Net::HTTP::Post, path, options, &block + end + + # Perform a PATCH request to a path + def patch(path, options={}, &block) + perform_request Net::HTTP::Patch, path, options, &block + end + + # Perform a PUT request to a path + def put(path, options={}, &block) + perform_request Net::HTTP::Put, path, options, &block + end + + # Perform a DELETE request to a path + def delete(path, options={}, &block) + perform_request Net::HTTP::Delete, path, options, &block + end + + # Perform a HEAD request to a path + def head(path, options={}, &block) + perform_request Net::HTTP::Head, path, options, &block + end + + # Perform an OPTIONS request to a path + def options(path, options={}, &block) + perform_request Net::HTTP::Options, path, options, &block + end + + def default_options #:nodoc: + @default_options + end + + private + + def perform_request(http_method, path, options, &block) #:nodoc: + options = default_options.dup.merge(options) + process_cookies(options) + Request.new(http_method, path, options).perform(&block) + end + + def process_cookies(options) #:nodoc: + return unless options[:cookies] || default_cookies.any? + options[:headers] ||= headers.dup + options[:headers]["cookie"] = cookies.merge(options.delete(:cookies) || {}).to_cookie_string + end + + def validate_format + if format && parser.respond_to?(:supports_format?) && !parser.supports_format?(format) + raise UnsupportedFormat, "'#{format.inspect}' Must be one of: #{parser.supported_formats.map{|f| f.to_s}.sort.join(', ')}" + end + end + end + + def self.normalize_base_uri(url) #:nodoc: + normalized_url = url.dup + use_ssl = (normalized_url =~ /^https/) || (normalized_url =~ /:443\b/) + ends_with_slash = normalized_url =~ /\/$/ + + normalized_url.chop! if ends_with_slash + normalized_url.gsub!(/^https?:\/\//i, '') + + "http#{'s' if use_ssl}://#{normalized_url}" + end + + class Basement #:nodoc: + include HTTParty + end + + def self.get(*args, &block) + Basement.get(*args, &block) + end + + def self.post(*args, &block) + Basement.post(*args, &block) + end + + def self.patch(*args, &block) + Basement.patch(*args, &block) + end + + def self.put(*args, &block) + Basement.put(*args, &block) + end + + def self.delete(*args, &block) + Basement.delete(*args, &block) + end + + def self.head(*args, &block) + Basement.head(*args, &block) + end + + def self.options(*args, &block) + Basement.options(*args, &block) + end +end + +require 'httparty/core_extensions' +require 'httparty/hash_conversions' +require 'httparty/exceptions' +require 'httparty/parser' +require 'httparty/request' +require 'httparty/response' diff --git a/vendor/ruby/1.9.1/gems/httparty-0.9.0/lib/httparty/connection_adapter.rb b/vendor/ruby/1.9.1/gems/httparty-0.9.0/lib/httparty/connection_adapter.rb new file mode 100644 index 0000000..df3e0cc --- /dev/null +++ b/vendor/ruby/1.9.1/gems/httparty-0.9.0/lib/httparty/connection_adapter.rb @@ -0,0 +1,116 @@ +module HTTParty + # Default connection adapter that returns a new Net::HTTP each time + # + # == Custom Connection Factories + # + # If you like to implement your own connection adapter, subclassing + # HTTPParty::ConnectionAdapter will make it easier. Just override + # the #connection method. The uri and options attributes will have + # all the info you need to construct your http connection. Whatever + # you return from your connection method needs to adhere to the + # Net::HTTP interface as this is what HTTParty expects. + # + # @example log the uri and options + # class LoggingConnectionAdapter < HTTParty::ConnectionAdapter + # def connection + # puts uri + # puts options + # Net::HTTP.new(uri) + # end + # end + # + # @example count number of http calls + # class CountingConnectionAdapter < HTTParty::ConnectionAdapter + # @@count = 0 + # + # self.count + # @@count + # end + # + # def connection + # self.count += 1 + # super + # end + # end + # + # === Configuration + # There is lots of configuration data available for your connection adapter + # in the #options attribute. It is up to you to interpret them within your + # connection adapter. Take a look at the implementation of + # HTTParty::ConnectionAdapter#connection for examples of how they are used. + # Something are probably interesting are as follows: + # * :+timeout+: timeout in seconds + # * :+debug_output+: see HTTParty::ClassMethods.debug_output. + # * :+pem+: contains pem data. see HTTParty::ClassMethods.pem. + # * :+ssl_ca_file+: see HTTParty::ClassMethods.ssl_ca_file. + # * :+ssl_ca_path+: see HTTParty::ClassMethods.ssl_ca_path. + # * :+connection_adapter_options+: contains the hash your passed to HTTParty.connection_adapter when you configured your connection adapter + class ConnectionAdapter + + def self.call(uri, options) + new(uri, options).connection + end + + attr_reader :uri, :options + + def initialize(uri, options={}) + raise ArgumentError, "uri must be a URI, not a #{uri.class}" unless uri.kind_of? URI + + @uri = uri + @options = options + end + + def connection + http = Net::HTTP.new(uri.host, uri.port, options[:http_proxyaddr], options[:http_proxyport], options[:http_proxyuser], options[:http_proxypass]) + + http.use_ssl = ssl_implied?(uri) + + attach_ssl_certificates(http, options) + + if options[:timeout] && (options[:timeout].is_a?(Integer) || options[:timeout].is_a?(Float)) + http.open_timeout = options[:timeout] + http.read_timeout = options[:timeout] + end + + if options[:debug_output] + http.set_debug_output(options[:debug_output]) + end + + return http + end + + private + def ssl_implied?(uri) + uri.port == 443 || uri.instance_of?(URI::HTTPS) + end + + def attach_ssl_certificates(http, options) + if http.use_ssl? + http.verify_mode = OpenSSL::SSL::VERIFY_NONE + + # Client certificate authentication + if options[:pem] + http.cert = OpenSSL::X509::Certificate.new(options[:pem]) + http.key = OpenSSL::PKey::RSA.new(options[:pem], options[:pem_password]) + http.verify_mode = OpenSSL::SSL::VERIFY_PEER + end + + # SSL certificate authority file and/or directory + if options[:ssl_ca_file] + http.ca_file = options[:ssl_ca_file] + http.verify_mode = OpenSSL::SSL::VERIFY_PEER + end + + if options[:ssl_ca_path] + http.ca_path = options[:ssl_ca_path] + http.verify_mode = OpenSSL::SSL::VERIFY_PEER + end + + # This is only Ruby 1.9+ + if options[:ssl_version] && http.respond_to?(:ssl_version=) + http.ssl_version = options[:ssl_version] + end + end + end + end +end diff --git a/vendor/ruby/1.9.1/gems/httparty-0.9.0/lib/httparty/cookie_hash.rb b/vendor/ruby/1.9.1/gems/httparty-0.9.0/lib/httparty/cookie_hash.rb new file mode 100644 index 0000000..e9ea92d --- /dev/null +++ b/vendor/ruby/1.9.1/gems/httparty-0.9.0/lib/httparty/cookie_hash.rb @@ -0,0 +1,22 @@ +class HTTParty::CookieHash < Hash #:nodoc: + + CLIENT_COOKIES = %w{path expires domain path secure HTTPOnly} + + def add_cookies(value) + case value + when Hash + merge!(value) + when String + value.split('; ').each do |cookie| + array = cookie.split('=') + self[array[0].to_sym] = array[1] + end + else + raise "add_cookies only takes a Hash or a String" + end + end + + def to_cookie_string + delete_if { |k, v| CLIENT_COOKIES.include?(k.to_s) }.collect { |k, v| "#{k}=#{v}" }.join("; ") + end +end diff --git a/vendor/ruby/1.9.1/gems/httparty-0.9.0/lib/httparty/core_extensions.rb b/vendor/ruby/1.9.1/gems/httparty-0.9.0/lib/httparty/core_extensions.rb new file mode 100644 index 0000000..b41c00e --- /dev/null +++ b/vendor/ruby/1.9.1/gems/httparty-0.9.0/lib/httparty/core_extensions.rb @@ -0,0 +1,32 @@ +module HTTParty + if defined?(::BasicObject) + BasicObject = ::BasicObject #:nodoc: + else + class BasicObject #:nodoc: + instance_methods.each { |m| undef_method m unless m =~ /^__|instance_eval/ } + end + end + + unless defined?(Net::HTTP::Patch) + class Net::HTTP + def patch(path, data, initheader = nil, dest = nil, &block) #:nodoc: + res = nil + request(Patch.new(path, initheader), data) {|r| + r.read_body dest, &block + res = r + } + unless @newimpl + res.value + return res, res.body + end + res + end + + class Patch < Net::HTTPRequest + METHOD = 'PATCH' + REQUEST_HAS_BODY = true + RESPONSE_HAS_BODY = true + end + end + end +end diff --git a/vendor/ruby/1.9.1/gems/httparty-0.9.0/lib/httparty/exceptions.rb b/vendor/ruby/1.9.1/gems/httparty-0.9.0/lib/httparty/exceptions.rb new file mode 100644 index 0000000..512aec7 --- /dev/null +++ b/vendor/ruby/1.9.1/gems/httparty-0.9.0/lib/httparty/exceptions.rb @@ -0,0 +1,26 @@ +module HTTParty + # Exception raised when you attempt to set a non-existant format + class UnsupportedFormat < StandardError; end + + # Exception raised when using a URI scheme other than HTTP or HTTPS + class UnsupportedURIScheme < StandardError; end + + # @abstract Exceptions which inherit from ResponseError contain the Net::HTTP + # response object accessible via the {#response} method. + class ResponseError < StandardError + # Returns the response of the last request + # @return [Net::HTTPResponse] A subclass of Net::HTTPResponse, e.g. + # Net::HTTPOK + attr_reader :response + + # Instantiate an instance of ResponseError with a Net::HTTPResponse object + # @param [Net::HTTPResponse] + def initialize(response) + @response = response + end + end + + # Exception that is raised when request has redirected too many times. + # Calling {#response} returns the Net:HTTP response object. + class RedirectionTooDeep < ResponseError; end +end diff --git a/vendor/ruby/1.9.1/gems/httparty-0.9.0/lib/httparty/hash_conversions.rb b/vendor/ruby/1.9.1/gems/httparty-0.9.0/lib/httparty/hash_conversions.rb new file mode 100644 index 0000000..87e08cf --- /dev/null +++ b/vendor/ruby/1.9.1/gems/httparty-0.9.0/lib/httparty/hash_conversions.rb @@ -0,0 +1,51 @@ +module HTTParty + module HashConversions + # @return This hash as a query string + # + # @example + # { :name => "Bob", + # :address => { + # :street => '111 Ruby Ave.', + # :city => 'Ruby Central', + # :phones => ['111-111-1111', '222-222-2222'] + # } + # }.to_params + # #=> "name=Bob&address[city]=Ruby Central&address[phones][]=111-111-1111&address[phones][]=222-222-2222&address[street]=111 Ruby Ave." + def self.to_params(hash) + params = hash.map { |k,v| normalize_param(k,v) }.join + params.chop! # trailing & + params + end + + # @param key The key for the param. + # @param value The value for the param. + # + # @return This key value pair as a param + # + # @example normalize_param(:name, "Bob Jones") #=> "name=Bob%20Jones&" + def self.normalize_param(key, value) + param = '' + stack = [] + + if value.is_a?(Array) + param << value.map { |element| normalize_param("#{key}[]", element) }.join + elsif value.is_a?(Hash) + stack << [key,value] + else + param << "#{key}=#{URI.encode(value.to_s, Regexp.new("[^#{URI::PATTERN::UNRESERVED}]"))}&" + end + + stack.each do |parent, hash| + hash.each do |key, value| + if value.is_a?(Hash) + stack << ["#{parent}[#{key}]", value] + else + param << normalize_param("#{parent}[#{key}]", value) + end + end + end + + param + end + end +end diff --git a/vendor/ruby/1.9.1/gems/httparty-0.9.0/lib/httparty/module_inheritable_attributes.rb b/vendor/ruby/1.9.1/gems/httparty-0.9.0/lib/httparty/module_inheritable_attributes.rb new file mode 100644 index 0000000..879ca25 --- /dev/null +++ b/vendor/ruby/1.9.1/gems/httparty-0.9.0/lib/httparty/module_inheritable_attributes.rb @@ -0,0 +1,44 @@ +module HTTParty + module ModuleInheritableAttributes #:nodoc: + def self.included(base) + base.extend(ClassMethods) + end + + # borrowed from Rails 3.2 ActiveSupport + def self.hash_deep_dup(h) + duplicate = h.dup + duplicate.each_pair do |k,v| + tv = duplicate[k] + duplicate[k] = tv.is_a?(Hash) && v.is_a?(Hash) ? hash_deep_dup(tv) : v + end + duplicate + end + + module ClassMethods #:nodoc: + def mattr_inheritable(*args) + @mattr_inheritable_attrs ||= [:mattr_inheritable_attrs] + @mattr_inheritable_attrs += args + args.each do |arg| + module_eval %(class << self; attr_accessor :#{arg} end) + end + @mattr_inheritable_attrs + end + + def inherited(subclass) + super + @mattr_inheritable_attrs.each do |inheritable_attribute| + ivar = "@#{inheritable_attribute}" + subclass.instance_variable_set(ivar, instance_variable_get(ivar).clone) + if instance_variable_get(ivar).respond_to?(:merge) + method = <<-EOM + def self.#{inheritable_attribute} + #{ivar} = superclass.#{inheritable_attribute}.merge ModuleInheritableAttributes.hash_deep_dup(#{ivar}) + end + EOM + subclass.class_eval method + end + end + end + end + end +end diff --git a/vendor/ruby/1.9.1/gems/httparty-0.9.0/lib/httparty/net_digest_auth.rb b/vendor/ruby/1.9.1/gems/httparty-0.9.0/lib/httparty/net_digest_auth.rb new file mode 100644 index 0000000..6e262d0 --- /dev/null +++ b/vendor/ruby/1.9.1/gems/httparty-0.9.0/lib/httparty/net_digest_auth.rb @@ -0,0 +1,84 @@ +require 'digest/md5' +require 'net/http' + +module Net + module HTTPHeader + def digest_auth(username, password, response) + @header['Authorization'] = DigestAuthenticator.new(username, password, + @method, @path, response).authorization_header + end + + + class DigestAuthenticator + def initialize(username, password, method, path, response_header) + @username = username + @password = password + @method = method + @path = path + @response = parse(response_header) + end + + def authorization_header + @cnonce = md5(random) + header = [ + %Q(Digest username="#{@username}"), + %Q(realm="#{@response['realm']}"), + %Q(nonce="#{@response['nonce']}"), + %Q(uri="#{@path}"), + %Q(response="#{request_digest}"), + ] + + if qop_present? + fields = [ + %Q(cnonce="#{@cnonce}"), + %Q(qop="#{@response['qop']}"), + %Q(nc="00000001") + ] + fields.each { |field| header << field } + end + + header << %Q(opaque="#{@response['opaque']}") if opaque_present? + header + end + + private + + def parse(response_header) + response_header['www-authenticate'] =~ /^(\w+) (.*)/ + params = {} + $2.gsub(/(\w+)="(.*?)"/) { params[$1] = $2 } + params + end + + def opaque_present? + @response.has_key?('opaque') and not @response['opaque'].empty? + end + + def qop_present? + @response.has_key?('qop') and not @response['qop'].empty? + end + + def random + "%x" % (Time.now.to_i + rand(65535)) + end + + def request_digest + a = [md5(a1), @response['nonce'], md5(a2)] + a.insert(2, "00000001", @cnonce, @response['qop']) if qop_present? + md5(a.join(":")) + end + + def md5(str) + Digest::MD5.hexdigest(str) + end + + def a1 + [@username, @response['realm'], @password].join(":") + end + + def a2 + [@method, @path].join(":") + end + end + end +end diff --git a/vendor/ruby/1.9.1/gems/httparty-0.9.0/lib/httparty/parser.rb b/vendor/ruby/1.9.1/gems/httparty-0.9.0/lib/httparty/parser.rb new file mode 100644 index 0000000..3b9e67e --- /dev/null +++ b/vendor/ruby/1.9.1/gems/httparty-0.9.0/lib/httparty/parser.rb @@ -0,0 +1,145 @@ +module HTTParty + # The default parser used by HTTParty, supports xml, json, html, yaml, and + # plain text. + # + # == Custom Parsers + # + # If you'd like to do your own custom parsing, subclassing HTTParty::Parser + # will make that process much easier. There are a few different ways you can + # utilize HTTParty::Parser as a superclass. + # + # @example Intercept the parsing for all formats + # class SimpleParser < HTTParty::Parser + # def parse + # perform_parsing + # end + # end + # + # @example Add the atom format and parsing method to the default parser + # class AtomParsingIncluded < HTTParty::Parser + # SupportedFormats.merge!( + # {"application/atom+xml" => :atom} + # ) + # + # def atom + # perform_atom_parsing + # end + # end + # + # @example Only support the atom format + # class ParseOnlyAtom < HTTParty::Parser + # SupportedFormats = {"application/atom+xml" => :atom} + # + # def atom + # perform_atom_parsing + # end + # end + # + # @abstract Read the Custom Parsers section for more information. + class Parser + SupportedFormats = { + 'text/xml' => :xml, + 'application/xml' => :xml, + 'application/json' => :json, + 'text/json' => :json, + 'application/javascript' => :json, + 'text/javascript' => :json, + 'text/html' => :html, + 'application/x-yaml' => :yaml, + 'text/yaml' => :yaml, + 'text/plain' => :plain + } + + # The response body of the request + # @return [String] + attr_reader :body + + # The intended parsing format for the request + # @return [Symbol] e.g. :json + attr_reader :format + + # Instantiate the parser and call {#parse}. + # @param [String] body the response body + # @param [Symbol] format the response format + # @return parsed response + def self.call(body, format) + new(body, format).parse + end + + # @return [Hash] the SupportedFormats hash + def self.formats + const_get(:SupportedFormats) + end + + # @param [String] mimetype response MIME type + # @return [Symbol] + # @return [nil] mime type not supported + def self.format_from_mimetype(mimetype) + formats[formats.keys.detect {|k| mimetype.include?(k)}] + end + + # @return [Array] list of supported formats + def self.supported_formats + formats.values.uniq + end + + # @param [Symbol] format e.g. :json, :xml + # @return [Boolean] + def self.supports_format?(format) + supported_formats.include?(format) + end + + def initialize(body, format) + @body = body + @format = format + end + + # @return [Object] the parsed body + # @return [nil] when the response body is nil, an empty string, spaces only or "null" + def parse + return nil if body.nil? || body.strip.empty? || body == "null" + if supports_format? + parse_supported_format + else + body + end + end + + protected + + def xml + MultiXml.parse(body) + end + + def json + # https://github.com/sferik/rails/commit/5e62670131dfa1718eaf21ff8dd3371395a5f1cc + if MultiJson.respond_to?(:adapter) + MultiJson.load(body) + else + MultiJson.decode(body) + end + end + + def yaml + YAML.load(body) + end + + def html + body + end + + def plain + body + end + + def supports_format? + self.class.supports_format?(format) + end + + def parse_supported_format + send(format) + rescue NoMethodError => e + raise NotImplementedError, "#{self.class.name} has not implemented a parsing method for the #{format.inspect} format.", e.backtrace + end + end +end diff --git a/vendor/ruby/1.9.1/gems/httparty-0.9.0/lib/httparty/request.rb b/vendor/ruby/1.9.1/gems/httparty-0.9.0/lib/httparty/request.rb new file mode 100644 index 0000000..032de69 --- /dev/null +++ b/vendor/ruby/1.9.1/gems/httparty-0.9.0/lib/httparty/request.rb @@ -0,0 +1,239 @@ +module HTTParty + class Request #:nodoc: + SupportedHTTPMethods = [ + Net::HTTP::Get, + Net::HTTP::Post, + Net::HTTP::Patch, + Net::HTTP::Put, + Net::HTTP::Delete, + Net::HTTP::Head, + Net::HTTP::Options + ] + + SupportedURISchemes = [URI::HTTP, URI::HTTPS] + + NON_RAILS_QUERY_STRING_NORMALIZER = Proc.new do |query| + Array(query).map do |key, value| + if value.nil? + key.to_s + elsif value.is_a?(Array) + value.map {|v| "#{key}=#{URI.encode(v.to_s, Regexp.new("[^#{URI::PATTERN::UNRESERVED}]"))}"} + else + HashConversions.to_params(key => value) + end + end.flatten.sort.join('&') + end + + attr_accessor :http_method, :path, :options, :last_response, :redirect, :last_uri + + def initialize(http_method, path, o={}) + self.http_method = http_method + self.path = path + self.options = { + :limit => o.delete(:no_follow) ? 1 : 5, + :default_params => {}, + :follow_redirects => true, + :parser => Parser, + :connection_adapter => ConnectionAdapter + }.merge(o) + end + + def path=(uri) + @path = URI.parse(uri) + end + + def uri + new_uri = path.relative? ? URI.parse("#{base_uri}#{path}") : path + + # avoid double query string on redirects [#12] + unless redirect + new_uri.query = query_string(new_uri) + end + + unless SupportedURISchemes.include? new_uri.class + raise UnsupportedURIScheme, "'#{new_uri}' Must be HTTP or HTTPS" + end + + @last_uri = new_uri + end + + def base_uri + redirect ? "#{@last_uri.scheme}://#{@last_uri.host}" : options[:base_uri] + end + + def format + options[:format] || (format_from_mimetype(last_response['content-type']) if last_response) + end + + def parser + options[:parser] + end + + def connection_adapter + options[:connection_adapter] + end + + def perform(&block) + validate + setup_raw_request + chunked_body = nil + + self.last_response = http.request(@raw_request) do |http_response| + if block + chunks = [] + + http_response.read_body do |fragment| + chunks << fragment + block.call(fragment) + end + + chunked_body = chunks.join + end + end + + handle_deflation + handle_response(chunked_body) + end + + private + + def http + connection_adapter.call(uri, options) + end + + def body + options[:body].is_a?(Hash) ? normalize_query(options[:body]) : options[:body] + end + + def credentials + options[:basic_auth] || options[:digest_auth] + end + + def username + credentials[:username] + end + + def password + credentials[:password] + end + + def normalize_query(query) + if query_string_normalizer + query_string_normalizer.call(query) + else + HashConversions.to_params(query) + end + end + + def query_string_normalizer + options[:query_string_normalizer] + end + + def setup_raw_request + @raw_request = http_method.new(uri.request_uri) + @raw_request.body = body if body + @raw_request.initialize_http_header(options[:headers]) + @raw_request.basic_auth(username, password) if options[:basic_auth] + setup_digest_auth if options[:digest_auth] + end + + def setup_digest_auth + auth_request = http_method.new(uri.request_uri) + auth_request.initialize_http_header(options[:headers]) + res = http.request(auth_request) + + if res['www-authenticate'] != nil && res['www-authenticate'].length > 0 + @raw_request.digest_auth(username, password, res) + end + end + + def query_string(uri) + query_string_parts = [] + query_string_parts << uri.query unless uri.query.nil? + + if options[:query].is_a?(Hash) + query_string_parts << normalize_query(options[:default_params].merge(options[:query])) + else + query_string_parts << normalize_query(options[:default_params]) unless options[:default_params].empty? + query_string_parts << options[:query] unless options[:query].nil? + end + + query_string_parts.size > 0 ? query_string_parts.join('&') : nil + end + + def handle_response(body) + if response_redirects? + options[:limit] -= 1 + self.path = last_response['location'] + self.redirect = true + self.http_method = Net::HTTP::Get unless options[:maintain_method_across_redirects] + capture_cookies(last_response) + perform + else + body = body || last_response.body + Response.new(self, last_response, lambda { parse_response(body) }, :body => body) + end + end + + # Inspired by Ruby 1.9 + def handle_deflation + case last_response["content-encoding"] + when "gzip", "x-gzip" + body_io = StringIO.new(last_response.body) + last_response.body.replace Zlib::GzipReader.new(body_io).read + last_response.delete('content-encoding') + when "deflate" + last_response.body.replace Zlib::Inflate.inflate(last_response.body) + last_response.delete('content-encoding') + end + end + + def response_redirects? + case last_response + when Net::HTTPMultipleChoice, # 300 + Net::HTTPMovedPermanently, # 301 + Net::HTTPFound, # 302 + Net::HTTPSeeOther, # 303 + Net::HTTPUseProxy, # 305 + Net::HTTPTemporaryRedirect + options[:follow_redirects] && last_response.key?('location') + end + end + + def parse_response(body) + parser.call(body, format) + end + + def capture_cookies(response) + return unless response['Set-Cookie'] + cookies_hash = HTTParty::CookieHash.new() + cookies_hash.add_cookies(options[:headers]['Cookie']) if options[:headers] && options[:headers]['Cookie'] + cookies_hash.add_cookies(response['Set-Cookie']) + options[:headers] ||= {} + options[:headers]['Cookie'] = cookies_hash.to_cookie_string + end + + # Uses the HTTP Content-Type header to determine the format of the + # response It compares the MIME type returned to the types stored in the + # SupportedFormats hash + def format_from_mimetype(mimetype) + if mimetype && parser.respond_to?(:format_from_mimetype) + parser.format_from_mimetype(mimetype) + end + end + + def validate + raise HTTParty::RedirectionTooDeep.new(last_response), 'HTTP redirects too deep' if options[:limit].to_i <= 0 + raise ArgumentError, 'only get, post, patch, put, delete, head, and options methods are supported' unless SupportedHTTPMethods.include?(http_method) + raise ArgumentError, ':headers must be a hash' if options[:headers] && !options[:headers].is_a?(Hash) + raise ArgumentError, 'only one authentication method, :basic_auth or :digest_auth may be used at a time' if options[:basic_auth] && options[:digest_auth] + raise ArgumentError, ':basic_auth must be a hash' if options[:basic_auth] && !options[:basic_auth].is_a?(Hash) + raise ArgumentError, ':digest_auth must be a hash' if options[:digest_auth] && !options[:digest_auth].is_a?(Hash) + raise ArgumentError, ':query must be hash if using HTTP Post' if post? && !options[:query].nil? && !options[:query].is_a?(Hash) + end + + def post? + Net::HTTP::Post == http_method + end + end +end diff --git a/vendor/ruby/1.9.1/gems/httparty-0.9.0/lib/httparty/response.rb b/vendor/ruby/1.9.1/gems/httparty-0.9.0/lib/httparty/response.rb new file mode 100644 index 0000000..3193b99 --- /dev/null +++ b/vendor/ruby/1.9.1/gems/httparty-0.9.0/lib/httparty/response.rb @@ -0,0 +1,62 @@ +module HTTParty + class Response < HTTParty::BasicObject #:nodoc: + def self.underscore(string) + string.gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').gsub(/([a-z])([A-Z])/,'\1_\2').downcase + end + + attr_reader :request, :response, :body, :headers + + def initialize(request, response, parsed_block, options={}) + @request = request + @response = response + @body = response.body || options[:body] + @parsed_block = parsed_block + @headers = Headers.new(response.to_hash) + end + + def parsed_response + @parsed_response ||= @parsed_block.call + end + + def class + Response + end + + def code + response.code.to_i + end + + def inspect + inspect_id = "%x" % (object_id * 2) + %(#<#{self.class}:0x#{inspect_id} parsed_response=#{parsed_response.inspect}, @response=#{response.inspect}, @headers=#{headers.inspect}>) + end + + CODES_TO_OBJ = ::Net::HTTPResponse::CODE_CLASS_TO_OBJ.merge ::Net::HTTPResponse::CODE_TO_OBJ + + CODES_TO_OBJ.each do |response_code, klass| + name = klass.name.sub("Net::HTTP", '') + define_method("#{underscore(name)}?") do + klass === response + end + end + + def respond_to?(name) + return true if [:request, :response, :parsed_response, :body, :headers].include?(name) + parsed_response.respond_to?(name) || response.respond_to?(name) + end + + protected + + def method_missing(name, *args, &block) + if parsed_response.respond_to?(name) + parsed_response.send(name, *args, &block) + elsif response.respond_to?(name) + response.send(name, *args, &block) + else + super + end + end + end +end + +require 'httparty/response/headers' diff --git a/vendor/ruby/1.9.1/gems/httparty-0.9.0/lib/httparty/response/headers.rb b/vendor/ruby/1.9.1/gems/httparty-0.9.0/lib/httparty/response/headers.rb new file mode 100644 index 0000000..c4ed90b --- /dev/null +++ b/vendor/ruby/1.9.1/gems/httparty-0.9.0/lib/httparty/response/headers.rb @@ -0,0 +1,31 @@ +module HTTParty + class Response #:nodoc: + class Headers + include ::Net::HTTPHeader + + def initialize(header = {}) + @header = header + end + + def ==(other) + @header == other + end + + def inspect + @header.inspect + end + + def method_missing(name, *args, &block) + if @header.respond_to?(name) + @header.send(name, *args, &block) + else + super + end + end + + def respond_to?(method) + super || @header.respond_to?(method) + end + end + end +end diff --git a/vendor/ruby/1.9.1/gems/httparty-0.9.0/lib/httparty/version.rb b/vendor/ruby/1.9.1/gems/httparty-0.9.0/lib/httparty/version.rb new file mode 100644 index 0000000..65999b8 --- /dev/null +++ b/vendor/ruby/1.9.1/gems/httparty-0.9.0/lib/httparty/version.rb @@ -0,0 +1,3 @@ +module HTTParty + VERSION = "0.9.0" +end diff --git a/vendor/ruby/1.9.1/gems/httparty-0.9.0/spec/fixtures/delicious.xml b/vendor/ruby/1.9.1/gems/httparty-0.9.0/spec/fixtures/delicious.xml new file mode 100644 index 0000000..f93a1ee --- /dev/null +++ b/vendor/ruby/1.9.1/gems/httparty-0.9.0/spec/fixtures/delicious.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/vendor/ruby/1.9.1/gems/httparty-0.9.0/spec/fixtures/empty.xml b/vendor/ruby/1.9.1/gems/httparty-0.9.0/spec/fixtures/empty.xml new file mode 100644 index 0000000..e69de29 diff --git a/vendor/ruby/1.9.1/gems/httparty-0.9.0/spec/fixtures/google.html b/vendor/ruby/1.9.1/gems/httparty-0.9.0/spec/fixtures/google.html new file mode 100644 index 0000000..1c4221d --- /dev/null +++ b/vendor/ruby/1.9.1/gems/httparty-0.9.0/spec/fixtures/google.html @@ -0,0 +1,3 @@ +Google

Google

 
  Advanced Search
  Preferences
  Language Tools


Advertising Programs - Business Solutions - About Google

©2008 - Privacy

\ No newline at end of file diff --git a/vendor/ruby/1.9.1/gems/httparty-0.9.0/spec/fixtures/ssl/generate.sh b/vendor/ruby/1.9.1/gems/httparty-0.9.0/spec/fixtures/ssl/generate.sh new file mode 100755 index 0000000..1ef76e2 --- /dev/null +++ b/vendor/ruby/1.9.1/gems/httparty-0.9.0/spec/fixtures/ssl/generate.sh @@ -0,0 +1,29 @@ +#!/bin/sh +set -e + +if [ -d "generated" ] ; then + echo >&2 "error: 'generated' directory already exists. Delete it first." + exit 1 +fi + +mkdir generated + +# Generate the CA private key and certificate +openssl req -batch -subj '/CN=INSECURE Test Certificate Authority' -newkey rsa:1024 -new -x509 -days 999999 -keyout generated/ca.key -nodes -out generated/ca.crt + +# Create symlinks for ssl_ca_path +c_rehash generated + +# Generate the server private key and self-signed certificate +openssl req -batch -subj '/CN=localhost' -newkey rsa:1024 -new -x509 -days 999999 -keyout generated/server.key -nodes -out generated/selfsigned.crt + +# Generate certificate signing request with bogus hostname +openssl req -batch -subj '/CN=bogo' -new -days 999999 -key generated/server.key -nodes -out generated/bogushost.csr + +# Sign the certificate requests +openssl x509 -CA generated/ca.crt -CAkey generated/ca.key -set_serial 1 -in generated/selfsigned.crt -out generated/server.crt -clrext -extfile openssl-exts.cnf -extensions cert -days 999999 +openssl x509 -req -CA generated/ca.crt -CAkey generated/ca.key -set_serial 1 -in generated/bogushost.csr -out generated/bogushost.crt -clrext -extfile openssl-exts.cnf -extensions cert -days 999999 + +# Remove certificate signing requests +rm -f generated/*.csr + diff --git a/vendor/ruby/1.9.1/gems/httparty-0.9.0/spec/fixtures/ssl/generated/1fe462c2.0 b/vendor/ruby/1.9.1/gems/httparty-0.9.0/spec/fixtures/ssl/generated/1fe462c2.0 new file mode 100644 index 0000000..215f366 --- /dev/null +++ b/vendor/ruby/1.9.1/gems/httparty-0.9.0/spec/fixtures/ssl/generated/1fe462c2.0 @@ -0,0 +1,16 @@ +-----BEGIN CERTIFICATE----- +MIICbTCCAdagAwIBAgIJAIAeO9TXtJ45MA0GCSqGSIb3DQEBBQUAMC4xLDAqBgNV +BAMTI0lOU0VDVVJFIFRlc3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MCAXDTEwMTAy +MDEzNDYyM1oYDzQ3NDgwOTE1MTM0NjIzWjAuMSwwKgYDVQQDEyNJTlNFQ1VSRSBU +ZXN0IENlcnRpZmljYXRlIEF1dGhvcml0eTCBnzANBgkqhkiG9w0BAQEFAAOBjQAw +gYkCgYEA3lkBcd352qiIIzqnyvvJj59cx1dnzMyjnuaK2cRH420rBfukLE2MbOVr +9nYq/7CdjqXpE8uFAF+UTSIK6MWZ/bidkr2xd/et/Ce2pVIVxH+rt3pJz3wZhC3H +Yz+HU4CD2iI9wAzsb6mMV7md1fjlYfir4SBGGPTkcqUJUp2/tQMCAwEAAaOBkDCB +jTAdBgNVHQ4EFgQUy0Lz6RgmtpywlBOXdPABQArp358wXgYDVR0jBFcwVYAUy0Lz +6RgmtpywlBOXdPABQArp35+hMqQwMC4xLDAqBgNVBAMTI0lOU0VDVVJFIFRlc3Qg +Q2VydGlmaWNhdGUgQXV0aG9yaXR5ggkAgB471Ne0njkwDAYDVR0TBAUwAwEB/zAN +BgkqhkiG9w0BAQUFAAOBgQCmi3JQm+EIWjkRlyz9sijkYS+Ps4opmd/weeaXwa4E +gVBWJGyiduB+kBnfv61+/tDjlrbjBDH5dP8suczHQL8gox4zGgjw64KH4o1ujZYR +cEPbhnUpwbXu7yItlajBZfpFefjF5P0Ao2iEzQldDy0D6nQ19h5QANvQxqweTPQp +pw== +-----END CERTIFICATE----- diff --git a/vendor/ruby/1.9.1/gems/httparty-0.9.0/spec/fixtures/ssl/generated/bogushost.crt b/vendor/ruby/1.9.1/gems/httparty-0.9.0/spec/fixtures/ssl/generated/bogushost.crt new file mode 100644 index 0000000..cf1e66d --- /dev/null +++ b/vendor/ruby/1.9.1/gems/httparty-0.9.0/spec/fixtures/ssl/generated/bogushost.crt @@ -0,0 +1,13 @@ +-----BEGIN CERTIFICATE----- +MIICBTCCAW6gAwIBAgIBATANBgkqhkiG9w0BAQUFADAuMSwwKgYDVQQDEyNJTlNF +Q1VSRSBUZXN0IENlcnRpZmljYXRlIEF1dGhvcml0eTAgFw0xMDEwMjAxMzQ2MjNa +GA80NzQ4MDkxNTEzNDYyM1owDzENMAsGA1UEAxMEYm9nbzCBnzANBgkqhkiG9w0B +AQEFAAOBjQAwgYkCgYEAr6b0ZBrRrVvPmPbQv36Jnj5jv00ZkhimXrmbv9Z1AdIZ +WSsBpMd8TP7exE5OR5/DaxKmiZqVskgRyRkLm52/Dkt7Ncrzr5I3unHnMqsAv/28 +5fGlYoRxnkCGMse/6NOFgCemRFw/bglxPNAGrFYKStameBRbCm0dCgtlvcwzdf8C +AwEAAaNQME4wDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQUddLPFtGmb0aFWbTl2kAo +xD+fd6kwHwYDVR0jBBgwFoAUy0Lz6RgmtpywlBOXdPABQArp358wDQYJKoZIhvcN +AQEFBQADgYEAosqpPVsFu6cOIhGFT85Y1wwRUaihO0vWO7ghBU5ScuRU3tuvyJDZ +Z/HoAMXV6XZjVZzRosjtPjFbyWkZYjUqJJRMyEaRiGArWe6urKLzwnD6R9O3eNa5 +7bgFhzZ5WBldJmtq4A3oNqBuvgZkYM6NVKvS4UoakkTliHB21/mDOSY= +-----END CERTIFICATE----- diff --git a/vendor/ruby/1.9.1/gems/httparty-0.9.0/spec/fixtures/ssl/generated/ca.crt b/vendor/ruby/1.9.1/gems/httparty-0.9.0/spec/fixtures/ssl/generated/ca.crt new file mode 100644 index 0000000..215f366 --- /dev/null +++ b/vendor/ruby/1.9.1/gems/httparty-0.9.0/spec/fixtures/ssl/generated/ca.crt @@ -0,0 +1,16 @@ +-----BEGIN CERTIFICATE----- +MIICbTCCAdagAwIBAgIJAIAeO9TXtJ45MA0GCSqGSIb3DQEBBQUAMC4xLDAqBgNV +BAMTI0lOU0VDVVJFIFRlc3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MCAXDTEwMTAy +MDEzNDYyM1oYDzQ3NDgwOTE1MTM0NjIzWjAuMSwwKgYDVQQDEyNJTlNFQ1VSRSBU +ZXN0IENlcnRpZmljYXRlIEF1dGhvcml0eTCBnzANBgkqhkiG9w0BAQEFAAOBjQAw +gYkCgYEA3lkBcd352qiIIzqnyvvJj59cx1dnzMyjnuaK2cRH420rBfukLE2MbOVr +9nYq/7CdjqXpE8uFAF+UTSIK6MWZ/bidkr2xd/et/Ce2pVIVxH+rt3pJz3wZhC3H +Yz+HU4CD2iI9wAzsb6mMV7md1fjlYfir4SBGGPTkcqUJUp2/tQMCAwEAAaOBkDCB +jTAdBgNVHQ4EFgQUy0Lz6RgmtpywlBOXdPABQArp358wXgYDVR0jBFcwVYAUy0Lz +6RgmtpywlBOXdPABQArp35+hMqQwMC4xLDAqBgNVBAMTI0lOU0VDVVJFIFRlc3Qg +Q2VydGlmaWNhdGUgQXV0aG9yaXR5ggkAgB471Ne0njkwDAYDVR0TBAUwAwEB/zAN +BgkqhkiG9w0BAQUFAAOBgQCmi3JQm+EIWjkRlyz9sijkYS+Ps4opmd/weeaXwa4E +gVBWJGyiduB+kBnfv61+/tDjlrbjBDH5dP8suczHQL8gox4zGgjw64KH4o1ujZYR +cEPbhnUpwbXu7yItlajBZfpFefjF5P0Ao2iEzQldDy0D6nQ19h5QANvQxqweTPQp +pw== +-----END CERTIFICATE----- diff --git a/vendor/ruby/1.9.1/gems/httparty-0.9.0/spec/fixtures/ssl/generated/ca.key b/vendor/ruby/1.9.1/gems/httparty-0.9.0/spec/fixtures/ssl/generated/ca.key new file mode 100644 index 0000000..49f22aa --- /dev/null +++ b/vendor/ruby/1.9.1/gems/httparty-0.9.0/spec/fixtures/ssl/generated/ca.key @@ -0,0 +1,15 @@ +-----BEGIN RSA PRIVATE KEY----- +MIICXgIBAAKBgQDeWQFx3fnaqIgjOqfK+8mPn1zHV2fMzKOe5orZxEfjbSsF+6Qs +TYxs5Wv2dir/sJ2OpekTy4UAX5RNIgroxZn9uJ2SvbF39638J7alUhXEf6u3eknP +fBmELcdjP4dTgIPaIj3ADOxvqYxXuZ3V+OVh+KvhIEYY9ORypQlSnb+1AwIDAQAB +AoGBAL147VFCDlM1gGU865V+wIFCFQbNxedwjxGuda4io/v6oEoF6R3Tq5F0Y27v +va6Lq4fOe/LhYGI0EKU2GEPJd3F2wA21r+81InPKAkqYI5CDQtKDDNLviur8ZVKF +i3UzutjeYoCqmWeHaKPD6w5DtqeBieem7LTWRyXlFtHZV/nBAkEA8nsMOSd1+JTm +ZT4HDsEFQrN8mIFUUioFSHPut2CwzvTEW+hTkLQiog3bua4n7uQOFImR63X9qMsh +IjZRJQNmowJBAOq+mQdnRWYKl0SYb++Eb3uW6L4h1zsW375+caKo9omtpeqDW/y0 +BWyY0q4DPkm3yU26Yr+b2JijISrml9/8PiECQQDHuXyG8y7jktn3GFE94NURbL+6 +6gPnLX9ufzdoSjc4MDowrbtvHEDOlHWgioeP6L6EQhA0DtrhlnbzNCRARX3bAkEA +jQOsF+dwqAjKr/lGnMKY2cxgyf64NZXbGKsKhmUrnK9E0SjR9G8MJx1yyffGzi/q +bJf/xAzRw3eTcBsPtwznIQJAHq5MOK7oaUuO+6cbsZYpOYOOkKIvDLiOtdSr7LTI +DziH/fpzB0VhCmFhhEQwHhlB4t3m66A9TelHmhrCDsIaLA== +-----END RSA PRIVATE KEY----- diff --git a/vendor/ruby/1.9.1/gems/httparty-0.9.0/spec/fixtures/ssl/generated/selfsigned.crt b/vendor/ruby/1.9.1/gems/httparty-0.9.0/spec/fixtures/ssl/generated/selfsigned.crt new file mode 100644 index 0000000..435856a --- /dev/null +++ b/vendor/ruby/1.9.1/gems/httparty-0.9.0/spec/fixtures/ssl/generated/selfsigned.crt @@ -0,0 +1,14 @@ +-----BEGIN CERTIFICATE----- +MIICHTCCAYagAwIBAgIJALT/G+ylQljIMA0GCSqGSIb3DQEBBQUAMBQxEjAQBgNV +BAMTCWxvY2FsaG9zdDAgFw0xMDEwMjAxMzQ2MjNaGA80NzQ4MDkxNTEzNDYyM1ow +FDESMBAGA1UEAxMJbG9jYWxob3N0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB +gQCvpvRkGtGtW8+Y9tC/fomePmO/TRmSGKZeuZu/1nUB0hlZKwGkx3xM/t7ETk5H +n8NrEqaJmpWySBHJGQubnb8OS3s1yvOvkje6cecyqwC//bzl8aVihHGeQIYyx7/o +04WAJ6ZEXD9uCXE80AasVgpK1qZ4FFsKbR0KC2W9zDN1/wIDAQABo3UwczAdBgNV +HQ4EFgQUddLPFtGmb0aFWbTl2kAoxD+fd6kwRAYDVR0jBD0wO4AUddLPFtGmb0aF +WbTl2kAoxD+fd6mhGKQWMBQxEjAQBgNVBAMTCWxvY2FsaG9zdIIJALT/G+ylQljI +MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADgYEAlOCBO54S88mD3VYviER6 +V+lkd7iWmdas2wUUDeMKA9CxnirWi7ne2U7wQH/5FJ1j3ImSfjb4h/98xiVJE84e +Ld7mb61g/M4g4b62kt0HK8/cGUxfuz5zwIfi28qJq3ow6AFEq1fywbJvUAnnamwU +cZF/qoVfJhus2mXjYc4hFWg= +-----END CERTIFICATE----- diff --git a/vendor/ruby/1.9.1/gems/httparty-0.9.0/spec/fixtures/ssl/generated/server.crt b/vendor/ruby/1.9.1/gems/httparty-0.9.0/spec/fixtures/ssl/generated/server.crt new file mode 100644 index 0000000..327f269 --- /dev/null +++ b/vendor/ruby/1.9.1/gems/httparty-0.9.0/spec/fixtures/ssl/generated/server.crt @@ -0,0 +1,13 @@ +-----BEGIN CERTIFICATE----- +MIICCjCCAXOgAwIBAgIBATANBgkqhkiG9w0BAQUFADAuMSwwKgYDVQQDEyNJTlNF +Q1VSRSBUZXN0IENlcnRpZmljYXRlIEF1dGhvcml0eTAgFw0xMDEwMjAxMzQ2MjNa +GA80NzQ4MDkxNTEzNDYyM1owFDESMBAGA1UEAxMJbG9jYWxob3N0MIGfMA0GCSqG +SIb3DQEBAQUAA4GNADCBiQKBgQCvpvRkGtGtW8+Y9tC/fomePmO/TRmSGKZeuZu/ +1nUB0hlZKwGkx3xM/t7ETk5Hn8NrEqaJmpWySBHJGQubnb8OS3s1yvOvkje6cecy +qwC//bzl8aVihHGeQIYyx7/o04WAJ6ZEXD9uCXE80AasVgpK1qZ4FFsKbR0KC2W9 +zDN1/wIDAQABo1AwTjAMBgNVHRMBAf8EAjAAMB0GA1UdDgQWBBR10s8W0aZvRoVZ +tOXaQCjEP593qTAfBgNVHSMEGDAWgBTLQvPpGCa2nLCUE5d08AFACunfnzANBgkq +hkiG9w0BAQUFAAOBgQCR4Oor0YAvK0tNFrOLtqmC6D0F5IYCyu7komk7JGn9L4nn +7VyVxd4MXdc1r1v+WP5JtnA9ZjMmEmH9gl4gwR/Cu+TMkArsq0Z8mREOLNL8pwpx +Zxgk0CwacYR9RQcpuJ9nSDzVoO5ecYkb5C9q7gwgqbmCzr7oz/rwTqRwiUZCVQ== +-----END CERTIFICATE----- diff --git a/vendor/ruby/1.9.1/gems/httparty-0.9.0/spec/fixtures/ssl/generated/server.key b/vendor/ruby/1.9.1/gems/httparty-0.9.0/spec/fixtures/ssl/generated/server.key new file mode 100644 index 0000000..010aec2 --- /dev/null +++ b/vendor/ruby/1.9.1/gems/httparty-0.9.0/spec/fixtures/ssl/generated/server.key @@ -0,0 +1,15 @@ +-----BEGIN RSA PRIVATE KEY----- +MIICXQIBAAKBgQCvpvRkGtGtW8+Y9tC/fomePmO/TRmSGKZeuZu/1nUB0hlZKwGk +x3xM/t7ETk5Hn8NrEqaJmpWySBHJGQubnb8OS3s1yvOvkje6cecyqwC//bzl8aVi +hHGeQIYyx7/o04WAJ6ZEXD9uCXE80AasVgpK1qZ4FFsKbR0KC2W9zDN1/wIDAQAB +AoGALIdgkTgTS6VovVhklwcXEBy04LxE7Tp+gqj/COTvCKUgc/BpHELOCh7ajl1j +jti7i5tQyLV9mZKXn6lPvgWBd0w+p6VhM4NFA97CoodEJm2ckFC9zUABCh9dOpbm +8KzF7hdpYWgJJchwwZ60tbcP7K1DkiNX6Kk9qKQEWvitMBECQQDpOSzzLldcEU9l +ze/nG2+rf6ecaPnKeafY8R2qVils8I7ZJAW3+0bNT5gQs7rT7aWo8vMvrXq++lWb +JkNV6hK9AkEAwM5wsmg7REmAaDwgUBq5mNt963/uG2ihAODFS70lYT23UYl5Y3rD +s3qU4ntG4DvWIQgPdwdstzDh9fMBVXa1awJBAID1WoOE5k1ETRDP1I2HwDGmPnng +Ge75YfQ1LuAXEITqZzJuFrNqv/Waw0zI9M9moqlO3WVJmYusRFWrzKPe8EkCQEwC +FlN+275z63csHOD3aCtmfCGW8VtEyBP8iErvagkHt3khZQVepD/hF0ihqLNFY4jq +EI6wEp+1WZ8ICYKTpbkCQQDhl5QLdy5Xo3k3agCnB9nktSzs2iqFvsGvfOAW4628 +iThKTNua6bBvbdiG0Vh2Sv0XBYVJoHB3WnTVgFyPJaaF +-----END RSA PRIVATE KEY----- diff --git a/vendor/ruby/1.9.1/gems/httparty-0.9.0/spec/fixtures/ssl/openssl-exts.cnf b/vendor/ruby/1.9.1/gems/httparty-0.9.0/spec/fixtures/ssl/openssl-exts.cnf new file mode 100644 index 0000000..a7bf5fd --- /dev/null +++ b/vendor/ruby/1.9.1/gems/httparty-0.9.0/spec/fixtures/ssl/openssl-exts.cnf @@ -0,0 +1,9 @@ +[ca] +basicConstraints=critical,CA:true +subjectKeyIdentifier=hash +authorityKeyIdentifier=keyid:always,issuer:always + +[cert] +basicConstraints=critical,CA:false +subjectKeyIdentifier=hash +authorityKeyIdentifier=keyid,issuer diff --git a/vendor/ruby/1.9.1/gems/httparty-0.9.0/spec/fixtures/twitter.json b/vendor/ruby/1.9.1/gems/httparty-0.9.0/spec/fixtures/twitter.json new file mode 100644 index 0000000..642dd01 --- /dev/null +++ b/vendor/ruby/1.9.1/gems/httparty-0.9.0/spec/fixtures/twitter.json @@ -0,0 +1 @@ +[{"user":{"followers_count":1,"description":null,"url":null,"profile_image_url":"http:\/\/static.twitter.com\/images\/default_profile_normal.png","protected":false,"location":"Opera Plaza, California","screen_name":"Pyk","name":"Pyk","id":"7694602"},"text":"@lapilofu If you need a faster transfer, target disk mode should work too :)","truncated":false,"favorited":false,"in_reply_to_user_id":6128642,"created_at":"Sat Dec 06 21:29:14 +0000 2008","source":"twitterrific","in_reply_to_status_id":1042497164,"id":"1042500587"},{"user":{"followers_count":278,"description":"しがないプログラマ\/とりあえず宮子は俺の嫁\u2026いや、娘だ!\/Delphi&Pythonプログラマ修行中\/bot製作にハマりつつある。三つほど製作&構想中\/[eof]","url":"http:\/\/logiq.orz.hm\/","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/59588711\/l_ワ_l↑_normal.png","protected":false,"location":"ひだまり荘202号室","screen_name":"feiz","name":"azkn3","id":"14310520"},"text":"@y_benjo ちょー遅レスですがただのはだいろすぎる・・・ ( ll ワ ll )","truncated":false,"favorited":false,"in_reply_to_user_id":8428752,"created_at":"Sat Dec 06 21:29:14 +0000 2008","source":"twit","in_reply_to_status_id":1042479758,"id":"1042500586"},{"user":{"followers_count":1233,"description":""to understand one life you must swallow the world." I run refine+focus: a marketing agency working w\/ brands, media and VCs. http:\/\/tinyurl.com\/63mrn","url":"http:\/\/www.quiverandquill.com","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/53684650\/539059005_2a3b462d20_normal.jpg","protected":false,"location":"Cambridge, MA ","screen_name":"quiverandquill","name":"zach Braiker","id":"6845872"},"text":"@18percentgrey I didn't see Damon on Palin. i'll look on youtube. thx .Z","truncated":false,"favorited":false,"in_reply_to_user_id":10529932,"created_at":"Sat Dec 06 21:29:12 +0000 2008","source":"web","in_reply_to_status_id":1042499331,"id":"1042500584"},{"user":{"followers_count":780,"description":"Mein Blog ist unter http:\/\/blog.helmschrott.de zu finden. Unter http:\/\/blogalm.de kannst Du Deinen Blog eintragen!","url":"http:\/\/helmschrott.de\/blog","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/60997686\/avatar-250_normal.jpg","protected":false,"location":"Münchner Straße","screen_name":"helmi","name":"Frank Helmschrott","id":"867641"},"text":"@gigold auch mist oder?ich glaub ich fangs jetzt dann einfach mal an - wird schon vernünftige update-prozesse geben.","truncated":false,"favorited":false,"in_reply_to_user_id":959931,"created_at":"Sat Dec 06 21:29:11 +0000 2008","source":"twhirl","in_reply_to_status_id":1042500095,"id":"1042500583"},{"user":{"followers_count":63,"description":"Liberation from Misconceptions","url":"http:\/\/sexorcism.blogspot.com","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/63897302\/having-sex-on-bed_normal.jpg","protected":false,"location":"USA","screen_name":"Sexorcism","name":"Sexorcism","id":"16929435"},"text":"@thursdays_child someecards might.","truncated":false,"favorited":false,"in_reply_to_user_id":14484963,"created_at":"Sat Dec 06 21:29:13 +0000 2008","source":"twittergadget","in_reply_to_status_id":1042499777,"id":"1042500581"},{"user":{"followers_count":106,"description":"Researcher. Maître de Conférences - Sémiologue - Spécialiste des médias audiovisuels. Analyste des médias, de la télévision et de la presse people (gossip). ","url":"http:\/\/semioblog.over-blog.org\/","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/57988482\/Thomas_et_Vic_pour_promo_2_058_normal.JPG","protected":false,"location":"France","screen_name":"semioblog","name":"Virginie Spies","id":"10078802"},"text":"@richardvonstern on reparle de tout cela bientôt, si vous voulez vraiment m'aider","truncated":false,"favorited":false,"in_reply_to_user_id":15835317,"created_at":"Sat Dec 06 21:29:13 +0000 2008","source":"twitterrific","in_reply_to_status_id":1042357537,"id":"1042500580"},{"user":{"followers_count":26,"description":"","url":"","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/63461084\/November2ndpics_125_normal.jpg","protected":false,"location":"Louisville, Ky","screen_name":"scrapaunt","name":"scrapaunt","id":"16660671"},"text":"@NKOTB4LIFE Hope your neck feels better after your nap.","truncated":false,"favorited":false,"in_reply_to_user_id":16041403,"created_at":"Sat Dec 06 21:29:10 +0000 2008","source":"web","in_reply_to_status_id":1042450159,"id":"1042500579"},{"user":{"followers_count":245,"description":"Maui HI Real Estate Salesperson specializing in off the grid lifestyle","url":"http:\/\/www.eastmaui.com","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/59558480\/face2_normal.jpg","protected":false,"location":"north shore maui hawaii","screen_name":"mauihunter","name":"Georgina M. Hunter ","id":"16161708"},"text":"@BeeRealty http:\/\/twitpic.com\/qpog - It's a good safe place to lay - no dogs up there.","truncated":false,"favorited":false,"in_reply_to_user_id":15781063,"created_at":"Sat Dec 06 21:29:13 +0000 2008","source":"twitpic","in_reply_to_status_id":1042497815,"id":"1042500578"},{"user":{"followers_count":95,"description":"","url":"","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/66581657\/nose-pick_normal.jpg","protected":false,"location":"zoetermeer","screen_name":"GsKlukkluk","name":"Klukkluk","id":"14218588"},"text":"twit \/off zalige nacht!","truncated":false,"favorited":false,"in_reply_to_user_id":null,"created_at":"Sat Dec 06 21:29:14 +0000 2008","source":"web","in_reply_to_status_id":null,"id":"1042500577"},{"user":{"followers_count":33,"description":"Living in denial that I live in a podunk town, I spend my time in search of good music in LA. Pure city-dweller and puma. That's about it.","url":"","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/56024131\/Photo_145_normal.jpg","protected":false,"location":"Santa Barbara, CA","screen_name":"pumainthemvmt","name":"Valerie","id":"15266837"},"text":"I love my parents with all my heart, but sometimes they make me want to scratch my eyes out.","truncated":false,"favorited":false,"in_reply_to_user_id":null,"created_at":"Sat Dec 06 21:29:10 +0000 2008","source":"sms","in_reply_to_status_id":null,"id":"1042500576"},{"user":{"followers_count":99,"description":"大学生ですよ。Ad[es]er。趣味で辭書とか編輯してゐます。JavaScriptでゲーム書きたいけど時間ねえ。","url":"http:\/\/greengablez.net\/diary\/","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/60269370\/zonu_1_normal.gif","protected":false,"location":"Sapporo, Hokkaido, Japan","screen_name":"tadsan","name":"船越次男","id":"11637282"},"text":"リトル・プリンセスとだけ書かれたら小公女を連想するだろ、常識的に考へて。","truncated":false,"favorited":false,"in_reply_to_user_id":null,"created_at":"Sat Dec 06 21:29:11 +0000 2008","source":"tiitan","in_reply_to_status_id":null,"id":"1042500575"},{"user":{"followers_count":68,"description":"I love all things beer. What goes better with beer than Porn, nothig I tell ya nothing.","url":"","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/66479069\/Picture_9_normal.jpg","protected":false,"location":"Durant","screen_name":"Jeffporn","name":"Jeffporn","id":"14065262"},"text":"At Lefthand having milk stout on cask - Photo: http:\/\/bkite.com\/02PeH","truncated":false,"favorited":false,"in_reply_to_user_id":null,"created_at":"Sat Dec 06 21:29:10 +0000 2008","source":"brightkite","in_reply_to_status_id":null,"id":"1042500574"},{"user":{"followers_count":7,"description":"","url":"http:\/\/www.PeteKinser.com","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/65572489\/PeteKinser-close_normal.jpg","protected":false,"location":"Denver, CO","screen_name":"pkinser","name":"pkinser","id":"15570525"},"text":"Snooze is where it's at for brunch if you're ever in Denver. Yum.","truncated":false,"favorited":false,"in_reply_to_user_id":null,"created_at":"Sat Dec 06 21:29:11 +0000 2008","source":"fring","in_reply_to_status_id":null,"id":"1042500572"},{"user":{"followers_count":75,"description":"I am a gamer and this is my gaming account, check out my other Twitter account for non-gaming tweets.","url":"http:\/\/twitter.com\/Nailhead","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/56881055\/nailhead_184x184_normal.jpg","protected":false,"location":"Huntsville, AL","screen_name":"Nailhead_Gamer","name":"Eric Fullerton","id":"15487663"},"text":"Completed the epic quest line for the Death Knight. Now what? Outlands? I wish to skip Outlands please, thanks.","truncated":false,"favorited":false,"in_reply_to_user_id":null,"created_at":"Sat Dec 06 21:29:13 +0000 2008","source":"twitterfox","in_reply_to_status_id":null,"id":"1042500571"},{"user":{"followers_count":111,"description":"","url":"http:\/\/www.ns-tech.com\/blog\/geldred.nsf","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/63865052\/brak2_normal.JPG","protected":false,"location":"Cleveland OH","screen_name":"geldred","name":"geldred","id":"14093394"},"text":"I'm at Target Store - Avon OH (35830 Detroit Rd, Avon, OH 44011, USA) - http:\/\/bkite.com\/02PeI","truncated":false,"favorited":false,"in_reply_to_user_id":null,"created_at":"Sat Dec 06 21:29:13 +0000 2008","source":"brightkite","in_reply_to_status_id":null,"id":"1042500570"},{"user":{"followers_count":16,"description":"Soundtrack Composer\/Musician\/Producer","url":"http:\/\/www.reverbnation\/musicbystratos","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/63311865\/logo-stratos_normal.png","protected":false,"location":"Grove City, Ohio 43123","screen_name":"Stratos","name":"Bryan K Borgman","id":"756062"},"text":"is reminded how beautiful the world can be when it's blanketed by clean white snow.","truncated":false,"favorited":false,"in_reply_to_user_id":null,"created_at":"Sat Dec 06 21:29:13 +0000 2008","source":"web","in_reply_to_status_id":null,"id":"1042500569"},{"user":{"followers_count":7,"description":null,"url":null,"profile_image_url":"http:\/\/static.twitter.com\/images\/default_profile_normal.png","protected":false,"location":null,"screen_name":"garrettromine","name":"garrettromine","id":"16120885"},"text":"Go Julio","truncated":false,"favorited":false,"in_reply_to_user_id":null,"created_at":"Sat Dec 06 21:29:10 +0000 2008","source":"sms","in_reply_to_status_id":null,"id":"1042500568"},{"user":{"followers_count":111,"description":"WHAT IS HAPPNING IN THE WORLD??? SEE DIFFERENT NEWS STORIES FROM MANY SOURCES.","url":"http:\/\/henrynews.wetpaint.com","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/65118112\/2008-election-map-nytimes_normal.png","protected":false,"location":"","screen_name":"HenryNews","name":"HenryNews","id":"17398510"},"text":"Svindal completes double at Beaver Creek: Read full story for latest details. http:\/\/tinyurl.com\/6qugub","truncated":false,"favorited":false,"in_reply_to_user_id":null,"created_at":"Sat Dec 06 21:29:13 +0000 2008","source":"twitterfeed","in_reply_to_status_id":null,"id":"1042500567"},{"user":{"followers_count":34,"description":"I am a man of many bio's, scott bio's!","url":"http:\/\/flickr.com\/photos\/giantcandy","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/25680382\/Icon_for_Twitter_normal.jpg","protected":false,"location":"Loves Park, IL, USA","screen_name":"Pychobj2001","name":"William Boehm Jr","id":"809103"},"text":"I have a 3rd break light and the license plate lights are out...just replacing 1 plate light...abide by law just enough","truncated":false,"favorited":false,"in_reply_to_user_id":null,"created_at":"Sat Dec 06 21:29:10 +0000 2008","source":"twidroid","in_reply_to_status_id":null,"id":"1042500566"},{"user":{"followers_count":61,"description":"Wife. Designer. Green Enthusiast. New Homeowner. Pet Owner. Internet Addict.","url":"http:\/\/confessionsofadesignjunkie.blogspot.com\/","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/66044439\/n27310459_33432814_6743-1_normal.jpg","protected":false,"location":"Indiana","screen_name":"smquaseb","name":"Stacy","id":"15530992"},"text":"@Indygardener We still had a few people shoveling in our neighborhood - I didn't think it was enough to shovel, but keeps the kids busy.","truncated":false,"favorited":false,"in_reply_to_user_id":12811482,"created_at":"Sat Dec 06 21:29:13 +0000 2008","source":"web","in_reply_to_status_id":1042488558,"id":"1042500565"}] \ No newline at end of file diff --git a/vendor/ruby/1.9.1/gems/httparty-0.9.0/spec/fixtures/twitter.xml b/vendor/ruby/1.9.1/gems/httparty-0.9.0/spec/fixtures/twitter.xml new file mode 100644 index 0000000..24abaa8 --- /dev/null +++ b/vendor/ruby/1.9.1/gems/httparty-0.9.0/spec/fixtures/twitter.xml @@ -0,0 +1,403 @@ + + + Sun Dec 07 00:36:16 +0000 2008 + 1042729116 + @sebbo Outlook not so good + web + false + 1042716367 + 2989541 + false + + 17656026 + Magic 8 Bot + magic8bot + ask me a question + + http://s3.amazonaws.com/twitter_production/profile_images/65565851/8ball_large_normal.jpg + + false + 90 + + + Sun Dec 07 00:36:14 +0000 2008 + 1042729115 + Azdel Slade :friends from midian city http://bloghud.com/id/27312 + web + false + + + false + + 801094 + BlogHUD + bloghud + + + http://s3.amazonaws.com/twitter_production/profile_images/25235272/bloghud_twitter_normal.jpg + + false + 313 + + + Sun Dec 07 00:36:14 +0000 2008 + 1042729114 + Reading: "The Reckoning - Debt Watchdogs - Tamed or Caught Napping? - Series - NYTimes.com" ( http://tinyurl.com/5754s6 ) + twitthat + false + + + false + + 3512101 + bill + niubi + in beijing learning socialism 2 prepare 4 return 2 us + beijing + http://s3.amazonaws.com/twitter_production/profile_images/53292616/realtwitterers_normal.jpg + + false + 710 + + + Sun Dec 07 00:36:14 +0000 2008 + 1042729113 + Fianlly done and headed home! + sms + false + + + false + + 13186842 + Okthirddayfan + Okthirddayfan + + Oklahoma! + http://s3.amazonaws.com/twitter_production/profile_images/61414367/mecropped_normal.jpg + http://thirddaypix.blogspot.com/ + false + 68 + + + Sun Dec 07 00:36:16 +0000 2008 + 1042729112 + Adobe Flashplayer 10 and Debug versions: http://www.adobe.com/support/flashplayer/downloads.html + toro + false + + + false + + 15243380 + cbrueggenolte + cbrueggenolte + 27, Male, Mac Geek, Developer Java &amp; Flex &amp; Air + Aachen + http://s3.amazonaws.com/twitter_production/profile_images/55929263/214508011845f026bfd407c_normal.jpg + http://my.opera.com/carstenbrueggenolte + false + 16 + + + Sun Dec 07 00:36:14 +0000 2008 + 1042729111 + Done and done. + twitterrific + false + + + false + + 10978752 + Sergey Safonov + iron_Lung + I have my fingers in many pies. + Moscow + http://s3.amazonaws.com/twitter_production/profile_images/57841057/eat38_normal.gif + http://www.flickr.com/photos/iron_Lung + false + 11 + + + Sun Dec 07 00:36:14 +0000 2008 + 1042729110 + Veja a tabela de preços do Acquaplay da Tecnisa aqui:http://tinyurl.com/acquaplaypreco + web + false + + + false + + 13735402 + Tecnisa S.A + Tecnisa + Mais construtora por m2 + Faria Lima, 3144 - SP + http://s3.amazonaws.com/twitter_production/profile_images/56572222/logo_normal.jpg + http://www.tecnisa.com.br + false + 77 + + + Sun Dec 07 00:36:16 +0000 2008 + 1042729108 + devin harris has the flu. always have the memory of jordan scoring 50 on the knicks at the garden with the flu + web + false + + + false + + 17930773 + 24 Seconds to Shoot + NBA24sts + NBA handicapping insight and analysis. + las vegas + http://s3.amazonaws.com/twitter_production/profile_images/66593862/fresno_normal.jpg + + false + 1 + + + Sun Dec 07 00:36:16 +0000 2008 + 1042729105 + At Brandon and Shannon's holiday party.. + twitterberry + false + + + false + + 5388602 + Mike J. (Telligent) + mjamrst + Video Game Account Manager + Palo Alto, CA + http://s3.amazonaws.com/twitter_production/profile_images/66375174/Thanksgiving_11272008-048_normal.jpg + http://www.telligent.com + false + 225 + + + Sun Dec 07 00:36:13 +0000 2008 + 1042729104 + Xinhua: Forty percent of Australian PM office' staff quit : CANBERRA, Dec. 7 (Xinhua) -- Only.. http://tinyurl.com/5gwotd + twitterfeed + false + + + false + + 11566502 + Headline News + headlinenews + + + http://s3.amazonaws.com/twitter_production/profile_images/41784602/1890_wires_normal.jpg + + false + 575 + + + Sun Dec 07 00:36:13 +0000 2008 + 1042729101 + @hilarycassman soo funnny + sms + false + 1042725825 + 17644455 + false + + 17887548 + katieballss + katieballss + + + http://s3.amazonaws.com/twitter_production/profile_images/66523737/th_Photo87_normal.jpg + http://www.myspace.com/xxpeachxx101 + false + 23 + + + Sun Dec 07 00:36:13 +0000 2008 + 1042729100 + d'ora in poi, oltre al ferragosto, odiera' anche il natale e tutto il mese che ci gira intorno.. =.='' + mobile + false + + + false + + 9719482 + trotto + trotto + sociologo di formazione... uno dei tanti attivisti! :) + Fano - Italy + http://s3.amazonaws.com/twitter_production/profile_images/55603933/mybob-calimetux-1526_normal.png + http://trotto1308.netsons.org/wordpress/ + false + 98 + + + Sun Dec 07 00:36:13 +0000 2008 + 1042729099 + Came across an ad on another site with a redneck looking santa... said "Bust Santa's zit and win a free ipod." Umm... disturbing much? + web + false + + + false + + 9937182 + froggybluesock + froggybluesock + + Indiana + http://s3.amazonaws.com/twitter_production/profile_images/35393032/about_me_normal.jpg + http://www.footprintsonthemoon.com + false + 82 + + + Sun Dec 07 00:36:17 +0000 2008 + 1042729098 + nothing + web + false + + + false + + 17932339 + treblehook + treblehook + + + http://static.twitter.com/images/default_profile_normal.png + + false + 0 + + + Sun Dec 07 00:36:13 +0000 2008 + 1042729095 + Setting up my new Windows Live profile + web + false + + + false + + 17906075 + Mark_Layton + Mark_Layton + + + http://static.twitter.com/images/default_profile_normal.png + + false + 2 + + + Sun Dec 07 00:36:13 +0000 2008 + 1042729092 + me voy a sobar, a ver si mañana estoy mejor, wenas noches a tod@s + web + false + + + false + + 14062655 + tmaniak + tmaniak + + + http://s3.amazonaws.com/twitter_production/profile_images/51680481/BF-109_normal.jpg + http://dhost.info/tmaniak + false + 10 + + + Sun Dec 07 00:36:14 +0000 2008 + 1042729090 + バイト延長戦入りましたー 店長が遅刻ってどうなんだ。しかも何回も + natsuliphone + false + + + false + + 15618846 + kabayaki + kabayaki + FPS(L4D、TF2、CS:S、BF)、TPS、RCG、マンガ、アニメ、デジモノが好きなとある学生 + tokyo + http://s3.amazonaws.com/twitter_production/profile_images/57305902/184_normal.jpg + http://kabayakiya.blog43.fc2.com/ + false + 20 + + + Sun Dec 07 00:36:13 +0000 2008 + 1042729089 + just drove to southern california and joy of children hugging grandparents made it all worthwhile. heading to imedia in la quinta tomorrow. + web + false + + + false + + 1630261 + mark silva + marksilva + digital media http://realbranding.com Principal, Managing Director + often san francisco + http://s3.amazonaws.com/twitter_production/profile_images/29807902/silvasimpson3th_normal.jpg + http://marksilva.com + false + 497 + + + Sun Dec 07 00:36:14 +0000 2008 + 1042729088 + @wholefoods would love to have a juicebar in one of your cambridge or boston locations + web + false + 1041125103 + 15131310 + false + + 15856582 + Maura McGovern + mmcgovern + photographer with a day job in venture capital; obsessed with design blogs, long walks, yoga, social networking, people watching. tea and music are essential! + Boston + http://s3.amazonaws.com/twitter_production/profile_images/66110383/DSCN1740_normal.JPG + http://lefteyephotography.blogspot.com + false + 244 + + + Sun Dec 07 00:36:15 +0000 2008 + 1042729087 + Going over the Advent lists. + web + false + + + false + + 17122107 + gsusan + gsusan + US American writer/sister/daughter/aunt/woman from New England living in SoCal. + San Diego, CA USA + http://s3.amazonaws.com/twitter_production/profile_images/63951854/susan_ocracoke_normal.jpg + + false + 6 + + + \ No newline at end of file diff --git a/vendor/ruby/1.9.1/gems/httparty-0.9.0/spec/fixtures/undefined_method_add_node_for_nil.xml b/vendor/ruby/1.9.1/gems/httparty-0.9.0/spec/fixtures/undefined_method_add_node_for_nil.xml new file mode 100644 index 0000000..43d96a7 --- /dev/null +++ b/vendor/ruby/1.9.1/gems/httparty-0.9.0/spec/fixtures/undefined_method_add_node_for_nil.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/vendor/ruby/1.9.1/gems/httparty-0.9.0/spec/httparty/connection_adapter_spec.rb b/vendor/ruby/1.9.1/gems/httparty-0.9.0/spec/httparty/connection_adapter_spec.rb new file mode 100644 index 0000000..f405e0f --- /dev/null +++ b/vendor/ruby/1.9.1/gems/httparty-0.9.0/spec/httparty/connection_adapter_spec.rb @@ -0,0 +1,206 @@ +require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper')) + +describe HTTParty::ConnectionAdapter do + + describe "initialization" do + let(:uri) { URI 'http://www.google.com' } + it "takes a URI as input" do + HTTParty::ConnectionAdapter.new(uri) + end + + it "raises an ArgumentError if the uri is nil" do + expect { HTTParty::ConnectionAdapter.new(nil) }.to raise_error ArgumentError + end + + it "raises an ArgumentError if the uri is a String" do + expect { HTTParty::ConnectionAdapter.new('http://www.google.com') }.to raise_error ArgumentError + end + + it "sets the uri" do + adapter = HTTParty::ConnectionAdapter.new(uri) + adapter.uri.should be uri + end + + it "also accepts an optional options hash" do + HTTParty::ConnectionAdapter.new(uri, {}) + end + + it "sets the options" do + options = {:foo => :bar} + adapter = HTTParty::ConnectionAdapter.new(uri, options) + adapter.options.should be options + end + end + + describe ".call" do + it "generates an HTTParty::ConnectionAdapter instance with the given uri and options" do + HTTParty::ConnectionAdapter.should_receive(:new).with(@uri, @options).and_return(stub(:connection => nil)) + HTTParty::ConnectionAdapter.call(@uri, @options) + end + + it "calls #connection on the connection adapter" do + adapter = mock('Adapter') + connection = mock('Connection') + adapter.should_receive(:connection).and_return(connection) + HTTParty::ConnectionAdapter.stub(:new => adapter) + HTTParty::ConnectionAdapter.call(@uri, @options).should be connection + end + end + + describe '#connection' do + let(:uri) { URI 'http://www.google.com' } + let(:options) { Hash.new } + let(:adapter) { HTTParty::ConnectionAdapter.new(uri, options) } + + describe "the resulting connection" do + subject { adapter.connection } + it { should be_an_instance_of Net::HTTP } + + context "using port 80" do + let(:uri) { URI 'http://foobar.com' } + it { should_not use_ssl } + end + + context "when dealing with ssl" do + let(:uri) { URI 'https://foobar.com' } + + context "using port 443 for ssl" do + let(:uri) { URI 'https://api.foo.com/v1:443' } + it { should use_ssl } + end + + context "https scheme with default port" do + it { should use_ssl } + end + + context "https scheme with non-standard port" do + let(:uri) { URI 'https://foobar.com:123456' } + it { should use_ssl } + end + + context "when ssl version is set" do + let(:options) { {:ssl_version => :TLSv1} } + + it "sets ssl version" do + subject.ssl_version.should == :TLSv1 + end + end if RUBY_VERSION > '1.9' + end + + context "when timeout is not set" do + it "doesn't set the timeout" do + http = mock("http", :null_object => true) + http.should_not_receive(:open_timeout=) + http.should_not_receive(:read_timeout=) + Net::HTTP.stub(:new => http) + + adapter.connection + end + end + + context "when setting timeout" do + context "to 5 seconds" do + let(:options) { {:timeout => 5} } + + its(:open_timeout) { should == 5 } + its(:read_timeout) { should == 5 } + end + + context "and timeout is a string" do + let(:options) { {:timeout => "five seconds"} } + + it "doesn't set the timeout" do + http = mock("http", :null_object => true) + http.should_not_receive(:open_timeout=) + http.should_not_receive(:read_timeout=) + Net::HTTP.stub(:new => http) + + adapter.connection + end + end + end + + context "when debug_output" do + let(:http) { Net::HTTP.new(uri) } + before do + Net::HTTP.stub(:new => http) + end + + context "is set to $stderr" do + let(:options) { {:debug_output => $stderr} } + it "has debug output set" do + http.should_receive(:set_debug_output).with($stderr) + adapter.connection + end + end + + context "is not provided" do + it "does not set_debug_output" do + http.should_not_receive(:set_debug_output) + adapter.connection + end + end + end + + context 'when providing proxy address and port' do + let(:options) { {:http_proxyaddr => '1.2.3.4', :http_proxyport => 8080} } + + it { should be_a_proxy } + its(:proxy_address) { should == '1.2.3.4' } + its(:proxy_port) { should == 8080 } + + context 'as well as proxy user and password' do + let(:options) do + {:http_proxyaddr => '1.2.3.4', :http_proxyport => 8080, + :http_proxyuser => 'user', :http_proxypass => 'pass'} + end + its(:proxy_user) { should == 'user' } + its(:proxy_pass) { should == 'pass' } + end + end + + context "when providing PEM certificates" do + let(:pem) { :pem_contents } + let(:options) { {:pem => pem, :pem_password => "password"} } + + context "when scheme is https" do + let(:uri) { URI 'https://google.com' } + let(:cert) { mock("OpenSSL::X509::Certificate") } + let(:key) { mock("OpenSSL::PKey::RSA") } + + before do + OpenSSL::X509::Certificate.should_receive(:new).with(pem).and_return(cert) + OpenSSL::PKey::RSA.should_receive(:new).with(pem, "password").and_return(key) + end + + it "uses the provided PEM certificate " do + subject.cert.should == cert + subject.key.should == key + end + + it "will verify the certificate" do + subject.verify_mode.should == OpenSSL::SSL::VERIFY_PEER + end + end + + context "when scheme is not https" do + let(:uri) { URI 'http://google.com' } + let(:http) { Net::HTTP.new(uri) } + + before do + Net::HTTP.stub(:new => http) + OpenSSL::X509::Certificate.should_not_receive(:new).with(pem) + OpenSSL::PKey::RSA.should_not_receive(:new).with(pem, "password") + http.should_not_receive(:cert=) + http.should_not_receive(:key=) + end + + it "has no PEM certificate " do + subject.cert.should be_nil + subject.key.should be_nil + end + end + end + end + end +end diff --git a/vendor/ruby/1.9.1/gems/httparty-0.9.0/spec/httparty/cookie_hash_spec.rb b/vendor/ruby/1.9.1/gems/httparty-0.9.0/spec/httparty/cookie_hash_spec.rb new file mode 100644 index 0000000..3a754cc --- /dev/null +++ b/vendor/ruby/1.9.1/gems/httparty-0.9.0/spec/httparty/cookie_hash_spec.rb @@ -0,0 +1,70 @@ +require File.expand_path(File.join(File.dirname(__FILE__), '../spec_helper')) + +describe HTTParty::CookieHash do + before(:each) do + @cookie_hash = HTTParty::CookieHash.new + end + + describe "#add_cookies" do + describe "with a hash" do + it "should add new key/value pairs to the hash" do + @cookie_hash.add_cookies(:foo => "bar") + @cookie_hash.add_cookies(:rofl => "copter") + @cookie_hash.length.should eql(2) + end + + it "should overwrite any existing key" do + @cookie_hash.add_cookies(:foo => "bar") + @cookie_hash.add_cookies(:foo => "copter") + @cookie_hash.length.should eql(1) + @cookie_hash[:foo].should eql("copter") + end + end + + describe "with a string" do + it "should add new key/value pairs to the hash" do + @cookie_hash.add_cookies("first=one; second=two; third") + @cookie_hash[:first].should == 'one' + @cookie_hash[:second].should == 'two' + @cookie_hash[:third].should == nil + end + + it "should overwrite any existing key" do + @cookie_hash[:foo] = 'bar' + @cookie_hash.add_cookies("foo=tar") + @cookie_hash.length.should eql(1) + @cookie_hash[:foo].should eql("tar") + end + end + + describe 'with other class' do + it "should error" do + lambda { + @cookie_hash.add_cookies(Array.new) + }.should raise_error + end + end + end + + # The regexen are required because Hashes aren't ordered, so a test against + # a hardcoded string was randomly failing. + describe "#to_cookie_string" do + before(:each) do + @cookie_hash.add_cookies(:foo => "bar") + @cookie_hash.add_cookies(:rofl => "copter") + @s = @cookie_hash.to_cookie_string + end + + it "should format the key/value pairs, delimited by semi-colons" do + @s.should match(/foo=bar/) + @s.should match(/rofl=copter/) + @s.should match(/^\w+=\w+; \w+=\w+$/) + end + + it "should not include client side only cookies" do + @cookie_hash.add_cookies(:path => "/") + @s = @cookie_hash.to_cookie_string + @s.should_not match(/path=\//) + end + end +end diff --git a/vendor/ruby/1.9.1/gems/httparty-0.9.0/spec/httparty/net_digest_auth_spec.rb b/vendor/ruby/1.9.1/gems/httparty-0.9.0/spec/httparty/net_digest_auth_spec.rb new file mode 100644 index 0000000..8b7a4d9 --- /dev/null +++ b/vendor/ruby/1.9.1/gems/httparty-0.9.0/spec/httparty/net_digest_auth_spec.rb @@ -0,0 +1,115 @@ +require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper')) + +describe Net::HTTPHeader::DigestAuthenticator do + def setup_digest(response) + digest = Net::HTTPHeader::DigestAuthenticator.new("Mufasa", + "Circle Of Life", "GET", "/dir/index.html", response) + digest.stub(:random).and_return("deadbeef") + Digest::MD5.stub(:hexdigest) { |str| "md5(#{str})" } + digest + end + + def authorization_header + @digest.authorization_header.join(", ") + end + + + context "with an opaque value in the response header" do + before do + @digest = setup_digest({ + 'www-authenticate' => 'Digest realm="myhost@testrealm.com", opaque="solid"' + }) + end + + it "should set opaque" do + authorization_header.should include(%Q(opaque="solid")) + end + end + + context "without an opaque valid in the response header" do + before do + @digest = setup_digest({ + 'www-authenticate' => 'Digest realm="myhost@testrealm.com"' + }) + end + + it "should not set opaque" do + authorization_header.should_not include(%Q(opaque=)) + end + end + + context "with specified quality of protection (qop)" do + before do + @digest = setup_digest({ + 'www-authenticate' => 'Digest realm="myhost@testrealm.com", nonce="NONCE", qop="auth"', + }) + end + + it "should set prefix" do + authorization_header.should =~ /^Digest / + end + + it "should set username" do + authorization_header.should include(%Q(username="Mufasa")) + end + + it "should set digest-uri" do + authorization_header.should include(%Q(uri="/dir/index.html")) + end + + it "should set qop" do + authorization_header.should include(%Q(qop="auth")) + end + + it "should set cnonce" do + authorization_header.should include(%Q(cnonce="md5(deadbeef)")) + end + + it "should set nonce-count" do + authorization_header.should include(%Q(nc="00000001")) + end + + it "should set response" do + request_digest = "md5(md5(Mufasa:myhost@testrealm.com:Circle Of Life):NONCE:00000001:md5(deadbeef):auth:md5(GET:/dir/index.html))" + authorization_header.should include(%Q(response="#{request_digest}")) + end + end + + + context "with unspecified quality of protection (qop)" do + before do + @digest = setup_digest({ + 'www-authenticate' => 'Digest realm="myhost@testrealm.com", nonce="NONCE"', + }) + end + + it "should set prefix" do + authorization_header.should =~ /^Digest / + end + + it "should set username" do + authorization_header.should include(%Q(username="Mufasa")) + end + + it "should set digest-uri" do + authorization_header.should include(%Q(uri="/dir/index.html")) + end + + it "should not set qop" do + authorization_header.should_not include(%Q(qop=)) + end + + it "should not set cnonce" do + authorization_header.should_not include(%Q(cnonce=)) + end + + it "should not set nonce-count" do + authorization_header.should_not include(%Q(nc=)) + end + + it "should set response" do + request_digest = "md5(md5(Mufasa:myhost@testrealm.com:Circle Of Life):NONCE:md5(GET:/dir/index.html))" + authorization_header.should include(%Q(response="#{request_digest}")) + end + end +end diff --git a/vendor/ruby/1.9.1/gems/httparty-0.9.0/spec/httparty/parser_spec.rb b/vendor/ruby/1.9.1/gems/httparty-0.9.0/spec/httparty/parser_spec.rb new file mode 100644 index 0000000..a72bbfd --- /dev/null +++ b/vendor/ruby/1.9.1/gems/httparty-0.9.0/spec/httparty/parser_spec.rb @@ -0,0 +1,171 @@ +require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper')) + +describe HTTParty::Parser do + describe ".SupportedFormats" do + it "returns a hash" do + HTTParty::Parser::SupportedFormats.should be_instance_of(Hash) + end + end + + describe ".call" do + it "generates an HTTParty::Parser instance with the given body and format" do + HTTParty::Parser.should_receive(:new).with('body', :plain).and_return(stub(:parse => nil)) + HTTParty::Parser.call('body', :plain) + end + + it "calls #parse on the parser" do + parser = mock('Parser') + parser.should_receive(:parse) + HTTParty::Parser.stub(:new => parser) + parser = HTTParty::Parser.call('body', :plain) + end + end + + describe ".formats" do + it "returns the SupportedFormats constant" do + HTTParty::Parser.formats.should == HTTParty::Parser::SupportedFormats + end + + it "returns the SupportedFormats constant for subclasses" do + class MyParser < HTTParty::Parser + SupportedFormats = {"application/atom+xml" => :atom} + end + MyParser.formats.should == {"application/atom+xml" => :atom} + end + end + + describe ".format_from_mimetype" do + it "returns a symbol representing the format mimetype" do + HTTParty::Parser.format_from_mimetype("text/plain").should == :plain + end + + it "returns nil when the mimetype is not supported" do + HTTParty::Parser.format_from_mimetype("application/atom+xml").should be_nil + end + end + + describe ".supported_formats" do + it "returns a unique set of supported formats represented by symbols" do + HTTParty::Parser.supported_formats.should == HTTParty::Parser::SupportedFormats.values.uniq + end + end + + describe ".supports_format?" do + it "returns true for a supported format" do + HTTParty::Parser.stub(:supported_formats => [:json]) + HTTParty::Parser.supports_format?(:json).should be_true + end + + it "returns false for an unsupported format" do + HTTParty::Parser.stub(:supported_formats => []) + HTTParty::Parser.supports_format?(:json).should be_false + end + end + + describe "#parse" do + before do + @parser = HTTParty::Parser.new('body', :json) + end + + it "attempts to parse supported formats" do + @parser.stub(:supports_format? => true) + @parser.should_receive(:parse_supported_format) + @parser.parse + end + + it "returns the unparsed body when the format is unsupported" do + @parser.stub(:supports_format? => false) + @parser.parse.should == @parser.body + end + + it "returns nil for an empty body" do + @parser.stub(:body => '') + @parser.parse.should be_nil + end + + it "returns nil for a nil body" do + @parser.stub(:body => nil) + @parser.parse.should be_nil + end + + it "returns nil for a 'null' body" do + @parser.stub(:body => "null") + @parser.parse.should be_nil + end + + it "returns nil for a body with spaces only" do + @parser.stub(:body => " ") + @parser.parse.should be_nil + end + end + + describe "#supports_format?" do + it "utilizes the class method to determine if the format is supported" do + HTTParty::Parser.should_receive(:supports_format?).with(:json) + parser = HTTParty::Parser.new('body', :json) + parser.send(:supports_format?) + end + end + + describe "#parse_supported_format" do + it "calls the parser for the given format" do + parser = HTTParty::Parser.new('body', :json) + parser.should_receive(:json) + parser.send(:parse_supported_format) + end + + context "when a parsing method does not exist for the given format" do + it "raises an exception" do + parser = HTTParty::Parser.new('body', :atom) + expect do + parser.send(:parse_supported_format) + end.to raise_error(NotImplementedError, "HTTParty::Parser has not implemented a parsing method for the :atom format.") + end + + it "raises a useful exception message for subclasses" do + atom_parser = Class.new(HTTParty::Parser) do + def self.name; 'AtomParser'; end + end + parser = atom_parser.new 'body', :atom + expect do + parser.send(:parse_supported_format) + end.to raise_error(NotImplementedError, "AtomParser has not implemented a parsing method for the :atom format.") + end + end + end + + context "parsers" do + subject do + HTTParty::Parser.new('body', nil) + end + + it "parses xml with MultiXml" do + MultiXml.should_receive(:parse).with('body') + subject.send(:xml) + end + + it "parses json with MultiJson" do + MultiJson.should_receive(:load).with('body') + subject.send(:json) + end + + it "uses MultiJson.decode if MultiJson does not respond to adapter" do + MultiJson.should_receive(:respond_to?).with(:adapter).and_return(false) + MultiJson.should_receive(:decode).with('body') + subject.send(:json) + end + + it "parses yaml" do + YAML.should_receive(:load).with('body') + subject.send(:yaml) + end + + it "parses html by simply returning the body" do + subject.send(:html).should == 'body' + end + + it "parses plain text by simply returning the body" do + subject.send(:plain).should == 'body' + end + end +end diff --git a/vendor/ruby/1.9.1/gems/httparty-0.9.0/spec/httparty/request_spec.rb b/vendor/ruby/1.9.1/gems/httparty-0.9.0/spec/httparty/request_spec.rb new file mode 100644 index 0000000..9db7b72 --- /dev/null +++ b/vendor/ruby/1.9.1/gems/httparty-0.9.0/spec/httparty/request_spec.rb @@ -0,0 +1,495 @@ +require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper')) + +describe HTTParty::Request do + before do + @request = HTTParty::Request.new(Net::HTTP::Get, 'http://api.foo.com/v1', :format => :xml) + end + + describe "::NON_RAILS_QUERY_STRING_NORMALIZER" do + let(:normalizer) { HTTParty::Request::NON_RAILS_QUERY_STRING_NORMALIZER } + + it "doesn't modify strings" do + query_string = normalizer["foo=bar&foo=baz"] + URI.unescape(query_string).should == "foo=bar&foo=baz" + end + + context "when the query is an array" do + + it "doesn't include brackets" do + query_string = normalizer[{:page => 1, :foo => %w(bar baz)}] + URI.unescape(query_string).should == "foo=bar&foo=baz&page=1" + end + + it "URI encodes array values" do + query_string = normalizer[{:people => ["Bob Marley", "Tim & Jon"]}] + query_string.should == "people=Bob%20Marley&people=Tim%20%26%20Jon" + end + end + + context "when the query is a hash" do + it "correctly handles nil values" do + query_string = normalizer[{:page => 1, :per_page => nil}] + query_string.should == "page=1&per_page" + end + end + end + + describe "initialization" do + it "sets parser to HTTParty::Parser" do + request = HTTParty::Request.new(Net::HTTP::Get, 'http://google.com') + request.parser.should == HTTParty::Parser + end + + it "sets parser to the optional parser" do + my_parser = lambda {} + request = HTTParty::Request.new(Net::HTTP::Get, 'http://google.com', :parser => my_parser) + request.parser.should == my_parser + end + + it "sets connection_adapter to HTTPParty::ConnectionAdapter" do + request = HTTParty::Request.new(Net::HTTP::Get, 'http://google.com') + request.connection_adapter.should == HTTParty::ConnectionAdapter + end + + it "sets connection_adapter to the optional connection_adapter" do + my_adapter = lambda {} + request = HTTParty::Request.new(Net::HTTP::Get, 'http://google.com', :connection_adapter => my_adapter) + request.connection_adapter.should == my_adapter + end + end + + describe "#format" do + context "request yet to be made" do + it "returns format option" do + request = HTTParty::Request.new 'get', '/', :format => :xml + request.format.should == :xml + end + + it "returns nil format" do + request = HTTParty::Request.new 'get', '/' + request.format.should be_nil + end + end + + context "request has been made" do + it "returns format option" do + request = HTTParty::Request.new 'get', '/', :format => :xml + request.last_response = stub + request.format.should == :xml + end + + it "returns the content-type from the last response when the option is not set" do + request = HTTParty::Request.new 'get', '/' + response = stub + response.should_receive(:[]).with('content-type').and_return('text/json') + request.last_response = response + request.format.should == :json + end + end + + end + + context "options" do + it "should use basic auth when configured" do + @request.options[:basic_auth] = {:username => 'foobar', :password => 'secret'} + @request.send(:setup_raw_request) + @request.instance_variable_get(:@raw_request)['authorization'].should_not be_nil + end + + it "should use digest auth when configured" do + FakeWeb.register_uri(:get, "http://api.foo.com/v1", + :www_authenticate => 'Digest realm="Log Viewer", qop="auth", nonce="2CA0EC6B0E126C4800E56BA0C0003D3C", opaque="5ccc069c403ebaf9f0171e9517f40e41", stale=false') + + @request.options[:digest_auth] = {:username => 'foobar', :password => 'secret'} + @request.send(:setup_raw_request) + + raw_request = @request.instance_variable_get(:@raw_request) + raw_request.instance_variable_get(:@header)['Authorization'].should_not be_nil + end + + it "should use the right http method for digest authentication" do + @post_request = HTTParty::Request.new(Net::HTTP::Post, 'http://api.foo.com/v1', :format => :xml) + FakeWeb.register_uri(:post, "http://api.foo.com/v1", {}) + + http = @post_request.send(:http) + @post_request.should_receive(:http).and_return(http) + http.should_not_receive(:head).and_return({'www-authenticate' => nil}) + @post_request.options[:digest_auth] = {:username => 'foobar', :password => 'secret'} + @post_request.send(:setup_raw_request) + end + end + + describe "#uri" do + context "query strings" do + it "does not add an empty query string when default_params are blank" do + @request.options[:default_params] = {} + @request.uri.query.should be_nil + end + + it "respects the query string normalization proc" do + empty_proc = lambda {|qs| ""} + @request.options[:query_string_normalizer] = empty_proc + @request.options[:query] = {:foo => :bar} + URI.unescape(@request.uri.query).should == "" + end + + context "when representing an array" do + it "returns a Rails style query string" do + @request.options[:query] = {:foo => %w(bar baz)} + URI.unescape(@request.uri.query).should == "foo[]=bar&foo[]=baz" + end + end + + end + end + + describe "#setup_raw_request" do + context "when query_string_normalizer is set" do + it "sets the body to the return value of the proc" do + @request.options[:query_string_normalizer] = HTTParty::Request::NON_RAILS_QUERY_STRING_NORMALIZER + @request.options[:body] = {:page => 1, :foo => %w(bar baz)} + @request.send(:setup_raw_request) + body = @request.instance_variable_get(:@raw_request).body + URI.unescape(body).should == "foo=bar&foo=baz&page=1" + end + end + end + + describe 'http' do + it "should get a connection from the connection_adapter" do + http = Net::HTTP.new('google.com') + adapter = mock('adapter') + request = HTTParty::Request.new(Net::HTTP::Get, 'https://api.foo.com/v1:443', :connection_adapter => adapter) + adapter.should_receive(:call).with(request.uri, request.options).and_return(http) + request.send(:http).should be http + end + end + + describe '#format_from_mimetype' do + it 'should handle text/xml' do + ["text/xml", "text/xml; charset=iso8859-1"].each do |ct| + @request.send(:format_from_mimetype, ct).should == :xml + end + end + + it 'should handle application/xml' do + ["application/xml", "application/xml; charset=iso8859-1"].each do |ct| + @request.send(:format_from_mimetype, ct).should == :xml + end + end + + it 'should handle text/json' do + ["text/json", "text/json; charset=iso8859-1"].each do |ct| + @request.send(:format_from_mimetype, ct).should == :json + end + end + + it 'should handle application/json' do + ["application/json", "application/json; charset=iso8859-1"].each do |ct| + @request.send(:format_from_mimetype, ct).should == :json + end + end + + it 'should handle text/javascript' do + ["text/javascript", "text/javascript; charset=iso8859-1"].each do |ct| + @request.send(:format_from_mimetype, ct).should == :json + end + end + + it 'should handle application/javascript' do + ["application/javascript", "application/javascript; charset=iso8859-1"].each do |ct| + @request.send(:format_from_mimetype, ct).should == :json + end + end + + it "returns nil for an unrecognized mimetype" do + @request.send(:format_from_mimetype, "application/atom+xml").should be_nil + end + + it "returns nil when using a default parser" do + @request.options[:parser] = lambda {} + @request.send(:format_from_mimetype, "text/json").should be_nil + end + end + + describe 'parsing responses' do + it 'should handle xml automatically' do + xml = %q[1234Foo Bar!] + @request.options[:format] = :xml + @request.send(:parse_response, xml).should == {'books' => {'book' => {'id' => '1234', 'name' => 'Foo Bar!'}}} + end + + it 'should handle json automatically' do + json = %q[{"books": {"book": {"name": "Foo Bar!", "id": "1234"}}}] + @request.options[:format] = :json + @request.send(:parse_response, json).should == {'books' => {'book' => {'id' => '1234', 'name' => 'Foo Bar!'}}} + end + + it 'should handle yaml automatically' do + yaml = "books: \n book: \n name: Foo Bar!\n id: \"1234\"\n" + @request.options[:format] = :yaml + @request.send(:parse_response, yaml).should == {'books' => {'book' => {'id' => '1234', 'name' => 'Foo Bar!'}}} + end + + it "should include any HTTP headers in the returned response" do + @request.options[:format] = :html + response = stub_response "Content" + response.initialize_http_header("key" => "value") + + @request.perform.headers.should == { "key" => ["value"] } + end + + describe 'with non-200 responses' do + context "3xx responses" do + it 'returns a valid object for 304 not modified' do + stub_response '', 304 + resp = @request.perform + resp.code.should == 304 + resp.body.should == '' + resp.should be_nil + end + + it "redirects if a 300 contains a location header" do + redirect = stub_response '', 300 + redirect['location'] = 'http://foo.com/foo' + ok = stub_response('bar', 200) + @http.stub!(:request).and_return(redirect, ok) + response = @request.perform + response.request.base_uri.to_s.should == "http://foo.com" + response.request.path.to_s.should == "http://foo.com/foo" + response.request.uri.request_uri.should == "/foo" + response.request.uri.to_s.should == "http://foo.com/foo" + response.should == {"hash" => {"foo" => "bar"}} + end + + it "redirects if a 300 contains a relative location header" do + redirect = stub_response '', 300 + redirect['location'] = '/foo/bar' + ok = stub_response('bar', 200) + @http.stub!(:request).and_return(redirect, ok) + response = @request.perform + response.request.base_uri.to_s.should == "http://api.foo.com" + response.request.path.to_s.should == "/foo/bar" + response.request.uri.request_uri.should == "/foo/bar" + response.request.uri.to_s.should == "http://api.foo.com/foo/bar" + response.should == {"hash" => {"foo" => "bar"}} + end + + it "handles multiple redirects and relative location headers on different hosts" do + @request = HTTParty::Request.new(Net::HTTP::Get, 'http://test.com/redirect', :format => :xml) + FakeWeb.register_uri(:get, "http://test.com/redirect", :status => [300, "REDIRECT"], :location => "http://api.foo.com/v2") + FakeWeb.register_uri(:get, "http://api.foo.com/v2", :status => [300, "REDIRECT"], :location => "/v3") + FakeWeb.register_uri(:get, "http://api.foo.com/v3", :body => "bar") + response = @request.perform + response.request.base_uri.to_s.should == "http://api.foo.com" + response.request.path.to_s.should == "/v3" + response.request.uri.request_uri.should == "/v3" + response.request.uri.to_s.should == "http://api.foo.com/v3" + response.should == {"hash" => {"foo" => "bar"}} + end + + it "returns the HTTParty::Response when the 300 does not contain a location header" do + net_response = stub_response '', 300 + HTTParty::Response.should === @request.perform + end + end + + it 'should return a valid object for 4xx response' do + stub_response 'yes', 401 + resp = @request.perform + resp.code.should == 401 + resp.body.should == "yes" + resp['foo']['bar'].should == "yes" + end + + it 'should return a valid object for 5xx response' do + stub_response 'error', 500 + resp = @request.perform + resp.code.should == 500 + resp.body.should == "error" + resp['foo']['bar'].should == "error" + end + + it "parses response lazily so codes can be checked prior" do + stub_response 'not xml', 500 + @request.options[:format] = :xml + lambda { + response = @request.perform + response.code.should == 500 + response.body.should == 'not xml' + }.should_not raise_error + end + end + end + + it "should not attempt to parse empty responses" do + [204, 304].each do |code| + stub_response "", code + + @request.options[:format] = :xml + @request.perform.should be_nil + end + end + + it "should not fail for missing mime type" do + stub_response "Content for you" + @request.options[:format] = :html + @request.perform.should == 'Content for you' + end + + describe "a request that redirects" do + before(:each) do + @redirect = stub_response("", 302) + @redirect['location'] = '/foo' + + @ok = stub_response('bar', 200) + end + + describe "once" do + before(:each) do + @http.stub!(:request).and_return(@redirect, @ok) + end + + it "should be handled by GET transparently" do + @request.perform.should == {"hash" => {"foo" => "bar"}} + end + + it "should be handled by POST transparently" do + @request.http_method = Net::HTTP::Post + @request.perform.should == {"hash" => {"foo" => "bar"}} + end + + it "should be handled by DELETE transparently" do + @request.http_method = Net::HTTP::Delete + @request.perform.should == {"hash" => {"foo" => "bar"}} + end + + it "should be handled by PATCH transparently" do + @request.http_method = Net::HTTP::Patch + @request.perform.should == {"hash" => {"foo" => "bar"}} + end + + it "should be handled by PUT transparently" do + @request.http_method = Net::HTTP::Put + @request.perform.should == {"hash" => {"foo" => "bar"}} + end + + it "should be handled by HEAD transparently" do + @request.http_method = Net::HTTP::Head + @request.perform.should == {"hash" => {"foo" => "bar"}} + end + + it "should be handled by OPTIONS transparently" do + @request.http_method = Net::HTTP::Options + @request.perform.should == {"hash" => {"foo" => "bar"}} + end + + it "should keep track of cookies between redirects" do + @redirect['Set-Cookie'] = 'foo=bar; name=value; HTTPOnly' + @request.perform + @request.options[:headers]['Cookie'].should match(/foo=bar/) + @request.options[:headers]['Cookie'].should match(/name=value/) + end + + it 'should update cookies with rediects' do + @request.options[:headers] = {'Cookie'=> 'foo=bar;'} + @redirect['Set-Cookie'] = 'foo=tar;' + @request.perform + @request.options[:headers]['Cookie'].should match(/foo=tar/) + end + + it 'should keep cookies between rediects' do + @request.options[:headers] = {'Cookie'=> 'keep=me'} + @redirect['Set-Cookie'] = 'foo=tar;' + @request.perform + @request.options[:headers]['Cookie'].should match(/keep=me/) + end + + it 'should make resulting request a get request if it not already' do + @request.http_method = Net::HTTP::Delete + @request.perform.should == {"hash" => {"foo" => "bar"}} + @request.http_method.should == Net::HTTP::Get + end + + it 'should not make resulting request a get request if options[:maintain_method_across_redirects] is true' do + @request.options[:maintain_method_across_redirects] = true + @request.http_method = Net::HTTP::Delete + @request.perform.should == {"hash" => {"foo" => "bar"}} + @request.http_method.should == Net::HTTP::Delete + end + end + + describe "infinitely" do + before(:each) do + @http.stub!(:request).and_return(@redirect) + end + + it "should raise an exception" do + lambda { @request.perform }.should raise_error(HTTParty::RedirectionTooDeep) + end + end + end + + describe "#handle_deflation" do + context "context-encoding" do + before do + @request.options[:format] = :html + @last_response = mock() + @last_response.stub!(:body).and_return('') + end + + it "should inflate the gzipped body with content-encoding: gzip" do + @last_response.stub!(:[]).with("content-encoding").and_return("gzip") + @request.stub!(:last_response).and_return(@last_response) + Zlib::GzipReader.should_receive(:new).and_return(StringIO.new('')) + @request.last_response.should_receive(:delete).with('content-encoding') + @request.send(:handle_deflation) + end + + it "should inflate the gzipped body with content-encoding: x-gzip" do + @last_response.stub!(:[]).with("content-encoding").and_return("x-gzip") + @request.stub!(:last_response).and_return(@last_response) + Zlib::GzipReader.should_receive(:new).and_return(StringIO.new('')) + @request.last_response.should_receive(:delete).with('content-encoding') + @request.send(:handle_deflation) + end + + it "should inflate the deflated body" do + @last_response.stub!(:[]).with("content-encoding").and_return("deflate") + @request.stub!(:last_response).and_return(@last_response) + Zlib::Inflate.should_receive(:inflate).and_return('') + @request.last_response.should_receive(:delete).with('content-encoding') + @request.send(:handle_deflation) + end + end + end + + context "with POST http method" do + it "should raise argument error if query is not a hash" do + lambda { + HTTParty::Request.new(Net::HTTP::Post, 'http://api.foo.com/v1', :format => :xml, :query => 'astring').perform + }.should raise_error(ArgumentError) + end + end + + describe "argument validation" do + it "should raise argument error if basic_auth and digest_auth are both present" do + lambda { + HTTParty::Request.new(Net::HTTP::Post, 'http://api.foo.com/v1', :basic_auth => {}, :digest_auth => {}).perform + }.should raise_error(ArgumentError, "only one authentication method, :basic_auth or :digest_auth may be used at a time") + end + + it "should raise argument error if basic_auth is not a hash" do + lambda { + HTTParty::Request.new(Net::HTTP::Post, 'http://api.foo.com/v1', :basic_auth => ["foo", "bar"]).perform + }.should raise_error(ArgumentError, ":basic_auth must be a hash") + end + + it "should raise argument error if digest_auth is not a hash" do + lambda { + HTTParty::Request.new(Net::HTTP::Post, 'http://api.foo.com/v1', :digest_auth => ["foo", "bar"]).perform + }.should raise_error(ArgumentError, ":digest_auth must be a hash") + end + end +end + diff --git a/vendor/ruby/1.9.1/gems/httparty-0.9.0/spec/httparty/response_spec.rb b/vendor/ruby/1.9.1/gems/httparty-0.9.0/spec/httparty/response_spec.rb new file mode 100644 index 0000000..35380d5 --- /dev/null +++ b/vendor/ruby/1.9.1/gems/httparty-0.9.0/spec/httparty/response_spec.rb @@ -0,0 +1,214 @@ +require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper')) + +describe HTTParty::Response do + before do + @last_modified = Date.new(2010, 1, 15).to_s + @content_length = '1024' + @request_object = HTTParty::Request.new Net::HTTP::Get, '/' + @response_object = Net::HTTPOK.new('1.1', 200, 'OK') + @response_object.stub(:body => "{foo:'bar'}") + @response_object['last-modified'] = @last_modified + @response_object['content-length'] = @content_length + @parsed_response = lambda { {"foo" => "bar"} } + @response = HTTParty::Response.new(@request_object, @response_object, @parsed_response) + end + + describe ".underscore" do + it "works with one capitalized word" do + HTTParty::Response.underscore("Accepted").should == "accepted" + end + + it "works with titlecase" do + HTTParty::Response.underscore("BadGateway").should == "bad_gateway" + end + + it "works with all caps" do + HTTParty::Response.underscore("OK").should == "ok" + end + end + + describe "initialization" do + it "should set the Net::HTTP Response" do + @response.response.should == @response_object + end + + it "should set body" do + @response.body.should == @response_object.body + end + + it "should set code" do + @response.code.should.to_s == @response_object.code + end + + it "should set code as a Fixnum" do + @response.code.should be_an_instance_of(Fixnum) + end + end + + it "returns response headers" do + response = HTTParty::Response.new(@request_object, @response_object, @parsed_response) + response.headers.should == {'last-modified' => [@last_modified], 'content-length' => [@content_length]} + end + + it "should send missing methods to delegate" do + response = HTTParty::Response.new(@request_object, @response_object, @parsed_response) + response['foo'].should == 'bar' + end + + it "response to request" do + response = HTTParty::Response.new(@request_object, @response_object, @parsed_response) + response.respond_to?(:request).should be_true + end + + it "responds to response" do + response = HTTParty::Response.new(@request_object, @response_object, @parsed_response) + response.respond_to?(:response).should be_true + end + + it "responds to body" do + response = HTTParty::Response.new(@request_object, @response_object, @parsed_response) + response.respond_to?(:body).should be_true + end + + it "responds to headers" do + response = HTTParty::Response.new(@request_object, @response_object, @parsed_response) + response.respond_to?(:headers).should be_true + end + + it "responds to parsed_response" do + response = HTTParty::Response.new(@request_object, @response_object, @parsed_response) + response.respond_to?(:parsed_response).should be_true + end + + it "responds to anything parsed_response responds to" do + response = HTTParty::Response.new(@request_object, @response_object, @parsed_response) + response.respond_to?(:[]).should be_true + end + + it "should be able to iterate if it is array" do + response = HTTParty::Response.new(@request_object, @response_object, lambda { [{'foo' => 'bar'}, {'foo' => 'baz'}] }) + response.size.should == 2 + expect { + response.each { |item| } + }.to_not raise_error + end + + it "allows headers to be accessed by mixed-case names in hash notation" do + response = HTTParty::Response.new(@request_object, @response_object, @parsed_response) + response.headers['Content-LENGTH'].should == @content_length + end + + it "returns a comma-delimited value when multiple values exist" do + @response_object.add_field 'set-cookie', 'csrf_id=12345; path=/' + @response_object.add_field 'set-cookie', '_github_ses=A123CdE; path=/' + response = HTTParty::Response.new(@request_object, @response_object, @parsed_response) + response.headers['set-cookie'].should == "csrf_id=12345; path=/, _github_ses=A123CdE; path=/" + end + + # Backwards-compatibility - previously, #headers returned a Hash + it "responds to hash methods" do + response = HTTParty::Response.new(@request_object, @response_object, @parsed_response) + hash_methods = {}.methods - response.headers.methods + hash_methods.each do |method_name| + response.headers.respond_to?(method_name).should be_true + end + end + + describe "semantic methods for response codes" do + def response_mock(klass) + response = klass.new('', '', '') + response.stub(:body) + response + end + + context "major codes" do + it "is information" do + net_response = response_mock(Net::HTTPInformation) + response = HTTParty::Response.new(@request_object, net_response, '') + response.information?.should be_true + end + + it "is success" do + net_response = response_mock(Net::HTTPSuccess) + response = HTTParty::Response.new(@request_object, net_response, '') + response.success?.should be_true + end + + it "is redirection" do + net_response = response_mock(Net::HTTPRedirection) + response = HTTParty::Response.new(@request_object, net_response, '') + response.redirection?.should be_true + end + + it "is client error" do + net_response = response_mock(Net::HTTPClientError) + response = HTTParty::Response.new(@request_object, net_response, '') + response.client_error?.should be_true + end + + it "is server error" do + net_response = response_mock(Net::HTTPServerError) + response = HTTParty::Response.new(@request_object, net_response, '') + response.server_error?.should be_true + end + end + + context "for specific codes" do + SPECIFIC_CODES = { + :accepted? => Net::HTTPAccepted, + :bad_gateway? => Net::HTTPBadGateway, + :bad_request? => Net::HTTPBadRequest, + :conflict? => Net::HTTPConflict, + :continue? => Net::HTTPContinue, + :created? => Net::HTTPCreated, + :expectation_failed? => Net::HTTPExpectationFailed, + :forbidden? => Net::HTTPForbidden, + :found? => Net::HTTPFound, + :gateway_time_out? => Net::HTTPGatewayTimeOut, + :gone? => Net::HTTPGone, + :internal_server_error? => Net::HTTPInternalServerError, + :length_required? => Net::HTTPLengthRequired, + :method_not_allowed? => Net::HTTPMethodNotAllowed, + :moved_permanently? => Net::HTTPMovedPermanently, + :multiple_choice? => Net::HTTPMultipleChoice, + :no_content? => Net::HTTPNoContent, + :non_authoritative_information? => Net::HTTPNonAuthoritativeInformation, + :not_acceptable? => Net::HTTPNotAcceptable, + :not_found? => Net::HTTPNotFound, + :not_implemented? => Net::HTTPNotImplemented, + :not_modified? => Net::HTTPNotModified, + :ok? => Net::HTTPOK, + :partial_content? => Net::HTTPPartialContent, + :payment_required? => Net::HTTPPaymentRequired, + :precondition_failed? => Net::HTTPPreconditionFailed, + :proxy_authentication_required? => Net::HTTPProxyAuthenticationRequired, + :request_entity_too_large? => Net::HTTPRequestEntityTooLarge, + :request_time_out? => Net::HTTPRequestTimeOut, + :request_uri_too_long? => Net::HTTPRequestURITooLong, + :requested_range_not_satisfiable? => Net::HTTPRequestedRangeNotSatisfiable, + :reset_content? => Net::HTTPResetContent, + :see_other? => Net::HTTPSeeOther, + :service_unavailable? => Net::HTTPServiceUnavailable, + :switch_protocol? => Net::HTTPSwitchProtocol, + :temporary_redirect? => Net::HTTPTemporaryRedirect, + :unauthorized? => Net::HTTPUnauthorized, + :unsupported_media_type? => Net::HTTPUnsupportedMediaType, + :use_proxy? => Net::HTTPUseProxy, + :version_not_supported? => Net::HTTPVersionNotSupported + }.each do |method, klass| + it "responds to #{method}" do + net_response = response_mock(klass) + response = HTTParty::Response.new(@request_object, net_response, '') + response.__send__(method).should be_true + end + end + end + end + + describe "headers" do + it "can initialize without headers" do + headers = HTTParty::Response::Headers.new + headers.should == {} + end + end +end diff --git a/vendor/ruby/1.9.1/gems/httparty-0.9.0/spec/httparty/ssl_spec.rb b/vendor/ruby/1.9.1/gems/httparty-0.9.0/spec/httparty/ssl_spec.rb new file mode 100644 index 0000000..221c4c9 --- /dev/null +++ b/vendor/ruby/1.9.1/gems/httparty-0.9.0/spec/httparty/ssl_spec.rb @@ -0,0 +1,62 @@ +require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper')) + +describe HTTParty::Request do + context "SSL certificate verification" do + before do + FakeWeb.allow_net_connect = true + end + + after do + FakeWeb.allow_net_connect = false + end + + it "should work when no trusted CA list is specified" do + ssl_verify_test(nil, nil, "selfsigned.crt").should == {'success' => true} + end + + it "should work when no trusted CA list is specified, even with a bogus hostname" do + ssl_verify_test(nil, nil, "bogushost.crt").should == {'success' => true} + end + + it "should work when using ssl_ca_file with a self-signed CA" do + ssl_verify_test(:ssl_ca_file, "selfsigned.crt", "selfsigned.crt").should == {'success' => true} + end + + it "should work when using ssl_ca_file with a certificate authority" do + ssl_verify_test(:ssl_ca_file, "ca.crt", "server.crt").should == {'success' => true} + end + + it "should work when using ssl_ca_path with a certificate authority" do + http = Net::HTTP.new('www.google.com', 443, nil, nil, nil, nil) + response = stub(Net::HTTPResponse, :[] => '', :body => '', :to_hash => {}) + http.stub(:request).and_return(response) + Net::HTTP.should_receive(:new).with('www.google.com', 443, nil, nil, nil, nil).and_return(http) + http.should_receive(:ca_path=).with('/foo/bar') + HTTParty.get('https://www.google.com', :ssl_ca_path => '/foo/bar') + end + + it "should fail when using ssl_ca_file and the server uses an unrecognized certificate authority" do + lambda do + ssl_verify_test(:ssl_ca_file, "ca.crt", "selfsigned.crt") + end.should raise_error(OpenSSL::SSL::SSLError) + end + + it "should fail when using ssl_ca_path and the server uses an unrecognized certificate authority" do + lambda do + ssl_verify_test(:ssl_ca_path, ".", "selfsigned.crt") + end.should raise_error(OpenSSL::SSL::SSLError) + end + + it "should fail when using ssl_ca_file and the server uses a bogus hostname" do + lambda do + ssl_verify_test(:ssl_ca_file, "ca.crt", "bogushost.crt") + end.should raise_error(OpenSSL::SSL::SSLError) + end + + it "should fail when using ssl_ca_path and the server uses a bogus hostname" do + lambda do + ssl_verify_test(:ssl_ca_path, ".", "bogushost.crt") + end.should raise_error(OpenSSL::SSL::SSLError) + end + end +end diff --git a/vendor/ruby/1.9.1/gems/httparty-0.9.0/spec/httparty_spec.rb b/vendor/ruby/1.9.1/gems/httparty-0.9.0/spec/httparty_spec.rb new file mode 100644 index 0000000..f62a322 --- /dev/null +++ b/vendor/ruby/1.9.1/gems/httparty-0.9.0/spec/httparty_spec.rb @@ -0,0 +1,703 @@ +require File.expand_path(File.join(File.dirname(__FILE__), 'spec_helper')) + +describe HTTParty do + before(:each) do + @klass = Class.new + @klass.instance_eval { include HTTParty } + end + + describe "AllowedFormats deprecated" do + before do + Kernel.stub(:warn) + end + + it "warns with a deprecation message" do + Kernel.should_receive(:warn).with("Deprecated: Use HTTParty::Parser::SupportedFormats") + HTTParty::AllowedFormats + end + + it "returns HTTPart::Parser::SupportedFormats" do + HTTParty::AllowedFormats.should == HTTParty::Parser::SupportedFormats + end + end + + describe "pem" do + it 'should set the pem content' do + @klass.pem 'PEM-CONTENT' + @klass.default_options[:pem].should == 'PEM-CONTENT' + end + + it "should set the password to nil if it's not provided" do + @klass.pem 'PEM-CONTENT' + @klass.default_options[:pem_password].should be_nil + end + + it 'should set the password' do + @klass.pem 'PEM-CONTENT', 'PASSWORD' + @klass.default_options[:pem_password].should == 'PASSWORD' + end + end + + describe 'ssl_version' do + it 'should set the ssl_version content' do + @klass.ssl_version :SSLv3 + @klass.default_options[:ssl_version].should == :SSLv3 + end + end + + describe 'http_proxy' do + it 'should set the address' do + @klass.http_proxy 'proxy.foo.com', 80 + options = @klass.default_options + options[:http_proxyaddr].should == 'proxy.foo.com' + options[:http_proxyport].should == 80 + end + + it 'should set the proxy user and pass when they are provided' do + @klass.http_proxy 'proxy.foo.com', 80, 'user', 'pass' + options = @klass.default_options + options[:http_proxyuser].should == 'user' + options[:http_proxypass].should == 'pass' + end + end + + describe "base uri" do + before(:each) do + @klass.base_uri('api.foo.com/v1') + end + + it "should have reader" do + @klass.base_uri.should == 'http://api.foo.com/v1' + end + + it 'should have writer' do + @klass.base_uri('http://api.foobar.com') + @klass.base_uri.should == 'http://api.foobar.com' + end + + it 'should not modify the parameter during assignment' do + uri = 'http://api.foobar.com' + @klass.base_uri(uri) + uri.should == 'http://api.foobar.com' + end + end + + describe ".disable_rails_query_string_format" do + it "sets the query string normalizer to HTTParty::Request::NON_RAILS_QUERY_STRING_NORMALIZER" do + @klass.disable_rails_query_string_format + @klass.default_options[:query_string_normalizer].should == HTTParty::Request::NON_RAILS_QUERY_STRING_NORMALIZER + end + end + + describe ".normalize_base_uri" do + it "should add http if not present for non ssl requests" do + uri = HTTParty.normalize_base_uri('api.foobar.com') + uri.should == 'http://api.foobar.com' + end + + it "should add https if not present for ssl requests" do + uri = HTTParty.normalize_base_uri('api.foo.com/v1:443') + uri.should == 'https://api.foo.com/v1:443' + end + + it "should not remove https for ssl requests" do + uri = HTTParty.normalize_base_uri('https://api.foo.com/v1:443') + uri.should == 'https://api.foo.com/v1:443' + end + + it 'should not modify the parameter' do + uri = 'http://api.foobar.com' + HTTParty.normalize_base_uri(uri) + uri.should == 'http://api.foobar.com' + end + + it "should not treat uri's with a port of 4430 as ssl" do + uri = HTTParty.normalize_base_uri('http://api.foo.com:4430/v1') + uri.should == 'http://api.foo.com:4430/v1' + end + end + + describe "headers" do + def expect_headers(header={}) + HTTParty::Request.should_receive(:new) \ + .with(anything, anything, hash_including({ :headers => header })) \ + .and_return(mock("mock response", :perform => nil)) + end + + it "should default to empty hash" do + @klass.headers.should == {} + end + + it "should be able to be updated" do + init_headers = {:foo => 'bar', :baz => 'spax'} + @klass.headers init_headers + @klass.headers.should == init_headers + end + + it "uses the class headers when sending a request" do + expect_headers(:foo => 'bar') + @klass.headers(:foo => 'bar') + @klass.get('') + end + + it "overwrites class headers when passing in headers" do + expect_headers(:baz => 'spax') + @klass.headers(:foo => 'bar') + @klass.get('', :headers => {:baz => 'spax'}) + end + + context "with cookies" do + it 'utilizes the class-level cookies' do + expect_headers(:foo => 'bar', 'cookie' => 'type=snickerdoodle') + @klass.headers(:foo => 'bar') + @klass.cookies(:type => 'snickerdoodle') + @klass.get('') + end + + it 'adds cookies to the headers' do + expect_headers(:foo => 'bar', 'cookie' => 'type=snickerdoodle') + @klass.headers(:foo => 'bar') + @klass.get('', :cookies => {:type => 'snickerdoodle'}) + end + + it 'adds optional cookies to the optional headers' do + expect_headers(:baz => 'spax', 'cookie' => 'type=snickerdoodle') + @klass.get('', :cookies => {:type => 'snickerdoodle'}, :headers => {:baz => 'spax'}) + end + end + end + + describe "cookies" do + def expect_cookie_header(s) + HTTParty::Request.should_receive(:new) \ + .with(anything, anything, hash_including({ :headers => { "cookie" => s } })) \ + .and_return(mock("mock response", :perform => nil)) + end + + it "should not be in the headers by default" do + HTTParty::Request.stub!(:new).and_return(stub(nil, :perform => nil)) + @klass.get("") + @klass.headers.keys.should_not include("cookie") + end + + it "should raise an ArgumentError if passed a non-Hash" do + lambda do + @klass.cookies("nonsense") + end.should raise_error(ArgumentError) + end + + it "should allow a cookie to be specified with a one-off request" do + expect_cookie_header "type=snickerdoodle" + @klass.get("", :cookies => { :type => "snickerdoodle" }) + end + + describe "when a cookie is set at the class level" do + before(:each) do + @klass.cookies({ :type => "snickerdoodle" }) + end + + it "should include that cookie in the request" do + expect_cookie_header "type=snickerdoodle" + @klass.get("") + end + + it "should pass the proper cookies when requested multiple times" do + 2.times do + expect_cookie_header "type=snickerdoodle" + @klass.get("") + end + end + + it "should allow the class defaults to be overridden" do + expect_cookie_header "type=chocolate_chip" + + @klass.get("", :cookies => { :type => "chocolate_chip" }) + end + end + + describe "in a class with multiple methods that use different cookies" do + before(:each) do + @klass.instance_eval do + def first_method + get("first_method", :cookies => { :first_method_cookie => "foo" }) + end + + def second_method + get("second_method", :cookies => { :second_method_cookie => "foo" }) + end + end + end + + it "should not allow cookies used in one method to carry over into other methods" do + expect_cookie_header "first_method_cookie=foo" + @klass.first_method + + expect_cookie_header "second_method_cookie=foo" + @klass.second_method + end + end + end + + describe "default params" do + it "should default to empty hash" do + @klass.default_params.should == {} + end + + it "should be able to be updated" do + new_defaults = {:foo => 'bar', :baz => 'spax'} + @klass.default_params new_defaults + @klass.default_params.should == new_defaults + end + end + + describe "default timeout" do + it "should default to nil" do + @klass.default_options[:timeout].should == nil + end + + it "should support updating" do + @klass.default_timeout 10 + @klass.default_options[:timeout].should == 10 + end + + it "should support floats" do + @klass.default_timeout 0.5 + @klass.default_options[:timeout].should == 0.5 + end + end + + describe "debug_output" do + it "stores the given stream as a default_option" do + @klass.debug_output $stdout + @klass.default_options[:debug_output].should == $stdout + end + + it "stores the $stderr stream by default" do + @klass.debug_output + @klass.default_options[:debug_output].should == $stderr + end + end + + describe "basic http authentication" do + it "should work" do + @klass.basic_auth 'foobar', 'secret' + @klass.default_options[:basic_auth].should == {:username => 'foobar', :password => 'secret'} + end + end + + describe "digest http authentication" do + it "should work" do + @klass.digest_auth 'foobar', 'secret' + @klass.default_options[:digest_auth].should == {:username => 'foobar', :password => 'secret'} + end + end + + describe "parser" do + class CustomParser + def self.parse(body) + return {:sexy => true} + end + end + + let(:parser) do + Proc.new{ |data, format| CustomParser.parse(data) } + end + + it "should set parser options" do + @klass.parser parser + @klass.default_options[:parser].should == parser + end + + it "should be able parse response with custom parser" do + @klass.parser parser + FakeWeb.register_uri(:get, 'http://twitter.com/statuses/public_timeline.xml', :body => 'tweets') + custom_parsed_response = @klass.get('http://twitter.com/statuses/public_timeline.xml') + custom_parsed_response[:sexy].should == true + end + + it "raises UnsupportedFormat when the parser cannot handle the format" do + @klass.format :json + class MyParser < HTTParty::Parser + SupportedFormats = {} + end unless defined?(MyParser) + expect do + @klass.parser MyParser + end.to raise_error(HTTParty::UnsupportedFormat) + end + + it 'does not validate format whe custom parser is a proc' do + expect do + @klass.format :json + @klass.parser lambda {|body, format|} + end.to_not raise_error(HTTParty::UnsupportedFormat) + end + end + + describe "connection_adapter" do + let(:uri) { 'http://google.com/api.json' } + let(:connection_adapter) { mock('CustomConnectionAdapter') } + + it "should set the connection_adapter" do + @klass.connection_adapter connection_adapter + @klass.default_options[:connection_adapter].should be connection_adapter + end + + it "should set the connection_adapter_options when provided" do + options = {:foo => :bar} + @klass.connection_adapter connection_adapter, options + @klass.default_options[:connection_adapter_options].should be options + end + + it "should not set the connection_adapter_options when not provided" do + @klass.connection_adapter connection_adapter + @klass.default_options[:connection_adapter_options].should be_nil + end + + it "should process a request with a connection from the adapter" do + connection_adapter_options = {:foo => :bar} + connection_adapter.should_receive(:call) do |u,o| + o[:connection_adapter_options].should == connection_adapter_options + HTTParty::ConnectionAdapter.call(u,o) + end.with(URI.parse(uri), kind_of(Hash)) + FakeWeb.register_uri(:get, uri, :body => 'stuff') + @klass.connection_adapter connection_adapter, connection_adapter_options + @klass.get(uri).should == 'stuff' + end + end + + describe "format" do + it "should allow xml" do + @klass.format :xml + @klass.default_options[:format].should == :xml + end + + it "should allow json" do + @klass.format :json + @klass.default_options[:format].should == :json + end + + it "should allow yaml" do + @klass.format :yaml + @klass.default_options[:format].should == :yaml + end + + it "should allow plain" do + @klass.format :plain + @klass.default_options[:format].should == :plain + end + + it 'should not allow funky format' do + lambda do + @klass.format :foobar + end.should raise_error(HTTParty::UnsupportedFormat) + end + + it 'should only print each format once with an exception' do + lambda do + @klass.format :foobar + end.should raise_error(HTTParty::UnsupportedFormat, "':foobar' Must be one of: html, json, plain, xml, yaml") + end + + it 'sets the default parser' do + @klass.default_options[:parser].should be_nil + @klass.format :json + @klass.default_options[:parser].should == HTTParty::Parser + end + + it 'does not reset parser to the default parser' do + my_parser = lambda {} + @klass.parser my_parser + @klass.format :json + @klass.parser.should == my_parser + end + end + + describe "#no_follow" do + it "sets no_follow to false by default" do + @klass.no_follow + @klass.default_options[:no_follow].should be_false + end + + it "sets the no_follow option to true" do + @klass.no_follow true + @klass.default_options[:no_follow].should be_true + end + end + + describe "#maintain_method_across_redirects" do + it "sets maintain_method_across_redirects to true by default" do + @klass.maintain_method_across_redirects + @klass.default_options[:maintain_method_across_redirects].should be_true + end + + it "sets the maintain_method_across_redirects option to false" do + @klass.maintain_method_across_redirects false + @klass.default_options[:maintain_method_across_redirects].should be_false + end + end + + describe ".follow_redirects" do + it "sets follow redirects to true by default" do + @klass.follow_redirects + @klass.default_options[:follow_redirects].should be_true + end + + it "sets the follow_redirects option to false" do + @klass.follow_redirects false + @klass.default_options[:follow_redirects].should be_false + end + end + + describe ".query_string_normalizer" do + it "sets the query_string_normalizer option" do + normalizer = proc {} + @klass.query_string_normalizer normalizer + @klass.default_options[:query_string_normalizer].should == normalizer + end + end + + describe "with explicit override of automatic redirect handling" do + before do + @request = HTTParty::Request.new(Net::HTTP::Get, 'http://api.foo.com/v1', :format => :xml, :no_follow => true) + @redirect = stub_response 'first redirect', 302 + @redirect['location'] = 'http://foo.com/bar' + HTTParty::Request.stub(:new => @request) + end + + it "should fail with redirected GET" do + lambda do + @error = @klass.get('/foo', :no_follow => true) + end.should raise_error(HTTParty::RedirectionTooDeep) {|e| e.response.body.should == 'first redirect'} + end + + it "should fail with redirected POST" do + lambda do + @klass.post('/foo', :no_follow => true) + end.should raise_error(HTTParty::RedirectionTooDeep) {|e| e.response.body.should == 'first redirect'} + end + + it "should fail with redirected PATCH" do + lambda do + @klass.patch('/foo', :no_follow => true) + end.should raise_error(HTTParty::RedirectionTooDeep) {|e| e.response.body.should == 'first redirect'} + end + + it "should fail with redirected DELETE" do + lambda do + @klass.delete('/foo', :no_follow => true) + end.should raise_error(HTTParty::RedirectionTooDeep) {|e| e.response.body.should == 'first redirect'} + end + + it "should fail with redirected PUT" do + lambda do + @klass.put('/foo', :no_follow => true) + end.should raise_error(HTTParty::RedirectionTooDeep) {|e| e.response.body.should == 'first redirect'} + end + + it "should fail with redirected HEAD" do + lambda do + @klass.head('/foo', :no_follow => true) + end.should raise_error(HTTParty::RedirectionTooDeep) {|e| e.response.body.should == 'first redirect'} + end + + it "should fail with redirected OPTIONS" do + lambda do + @klass.options('/foo', :no_follow => true) + end.should raise_error(HTTParty::RedirectionTooDeep) {|e| e.response.body.should == 'first redirect'} + end + end + + describe "with multiple class definitions" do + before(:each) do + @klass.instance_eval do + base_uri "http://first.com" + default_params :one => 1 + end + + @additional_klass = Class.new + @additional_klass.instance_eval do + include HTTParty + base_uri "http://second.com" + default_params :two => 2 + end + end + + it "should not run over each others options" do + @klass.default_options.should == { :base_uri => 'http://first.com', :default_params => { :one => 1 } } + @additional_klass.default_options.should == { :base_uri => 'http://second.com', :default_params => { :two => 2 } } + end + end + + describe "two child classes inheriting from one parent" do + before(:each) do + @parent = Class.new do + include HTTParty + def self.name + "Parent" + end + end + + @child1 = Class.new(@parent) + @child2 = Class.new(@parent) + end + + it "does not modify each others inherited attributes" do + @child1.default_params :joe => "alive" + @child2.default_params :joe => "dead" + + @child1.default_options.should == { :default_params => {:joe => "alive"} } + @child2.default_options.should == { :default_params => {:joe => "dead"} } + + @parent.default_options.should == { } + end + + it "inherits default_options from the superclass" do + @parent.basic_auth 'user', 'password' + @child1.default_options.should == {:basic_auth => {:username => 'user', :password => 'password'}} + @child1.basic_auth 'u', 'p' # modifying child1 has no effect on child2 + @child2.default_options.should == {:basic_auth => {:username => 'user', :password => 'password'}} + end + + it "doesn't modify the parent's default options" do + @parent.basic_auth 'user', 'password' + + @child1.basic_auth 'u', 'p' + @child1.default_options.should == {:basic_auth => {:username => 'u', :password => 'p'}} + + @child1.basic_auth 'email', 'token' + @child1.default_options.should == {:basic_auth => {:username => 'email', :password => 'token'}} + + @parent.default_options.should == {:basic_auth => {:username => 'user', :password => 'password'}} + end + + it "doesn't modify hashes in the parent's default options" do + @parent.headers 'Accept' => 'application/json' + @child1.headers 'Accept' => 'application/xml' + + @parent.default_options[:headers].should == {'Accept' => 'application/json'} + @child1.default_options[:headers].should == {'Accept' => 'application/xml'} + end + + it "inherits default_cookies from the parent class" do + @parent.cookies 'type' => 'chocolate_chip' + @child1.default_cookies.should == {"type" => "chocolate_chip"} + @child1.cookies 'type' => 'snickerdoodle' + @child1.default_cookies.should == {"type" => "snickerdoodle"} + @child2.default_cookies.should == {"type" => "chocolate_chip"} + end + + it "doesn't modify the parent's default cookies" do + @parent.cookies 'type' => 'chocolate_chip' + + @child1.cookies 'type' => 'snickerdoodle' + @child1.default_cookies.should == {"type" => "snickerdoodle"} + + @parent.default_cookies.should == {"type" => "chocolate_chip"} + end + end + + describe "grand parent with inherited callback" do + before do + @grand_parent = Class.new do + def self.inherited(subclass) + subclass.instance_variable_set(:@grand_parent, true) + end + end + @parent = Class.new(@grand_parent) do + include HTTParty + end + end + it "continues running the #inherited on the parent" do + child = Class.new(@parent) + child.instance_variable_get(:@grand_parent).should be_true + end + end + + describe "#get" do + it "should be able to get html" do + stub_http_response_with('google.html') + HTTParty.get('http://www.google.com').should == file_fixture('google.html') + end + + it "should be able to get chunked html" do + chunks = ["Chunk1", "Chunk2", "Chunk3", "Chunk4"] + stub_chunked_http_response_with(chunks) + + HTTParty.get('http://www.google.com') do |fragment| + chunks.should include(fragment) + end.should == chunks.join + end + + it "should be able parse response type json automatically" do + stub_http_response_with('twitter.json') + tweets = HTTParty.get('http://twitter.com/statuses/public_timeline.json') + tweets.size.should == 20 + tweets.first['user'].should == { + "name" => "Pyk", + "url" => nil, + "id" => "7694602", + "description" => nil, + "protected" => false, + "screen_name" => "Pyk", + "followers_count" => 1, + "location" => "Opera Plaza, California", + "profile_image_url" => "http://static.twitter.com/images/default_profile_normal.png" + } + end + + it "should be able parse response type xml automatically" do + stub_http_response_with('twitter.xml') + tweets = HTTParty.get('http://twitter.com/statuses/public_timeline.xml') + tweets['statuses'].size.should == 20 + tweets['statuses'].first['user'].should == { + "name" => "Magic 8 Bot", + "url" => nil, + "id" => "17656026", + "description" => "ask me a question", + "protected" => "false", + "screen_name" => "magic8bot", + "followers_count" => "90", + "profile_image_url" => "http://s3.amazonaws.com/twitter_production/profile_images/65565851/8ball_large_normal.jpg", + "location" => nil + } + end + + it "should not get undefined method add_node for nil class for the following xml" do + stub_http_response_with('undefined_method_add_node_for_nil.xml') + result = HTTParty.get('http://foobar.com') + result.should == {"Entities"=>{"href"=>"https://s3-sandbox.parature.com/api/v1/5578/5633/Account", "results"=>"0", "total"=>"0", "page_size"=>"25", "page"=>"1"}} + end + + it "should parse empty response fine" do + stub_http_response_with('empty.xml') + result = HTTParty.get('http://foobar.com') + result.should be_nil + end + + it "should accept http URIs" do + stub_http_response_with('google.html') + lambda do + HTTParty.get('http://google.com') + end.should_not raise_error(HTTParty::UnsupportedURIScheme) + end + + it "should accept https URIs" do + stub_http_response_with('google.html') + lambda do + HTTParty.get('https://google.com') + end.should_not raise_error(HTTParty::UnsupportedURIScheme) + end + + it "should raise an ArgumentError on URIs that are not http or https" do + lambda do + HTTParty.get("file:///there_is_no_party_on/my/filesystem") + end.should raise_error(HTTParty::UnsupportedURIScheme) + end + + it "should raise an InvalidURIError on URIs that can't be parsed at all" do + lambda do + HTTParty.get("It's the one that says 'Bad URI'") + end.should raise_error(URI::InvalidURIError) + end + end +end diff --git a/vendor/ruby/1.9.1/gems/httparty-0.9.0/spec/spec.opts b/vendor/ruby/1.9.1/gems/httparty-0.9.0/spec/spec.opts new file mode 100644 index 0000000..616c433 --- /dev/null +++ b/vendor/ruby/1.9.1/gems/httparty-0.9.0/spec/spec.opts @@ -0,0 +1,2 @@ +--colour +--backtrace diff --git a/vendor/ruby/1.9.1/gems/httparty-0.9.0/spec/spec_helper.rb b/vendor/ruby/1.9.1/gems/httparty-0.9.0/spec/spec_helper.rb new file mode 100644 index 0000000..a85b2b1 --- /dev/null +++ b/vendor/ruby/1.9.1/gems/httparty-0.9.0/spec/spec_helper.rb @@ -0,0 +1,30 @@ +$:.push File.expand_path("../lib", __FILE__) +require "httparty" + +require 'spec/autorun' +require 'fakeweb' + +def file_fixture(filename) + open(File.join(File.dirname(__FILE__), 'fixtures', "#{filename.to_s}")).read +end + +Dir[File.expand_path(File.join(File.dirname(__FILE__),'support','**','*.rb'))].each {|f| require f} + +Spec::Runner.configure do |config| + config.include HTTParty::StubResponse + config.include HTTParty::SSLTestHelper + + config.before(:suite) do + FakeWeb.allow_net_connect = false + end + + config.after(:suite) do + FakeWeb.allow_net_connect = true + end +end + +Spec::Matchers.define :use_ssl do + match do |connection| + connection.use_ssl? + end +end diff --git a/vendor/ruby/1.9.1/gems/httparty-0.9.0/spec/support/ssl_test_helper.rb b/vendor/ruby/1.9.1/gems/httparty-0.9.0/spec/support/ssl_test_helper.rb new file mode 100644 index 0000000..0aa6818 --- /dev/null +++ b/vendor/ruby/1.9.1/gems/httparty-0.9.0/spec/support/ssl_test_helper.rb @@ -0,0 +1,47 @@ +require 'pathname' + +module HTTParty + module SSLTestHelper + def ssl_verify_test(mode, ca_basename, server_cert_filename) + options = { + :format => :json, + :timeout => 30, + } + + if mode + ca_path = File.expand_path("../../fixtures/ssl/generated/#{ca_basename}", __FILE__) + raise ArgumentError.new("#{ca_path} does not exist") unless File.exist?(ca_path) + options[mode] = ca_path + end + + begin + test_server = SSLTestServer.new( + :rsa_key => File.read(File.expand_path("../../fixtures/ssl/generated/server.key", __FILE__)), + :cert => File.read(File.expand_path("../../fixtures/ssl/generated/#{server_cert_filename}", __FILE__))) + + test_server.start + + if mode + ca_path = File.expand_path("../../fixtures/ssl/generated/#{ca_basename}", __FILE__) + raise ArgumentError.new("#{ca_path} does not exist") unless File.exist?(ca_path) + return HTTParty.get("https://localhost:#{test_server.port}/", :format => :json, :timeout => 30, mode => ca_path) + else + return HTTParty.get("https://localhost:#{test_server.port}/", :format => :json, :timeout => 30) + end + ensure + test_server.stop if test_server + end + + test_server = SSLTestServer.new({ + :rsa_key => path.join('server.key').read, + :cert => path.join(server_cert_filename).read, + }) + + test_server.start + + HTTParty.get("https://localhost:#{test_server.port}/", options) + ensure + test_server.stop if test_server + end + end +end diff --git a/vendor/ruby/1.9.1/gems/httparty-0.9.0/spec/support/ssl_test_server.rb b/vendor/ruby/1.9.1/gems/httparty-0.9.0/spec/support/ssl_test_server.rb new file mode 100644 index 0000000..a2e2d73 --- /dev/null +++ b/vendor/ruby/1.9.1/gems/httparty-0.9.0/spec/support/ssl_test_server.rb @@ -0,0 +1,80 @@ +require 'openssl' +require 'socket' +require 'thread' + +# NOTE: This code is garbage. It probably has deadlocks, it might leak +# threads, and otherwise cause problems in a real system. It's really only +# intended for testing HTTParty. +class SSLTestServer + attr_accessor :ctx # SSLContext object + attr_reader :port + + def initialize(options={}) + @ctx = OpenSSL::SSL::SSLContext.new + @ctx.cert = OpenSSL::X509::Certificate.new(options[:cert]) + @ctx.key = OpenSSL::PKey::RSA.new(options[:rsa_key]) + @ctx.verify_mode = OpenSSL::SSL::VERIFY_NONE # Don't verify client certificate + @port = options[:port] || 0 + @thread = nil + @stopping_mutex = Mutex.new + @stopping = false + end + + def start + @raw_server = TCPServer.new(@port) + + if @port == 0 + @port = Socket::getnameinfo(@raw_server.getsockname, Socket::NI_NUMERICHOST|Socket::NI_NUMERICSERV)[1].to_i + end + + @ssl_server = OpenSSL::SSL::SSLServer.new(@raw_server, @ctx) + + @stopping_mutex.synchronize{ + return if @stopping + @thread = Thread.new{ thread_main } + } + + nil + end + + def stop + @stopping_mutex.synchronize{ + return if @stopping + @stopping = true + } + @thread.join + end + + private + + def thread_main + until @stopping_mutex.synchronize{ @stopping } + (rr,ww,ee) = select([@ssl_server.to_io], nil, nil, 0.1) + + next unless rr && rr.include?(@ssl_server.to_io) + + socket = @ssl_server.accept + + Thread.new{ + header = [] + + until (line = socket.readline).rstrip.empty? + header << line + end + + response =< format) + http_request.stub_chain(:http, :request).and_return(response) + + HTTParty::Request.should_receive(:new).and_return(http_request) + end + + def stub_chunked_http_response_with(chunks) + response = Net::HTTPResponse.new("1.1", 200, nil) + response.stub(:chunked_data).and_return(chunks) + def response.read_body(&block) + @body || chunked_data.each(&block) + end + + http_request = HTTParty::Request.new(Net::HTTP::Get, 'http://localhost', :format => "html") + http_request.stub_chain(:http, :request).and_yield(response).and_return(response) + + HTTParty::Request.should_receive(:new).and_return(http_request) + end + + def stub_response(body, code = 200) + @request.options[:base_uri] ||= 'http://localhost' + unless defined?(@http) && @http + @http = Net::HTTP.new('localhost', 80) + @request.stub!(:http).and_return(@http) + end + + response = Net::HTTPResponse::CODE_TO_OBJ[code.to_s].new("1.1", code, body) + response.stub!(:body).and_return(body) + + @http.stub!(:request).and_return(response) + response + end + end +end diff --git a/vendor/ruby/1.9.1/gems/httparty-0.9.0/website/css/common.css b/vendor/ruby/1.9.1/gems/httparty-0.9.0/website/css/common.css new file mode 100644 index 0000000..61f38ac --- /dev/null +++ b/vendor/ruby/1.9.1/gems/httparty-0.9.0/website/css/common.css @@ -0,0 +1,47 @@ +@media screen, projection { + /* + Copyright (c) 2007, Yahoo! Inc. All rights reserved. + Code licensed under the BSD License: + http://developer.yahoo.net/yui/license.txt + version: 2.2.0 + */ + body {font:13px arial,helvetica,clean,sans-serif;*font-size:small;*font:x-small;}table {font-size:inherit;font:100%;}select, input, textarea {font:99% arial,helvetica,clean,sans-serif;}pre, code {font:115% monospace;*font-size:100%;}body * {line-height:1.22em;} + body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,form,fieldset,input,textarea,p,blockquote,th,td{margin:0;padding:0;}table{border-collapse:collapse;border-spacing:0;}fieldset,img{border:0;}address,caption,cite,code,dfn,em,strong,th,var{font-style:normal;font-weight:normal;}/*ol,ul {list-style:none;}*/caption,th {text-align:left;}h1,h2,h3,h4,h5,h6{font-size:100%;font-weight:normal;}q:before,q:after{content:'';}abbr,acronym {border:0;} + /* end of yahoo reset and fonts */ + + body {color:#333; background:#4b1a1a; line-height:1.3;} + p {margin:0 0 20px;} + a {color:#4b1a1a;} + a:hover {text-decoration:none;} + strong {font-weight:bold;} + em {font-style:italics;} + h1,h2,h3,h4,h5,h6 {font-weight:bold;} + h1 {font-size:197%; margin:30px 0; color:#4b1a1a;} + h2 {font-size:174%; margin:20px 0; color:#b8111a;} + h3 {font-size:152%; margin:10px 0;} + h4 {font-size:129%; margin:10px 0;} + pre {background:#eee; margin:0 0 20px; padding:20px; border:1px solid #ccc; font-size:100%; overflow:auto;} + code {font-size:100%; margin:0; padding:0;} + ul, ol {margin:10px 0 10px 25px;} + ol li {margin:0 0 10px;} + + + + + + div#wrapper {background:#fff; width:560px; margin:0 auto; padding:20px; border:10px solid #bc8c46; border-width:0 10px;} + div#header {position:relative; border-bottom:1px dotted; margin:0 0 10px; padding:0 0 10px;} + div#header p {margin:0; padding:0;} + div#header h1 {margin:0; padding:0;} + ul#nav {position:absolute; top:0; right:0; list-style:none; margin:0; padding:0;} + ul#nav li {display:inline; padding:0 0 0 5px;} + ul#nav li a {} + div#content {} + div#footer {margin:40px 0 0; border-top:1px dotted; padding:10px 0 0;} + + + + + + +} \ No newline at end of file diff --git a/vendor/ruby/1.9.1/gems/httparty-0.9.0/website/index.html b/vendor/ruby/1.9.1/gems/httparty-0.9.0/website/index.html new file mode 100644 index 0000000..3b4c86f --- /dev/null +++ b/vendor/ruby/1.9.1/gems/httparty-0.9.0/website/index.html @@ -0,0 +1,73 @@ + + + + + HTTParty by John Nunemaker + + + + +
+ + +
+

Install

+
$ sudo gem install httparty
+ +

Some Quick Examples

+ +

The following is a simple example of wrapping Twitter's API for posting updates.

+ +
class Twitter
+  include HTTParty
+  base_uri 'twitter.com'
+  basic_auth 'username', 'password'
+end
+
+Twitter.post('/statuses/update.json', :query => {:status => "It's an HTTParty and everyone is invited!"})
+ +

That is really it! The object returned is a ruby hash that is decoded from Twitter's json response. JSON parsing is used because of the .json extension in the path of the request. You can also explicitly set a format (see the examples).

+ +

That works and all but what if you don't want to embed your username and password in the class? Below is an example to fix that:

+ +
class Twitter
+  include HTTParty
+  base_uri 'twitter.com'
+
+  def initialize(u, p)
+    @auth = {:username => u, :password => p}
+  end
+
+  def post(text)
+    options = { :query => {:status => text}, :basic_auth => @auth }
+    self.class.post('/statuses/update.json', options)
+  end
+end
+
+Twitter.new('username', 'password').post("It's an HTTParty and everyone is invited!")
+ +

More Examples: There are several examples in the gem itself.

+ +

Support

+

Conversations welcome in the google group and bugs/features over at Github.

+ + +
+ + +
+ + + \ No newline at end of file diff --git a/vendor/ruby/1.9.1/gems/multi_json-1.4.0/.document b/vendor/ruby/1.9.1/gems/multi_json-1.4.0/.document new file mode 100644 index 0000000..3b0c733 --- /dev/null +++ b/vendor/ruby/1.9.1/gems/multi_json-1.4.0/.document @@ -0,0 +1,5 @@ +LICENSE.md +README.md +bin/* +features/**/*.feature +lib/**/*.rb diff --git a/vendor/ruby/1.9.1/gems/multi_json-1.4.0/.rspec b/vendor/ruby/1.9.1/gems/multi_json-1.4.0/.rspec new file mode 100644 index 0000000..0ea59b0 --- /dev/null +++ b/vendor/ruby/1.9.1/gems/multi_json-1.4.0/.rspec @@ -0,0 +1,3 @@ +--color +--fail-fast +--order random diff --git a/vendor/ruby/1.9.1/gems/multi_json-1.4.0/.travis.yml b/vendor/ruby/1.9.1/gems/multi_json-1.4.0/.travis.yml new file mode 100644 index 0000000..0828e27 --- /dev/null +++ b/vendor/ruby/1.9.1/gems/multi_json-1.4.0/.travis.yml @@ -0,0 +1,10 @@ +language: ruby +rvm: + - rbx-18mode + - rbx-19mode + - jruby-18mode + - jruby-19mode + - 1.8.7 + - 1.9.2 + - 1.9.3 + - ruby-head diff --git a/vendor/ruby/1.9.1/gems/multi_json-1.4.0/Gemfile b/vendor/ruby/1.9.1/gems/multi_json-1.4.0/Gemfile new file mode 100644 index 0000000..d217dbb --- /dev/null +++ b/vendor/ruby/1.9.1/gems/multi_json-1.4.0/Gemfile @@ -0,0 +1,7 @@ +source 'https://rubygems.org' + +gem 'json', '~> 1.4', :require => nil +gem 'oj', '~> 1.0', :require => nil, :platforms => [:ruby, :mswin, :mingw] +gem 'yajl-ruby', '~> 1.0', :require => nil, :platforms => [:ruby, :mswin, :mingw] + +gemspec diff --git a/vendor/ruby/1.9.1/gems/multi_json-1.4.0/LICENSE.md b/vendor/ruby/1.9.1/gems/multi_json-1.4.0/LICENSE.md new file mode 100644 index 0000000..c925ac6 --- /dev/null +++ b/vendor/ruby/1.9.1/gems/multi_json-1.4.0/LICENSE.md @@ -0,0 +1,20 @@ +Copyright (c) 2010 Michael Bleigh, Josh Kalderimis, Erik Michaels-Ober, and Intridea, Inc. + +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. diff --git a/vendor/ruby/1.9.1/gems/multi_json-1.4.0/README.md b/vendor/ruby/1.9.1/gems/multi_json-1.4.0/README.md new file mode 100644 index 0000000..988a574 --- /dev/null +++ b/vendor/ruby/1.9.1/gems/multi_json-1.4.0/README.md @@ -0,0 +1,72 @@ +# MultiJSON [![Build Status](https://secure.travis-ci.org/intridea/multi_json.png?branch=master)][travis] [![Dependency Status](https://gemnasium.com/intridea/multi_json.png?travis)][gemnasium] + +[travis]: http://travis-ci.org/intridea/multi_json +[gemnasium]: https://gemnasium.com/intridea/multi_json + +Lots of Ruby libraries parse JSON and everyone has their favorite JSON coder. +Instead of choosing a single JSON coder and forcing users of your library to be +stuck with it, you can use MultiJSON instead, which will simply choose the +fastest available JSON coder. Here's how to use it: + + require 'multi_json' + + MultiJson.load('{"abc":"def"}') #=> {"abc" => "def"} + MultiJson.load('{"abc":"def"}', :symbolize_keys => true) #=> {:abc => "def"} + MultiJson.dump({:abc => 'def'}) # convert Ruby back to JSON + MultiJson.dump({:abc => 'def'}, :pretty => true) # encoded in a pretty form (if supported by the coder) + +The `use` method, which sets the MultiJson adapter, takes either a symbol or a +class (to allow for custom JSON parsers) that responds to both `.load` and `.dump` +at the class level. + +MultiJSON tries to have intelligent defaulting. That is, if you have any of the +supported engines already loaded, it will utilize them before attempting to +load any. When loading, libraries are ordered by speed. First Oj, then Yajl, +then the JSON gem, then JSON pure. If no other JSON library is available, +MultiJSON falls back to [OkJson][], a simple, vendorable JSON parser. + +[okjson]: https://github.com/kr/okjson + +## Supported JSON Engines + +* [Oj](https://github.com/ohler55/oj) Optimized JSON by Peter Ohler +* [Yajl](https://github.com/brianmario/yajl-ruby) Yet Another JSON Library by Brian Lopez +* [JSON](https://github.com/flori/json) The default JSON gem with C-extensions (ships with Ruby 1.9) +* [JSON Pure](https://github.com/flori/json) A Ruby variant of the JSON gem +* [NSJSONSerialization](https://developer.apple.com/library/ios/#documentation/Foundation/Reference/NSJSONSerialization_Class/Reference/Reference.html) Wrapper for Apple's NSJSONSerialization in the Cocoa Framework (MacRuby only) +* [OkJson][okjson] A simple, vendorable JSON parser + +## Supported Ruby Versions +This library aims to support and is [tested against][travis] the following Ruby +implementations: + +* Ruby 1.8.7 +* Ruby 1.9.2 +* Ruby 1.9.3 +* [JRuby][] +* [Rubinius][] +* [MacRuby][] (not tested on Travis CI) + +[jruby]: http://www.jruby.org/ +[rubinius]: http://rubini.us/ +[macruby]: http://www.macruby.org/ + +If something doesn't work on one of these interpreters, it should be considered +a bug. + +This library may inadvertently work (or seem to work) on other Ruby +implementations, however support will only be provided for the versions listed +above. + +If you would like this library to support another Ruby version, you may +volunteer to be a maintainer. Being a maintainer entails making sure all tests +run and pass on that implementation. When something breaks on your +implementation, you will be personally responsible for providing patches in a +timely fashion. If critical issues for a particular implementation exist at the +time of a major release, support for that Ruby version may be dropped. + +## Copyright +Copyright (c) 2010 Michael Bleigh, Josh Kalderimis, Erik Michaels-Ober, and Intridea, Inc. +See [LICENSE][] for details. + +[license]: https://github.com/intridea/multi_json/blob/master/LICENSE.md diff --git a/vendor/ruby/1.9.1/gems/multi_json-1.4.0/Rakefile b/vendor/ruby/1.9.1/gems/multi_json-1.4.0/Rakefile new file mode 100644 index 0000000..d9d4646 --- /dev/null +++ b/vendor/ruby/1.9.1/gems/multi_json-1.4.0/Rakefile @@ -0,0 +1,20 @@ +require 'bundler' +Bundler::GemHelper.install_tasks + +require 'rspec/core/rake_task' +desc "Run all examples" +RSpec::Core::RakeTask.new(:spec) + +task :default => :spec +task :test => :spec + +namespace :doc do + require 'rdoc/task' + require File.expand_path('../lib/multi_json/version', __FILE__) + RDoc::Task.new do |rdoc| + rdoc.rdoc_dir = 'rdoc' + rdoc.title = "multi_json #{MultiJson::VERSION}" + rdoc.main = 'README.md' + rdoc.rdoc_files.include('README.md', 'LICENSE.md', 'lib/**/*.rb') + end +end diff --git a/vendor/ruby/1.9.1/gems/multi_json-1.4.0/lib/multi_json.rb b/vendor/ruby/1.9.1/gems/multi_json-1.4.0/lib/multi_json.rb new file mode 100644 index 0000000..a9a965e --- /dev/null +++ b/vendor/ruby/1.9.1/gems/multi_json-1.4.0/lib/multi_json.rb @@ -0,0 +1,122 @@ +module MultiJson + class DecodeError < StandardError + attr_reader :data + def initialize(message="", backtrace=[], data="") + super(message) + self.set_backtrace(backtrace) + @data = data + end + end + + @adapter = nil + + REQUIREMENT_MAP = [ + ["oj", :oj], + ["yajl", :yajl], + ["json", :json_gem], + ["json/pure", :json_pure] + ] + + class << self + + # The default adapter based on what you currently + # have loaded and installed. First checks to see + # if any adapters are already loaded, then checks + # to see which are installed if none are loaded. + def default_adapter + return :oj if defined?(::Oj) + return :yajl if defined?(::Yajl) + return :json_gem if defined?(::JSON) + + REQUIREMENT_MAP.each do |(library, adapter)| + begin + require library + return adapter + rescue LoadError + next + end + end + + Kernel.warn "[WARNING] MultiJson is using the default adapter (ok_json). We recommend loading a different JSON library to improve performance." + :ok_json + end + # :nodoc: + alias :default_engine :default_adapter + + # Get the current adapter class. + def adapter + return @adapter if @adapter + self.use self.default_adapter + @adapter + end + # :nodoc: + alias :engine :adapter + + # Set the JSON parser utilizing a symbol, string, or class. + # Supported by default are: + # + # * :oj + # * :json_gem + # * :json_pure + # * :ok_json + # * :yajl + # * :nsjsonserialization (MacRuby only) + def use(new_adapter) + @adapter = load_adapter(new_adapter) + end + alias :adapter= :use + # :nodoc: + alias :engine= :use + + def load_adapter(new_adapter) + case new_adapter + when String, Symbol + require "multi_json/adapters/#{new_adapter}" + MultiJson::Adapters.const_get(:"#{new_adapter.to_s.split('_').map{|s| s.capitalize}.join('')}") + when NilClass, FalseClass + default_adapter = self.default_adapter + require "multi_json/adapters/#{default_adapter}" + MultiJson::Adapters.const_get(:"#{default_adapter.to_s.split('_').map{|s| s.capitalize}.join('')}") + when Class + new_adapter + else + raise "Did not recognize your adapter specification. Please specify either a symbol or a class." + end + end + + # Decode a JSON string into Ruby. + # + # Options + # + # :symbolize_keys :: If true, will use symbols instead of strings for the keys. + # :adapter :: If set, the selected engine will be used just for the call. + def load(string, options={}) + adapter = current_adapter(options) + begin + adapter.load(string, options) + rescue adapter::ParseError => exception + raise DecodeError.new(exception.message, exception.backtrace, string) + end + end + # :nodoc: + alias :decode :load + + def current_adapter(options) + if new_adapter = (options || {}).delete(:adapter) + load_adapter(new_adapter) + else + adapter + end + end + + # Encodes a Ruby object as JSON. + def dump(object, options={}) + adapter = current_adapter(options) + adapter.dump(object, options) + end + # :nodoc: + alias :encode :dump + + end + +end diff --git a/vendor/ruby/1.9.1/gems/multi_json-1.4.0/lib/multi_json/adapters/json_common.rb b/vendor/ruby/1.9.1/gems/multi_json-1.4.0/lib/multi_json/adapters/json_common.rb new file mode 100644 index 0000000..992cc5a --- /dev/null +++ b/vendor/ruby/1.9.1/gems/multi_json-1.4.0/lib/multi_json/adapters/json_common.rb @@ -0,0 +1,25 @@ +module MultiJson + module Adapters + module JsonCommon + + def load(string, options={}) + string = string.read if string.respond_to?(:read) + ::JSON.parse(string, :symbolize_names => options[:symbolize_keys], :quirks_mode => true) + end + + def dump(object, options={}) + object.to_json(process_options(options)) + end + + protected + + def process_options(options={}) + return options if options.empty? + opts = {} + opts.merge!(JSON::PRETTY_STATE_PROTOTYPE.to_h) if options.delete(:pretty) + opts.merge!(options) + end + + end + end +end diff --git a/vendor/ruby/1.9.1/gems/multi_json-1.4.0/lib/multi_json/adapters/json_gem.rb b/vendor/ruby/1.9.1/gems/multi_json-1.4.0/lib/multi_json/adapters/json_gem.rb new file mode 100644 index 0000000..7b34e91 --- /dev/null +++ b/vendor/ruby/1.9.1/gems/multi_json-1.4.0/lib/multi_json/adapters/json_gem.rb @@ -0,0 +1,12 @@ +require 'json' unless defined?(::JSON) +require 'multi_json/adapters/json_common' + +module MultiJson + module Adapters + # Use the JSON gem to dump/load. + class JsonGem + ParseError = ::JSON::ParserError + extend JsonCommon + end + end +end diff --git a/vendor/ruby/1.9.1/gems/multi_json-1.4.0/lib/multi_json/adapters/json_pure.rb b/vendor/ruby/1.9.1/gems/multi_json-1.4.0/lib/multi_json/adapters/json_pure.rb new file mode 100644 index 0000000..5d06ea6 --- /dev/null +++ b/vendor/ruby/1.9.1/gems/multi_json-1.4.0/lib/multi_json/adapters/json_pure.rb @@ -0,0 +1,12 @@ +require 'json/pure' unless defined?(::JSON) +require 'multi_json/adapters/json_common' + +module MultiJson + module Adapters + # Use JSON pure to dump/load. + class JsonPure + ParseError = ::JSON::ParserError + extend JsonCommon + end + end +end diff --git a/vendor/ruby/1.9.1/gems/multi_json-1.4.0/lib/multi_json/adapters/nsjsonserialization.rb b/vendor/ruby/1.9.1/gems/multi_json-1.4.0/lib/multi_json/adapters/nsjsonserialization.rb new file mode 100644 index 0000000..77ae4f1 --- /dev/null +++ b/vendor/ruby/1.9.1/gems/multi_json-1.4.0/lib/multi_json/adapters/nsjsonserialization.rb @@ -0,0 +1,34 @@ +framework 'Foundation' +require 'multi_json/adapters/ok_json' + +module MultiJson + module Adapters + class Nsjsonserialization < MultiJson::Adapters::OkJson + ParseError = ::MultiJson::OkJson::Error + + def self.load(string, options={}) + string = string.read if string.respond_to?(:read) + data = string.dataUsingEncoding(NSUTF8StringEncoding) + object = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingMutableContainers | NSJSONReadingMutableLeaves, error: nil) + if object + object = symbolize_keys(object) if options[:symbolize_keys] + object + else + super(string, options={}) + end + end + + def self.dump(object, options={}) + pretty = options[:pretty] ? NSJSONWritingPrettyPrinted : 0 + object = object.as_json if object.respond_to?(:as_json) + if NSJSONSerialization.isValidJSONObject(object) + data = NSJSONSerialization.dataWithJSONObject(object, options: pretty, error: nil) + NSMutableString.alloc.initWithData(data, encoding: NSUTF8StringEncoding) + else + super(object, options) + end + end + + end + end +end diff --git a/vendor/ruby/1.9.1/gems/multi_json-1.4.0/lib/multi_json/adapters/oj.rb b/vendor/ruby/1.9.1/gems/multi_json-1.4.0/lib/multi_json/adapters/oj.rb new file mode 100644 index 0000000..4c5e7fb --- /dev/null +++ b/vendor/ruby/1.9.1/gems/multi_json-1.4.0/lib/multi_json/adapters/oj.rb @@ -0,0 +1,26 @@ +require 'oj' unless defined?(::Oj) + +module MultiJson + module Adapters + # Use the Oj library to dump/load. + class Oj + ParseError = if defined?(::Oj::ParseError) + ::Oj::ParseError + else + SyntaxError + end + + ::Oj.default_options = {:mode => :compat} + + def self.load(string, options={}) #:nodoc: + options.merge!(:symbol_keys => options[:symbolize_keys]) + ::Oj.load(string, options) + end + + def self.dump(object, options={}) #:nodoc: + options.merge!(:indent => 2) if options[:pretty] + ::Oj.dump(object, options) + end + end + end +end diff --git a/vendor/ruby/1.9.1/gems/multi_json-1.4.0/lib/multi_json/adapters/ok_json.rb b/vendor/ruby/1.9.1/gems/multi_json-1.4.0/lib/multi_json/adapters/ok_json.rb new file mode 100644 index 0000000..6426179 --- /dev/null +++ b/vendor/ruby/1.9.1/gems/multi_json-1.4.0/lib/multi_json/adapters/ok_json.rb @@ -0,0 +1,48 @@ +require 'multi_json/vendor/okjson' + +module MultiJson + module Adapters + class OkJson + ParseError = ::MultiJson::OkJson::Error + + def self.load(string, options={}) #:nodoc: + string = string.read if string.respond_to?(:read) + result = ::MultiJson::OkJson.decode("[#{string}]").first + options[:symbolize_keys] ? symbolize_keys(result) : result + end + + def self.dump(object, options={}) #:nodoc: + ::MultiJson::OkJson.valenc(stringify_keys(object)) + end + + def self.symbolize_keys(object) #:nodoc: + modify_keys(object) do |key| + key.is_a?(String) ? key.to_sym : key + end + end + + def self.stringify_keys(object) #:nodoc: + modify_keys(object) do |key| + key.is_a?(Symbol) ? key.to_s : key + end + end + + def self.modify_keys(object, &modifier) #:nodoc: + case object + when Array + object.map do |value| + modify_keys(value, &modifier) + end + when Hash + object.inject({}) do |result, (key, value)| + new_key = modifier.call(key) + new_value = modify_keys(value, &modifier) + result.merge! new_key => new_value + end + else + object + end + end + end + end +end diff --git a/vendor/ruby/1.9.1/gems/multi_json-1.4.0/lib/multi_json/adapters/yajl.rb b/vendor/ruby/1.9.1/gems/multi_json-1.4.0/lib/multi_json/adapters/yajl.rb new file mode 100644 index 0000000..3c0987d --- /dev/null +++ b/vendor/ruby/1.9.1/gems/multi_json-1.4.0/lib/multi_json/adapters/yajl.rb @@ -0,0 +1,18 @@ +require 'yajl' unless defined?(::Yajl) + +module MultiJson + module Adapters + # Use the Yajl-Ruby library to dump/load. + class Yajl + ParseError = ::Yajl::ParseError + + def self.load(string, options={}) #:nodoc: + ::Yajl::Parser.new(:symbolize_keys => options[:symbolize_keys]).parse(string) + end + + def self.dump(object, options={}) #:nodoc: + ::Yajl::Encoder.encode(object, options) + end + end + end +end diff --git a/vendor/ruby/1.9.1/gems/multi_json-1.4.0/lib/multi_json/vendor/okjson.rb b/vendor/ruby/1.9.1/gems/multi_json-1.4.0/lib/multi_json/vendor/okjson.rb new file mode 100644 index 0000000..c18ed41 --- /dev/null +++ b/vendor/ruby/1.9.1/gems/multi_json-1.4.0/lib/multi_json/vendor/okjson.rb @@ -0,0 +1,602 @@ +# encoding: UTF-8 +# +# Copyright 2011, 2012 Keith Rarick +# +# 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. + +# See https://github.com/kr/okjson for updates. + +require 'stringio' + +# Some parts adapted from +# http://golang.org/src/pkg/json/decode.go and +# http://golang.org/src/pkg/utf8/utf8.go +module MultiJson + module OkJson + extend self + + + # Decodes a json document in string s and + # returns the corresponding ruby value. + # String s must be valid UTF-8. If you have + # a string in some other encoding, convert + # it first. + # + # String values in the resulting structure + # will be UTF-8. + def decode(s) + ts = lex(s) + v, ts = textparse(ts) + if ts.length > 0 + raise Error, 'trailing garbage' + end + v + end + + + # Parses a "json text" in the sense of RFC 4627. + # Returns the parsed value and any trailing tokens. + # Note: this is almost the same as valparse, + # except that it does not accept atomic values. + def textparse(ts) + if ts.length < 0 + raise Error, 'empty' + end + + typ, _, val = ts[0] + case typ + when '{' then objparse(ts) + when '[' then arrparse(ts) + else + raise Error, "unexpected #{val.inspect}" + end + end + + + # Parses a "value" in the sense of RFC 4627. + # Returns the parsed value and any trailing tokens. + def valparse(ts) + if ts.length < 0 + raise Error, 'empty' + end + + typ, _, val = ts[0] + case typ + when '{' then objparse(ts) + when '[' then arrparse(ts) + when :val,:str then [val, ts[1..-1]] + else + raise Error, "unexpected #{val.inspect}" + end + end + + + # Parses an "object" in the sense of RFC 4627. + # Returns the parsed value and any trailing tokens. + def objparse(ts) + ts = eat('{', ts) + obj = {} + + if ts[0][0] == '}' + return obj, ts[1..-1] + end + + k, v, ts = pairparse(ts) + obj[k] = v + + if ts[0][0] == '}' + return obj, ts[1..-1] + end + + loop do + ts = eat(',', ts) + + k, v, ts = pairparse(ts) + obj[k] = v + + if ts[0][0] == '}' + return obj, ts[1..-1] + end + end + end + + + # Parses a "member" in the sense of RFC 4627. + # Returns the parsed values and any trailing tokens. + def pairparse(ts) + (typ, _, k), ts = ts[0], ts[1..-1] + if typ != :str + raise Error, "unexpected #{k.inspect}" + end + ts = eat(':', ts) + v, ts = valparse(ts) + [k, v, ts] + end + + + # Parses an "array" in the sense of RFC 4627. + # Returns the parsed value and any trailing tokens. + def arrparse(ts) + ts = eat('[', ts) + arr = [] + + if ts[0][0] == ']' + return arr, ts[1..-1] + end + + v, ts = valparse(ts) + arr << v + + if ts[0][0] == ']' + return arr, ts[1..-1] + end + + loop do + ts = eat(',', ts) + + v, ts = valparse(ts) + arr << v + + if ts[0][0] == ']' + return arr, ts[1..-1] + end + end + end + + + def eat(typ, ts) + if ts[0][0] != typ + raise Error, "expected #{typ} (got #{ts[0].inspect})" + end + ts[1..-1] + end + + + # Scans s and returns a list of json tokens, + # excluding white space (as defined in RFC 4627). + def lex(s) + ts = [] + while s.length > 0 + typ, lexeme, val = tok(s) + if typ == nil + raise Error, "invalid character at #{s[0,10].inspect}" + end + if typ != :space + ts << [typ, lexeme, val] + end + s = s[lexeme.length..-1] + end + ts + end + + + # Scans the first token in s and + # returns a 3-element list, or nil + # if s does not begin with a valid token. + # + # The first list element is one of + # '{', '}', ':', ',', '[', ']', + # :val, :str, and :space. + # + # The second element is the lexeme. + # + # The third element is the value of the + # token for :val and :str, otherwise + # it is the lexeme. + def tok(s) + case s[0] + when ?{ then ['{', s[0,1], s[0,1]] + when ?} then ['}', s[0,1], s[0,1]] + when ?: then [':', s[0,1], s[0,1]] + when ?, then [',', s[0,1], s[0,1]] + when ?[ then ['[', s[0,1], s[0,1]] + when ?] then [']', s[0,1], s[0,1]] + when ?n then nulltok(s) + when ?t then truetok(s) + when ?f then falsetok(s) + when ?" then strtok(s) + when Spc then [:space, s[0,1], s[0,1]] + when ?\t then [:space, s[0,1], s[0,1]] + when ?\n then [:space, s[0,1], s[0,1]] + when ?\r then [:space, s[0,1], s[0,1]] + else numtok(s) + end + end + + + def nulltok(s); s[0,4] == 'null' ? [:val, 'null', nil] : [] end + def truetok(s); s[0,4] == 'true' ? [:val, 'true', true] : [] end + def falsetok(s); s[0,5] == 'false' ? [:val, 'false', false] : [] end + + + def numtok(s) + m = /-?([1-9][0-9]+|[0-9])([.][0-9]+)?([eE][+-]?[0-9]+)?/.match(s) + if m && m.begin(0) == 0 + if m[3] && !m[2] + [:val, m[0], Integer(m[1])*(10**Integer(m[3][1..-1]))] + elsif m[2] + [:val, m[0], Float(m[0])] + else + [:val, m[0], Integer(m[0])] + end + else + [] + end + end + + + def strtok(s) + m = /"([^"\\]|\\["\/\\bfnrt]|\\u[0-9a-fA-F]{4})*"/.match(s) + if ! m + raise Error, "invalid string literal at #{abbrev(s)}" + end + [:str, m[0], unquote(m[0])] + end + + + def abbrev(s) + t = s[0,10] + p = t['`'] + t = t[0,p] if p + t = t + '...' if t.length < s.length + '`' + t + '`' + end + + + # Converts a quoted json string literal q into a UTF-8-encoded string. + # The rules are different than for Ruby, so we cannot use eval. + # Unquote will raise an error if q contains control characters. + def unquote(q) + q = q[1...-1] + a = q.dup # allocate a big enough string + rubydoesenc = false + # In ruby >= 1.9, a[w] is a codepoint, not a byte. + if a.class.method_defined?(:force_encoding) + a.force_encoding('UTF-8') + rubydoesenc = true + end + r, w = 0, 0 + while r < q.length + c = q[r] + case true + when c == ?\\ + r += 1 + if r >= q.length + raise Error, "string literal ends with a \"\\\": \"#{q}\"" + end + + case q[r] + when ?",?\\,?/,?' + a[w] = q[r] + r += 1 + w += 1 + when ?b,?f,?n,?r,?t + a[w] = Unesc[q[r]] + r += 1 + w += 1 + when ?u + r += 1 + uchar = begin + hexdec4(q[r,4]) + rescue RuntimeError => e + raise Error, "invalid escape sequence \\u#{q[r,4]}: #{e}" + end + r += 4 + if surrogate? uchar + if q.length >= r+6 + uchar1 = hexdec4(q[r+2,4]) + uchar = subst(uchar, uchar1) + if uchar != Ucharerr + # A valid pair; consume. + r += 6 + end + end + end + if rubydoesenc + a[w] = '' << uchar + w += 1 + else + w += ucharenc(a, w, uchar) + end + else + raise Error, "invalid escape char #{q[r]} in \"#{q}\"" + end + when c == ?", c < Spc + raise Error, "invalid character in string literal \"#{q}\"" + else + # Copy anything else byte-for-byte. + # Valid UTF-8 will remain valid UTF-8. + # Invalid UTF-8 will remain invalid UTF-8. + # In ruby >= 1.9, c is a codepoint, not a byte, + # in which case this is still what we want. + a[w] = c + r += 1 + w += 1 + end + end + a[0,w] + end + + + # Encodes unicode character u as UTF-8 + # bytes in string a at position i. + # Returns the number of bytes written. + def ucharenc(a, i, u) + case true + when u <= Uchar1max + a[i] = (u & 0xff).chr + 1 + when u <= Uchar2max + a[i+0] = (Utag2 | ((u>>6)&0xff)).chr + a[i+1] = (Utagx | (u&Umaskx)).chr + 2 + when u <= Uchar3max + a[i+0] = (Utag3 | ((u>>12)&0xff)).chr + a[i+1] = (Utagx | ((u>>6)&Umaskx)).chr + a[i+2] = (Utagx | (u&Umaskx)).chr + 3 + else + a[i+0] = (Utag4 | ((u>>18)&0xff)).chr + a[i+1] = (Utagx | ((u>>12)&Umaskx)).chr + a[i+2] = (Utagx | ((u>>6)&Umaskx)).chr + a[i+3] = (Utagx | (u&Umaskx)).chr + 4 + end + end + + + def hexdec4(s) + if s.length != 4 + raise Error, 'short' + end + (nibble(s[0])<<12) | (nibble(s[1])<<8) | (nibble(s[2])<<4) | nibble(s[3]) + end + + + def subst(u1, u2) + if Usurr1 <= u1 && u1 < Usurr2 && Usurr2 <= u2 && u2 < Usurr3 + return ((u1-Usurr1)<<10) | (u2-Usurr2) + Usurrself + end + return Ucharerr + end + + + def surrogate?(u) + Usurr1 <= u && u < Usurr3 + end + + + def nibble(c) + case true + when ?0 <= c && c <= ?9 then c.ord - ?0.ord + when ?a <= c && c <= ?z then c.ord - ?a.ord + 10 + when ?A <= c && c <= ?Z then c.ord - ?A.ord + 10 + else + raise Error, "invalid hex code #{c}" + end + end + + + # Encodes x into a json text. It may contain only + # Array, Hash, String, Numeric, true, false, nil. + # (Note, this list excludes Symbol.) + # X itself must be an Array or a Hash. + # No other value can be encoded, and an error will + # be raised if x contains any other value, such as + # Nan, Infinity, Symbol, and Proc, or if a Hash key + # is not a String. + # Strings contained in x must be valid UTF-8. + def encode(x) + case x + when Hash then objenc(x) + when Array then arrenc(x) + else + raise Error, 'root value must be an Array or a Hash' + end + end + + + def valenc(x) + case x + when Hash then objenc(x) + when Array then arrenc(x) + when String then strenc(x) + when Numeric then numenc(x) + when true then "true" + when false then "false" + when nil then "null" + else + if x.respond_to?(:to_json) + x.to_json + else + raise Error, "cannot encode #{x.class}: #{x.inspect}" + end + end + end + + + def objenc(x) + '{' + x.map{|k,v| keyenc(k) + ':' + valenc(v)}.join(',') + '}' + end + + + def arrenc(a) + '[' + a.map{|x| valenc(x)}.join(',') + ']' + end + + + def keyenc(k) + case k + when String then strenc(k) + else + raise Error, "Hash key is not a string: #{k.inspect}" + end + end + + + def strenc(s) + t = StringIO.new + t.putc(?") + r = 0 + + # In ruby >= 1.9, s[r] is a codepoint, not a byte. + rubydoesenc = s.class.method_defined?(:encoding) + + while r < s.length + case s[r] + when ?" then t.print('\\"') + when ?\\ then t.print('\\\\') + when ?\b then t.print('\\b') + when ?\f then t.print('\\f') + when ?\n then t.print('\\n') + when ?\r then t.print('\\r') + when ?\t then t.print('\\t') + else + c = s[r] + case true + when rubydoesenc + begin + c.ord # will raise an error if c is invalid UTF-8 + t.write(c) + rescue + t.write(Ustrerr) + end + when Spc <= c && c <= ?~ + t.putc(c) + else + n = ucharcopy(t, s, r) # ensure valid UTF-8 output + r += n - 1 # r is incremented below + end + end + r += 1 + end + t.putc(?") + t.string + end + + + def numenc(x) + if ((x.nan? || x.infinite?) rescue false) + raise Error, "Numeric cannot be represented: #{x}" + end + "#{x}" + end + + + # Copies the valid UTF-8 bytes of a single character + # from string s at position i to I/O object t, and + # returns the number of bytes copied. + # If no valid UTF-8 char exists at position i, + # ucharcopy writes Ustrerr and returns 1. + def ucharcopy(t, s, i) + n = s.length - i + raise Utf8Error if n < 1 + + c0 = s[i].ord + + # 1-byte, 7-bit sequence? + if c0 < Utagx + t.putc(c0) + return 1 + end + + raise Utf8Error if c0 < Utag2 # unexpected continuation byte? + + raise Utf8Error if n < 2 # need continuation byte + c1 = s[i+1].ord + raise Utf8Error if c1 < Utagx || Utag2 <= c1 + + # 2-byte, 11-bit sequence? + if c0 < Utag3 + raise Utf8Error if ((c0&Umask2)<<6 | (c1&Umaskx)) <= Uchar1max + t.putc(c0) + t.putc(c1) + return 2 + end + + # need second continuation byte + raise Utf8Error if n < 3 + + c2 = s[i+2].ord + raise Utf8Error if c2 < Utagx || Utag2 <= c2 + + # 3-byte, 16-bit sequence? + if c0 < Utag4 + u = (c0&Umask3)<<12 | (c1&Umaskx)<<6 | (c2&Umaskx) + raise Utf8Error if u <= Uchar2max + t.putc(c0) + t.putc(c1) + t.putc(c2) + return 3 + end + + # need third continuation byte + raise Utf8Error if n < 4 + c3 = s[i+3].ord + raise Utf8Error if c3 < Utagx || Utag2 <= c3 + + # 4-byte, 21-bit sequence? + if c0 < Utag5 + u = (c0&Umask4)<<18 | (c1&Umaskx)<<12 | (c2&Umaskx)<<6 | (c3&Umaskx) + raise Utf8Error if u <= Uchar3max + t.putc(c0) + t.putc(c1) + t.putc(c2) + t.putc(c3) + return 4 + end + + raise Utf8Error + rescue Utf8Error + t.write(Ustrerr) + return 1 + end + + + class Utf8Error < ::StandardError + end + + + class Error < ::StandardError + end + + + Utagx = 0x80 # 1000 0000 + Utag2 = 0xc0 # 1100 0000 + Utag3 = 0xe0 # 1110 0000 + Utag4 = 0xf0 # 1111 0000 + Utag5 = 0xF8 # 1111 1000 + Umaskx = 0x3f # 0011 1111 + Umask2 = 0x1f # 0001 1111 + Umask3 = 0x0f # 0000 1111 + Umask4 = 0x07 # 0000 0111 + Uchar1max = (1<<7) - 1 + Uchar2max = (1<<11) - 1 + Uchar3max = (1<<16) - 1 + Ucharerr = 0xFFFD # unicode "replacement char" + Ustrerr = "\xef\xbf\xbd" # unicode "replacement char" + Usurrself = 0x10000 + Usurr1 = 0xd800 + Usurr2 = 0xdc00 + Usurr3 = 0xe000 + + Spc = ' '[0] + Unesc = {?b=>?\b, ?f=>?\f, ?n=>?\n, ?r=>?\r, ?t=>?\t} + end +end diff --git a/vendor/ruby/1.9.1/gems/multi_json-1.4.0/lib/multi_json/version.rb b/vendor/ruby/1.9.1/gems/multi_json-1.4.0/lib/multi_json/version.rb new file mode 100644 index 0000000..ce4d229 --- /dev/null +++ b/vendor/ruby/1.9.1/gems/multi_json-1.4.0/lib/multi_json/version.rb @@ -0,0 +1,3 @@ +module MultiJson + VERSION = "1.4.0" unless defined?(MultiJson::VERSION) +end diff --git a/vendor/ruby/1.9.1/gems/multi_json-1.4.0/multi_json.gemspec b/vendor/ruby/1.9.1/gems/multi_json-1.4.0/multi_json.gemspec new file mode 100644 index 0000000..10d5e12 --- /dev/null +++ b/vendor/ruby/1.9.1/gems/multi_json-1.4.0/multi_json.gemspec @@ -0,0 +1,23 @@ +# encoding: utf-8 +require File.expand_path("../lib/multi_json/version", __FILE__) + +Gem::Specification.new do |gem| + gem.add_development_dependency 'rake', '~> 0.9' + gem.add_development_dependency 'rdoc', '~> 3.9' + gem.add_development_dependency 'rspec', '~> 2.6' + gem.add_development_dependency 'simplecov', '~> 0.4' + gem.authors = ["Michael Bleigh", "Josh Kalderimis", "Erik Michaels-Ober"] + gem.description = %q{A gem to provide easy switching between different JSON backends, including Oj, Yajl, the JSON gem (with C-extensions), the pure-Ruby JSON gem, and OkJson.} + gem.email = ['michael@intridea.com', 'josh.kalderimis@gmail.com', 'sferik@gmail.com'] + gem.extra_rdoc_files = ['LICENSE.md', 'README.md'] + gem.files = Dir['LICENSE.md', 'README.md', 'Rakefile', 'multi_json.gemspec', 'Gemfile', '.document', '.rspec', '.travis.yml' ,'spec/**/*', 'lib/**/*'] + gem.homepage = 'http://github.com/intridea/multi_json' + gem.licenses = ['MIT'] + gem.name = 'multi_json' + gem.rdoc_options = ["--charset=UTF-8"] + gem.require_paths = ['lib'] + gem.required_rubygems_version = Gem::Requirement.new(">= 1.3.6") + gem.summary = %q{A gem to provide swappable JSON backends.} + gem.test_files = Dir['spec/**/*'] + gem.version = MultiJson::VERSION +end diff --git a/vendor/ruby/1.9.1/gems/multi_json-1.4.0/spec/adapter_shared_example.rb b/vendor/ruby/1.9.1/gems/multi_json-1.4.0/spec/adapter_shared_example.rb new file mode 100644 index 0000000..03edf0d --- /dev/null +++ b/vendor/ruby/1.9.1/gems/multi_json-1.4.0/spec/adapter_shared_example.rb @@ -0,0 +1,123 @@ +shared_examples_for "an adapter" do |adapter| + + before do + begin + MultiJson.use adapter + rescue LoadError + pending "Adapter #{adapter} couldn't be loaded (not installed?)" + end + end + + describe '.dump' do + it 'writes decodable JSON' do + [ + {'abc' => 'def'}, + [1, 2, 3, "4"], + ].each do |example| + expect(MultiJson.load(MultiJson.dump(example))).to eq example + end + end + + it 'dumps symbol keys as strings' do + [ + [ + {:foo => {:bar => 'baz'}}, + {'foo' => {'bar' => 'baz'}}, + ], + [ + [{:foo => {:bar => 'baz'}}], + [{'foo' => {'bar' => 'baz'}}], + ], + [ + {:foo => [{:bar => 'baz'}]}, + {'foo' => [{'bar' => 'baz'}]}, + ] + ].each do |example, expected| + dumped_json = MultiJson.dump(example) + expect(MultiJson.load(dumped_json)).to eq expected + end + end + + it 'dumps rootless JSON' do + expect(MultiJson.dump("random rootless string")).to eq "\"random rootless string\"" + expect(MultiJson.dump(123)).to eq "123" + end + + it 'passes options to the adapter' do + MultiJson.adapter.should_receive(:dump).with('foo', {:bar => :baz}) + MultiJson.dump('foo', :bar => :baz) + end + + if adapter == 'json_gem' || adapter == 'json_pure' + describe 'with :pretty option set to true' do + it 'passes default pretty options' do + object = 'foo' + object.should_receive(:to_json).with(JSON::PRETTY_STATE_PROTOTYPE.to_h) + MultiJson.dump(object,:pretty => true) + end + end + end + + it 'dumps custom objects which implement as_json' do + expect(MultiJson.dump(TimeWithZone.new)).to eq "\"2005-02-01T15:15:10Z\"" + end + + it 'allow to dump JSON values' do + expect(MultiJson.dump(42)).to eq '42' + end + + end + + describe '.load' do + it 'properly loads valid JSON' do + expect(MultiJson.load('{"abc":"def"}')).to eq({'abc' => 'def'}) + end + + it 'raises MultiJson::DecodeError on invalid JSON' do + expect{MultiJson.load('{"abc"}')}.to raise_error(MultiJson::DecodeError) + end + + it 'raises MultiJson::DecodeError with data on invalid JSON' do + data = '{invalid}' + begin + MultiJson.load(data) + rescue MultiJson::DecodeError => de + expect(de.data).to eq data + end + end + + it 'stringifys symbol keys when encoding' do + dumped_json = MultiJson.dump(:a => 1, :b => {:c => 2}) + expect(MultiJson.load(dumped_json)).to eq({"a" => 1, "b" => {"c" => 2}}) + end + + it 'properly loads valid JSON in StringIOs' do + json = StringIO.new('{"abc":"def"}') + expect(MultiJson.load(json)).to eq({'abc' => 'def'}) + end + + it 'allows for symbolization of keys' do + [ + [ + '{"abc":{"def":"hgi"}}', + {:abc => {:def => 'hgi'}}, + ], + [ + '[{"abc":{"def":"hgi"}}]', + [{:abc => {:def => 'hgi'}}], + ], + [ + '{"abc":[{"def":"hgi"}]}', + {:abc => [{:def => 'hgi'}]}, + ], + ].each do |example, expected| + expect(MultiJson.load(example, :symbolize_keys => true)).to eq expected + end + end + + it 'allow to load JSON values' do + expect(MultiJson.load('42')).to eq 42 + end + + end +end diff --git a/vendor/ruby/1.9.1/gems/multi_json-1.4.0/spec/helper.rb b/vendor/ruby/1.9.1/gems/multi_json-1.4.0/spec/helper.rb new file mode 100644 index 0000000..803cf78 --- /dev/null +++ b/vendor/ruby/1.9.1/gems/multi_json-1.4.0/spec/helper.rb @@ -0,0 +1,39 @@ +def jruby? + defined?(RUBY_ENGINE) && RUBY_ENGINE == 'jruby' +end + +def macruby? + defined?(RUBY_ENGINE) && RUBY_ENGINE == 'macruby' +end + +unless ENV['CI'] || macruby? + require 'simplecov' + SimpleCov.start do + add_filter 'spec' + end +end + +require 'multi_json' +require 'rspec' + +RSpec.configure do |config| + config.expect_with :rspec do |c| + c.syntax = :expect + end +end + +class MockDecoder + def self.load(string, options={}) + {'abc' => 'def'} + end + + def self.dump(string) + '{"abc":"def"}' + end +end + +class TimeWithZone + def to_json(options={}) + "\"2005-02-01T15:15:10Z\"" + end +end diff --git a/vendor/ruby/1.9.1/gems/multi_json-1.4.0/spec/multi_json_spec.rb b/vendor/ruby/1.9.1/gems/multi_json-1.4.0/spec/multi_json_spec.rb new file mode 100644 index 0000000..f445e93 --- /dev/null +++ b/vendor/ruby/1.9.1/gems/multi_json-1.4.0/spec/multi_json_spec.rb @@ -0,0 +1,89 @@ +require 'helper' +require 'adapter_shared_example' +require 'stringio' + +describe 'MultiJson' do + context 'adapters' do + before do + MultiJson.use nil + end + context 'when no other json implementations are available' do + before do + @old_map = MultiJson::REQUIREMENT_MAP + @old_json = Object.const_get :JSON if Object.const_defined?(:JSON) + @old_oj = Object.const_get :Oj if Object.const_defined?(:Oj) + @old_yajl = Object.const_get :Yajl if Object.const_defined?(:Yajl) + MultiJson::REQUIREMENT_MAP.each_with_index do |(library, adapter), index| + MultiJson::REQUIREMENT_MAP[index] = ["foo/#{library}", adapter] + end + Object.send :remove_const, :JSON if @old_json + Object.send :remove_const, :Oj if @old_oj + Object.send :remove_const, :Yajl if @old_yajl + end + + after do + @old_map.each_with_index do |(library, adapter), index| + MultiJson::REQUIREMENT_MAP[index] = [library, adapter] + end + Object.const_set :JSON, @old_json if @old_json + Object.const_set :Oj, @old_oj if @old_oj + Object.const_set :Yajl, @old_yajl if @old_yajl + end + + it 'defaults to ok_json if no other json implementions are available' do + expect(MultiJson.default_adapter).to eq :ok_json + end + + it 'prints a warning' do + Kernel.should_receive(:warn).with(/warning/i) + MultiJson.default_adapter + end + end + + it 'defaults to the best available gem' do + # Clear cache variable already set by previous tests + MultiJson.send(:remove_instance_variable, :@adapter) + unless jruby? + require 'oj' + expect(MultiJson.adapter.name).to eq 'MultiJson::Adapters::Oj' + else + require 'json' + expect(MultiJson.adapter.name).to eq 'MultiJson::Adapters::JsonGem' + end + end + + it 'is settable via a symbol' do + MultiJson.use :json_gem + expect(MultiJson.adapter.name).to eq 'MultiJson::Adapters::JsonGem' + end + + it 'is settable via a class' do + MultiJson.use MockDecoder + expect(MultiJson.adapter.name).to eq 'MockDecoder' + end + + context "using one-shot parser" do + before(:each) do + require 'multi_json/adapters/json_pure' + MultiJson::Adapters::JsonPure.should_receive(:dump).exactly(1).times.and_return('dump_something') + MultiJson::Adapters::JsonPure.should_receive(:load).exactly(1).times.and_return('load_something') + end + + it "should use the defined parser just for the call" do + MultiJson.use :json_gem + expect(MultiJson.dump('', :adapter => :json_pure)).to eq 'dump_something' + expect(MultiJson.load('', :adapter => :json_pure)).to eq 'load_something' + expect(MultiJson.adapter.to_s).to eq "MultiJson::Adapters::JsonGem" + end + end + end + + %w(json_gem json_pure nsjsonserialization oj ok_json yajl).each do |adapter| + next if !macruby? && adapter == 'nsjsonserialization' + next if jruby? && (adapter == 'oj' || adapter == 'yajl') + + context adapter do + it_behaves_like "an adapter", adapter + end + end +end diff --git a/vendor/ruby/1.9.1/gems/multi_xml-0.5.1/.gemtest b/vendor/ruby/1.9.1/gems/multi_xml-0.5.1/.gemtest new file mode 100644 index 0000000..e69de29 diff --git a/vendor/ruby/1.9.1/gems/multi_xml-0.5.1/.gitignore b/vendor/ruby/1.9.1/gems/multi_xml-0.5.1/.gitignore new file mode 100644 index 0000000..c6de9ad --- /dev/null +++ b/vendor/ruby/1.9.1/gems/multi_xml-0.5.1/.gitignore @@ -0,0 +1,9 @@ +*.gem +*.rbc +.bundle +.yardoc +Gemfile.lock +coverage/* +doc/* +log/* +pkg/* diff --git a/vendor/ruby/1.9.1/gems/multi_xml-0.5.1/.rspec b/vendor/ruby/1.9.1/gems/multi_xml-0.5.1/.rspec new file mode 100644 index 0000000..0912718 --- /dev/null +++ b/vendor/ruby/1.9.1/gems/multi_xml-0.5.1/.rspec @@ -0,0 +1,2 @@ +--color +--order random diff --git a/vendor/ruby/1.9.1/gems/multi_xml-0.5.1/.travis.yml b/vendor/ruby/1.9.1/gems/multi_xml-0.5.1/.travis.yml new file mode 100644 index 0000000..d268672 --- /dev/null +++ b/vendor/ruby/1.9.1/gems/multi_xml-0.5.1/.travis.yml @@ -0,0 +1,9 @@ +language: ruby +matrix: + allow_failures: + - rvm: ruby-head +rvm: + - 1.8.7 + - 1.9.2 + - 1.9.3 + - ruby-head diff --git a/vendor/ruby/1.9.1/gems/multi_xml-0.5.1/.yardopts b/vendor/ruby/1.9.1/gems/multi_xml-0.5.1/.yardopts new file mode 100644 index 0000000..980a7c1 --- /dev/null +++ b/vendor/ruby/1.9.1/gems/multi_xml-0.5.1/.yardopts @@ -0,0 +1,5 @@ +--no-private +--protected +--markup markdown +- +LICENSE.md diff --git a/vendor/ruby/1.9.1/gems/multi_xml-0.5.1/Gemfile b/vendor/ruby/1.9.1/gems/multi_xml-0.5.1/Gemfile new file mode 100644 index 0000000..f784d54 --- /dev/null +++ b/vendor/ruby/1.9.1/gems/multi_xml-0.5.1/Gemfile @@ -0,0 +1,9 @@ +source 'https://rubygems.org' + +group :development, :test do + gem 'libxml-ruby', :require => nil, :platforms => :mri + gem 'nokogiri', :require => nil + gem 'ox', :require => nil +end + +gemspec diff --git a/vendor/ruby/1.9.1/gems/multi_xml-0.5.1/LICENSE.md b/vendor/ruby/1.9.1/gems/multi_xml-0.5.1/LICENSE.md new file mode 100644 index 0000000..0420edb --- /dev/null +++ b/vendor/ruby/1.9.1/gems/multi_xml-0.5.1/LICENSE.md @@ -0,0 +1,20 @@ +Copyright (c) 2010 Erik Michaels-Ober + +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. diff --git a/vendor/ruby/1.9.1/gems/multi_xml-0.5.1/README.md b/vendor/ruby/1.9.1/gems/multi_xml-0.5.1/README.md new file mode 100644 index 0000000..7cdab6e --- /dev/null +++ b/vendor/ruby/1.9.1/gems/multi_xml-0.5.1/README.md @@ -0,0 +1,126 @@ +# MultiXML [![Build Status](https://secure.travis-ci.org/sferik/multi_xml.png?branch=master)][travis] [![Dependency Status](https://gemnasium.com/sferik/multi_xml.png?travis)][gemnasium] +A generic swappable back-end for XML parsing + +[travis]: http://travis-ci.org/sferik/multi_xml +[gemnasium]: https://gemnasium.com/sferik/multi_xml + +## Installation + gem install multi_xml + +## Documentation +[http://rdoc.info/gems/multi_xml][documentation] + +[documentation]: http://rdoc.info/gems/multi_xml + +## Usage Examples +Lots of Ruby libraries utilize XML parsing in some form, and everyone has their +favorite XML library. In order to best support multiple XML parsers and +libraries, `multi_xml` is a general-purpose swappable XML backend library. You +use it like so: + + require 'multi_xml' + + MultiXml.parser = :ox MultiXml.parser = MultiXml::Parsers::Ox # Same as + above MultiXml.parse('This is the contents') # Parsed using Ox + + MultiXml.parser = :libxml MultiXml.parser = MultiXml::Parsers::Libxml # + Same as above MultiXml.parse('This is the contents') # Parsed + using LibXML + + MultiXml.parser = :nokogiri MultiXml.parser = MultiXml::Parsers::Nokogiri # + Same as above MultiXml.parse('This is the contents') # Parsed + using Nokogiri + + MultiXml.parser = :rexml MultiXml.parser = MultiXml::Parsers::Rexml # Same + as above MultiXml.parse('This is the contents') # Parsed using + REXML + +The `parser` setter takes either a symbol or a class (to allow for custom XML +parsers) that responds to `.parse` at the class level. + +MultiXML tries to have intelligent defaulting. That is, if you have any of the +supported parsers already loaded, it will utilize them before attempting to +load any. When loading, libraries are ordered by speed: first Ox, then LibXML, +then Nokogiri, and finally REXML. + +## Contributing +In the spirit of [free software][free-sw] , **everyone** is encouraged to help +improve this project. + +[free-sw]: http://www.fsf.org/licensing/essays/free-sw.html + +Here are some ways *you* can contribute: + +* by using alpha, beta, and prerelease versions +* by reporting bugs +* by suggesting new features +* by writing or editing documentation +* by writing specifications +* by writing code (**no patch is too small**: fix typos, add comments, clean up + inconsistent whitespace) +* by refactoring code +* by resolving [issues][] +* by reviewing patches + +[issues]: https://github.com/sferik/multi_xml/issues + +## Submitting an Issue +We use the [GitHub issue tracker][issues] to track bugs and features. Before +submitting a bug report or feature request, check to make sure it hasn't +already been submitted. When submitting a bug report, please include a [Gist][] +that includes a stack trace and any details that may be necessary to reproduce +the bug, including your gem version, Ruby version, and operating system. +Ideally, a bug report should include a pull request with failing specs. + +[gist]: https://gist.github.com/ + +## Submitting a Pull Request +1. [Fork the repository.][fork] +2. [Create a topic branch.][branch] +3. Add specs for your unimplemented feature or bug fix. +4. Run `bundle exec rake spec`. If your specs pass, return to step 3. +5. Implement your feature or bug fix. +6. Run `bundle exec rake spec`. If your specs fail, return to step 5. +7. Run `open coverage/index.html`. If your changes are not completely covered + by your tests, return to step 3. +8. Add documentation for your feature or bug fix. +9. Run `bundle exec rake yard`. If your changes are not 100% documented, go + back to step 8. +10. Add, commit, and push your changes. +11. [Submit a pull request.][pr] + +[fork]: http://help.github.com/fork-a-repo/ +[branch]: http://learn.github.com/p/branching.html +[pr]: http://help.github.com/send-pull-requests/ + +## Supported Ruby Versions +This library aims to support and is [tested against][travis] the following Ruby +implementations: + +* Ruby 1.8.7 +* Ruby 1.9.2 +* Ruby 1.9.3 + +If something doesn't work on one of these interpreters, it should be considered +a bug. + +This library may inadvertently work (or seem to work) on other Ruby +implementations, however support will only be provided for the versions listed +above. + +If you would like this library to support another Ruby version, you may +volunteer to be a maintainer. Being a maintainer entails making sure all tests +run and pass on that implementation. When something breaks on your +implementation, you will be personally responsible for providing patches in a +timely fashion. If critical issues for a particular implementation exist at the +time of a major release, support for that Ruby version may be dropped. + +## Inspiration +MultiXML was inspired by [MultiJSON][]. + +[multijson]: https://github.com/intridea/multi_json/ + +## Copyright +Copyright (c) 2010 Erik Michaels-Ober. See [LICENSE][] for details. + +[license]: https://github.com/sferik/multi_xml/blob/master/LICENSE.md diff --git a/vendor/ruby/1.9.1/gems/multi_xml-0.5.1/Rakefile b/vendor/ruby/1.9.1/gems/multi_xml-0.5.1/Rakefile new file mode 100644 index 0000000..0e3699b --- /dev/null +++ b/vendor/ruby/1.9.1/gems/multi_xml-0.5.1/Rakefile @@ -0,0 +1,21 @@ +require 'bundler' +Bundler::GemHelper.install_tasks + +require 'rspec/core/rake_task' +RSpec::Core::RakeTask.new(:spec) + +task :test => :spec +task :default => :spec + +namespace :doc do + require 'yard' + YARD::Rake::YardocTask.new do |task| + task.files = ['LICENSE.md', 'lib/**/*.rb'] + task.options = [ + '--no-private', + '--protected', + '--output-dir', 'doc/yard', + '--markup', 'markdown', + ] + end +end diff --git a/vendor/ruby/1.9.1/gems/multi_xml-0.5.1/lib/multi_xml.rb b/vendor/ruby/1.9.1/gems/multi_xml-0.5.1/lib/multi_xml.rb new file mode 100644 index 0000000..09c9d98 --- /dev/null +++ b/vendor/ruby/1.9.1/gems/multi_xml-0.5.1/lib/multi_xml.rb @@ -0,0 +1,274 @@ +require 'base64' +require 'bigdecimal' +require 'date' +require 'stringio' +require 'time' +require 'yaml' + +module MultiXml + class ParseError < StandardError; end + + REQUIREMENT_MAP = [ + ['ox', :ox], + ['libxml', :libxml], + ['nokogiri', :nokogiri], + ['rexml/document', :rexml] + ] unless defined?(REQUIREMENT_MAP) + + CONTENT_ROOT = '__content__'.freeze unless defined?(CONTENT_ROOT) + + unless defined?(PARSING) + PARSING = { + 'symbol' => Proc.new{|symbol| symbol.to_sym}, + 'date' => Proc.new{|date| Date.parse(date)}, + 'datetime' => Proc.new{|time| Time.parse(time).utc rescue DateTime.parse(time).utc}, + 'integer' => Proc.new{|integer| integer.to_i}, + 'float' => Proc.new{|float| float.to_f}, + 'decimal' => Proc.new{|number| BigDecimal(number)}, + 'boolean' => Proc.new{|boolean| !%w(0 false).include?(boolean.strip)}, + 'string' => Proc.new{|string| string.to_s}, + 'yaml' => Proc.new{|yaml| YAML::load(yaml) rescue yaml}, + 'base64Binary' => Proc.new{|binary| ::Base64.decode64(binary)}, + 'binary' => Proc.new{|binary, entity| parse_binary(binary, entity)}, + 'file' => Proc.new{|file, entity| parse_file(file, entity)}, + } + + PARSING.update( + 'double' => PARSING['float'], + 'dateTime' => PARSING['datetime'] + ) + end + + TYPE_NAMES = { + 'Symbol' => 'symbol', + 'Fixnum' => 'integer', + 'Bignum' => 'integer', + 'BigDecimal' => 'decimal', + 'Float' => 'float', + 'TrueClass' => 'boolean', + 'FalseClass' => 'boolean', + 'Date' => 'date', + 'DateTime' => 'datetime', + 'Time' => 'datetime', + 'Array' => 'array', + 'Hash' => 'hash' + } unless defined?(TYPE_NAMES) + + class << self + # Get the current parser class. + def parser + return @@parser if defined?(@@parser) + self.parser = self.default_parser + @@parser + end + + # The default parser based on what you currently + # have loaded and installed. First checks to see + # if any parsers are already loaded, then checks + # to see which are installed if none are loaded. + def default_parser + return :ox if defined?(::Ox) + return :libxml if defined?(::LibXML) + return :nokogiri if defined?(::Nokogiri) + + REQUIREMENT_MAP.each do |(library, parser)| + begin + require library + return parser + rescue LoadError + next + end + end + end + + # Set the XML parser utilizing a symbol, string, or class. + # Supported by default are: + # + # * :libxml + # * :nokogiri + # * :ox + # * :rexml + def parser=(new_parser) + case new_parser + when String, Symbol + require "multi_xml/parsers/#{new_parser.to_s.downcase}" + @@parser = MultiXml::Parsers.const_get("#{new_parser.to_s.split('_').map{|s| s.capitalize}.join('')}") + when Class, Module + @@parser = new_parser + else + raise "Did not recognize your parser specification. Please specify either a symbol or a class." + end + end + + # Parse an XML string or IO into Ruby. + # + # Options + # + # :symbolize_keys :: If true, will use symbols instead of strings for the keys. + def parse(xml, options={}) + xml ||= '' + + xml.strip! if xml.respond_to?(:strip!) + begin + xml = StringIO.new(xml) unless xml.respond_to?(:read) + + char = xml.getc + return {} if char.nil? + xml.ungetc(char) + + hash = typecast_xml_value(undasherize_keys(parser.parse(xml))) || {} + rescue parser.parse_error => error + raise ParseError, error.to_s, error.backtrace + end + hash = symbolize_keys(hash) if options[:symbolize_keys] + hash + end + + # This module decorates files with the original_filename + # and content_type methods. + module FileLike #:nodoc: + attr_writer :original_filename, :content_type + + def original_filename + @original_filename || 'untitled' + end + + def content_type + @content_type || 'application/octet-stream' + end + end + + private + + # TODO: Add support for other encodings + def parse_binary(binary, entity) #:nodoc: + case entity['encoding'] + when 'base64' + Base64.decode64(binary) + else + binary + end + end + + def parse_file(file, entity) + f = StringIO.new(Base64.decode64(file)) + f.extend(FileLike) + f.original_filename = entity['name'] + f.content_type = entity['content_type'] + f + end + + def symbolize_keys(hash) + hash.inject({}) do |result, (key, value)| + new_key = case key + when String + key.to_sym + else + key + end + new_value = case value + when Hash + symbolize_keys(value) + else + value + end + result[new_key] = new_value + result + end + end + + def undasherize_keys(params) + case params + when Hash + params.inject({}) do |hash, (key, value)| + hash[key.to_s.tr('-', '_')] = undasherize_keys(value) + hash + end + when Array + params.map{|value| undasherize_keys(value)} + else + params + end + end + + def typecast_xml_value(value) + case value + when Hash + if value['type'] == 'array' + + # this commented-out suggestion helps to avoid the multiple attribute + # problem, but it breaks when there is only one item in the array. + # + # from: https://github.com/jnunemaker/httparty/issues/102 + # + # _, entries = value.detect { |k, v| k != 'type' && v.is_a?(Array) } + + # This attempt fails to consider the order that the detect method + # retrieves the entries. + #_, entries = value.detect {|key, _| key != 'type'} + + # This approach ignores attribute entries that are not convertable + # to an Array which allows attributes to be ignored. + _, entries = value.detect {|k, v| k != 'type' && (v.is_a?(Array) || v.is_a?(Hash)) } + + if entries.nil? || (entries.is_a?(String) && entries.strip.empty?) + [] + else + case entries + when Array + entries.map {|entry| typecast_xml_value(entry)} + when Hash + [typecast_xml_value(entries)] + else + raise "can't typecast #{entries.class.name}: #{entries.inspect}" + end + end + elsif value.has_key?(CONTENT_ROOT) + content = value[CONTENT_ROOT] + if block = PARSING[value['type']] + if block.arity == 1 + value.delete('type') if PARSING[value['type']] + if value.keys.size > 1 + value[CONTENT_ROOT] = block.call(content) + value + else + block.call(content) + end + else + block.call(content, value) + end + else + value.keys.size > 1 ? value : content + end + elsif value['type'] == 'string' && value['nil'] != 'true' + '' + # blank or nil parsed values are represented by nil + elsif value.empty? || value['nil'] == 'true' + nil + # If the type is the only element which makes it then + # this still makes the value nil, except if type is + # a XML node(where type['value'] is a Hash) + elsif value['type'] && value.size == 1 && !value['type'].is_a?(Hash) + nil + else + xml_value = value.inject({}) do |hash, (k, v)| + hash[k] = typecast_xml_value(v) + hash + end + + # Turn {:files => {:file => #} into {:files => #} so it is compatible with + # how multipart uploaded files from HTML appear + xml_value['file'].is_a?(StringIO) ? xml_value['file'] : xml_value + end + when Array + value.map!{|i| typecast_xml_value(i)} + value.length > 1 ? value : value.first + when String + value + else + raise "can't typecast #{value.class.name}: #{value.inspect}" + end + end + end + +end diff --git a/vendor/ruby/1.9.1/gems/multi_xml-0.5.1/lib/multi_xml/parsers/libxml.rb b/vendor/ruby/1.9.1/gems/multi_xml-0.5.1/lib/multi_xml/parsers/libxml.rb new file mode 100644 index 0000000..1fb6353 --- /dev/null +++ b/vendor/ruby/1.9.1/gems/multi_xml-0.5.1/lib/multi_xml/parsers/libxml.rb @@ -0,0 +1,30 @@ +require 'libxml' unless defined?(LibXML) +require 'multi_xml/parsers/libxml2_parser' + +module MultiXml + module Parsers + module Libxml #:nodoc: + include Libxml2Parser + + extend self + + def parse_error() ::LibXML::XML::Error end + + def parse(xml) + node_to_hash(LibXML::XML::Parser.io(xml).parse.root) + end + + def each_child(node, &block) + node.each_child(&block) + end + + def each_attr(node, &block) + node.each_attr(&block) + end + + def node_name(node) + node.name + end + end + end +end diff --git a/vendor/ruby/1.9.1/gems/multi_xml-0.5.1/lib/multi_xml/parsers/libxml2_parser.rb b/vendor/ruby/1.9.1/gems/multi_xml-0.5.1/lib/multi_xml/parsers/libxml2_parser.rb new file mode 100644 index 0000000..f51fbf5 --- /dev/null +++ b/vendor/ruby/1.9.1/gems/multi_xml-0.5.1/lib/multi_xml/parsers/libxml2_parser.rb @@ -0,0 +1,66 @@ +module MultiXml + module Parsers + module Libxml2Parser #:nodoc: + # Convert XML document to hash + # + # node:: + # The XML node object to convert to a hash. + # + # hash:: + # Hash to merge the converted element into. + def node_to_hash(node, hash={}) + node_hash = {MultiXml::CONTENT_ROOT => ''} + + name = node_name(node) + + # Insert node hash into parent hash correctly. + case hash[name] + when Array then hash[name] << node_hash + when Hash then hash[name] = [hash[name], node_hash] + when nil then hash[name] = node_hash + end + + # Handle child elements + each_child(node) do |c| + if c.element? + node_to_hash(c, node_hash) + elsif c.text? || c.cdata? + node_hash[MultiXml::CONTENT_ROOT] << c.content + end + end + + # Remove content node if it is empty + if node_hash[MultiXml::CONTENT_ROOT].strip.empty? + node_hash.delete(MultiXml::CONTENT_ROOT) + end + + # Handle attributes + each_attr(node) {|a| node_hash[node_name(a)] = a.value } + + hash + end + + # Parse an XML Document IO into a simple hash. + # xml:: + # XML Document IO to parse + def parse(xml) + raise NotImplementedError, "inheritor should define #{__method__}" + end + + # :stopdoc: + private + + def each_child(*args) + raise NotImplementedError, "inheritor should define #{__method__}" + end + + def each_attr(*args) + raise NotImplementedError, "inheritor should define #{__method__}" + end + + def node_name(*args) + raise NotImplementedError, "inheritor should define #{__method__}" + end + end + end +end diff --git a/vendor/ruby/1.9.1/gems/multi_xml-0.5.1/lib/multi_xml/parsers/nokogiri.rb b/vendor/ruby/1.9.1/gems/multi_xml-0.5.1/lib/multi_xml/parsers/nokogiri.rb new file mode 100644 index 0000000..bb546ee --- /dev/null +++ b/vendor/ruby/1.9.1/gems/multi_xml-0.5.1/lib/multi_xml/parsers/nokogiri.rb @@ -0,0 +1,32 @@ +require 'nokogiri' unless defined?(Nokogiri) +require 'multi_xml/parsers/libxml2_parser' + +module MultiXml + module Parsers + module Nokogiri #:nodoc: + include Libxml2Parser + + extend self + + def parse_error() ::Nokogiri::XML::SyntaxError end + + def parse(xml) + doc = ::Nokogiri::XML(xml) + raise doc.errors.first if doc.errors.length > 0 + node_to_hash(doc.root) + end + + def each_child(node, &block) + node.children.each(&block) + end + + def each_attr(node, &block) + node.attribute_nodes.each(&block) + end + + def node_name(node) + node.node_name + end + end + end +end diff --git a/vendor/ruby/1.9.1/gems/multi_xml-0.5.1/lib/multi_xml/parsers/ox.rb b/vendor/ruby/1.9.1/gems/multi_xml-0.5.1/lib/multi_xml/parsers/ox.rb new file mode 100644 index 0000000..78d7643 --- /dev/null +++ b/vendor/ruby/1.9.1/gems/multi_xml-0.5.1/lib/multi_xml/parsers/ox.rb @@ -0,0 +1,97 @@ +require 'ox' unless defined?(Ox) + +# Each MultiXml parser is expected to parse an XML document into a Hash. The +# conversion rules are: +# +# - Each document starts out as an empty Hash. +# +# - Reading an element created an entry in the parent Hash that has a key of +# the element name and a value of a Hash with attributes as key value +# pairs. Children are added as described by this rule. +# +# - Text and CDATE is stored in the parent element Hash with a key of +# '__content__' and a value of the text itself. +# +# - If a key already exists in the Hash then the value associated with the key +# is converted to an Array with the old and new value in it. +# +# - Other elements such as the xml prolog, doctype, and comments are ignored. +# + +module MultiXml + module Parsers + module Ox #:nodoc: + + extend self + + def parse_error + Exception + end + + def parse(io) + handler = Handler.new + ::Ox.sax_parse(handler, io, :convert_special => true) + handler.doc + end + + class Handler + attr_accessor :stack + + def initialize() + @stack = [] + end + + def doc + @stack[0] + end + + def attr(name, value) + unless @stack.empty? + append(name, value) + end + end + + def text(value) + append('__content__', value) + end + + def cdata(value) + append('__content__', value) + end + + def start_element(name) + if @stack.empty? + @stack.push(Hash.new) + end + h = Hash.new + append(name, h) + @stack.push(h) + end + + def end_element(name) + @stack.pop() + end + + def error(message, line, column) + raise Exception.new("#{message} at #{line}:#{column}") + end + + def append(key, value) + key = key.to_s + h = @stack.last + if h.has_key?(key) + v = h[key] + if v.is_a?(Array) + v << value + else + h[key] = [v, value] + end + else + h[key] = value + end + end + + end # Handler + end # Ox + end # Parsers +end # MultiXml diff --git a/vendor/ruby/1.9.1/gems/multi_xml-0.5.1/lib/multi_xml/parsers/rexml.rb b/vendor/ruby/1.9.1/gems/multi_xml-0.5.1/lib/multi_xml/parsers/rexml.rb new file mode 100644 index 0000000..2713c89 --- /dev/null +++ b/vendor/ruby/1.9.1/gems/multi_xml-0.5.1/lib/multi_xml/parsers/rexml.rb @@ -0,0 +1,113 @@ +require 'rexml/document' unless defined?(REXML::Document) + +module MultiXml + module Parsers + module Rexml #:nodoc: + extend self + def parse_error; ::REXML::ParseException; end + + # Parse an XML Document IO into a simple hash using REXML + # + # xml:: + # XML Document IO to parse + def parse(xml) + doc = REXML::Document.new(xml) + if doc.root + merge_element!({}, doc.root) + else + raise REXML::ParseException, "The document #{doc.to_s.inspect} does not have a valid root" + end + end + + private + + # Convert an XML element and merge into the hash + # + # hash:: + # Hash to merge the converted element into. + # element:: + # XML element to merge into hash + def merge_element!(hash, element) + merge!(hash, element.name, collapse(element)) + end + + # Actually converts an XML document element into a data structure. + # + # element:: + # The document element to be collapsed. + def collapse(element) + hash = get_attributes(element) + + if element.has_elements? + element.each_element {|child| merge_element!(hash, child) } + merge_texts!(hash, element) unless empty_content?(element) + hash + else + merge_texts!(hash, element) + end + end + + # Merge all the texts of an element into the hash + # + # hash:: + # Hash to add the converted element to. + # element:: + # XML element whose texts are to me merged into the hash + def merge_texts!(hash, element) + unless element.has_text? + hash + else + # must use value to prevent double-escaping + texts = '' + element.texts.each { |t| texts << t.value } + merge!(hash, MultiXml::CONTENT_ROOT, texts) + end + end + + # Adds a new key/value pair to an existing Hash. If the key to be added + # already exists and the existing value associated with key is not + # an Array, it will be wrapped in an Array. Then the new value is + # appended to that Array. + # + # hash:: + # Hash to add key/value pair to. + # key:: + # Key to be added. + # value:: + # Value to be associated with key. + def merge!(hash, key, value) + if hash.has_key?(key) + if hash[key].instance_of?(Array) + hash[key] << value + else + hash[key] = [hash[key], value] + end + elsif value.instance_of?(Array) + hash[key] = [value] + else + hash[key] = value + end + hash + end + + # Converts the attributes array of an XML element into a hash. + # Returns an empty Hash if node has no attributes. + # + # element:: + # XML element to extract attributes from. + def get_attributes(element) + attributes = {} + element.attributes.each { |n,v| attributes[n] = v } + attributes + end + + # Determines if a document element has text content + # + # element:: + # XML element to be checked. + def empty_content?(element) + element.texts.join.strip.empty? + end + end + end +end diff --git a/vendor/ruby/1.9.1/gems/multi_xml-0.5.1/lib/multi_xml/version.rb b/vendor/ruby/1.9.1/gems/multi_xml-0.5.1/lib/multi_xml/version.rb new file mode 100644 index 0000000..9a579cc --- /dev/null +++ b/vendor/ruby/1.9.1/gems/multi_xml-0.5.1/lib/multi_xml/version.rb @@ -0,0 +1,3 @@ +module MultiXml + VERSION = "0.5.1" +end diff --git a/vendor/ruby/1.9.1/gems/multi_xml-0.5.1/multi_xml.gemspec b/vendor/ruby/1.9.1/gems/multi_xml-0.5.1/multi_xml.gemspec new file mode 100644 index 0000000..fdaa804 --- /dev/null +++ b/vendor/ruby/1.9.1/gems/multi_xml-0.5.1/multi_xml.gemspec @@ -0,0 +1,21 @@ +# encoding: utf-8 +require File.expand_path('../lib/multi_xml/version', __FILE__) + +Gem::Specification.new do |gem| + gem.add_development_dependency 'maruku' + gem.add_development_dependency 'rake' + gem.add_development_dependency 'rspec' + gem.add_development_dependency 'simplecov' + gem.add_development_dependency 'yard' + gem.author = "Erik Michaels-Ober" + gem.description = %q{A gem to provide swappable XML backends utilizing LibXML, Nokogiri, Ox, or REXML.} + gem.email = 'sferik@gmail.com' + gem.files = `git ls-files`.split("\n") + gem.homepage = 'https://github.com/sferik/multi_xml' + gem.name = 'multi_xml' + gem.platform = Gem::Platform::RUBY + gem.require_paths = ['lib'] + gem.summary = %q{A generic swappable back-end for XML parsing} + gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n") + gem.version = MultiXml::VERSION +end diff --git a/vendor/ruby/1.9.1/gems/multi_xml-0.5.1/spec/helper.rb b/vendor/ruby/1.9.1/gems/multi_xml-0.5.1/spec/helper.rb new file mode 100644 index 0000000..3e080ce --- /dev/null +++ b/vendor/ruby/1.9.1/gems/multi_xml-0.5.1/spec/helper.rb @@ -0,0 +1,7 @@ +unless ENV['CI'] + require 'simplecov' + SimpleCov.start do + add_filter 'spec' + end +end +require 'multi_xml' diff --git a/vendor/ruby/1.9.1/gems/multi_xml-0.5.1/spec/multi_xml_spec.rb b/vendor/ruby/1.9.1/gems/multi_xml-0.5.1/spec/multi_xml_spec.rb new file mode 100644 index 0000000..782325c --- /dev/null +++ b/vendor/ruby/1.9.1/gems/multi_xml-0.5.1/spec/multi_xml_spec.rb @@ -0,0 +1,46 @@ +require 'helper' +require 'parser_shared_example' + +class MockDecoder; end + +describe "MultiXml" do + context "Parsers" do + it "should pick a default parser" do + MultiXml.parser.should be_kind_of(Module) + MultiXml.parser.should respond_to(:parse) + end + + it "should default to the best available gem" do + pending + MultiXml.parser.name.should be == 'MultiXml::Parsers::Rexml' + require 'nokogiri' + MultiXml.parser.name.should be == 'MultiXml::Parsers::Nokogiri' + require 'libxml' + MultiXml.parser.name.should == 'MultiXml::Parsers::Libxml' + end + + it "should be settable via a symbol" do + MultiXml.parser = :nokogiri + MultiXml.parser.name.should == 'MultiXml::Parsers::Nokogiri' + end + + it "should be settable via a class" do + MultiXml.parser = MockDecoder + MultiXml.parser.name.should == 'MockDecoder' + end + end + + [['LibXML', 'libxml'], + ['REXML', 'rexml/document'], + ['Nokogiri', 'nokogiri'], + ['Ox', 'ox']].each do |parser| + begin + require parser.last + context "#{parser.first} parser" do + it_should_behave_like "a parser", parser.first + end + rescue LoadError => e + puts "Tests not run for #{parser.first} due to a LoadError" + end + end +end diff --git a/vendor/ruby/1.9.1/gems/multi_xml-0.5.1/spec/parser_shared_example.rb b/vendor/ruby/1.9.1/gems/multi_xml-0.5.1/spec/parser_shared_example.rb new file mode 100644 index 0000000..86e0ec9 --- /dev/null +++ b/vendor/ruby/1.9.1/gems/multi_xml-0.5.1/spec/parser_shared_example.rb @@ -0,0 +1,677 @@ +shared_examples_for "a parser" do |parser| + + before do + begin + MultiXml.parser = parser + rescue LoadError + pending "Parser #{parser} couldn't be loaded" + end + end + + describe ".parse" do + context "a blank string" do + before do + @xml = '' + end + + it "should return an empty Hash" do + MultiXml.parse(@xml).should == {} + end + end + + context "a whitespace string" do + before do + @xml = ' ' + end + + it "should return an empty Hash" do + MultiXml.parse(@xml).should == {} + end + end + + context "an invalid XML document" do + before do + @xml = '' + end + + it "should raise MultiXml::ParseError" do + lambda do + MultiXml.parse(@xml) + end.should raise_error(MultiXml::ParseError) + end + end + + context "a valid XML document" do + before do + @xml = '' + end + + it "should parse correctly" do + MultiXml.parse(@xml).should == {'user' => nil} + end + + context "with CDATA" do + before do + @xml = '' + end + + it "should return the correct CDATA" do + MultiXml.parse(@xml)['user'].should == "Erik Michaels-Ober" + end + end + + context "with content" do + before do + @xml = 'Erik Michaels-Ober' + end + + it "should return the correct content" do + MultiXml.parse(@xml)['user'].should == "Erik Michaels-Ober" + end + end + + context "with an attribute" do + before do + @xml = '' + end + + it "should return the correct attribute" do + MultiXml.parse(@xml)['user']['name'].should == "Erik Michaels-Ober" + end + end + + context "with multiple attributes" do + before do + @xml = '' + end + + it "should return the correct attributes" do + MultiXml.parse(@xml)['user']['name'].should be == "Erik Michaels-Ober" + MultiXml.parse(@xml)['user']['screen_name'].should be == "sferik" + end + end + + context "with :symbolize_keys => true" do + before do + @xml = 'Erik Michaels-Ober' + end + + it "should symbolize keys" do + MultiXml.parse(@xml, :symbolize_keys => true).should == {:user => {:name => "Erik Michaels-Ober"}} + end + end + + context "when value is true" do + before do + pending + @xml = 'true' + end + + it "should return true" do + MultiXml.parse(@xml)['tag'].should be_true + end + end + + context "when value is false" do + before do + pending + @xml = 'false' + end + + it "should return false" do + MultiXml.parse(@xml)['tag'].should be_false + end + end + + context "when key is id" do + before do + pending + @xml = '1' + end + + it "should return a Fixnum" do + MultiXml.parse(@xml)['id'].should be_a(Fixnum) + end + + it "should return the correct number" do + MultiXml.parse(@xml)['id'].should == 1 + end + end + + context "when key contains _id" do + before do + pending + @xml = '1' + end + + it "should return a Fixnum" do + MultiXml.parse(@xml)['tag_id'].should be_a(Fixnum) + end + + it "should return the correct number" do + MultiXml.parse(@xml)['tag_id'].should == 1 + end + end + + context "with an attribute type=\"boolean\"" do + %w(true false).each do |boolean| + context "when #{boolean}" do + it "should return #{boolean}" do + xml = "#{boolean}" + MultiXml.parse(xml)['tag'].should instance_eval("be_#{boolean}") + end + end + end + + context "when 1" do + before do + @xml = '1' + end + + it "should return true" do + MultiXml.parse(@xml)['tag'].should be_true + end + end + + context "when 0" do + before do + @xml = '0' + end + + it "should return false" do + MultiXml.parse(@xml)['tag'].should be_false + end + end + end + + context "with an attribute type=\"integer\"" do + context "with a positive integer" do + before do + @xml = '1' + end + + it "should return a Fixnum" do + MultiXml.parse(@xml)['tag'].should be_a(Fixnum) + end + + it "should return a positive number" do + MultiXml.parse(@xml)['tag'].should > 0 + end + + it "should return the correct number" do + MultiXml.parse(@xml)['tag'].should == 1 + end + end + + context "with a negative integer" do + before do + @xml = '-1' + end + + it "should return a Fixnum" do + MultiXml.parse(@xml)['tag'].should be_a(Fixnum) + end + + it "should return a negative number" do + MultiXml.parse(@xml)['tag'].should < 0 + end + + it "should return the correct number" do + MultiXml.parse(@xml)['tag'].should == -1 + end + end + end + + context "with an attribute type=\"string\"" do + before do + @xml = '' + end + + it "should return a String" do + MultiXml.parse(@xml)['tag'].should be_a(String) + end + + it "should return the correct string" do + MultiXml.parse(@xml)['tag'].should == "" + end + end + + context "with an attribute type=\"date\"" do + before do + @xml = '1970-01-01' + end + + it "should return a Date" do + MultiXml.parse(@xml)['tag'].should be_a(Date) + end + + it "should return the correct date" do + MultiXml.parse(@xml)['tag'].should == Date.parse('1970-01-01') + end + end + + context "with an attribute type=\"datetime\"" do + before do + @xml = '1970-01-01 00:00' + end + + it "should return a Time" do + MultiXml.parse(@xml)['tag'].should be_a(Time) + end + + it "should return the correct time" do + MultiXml.parse(@xml)['tag'].should == Time.parse('1970-01-01 00:00') + end + end + + context "with an attribute type=\"dateTime\"" do + before do + @xml = '1970-01-01 00:00' + end + + it "should return a Time" do + MultiXml.parse(@xml)['tag'].should be_a(Time) + end + + it "should return the correct time" do + MultiXml.parse(@xml)['tag'].should == Time.parse('1970-01-01 00:00') + end + end + + context "with an attribute type=\"double\"" do + before do + @xml = '3.14159265358979' + end + + it "should return a Float" do + MultiXml.parse(@xml)['tag'].should be_a(Float) + end + + it "should return the correct number" do + MultiXml.parse(@xml)['tag'].should == 3.14159265358979 + end + end + + context "with an attribute type=\"decimal\"" do + before do + @xml = '3.14159265358979' + end + + it "should return a BigDecimal" do + MultiXml.parse(@xml)['tag'].should be_a(BigDecimal) + end + + it "should return the correct number" do + MultiXml.parse(@xml)['tag'].should == 3.14159265358979 + end + end + + context "with an attribute type=\"base64Binary\"" do + before do + @xml = 'aW1hZ2UucG5n' + end + + it "should return a String" do + MultiXml.parse(@xml)['tag'].should be_a(String) + end + + it "should return the correct string" do + MultiXml.parse(@xml)['tag'].should == "image.png" + end + end + + context "with an attribute type=\"yaml\"" do + before do + @xml = "--- \n1: should return an integer\n:message: Have a nice day\narray: \n- should-have-dashes: true\n should_have_underscores: true\n" + end + + it "should return a Hash" do + MultiXml.parse(@xml)['tag'].should be_a(Hash) + end + + it "should return the correctly parsed YAML" do + MultiXml.parse(@xml)['tag'].should == {:message => "Have a nice day", 1 => "should return an integer", "array" => [{"should-have-dashes" => true, "should_have_underscores" => true}]} + end + end + + context "with an attribute type=\"file\"" do + before do + @xml = 'ZGF0YQ==' + end + + it "should return a StringIO" do + MultiXml.parse(@xml)['tag'].should be_a(StringIO) + end + + it "should be decoded correctly" do + MultiXml.parse(@xml)['tag'].string.should == 'data' + end + + it "should have the correct file name" do + MultiXml.parse(@xml)['tag'].original_filename.should == 'data.txt' + end + + it "should have the correct content type" do + MultiXml.parse(@xml)['tag'].content_type.should == 'text/plain' + end + + context "with missing name and content type" do + before do + @xml = 'ZGF0YQ==' + end + + it "should return a StringIO" do + MultiXml.parse(@xml)['tag'].should be_a(StringIO) + end + + it "should be decoded correctly" do + MultiXml.parse(@xml)['tag'].string.should == 'data' + end + + it "should have the default file name" do + MultiXml.parse(@xml)['tag'].original_filename.should == 'untitled' + end + + it "should have the default content type" do + MultiXml.parse(@xml)['tag'].content_type.should == 'application/octet-stream' + end + end + end + + context "with an attribute type=\"array\"" do + before do + @xml = 'Erik Michaels-OberWynn Netherland' + end + + it "should return an Array" do + MultiXml.parse(@xml)['users'].should be_a(Array) + end + + it "should return the correct array" do + MultiXml.parse(@xml)['users'].should == ["Erik Michaels-Ober", "Wynn Netherland"] + end + end + + context "with an attribute type=\"array\" in addition to other attributes" do + before do + @xml = 'Erik Michaels-OberWynn Netherland' + end + + it "should return an Array" do + MultiXml.parse(@xml)['users'].should be_a(Array) + end + + it "should return the correct array" do + MultiXml.parse(@xml)['users'].should == ["Erik Michaels-Ober", "Wynn Netherland"] + end + end + + context "with an attribute type=\"array\" containing only one item" do + before do + @xml = 'Erik Michaels-Ober' + end + + it "should return an Array" do + MultiXml.parse(@xml)['users'].should be_a(Array) + end + + it "should return the correct array" do + MultiXml.parse(@xml)['users'].should == ["Erik Michaels-Ober"] + end + end + + %w(integer boolean date datetime yaml file).each do |type| + context "with an empty attribute type=\"#{type}\"" do + before do + @xml = "" + end + + it "should return nil" do + MultiXml.parse(@xml)['tag'].should be_nil + end + end + end + + context "with an empty attribute type=\"array\"" do + before do + @xml = '' + end + + it "should return an empty Array" do + MultiXml.parse(@xml)['tag'].should == [] + end + + context "with whitespace" do + before do + @xml = ' ' + end + + it "should return an empty Array" do + MultiXml.parse(@xml)['tag'].should == [] + end + end + end + + context "with XML entities" do + before do + @xml_entities = { + "<" => "<", + ">" => ">", + '"' => """, + "'" => "'", + "&" => "&" + } + end + + context "in content" do + it "should return unescaped XML entities" do + @xml_entities.each do |key, value| + xml = "#{value}" + MultiXml.parse(xml)['tag'].should == key + end + end + end + + context "in attribute" do + it "should return unescaped XML entities" do + @xml_entities.each do |key, value| + xml = "" + MultiXml.parse(xml)['tag']['attribute'].should == key + end + end + end + end + + + context "with dasherized tag" do + before do + @xml = '' + end + + it "should return undasherize tag" do + MultiXml.parse(@xml).keys.should include('tag_1') + end + end + + context "with dasherized attribute" do + before do + @xml = '' + end + + it "should return undasherize attribute" do + MultiXml.parse(@xml)['tag'].keys.should include('attribute_1') + end + end + + context "with children" do + context "with attributes" do + before do + @xml = '' + end + + it "should return the correct attributes" do + MultiXml.parse(@xml)['users']['user']['name'].should == "Erik Michaels-Ober" + end + end + + context "with text" do + before do + @xml = 'Erik Michaels-Ober' + end + + it "should return the correct text" do + MultiXml.parse(@xml)['user']['name'].should == "Erik Michaels-Ober" + end + end + + context "with an unrecognized attribute type" do + before do + @xml = 'Erik Michaels-Ober' + end + + it "should pass through the type" do + MultiXml.parse(@xml)['user']['type'].should == 'admin' + end + end + + context "with attribute tags on content nodes" do + context "non 'type' attributes" do + before do + @xml = <<-XML + + 123 + 0.123 + + XML + @parsed_xml = MultiXml.parse(@xml) + end + + it "should add the attributes to the value hash" do + @parsed_xml['options']['value'][0]['__content__'].should == '123' + @parsed_xml['options']['value'][0]['currency'].should == 'USD' + @parsed_xml['options']['value'][1]['__content__'].should == '0.123' + @parsed_xml['options']['value'][1]['number'].should == 'percent' + end + end + + context "unrecognized type attributes" do + before do + @xml = <<-XML + + 123 + 0.123 + 123 + + XML + @parsed_xml = MultiXml.parse(@xml) + end + + it "should add the attributes to the value hash passing through the type" do + @parsed_xml['options']['value'][0]['__content__'].should == '123' + @parsed_xml['options']['value'][0]['type'].should == 'USD' + @parsed_xml['options']['value'][1]['__content__'].should == '0.123' + @parsed_xml['options']['value'][1]['type'].should == 'percent' + @parsed_xml['options']['value'][2]['__content__'].should == '123' + @parsed_xml['options']['value'][2]['currency'].should == 'USD' + end + end + + context "mixing attributes and non-attributes content nodes type attributes" do + before do + @xml = <<-XML + + 123 + 0.123 + 123 + + XML + @parsed_xml = MultiXml.parse(@xml) + end + + it "should add the attributes to the value hash passing through the type" do + @parsed_xml['options']['value'][0]['__content__'].should == '123' + @parsed_xml['options']['value'][0]['type'].should == 'USD' + @parsed_xml['options']['value'][1]['__content__'].should == '0.123' + @parsed_xml['options']['value'][1]['type'].should == 'percent' + @parsed_xml['options']['value'][2].should == '123' + end + end + + context "mixing recognized type attribute and non-type attributes on content nodes" do + before do + @xml = <<-XML + + 123 + + XML + @parsed_xml = MultiXml.parse(@xml) + end + + it "should add the the non-type attribute and remove the recognized type attribute and do the typecast" do + @parsed_xml['options']['value']['__content__'].should == 123 + @parsed_xml['options']['value']['number'].should == 'USD' + end + end + + context "mixing unrecognized type attribute and non-type attributes on content nodes" do + before do + @xml = <<-XML + + 123 + + XML + @parsed_xml = MultiXml.parse(@xml) + end + + it "should add the the non-type attributes and type attribute to the value hash" do + @parsed_xml['options']['value']['__content__'].should == '123' + @parsed_xml['options']['value']['number'].should == 'USD' + @parsed_xml['options']['value']['type'].should == 'currency' + end + end + end + + context "with newlines and whitespace" do + before do + @xml = <<-XML + + Erik Michaels-Ober + + XML + end + + it "should parse correctly" do + MultiXml.parse(@xml).should == {"user" => {"name" => "Erik Michaels-Ober"}} + end + end + + # Babies having babies + context "with children" do + before do + @xml = '' + end + + it "should parse correctly" do + MultiXml.parse(@xml).should == {"users" => {"user" => {"name" => "Erik Michaels-Ober", "status" => {"text" => "Hello"}}}} + end + end + end + + context "with sibling children" do + before do + @xml = 'Erik Michaels-OberWynn Netherland' + end + + it "should return an Array" do + MultiXml.parse(@xml)['users']['user'].should be_a(Array) + end + + it "should parse correctly" do + MultiXml.parse(@xml).should == {"users" => {"user" => ["Erik Michaels-Ober", "Wynn Netherland"]}} + end + end + + end + end + +end diff --git a/vendor/ruby/1.9.1/gems/multi_xml-0.5.1/spec/speed.rb b/vendor/ruby/1.9.1/gems/multi_xml-0.5.1/spec/speed.rb new file mode 100755 index 0000000..284c2a3 --- /dev/null +++ b/vendor/ruby/1.9.1/gems/multi_xml-0.5.1/spec/speed.rb @@ -0,0 +1,63 @@ +#!/usr/bin/env ruby -wW1 + +$: << '.' +$: << '../lib' + +if __FILE__ == $0 + while (i = ARGV.index('-I')) + x,path = ARGV.slice!(i, 2) + $: << path + end +end + +require 'optparse' +require 'stringio' +require 'multi_xml' + +begin + require 'libxml' +rescue Exception => e +end +begin + require 'nokogiri' +rescue Exception => e +end +begin + require 'ox' +rescue Exception => e +end + +$verbose = 0 +$parsers = [] +$iter = 10 + +opts = OptionParser.new +opts.on("-v", "increase verbosity") { $verbose += 1 } +opts.on("-p", "--parser [String]", String, "parser to test") { |p| $parsers = [p] } +opts.on("-i", "--iterations [Int]", Integer, "iterations") { |i| $iter = i } +opts.on("-h", "--help", "Show this display") { puts opts; Process.exit!(0) } +files = opts.parse(ARGV) + +if $parsers.empty? + $parsers << 'libxml' if defined?(::LibXML) + $parsers << 'nokogiri' if defined?(::Nokogiri) + $parsers << 'ox' if defined?(::Ox) +end + +files.each do |filename| + times = { } + xml = File.read(filename) + $parsers.each do |p| + MultiXml.parser = p + start = Time.now + $iter.times do |i| + io = StringIO.new(xml) + MultiXml.parse(io) + end + dt = Time.now - start + times[p] = Time.now - start + end + times.each do |p,t| + puts "%8s took %0.3f seconds to parse %s %d times." % [p, t, filename, $iter] + end +end diff --git a/vendor/ruby/1.9.1/specifications/httparty-0.9.0.gemspec b/vendor/ruby/1.9.1/specifications/httparty-0.9.0.gemspec new file mode 100644 index 0000000..12f601c --- /dev/null +++ b/vendor/ruby/1.9.1/specifications/httparty-0.9.0.gemspec @@ -0,0 +1,34 @@ +# -*- encoding: utf-8 -*- + +Gem::Specification.new do |s| + s.name = "httparty" + s.version = "0.9.0" + + s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= + s.authors = ["John Nunemaker", "Sandro Turriate"] + s.date = "2012-09-07" + s.description = "Makes http fun! Also, makes consuming restful web services dead easy." + s.email = ["nunemaker@gmail.com"] + s.executables = ["httparty"] + s.files = ["bin/httparty"] + s.homepage = "http://jnunemaker.github.com/httparty" + s.post_install_message = "When you HTTParty, you must party hard!" + s.require_paths = ["lib"] + s.rubygems_version = "1.8.10" + s.summary = "Makes http fun! Also, makes consuming restful web services dead easy." + + if s.respond_to? :specification_version then + s.specification_version = 3 + + if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then + s.add_runtime_dependency(%q, ["~> 1.0"]) + s.add_runtime_dependency(%q, [">= 0"]) + else + s.add_dependency(%q, ["~> 1.0"]) + s.add_dependency(%q, [">= 0"]) + end + else + s.add_dependency(%q, ["~> 1.0"]) + s.add_dependency(%q, [">= 0"]) + end +end diff --git a/vendor/ruby/1.9.1/specifications/multi_json-1.4.0.gemspec b/vendor/ruby/1.9.1/specifications/multi_json-1.4.0.gemspec new file mode 100644 index 0000000..7bc79b9 --- /dev/null +++ b/vendor/ruby/1.9.1/specifications/multi_json-1.4.0.gemspec @@ -0,0 +1,41 @@ +# -*- encoding: utf-8 -*- + +Gem::Specification.new do |s| + s.name = "multi_json" + s.version = "1.4.0" + + s.required_rubygems_version = Gem::Requirement.new(">= 1.3.6") if s.respond_to? :required_rubygems_version= + s.authors = ["Michael Bleigh", "Josh Kalderimis", "Erik Michaels-Ober"] + s.date = "2012-11-30" + s.description = "A gem to provide easy switching between different JSON backends, including Oj, Yajl, the JSON gem (with C-extensions), the pure-Ruby JSON gem, and OkJson." + s.email = ["michael@intridea.com", "josh.kalderimis@gmail.com", "sferik@gmail.com"] + s.extra_rdoc_files = ["LICENSE.md", "README.md"] + s.files = ["LICENSE.md", "README.md"] + s.homepage = "http://github.com/intridea/multi_json" + s.licenses = ["MIT"] + s.rdoc_options = ["--charset=UTF-8"] + s.require_paths = ["lib"] + s.rubygems_version = "1.8.10" + s.summary = "A gem to provide swappable JSON backends." + + if s.respond_to? :specification_version then + s.specification_version = 3 + + if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then + s.add_development_dependency(%q, ["~> 0.9"]) + s.add_development_dependency(%q, ["~> 3.9"]) + s.add_development_dependency(%q, ["~> 2.6"]) + s.add_development_dependency(%q, ["~> 0.4"]) + else + s.add_dependency(%q, ["~> 0.9"]) + s.add_dependency(%q, ["~> 3.9"]) + s.add_dependency(%q, ["~> 2.6"]) + s.add_dependency(%q, ["~> 0.4"]) + end + else + s.add_dependency(%q, ["~> 0.9"]) + s.add_dependency(%q, ["~> 3.9"]) + s.add_dependency(%q, ["~> 2.6"]) + s.add_dependency(%q, ["~> 0.4"]) + end +end diff --git a/vendor/ruby/1.9.1/specifications/multi_xml-0.5.1.gemspec b/vendor/ruby/1.9.1/specifications/multi_xml-0.5.1.gemspec new file mode 100644 index 0000000..db74f1f --- /dev/null +++ b/vendor/ruby/1.9.1/specifications/multi_xml-0.5.1.gemspec @@ -0,0 +1,40 @@ +# -*- encoding: utf-8 -*- + +Gem::Specification.new do |s| + s.name = "multi_xml" + s.version = "0.5.1" + + s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= + s.authors = ["Erik Michaels-Ober"] + s.date = "2012-05-10" + s.description = "A gem to provide swappable XML backends utilizing LibXML, Nokogiri, Ox, or REXML." + s.email = "sferik@gmail.com" + s.homepage = "https://github.com/sferik/multi_xml" + s.require_paths = ["lib"] + s.rubygems_version = "1.8.10" + s.summary = "A generic swappable back-end for XML parsing" + + if s.respond_to? :specification_version then + s.specification_version = 3 + + if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then + s.add_development_dependency(%q, [">= 0"]) + s.add_development_dependency(%q, [">= 0"]) + s.add_development_dependency(%q, [">= 0"]) + s.add_development_dependency(%q, [">= 0"]) + s.add_development_dependency(%q, [">= 0"]) + else + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + end + else + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + end +end