rack-test-0.6.2/0000755000004100000410000000000012055434046013447 5ustar www-datawww-datarack-test-0.6.2/README.rdoc0000644000004100000410000000401112055434046015251 0ustar www-datawww-data= Rack::Test {}[https://codeclimate.com/github/brynary/rack-test] - Code: http://github.com/brynary/rack-test == Description Rack::Test is a small, simple testing API for Rack apps. It can be used on its own or as a reusable starting point for Web frameworks and testing libraries to build on. Most of its initial functionality is an extraction of Merb 1.0's request helpers feature. == Features * Maintains a cookie jar across requests * Easily follow redirects when desired * Set request headers to be used by all subsequent requests * Small footprint. Approximately 200 LOC == Examples require "rack/test" class HomepageTest < Test::Unit::TestCase include Rack::Test::Methods def app MyApp.new end def test_redirect_logged_in_users_to_dashboard authorize "bryan", "secret" get "/" follow_redirect! assert_equal "http://example.org/redirected", last_request.url assert last_response.ok? end end If you want to test one app in isolation, you just return that app as shown above. But if you want to test the entire app stack, including middlewares, cascades etc. you need to parse the app defined in config.ru. OUTER_APP = Rack::Builder.parse_file('config.ru').first class TestApp < Test::Unit::TestCase include Rack::Test::Methods def app OUTER_APP end def test_root get '/' assert last_response.ok? end end == Install To install the latest release as a gem: sudo gem install rack-test Or via Bundler: gem "rack-test", require: "rack/test" == Authors - Maintained by {Bryan Helmkamp}[mailto:bryan@brynary.com] - Contributions from Simon Rozet, Pat Nakajima and others - Much of the original code was extracted from Merb 1.0's request helper == License Copyright (c) 2008-2009 Bryan Helmkamp, Engine Yard Inc. See MIT-LICENSE.txt in this directory. == Releasing * Ensure History.txt is up-to-date * Bump VERSION in lib/rack/test.rb * thor :release rack-test-0.6.2/Rakefile0000644000004100000410000000125512055434046015117 0ustar www-datawww-datarequire "rubygems" require 'rspec/core' require "rspec/core/rake_task" RSpec::Core::RakeTask.new do |t| t.pattern = "./**/*_spec.rb" t.ruby_opts = "-w" end task :default => :spec # desc "Run all specs in spec directory with RCov" # RSpec::Core::RakeTask.new(:rcov) do |t| # t.libs << 'lib' # t.libs << 'spec' # t.warning = true # t.rcov = true # t.rcov_opts = ['-x spec'] # end desc "Generate RDoc" task :docs do FileUtils.rm_rf("doc") require "rack/test" system "hanna --title 'Rack::Test #{Rack::Test::VERSION} API Documentation'" end desc 'Removes trailing whitespace' task :whitespace do sh %{find . -name '*.rb' -exec sed -i '' 's/ *$//g' {} \\;} end rack-test-0.6.2/History.txt0000644000004100000410000001155012055434046015653 0ustar www-datawww-data== 0.6.2 / 2012-09-27 * Minor enhancements * Support HTTP PATCH method (Marjan Krekoten' #33) * Preserve the exact query string when possible (Paul Grayson #63) * Add a #delete method to CookieJar (Paul Grayson #63) * Bug fixes * Fix HTTP Digest authentication when the URI has query params * Don't append default ports to HTTP_HOST (David Lee #57) == 0.6.1 / 2011-07-27 * Bug fixes * Fix support for params with arrays in multipart forms (Joel Chippindale) * Add respond_to? to Rack::Test::UploadedFile to match method_missing (Josh Nichols) * Set the Referer header on requests issued by follow_redirect! (Ryan Bigg) == 0.6.0 / 2011-05-03 * Bug fixes * Add support for HTTP OPTIONS verb (Paolo "Nusco" Perrotta) * Call #finish on MockResponses if it's available (Aaron Patterson) * Allow HTTP_HOST to be set via #header (Geoff Buesing) == 0.5.7 / 2011-01-01 * Bug fixes * If no URI is present, include all cookies (Pratik Naik) == 0.5.6 / 2010-09-25 * Bug fixes * Use parse_nested_query for parsing URI like Rack does (Eugene Bolshakov) * Don't depend on ActiveSupport extension to String (Bryan Helmkamp) * Do not overwrite HTTP_HOST if it is set (Krekoten' Marjan) == 0.5.5 / 2010-09-22 * Bug fixes * Fix encoding of file uploads on Ruby 1.9 (Alan Kennedy) * Set env["HTTP_HOST"] when making requests (Istvan Hoka) == 0.5.4 / 2010-05-26 * Bug fixes * Don't stomp on Content-Type's supplied via #header (Bryan Helmkamp) * Fixed build_multipart to allow for arrays of files (Louis Rose) * Don't raise an error if raw cookies contain a blank line (John Reilly) * Handle parameter names with brackets properly (Tanner Donovan) == 0.5.3 / 2009-11-27 * Bug fixes * Fix cookie matching for subdomains (Marcin Kulik) == 0.5.2 / 2009-11-13 * Bug fixes * Call close on response body after iteration, not before (Simon Rozet) * Add missing require for time in cookie_jar.rb (Jerry West) == 0.5.1 / 2009-10-27 * Bug fixes * Escape cookie values (John Pignata) * Close the response body after each request, as per the Rack spec (Elomar França) == 0.5.0 / 2009-09-19 * Bug fixes * Set HTTP_X_REQUESTED_WITH in the Rack env when a request is made with :xhr => true (Ben Sales) * Set headers in the Rack env in HTTP_USER_AGENT form * Rack::Test now generates no Ruby warnings == 0.4.2 / 2009-09-01 * Minor enhancements * Merge in rack/master's build_multipart method which covers additional cases * Accept raw :params string input and merge it with the query string * Stringify and upcase request method (e.g. :post => "POST") (Josh Peek) * Bug fixes * Properly convert hashes with nil values (e.g. :foo => nil becomes simply "foo", not "foo=") * Prepend a slash to the URI path if it doesn't start with one (Josh Peek) * Requiring Rack-Test never modifies the Ruby load path anymore (Josh Peek) * Fixed using multiple cookies in a string on Ruby 1.8 (Tuomas Kareinen and Hermanni Hyytiälä) == 0.4.1 / 2009-08-06 * Minor enhancements * Support initializing a Rack::Test::Session with an app in addition to a Rack::MockSession * Allow CONTENT_TYPE to be specified in the env and not overwritten when sending a POST or PUT == 0.4.0 / 2009-06-25 * Minor enhancements * Expose hook for building Rack::MockSessions for frameworks that need to configure them before use * Support passing in arrays of raw cookies in addition to a newline separated string * Support after_request callbacks in MockSession for things like running background jobs * Allow multiple named sessions using with_session * Initialize Rack::Test::Sessions with Rack::MockSessions instead of apps. This change should help integration with other Ruby web frameworks (like Merb). * Support sending bodies for PUT requests (Larry Diehl) == 0.3.0 / 2009-05-17 * Major enhancements * Ruby 1.9 compatible (Simon Rozet, Michael Fellinger) * Minor enhancements * Add CookieJar#[] and CookieJar#[]= methods * Make the default host configurable * Use Rack::Lint and fix errors (Simon Rozet) * Extract Rack::MockSession from Rack::Test::Session to handle tracking the last request and response and the cookie jar * Add #set_cookie and #clear_cookies methods * Rename #authorize to #basic_authorize (#authorize remains as an alias) (Simon Rozet) == 0.2.0 / 2009-04-26 Because #last_response is now a MockResponse instead of a Rack::Response, #last_response.body now returns a string instead of an array. * Major enhancements * Support multipart requests via the UploadedFile class (thanks, Rails) * Minor enhancements * Updated for Rack 1.0 * Don't require rubygems (See http://gist.github.com/54177) * Support HTTP Digest authentication with the #digest_authorize method * #last_response returns a MockResponse instead of a Response (Michael Fellinger) == 0.1.0 / 2009-03-02 * 1 major enhancement * Birthday! rack-test-0.6.2/rack-test.gemspec0000644000004100000410000000463712055434046016723 0ustar www-datawww-data# -*- encoding: utf-8 -*- Gem::Specification.new do |s| s.name = "rack-test" s.version = "0.6.2" s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= s.authors = ["Bryan Helmkamp"] s.date = "2012-09-27" s.description = "Rack::Test is a small, simple testing API for Rack apps. It can be used on its\nown or as a reusable starting point for Web frameworks and testing libraries\nto build on. Most of its initial functionality is an extraction of Merb 1.0's\nrequest helpers feature." s.email = "bryan@brynary.com" s.extra_rdoc_files = [ "README.rdoc", "MIT-LICENSE.txt" ] s.files = [ ".document", ".gitignore", "Gemfile", "Gemfile.lock", "History.txt", "MIT-LICENSE.txt", "README.rdoc", "Rakefile", "Thorfile", "lib/rack/mock_session.rb", "lib/rack/test.rb", "lib/rack/test/cookie_jar.rb", "lib/rack/test/methods.rb", "lib/rack/test/mock_digest_request.rb", "lib/rack/test/uploaded_file.rb", "lib/rack/test/utils.rb", "rack-test.gemspec", "spec/fixtures/bar.txt", "spec/fixtures/config.ru", "spec/fixtures/fake_app.rb", "spec/fixtures/foo.txt", "spec/rack/test/cookie_spec.rb", "spec/rack/test/digest_auth_spec.rb", "spec/rack/test/multipart_spec.rb", "spec/rack/test/uploaded_file_spec.rb", "spec/rack/test/utils_spec.rb", "spec/rack/test_spec.rb", "spec/spec_helper.rb", "spec/support/matchers/body.rb", "spec/support/matchers/challenge.rb" ] s.homepage = "http://github.com/brynary/rack-test" s.require_paths = ["lib"] s.rubyforge_project = "rack-test" s.rubygems_version = "1.8.23" s.summary = "Simple testing API built on Rack" s.test_files = [ "spec/fixtures/fake_app.rb", "spec/rack/test/cookie_spec.rb", "spec/rack/test/digest_auth_spec.rb", "spec/rack/test/multipart_spec.rb", "spec/rack/test/uploaded_file_spec.rb", "spec/rack/test/utils_spec.rb", "spec/rack/test_spec.rb", "spec/spec_helper.rb", "spec/support/matchers/body.rb", "spec/support/matchers/challenge.rb" ] 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"]) else s.add_dependency(%q, [">= 1.0"]) end else s.add_dependency(%q, [">= 1.0"]) end end rack-test-0.6.2/Thorfile0000644000004100000410000000613612055434046015154 0ustar www-datawww-datamodule GemHelpers def generate_gemspec $LOAD_PATH.unshift(File.expand_path(File.join(File.dirname(__FILE__), "lib"))) require "rack/test" Gem::Specification.new do |s| s.name = "rack-test" s.version = Rack::Test::VERSION s.author = "Bryan Helmkamp" s.email = "bryan@brynary.com" s.homepage = "http://github.com/brynary/rack-test" s.summary = "Simple testing API built on Rack" s.description = <<-EOS.strip Rack::Test is a small, simple testing API for Rack apps. It can be used on its own or as a reusable starting point for Web frameworks and testing libraries to build on. Most of its initial functionality is an extraction of Merb 1.0's request helpers feature. EOS s.rubyforge_project = "rack-test" require "git" repo = Git.open(".") s.files = normalize_files(repo.ls_files.keys - repo.lib.ignored_files) s.test_files = normalize_files(Dir['spec/**/*.rb'] - repo.lib.ignored_files) s.has_rdoc = true s.extra_rdoc_files = %w[README.rdoc MIT-LICENSE.txt] s.add_dependency "rack", ">= 1.0" end end def normalize_files(array) # only keep files, no directories, and sort array.select do |path| File.file?(path) end.sort end # Adds extra space when outputting an array. This helps create better version # control diffs, because otherwise it is all on the same line. def prettyify_array(gemspec_ruby, array_name) gemspec_ruby.gsub(/s\.#{array_name.to_s} = \[.+?\]/) do |match| leadin, files = match[0..-2].split("[") leadin + "[\n #{files.split(",").join(",\n ")}\n ]" end end def read_gemspec @read_gemspec ||= eval(File.read("rack-test.gemspec")) end def sh(command) puts command system command end end class Default < Thor include GemHelpers desc "gemspec", "Regenerate rack-test.gemspec" def gemspec File.open("rack-test.gemspec", "w") do |file| gemspec_ruby = generate_gemspec.to_ruby gemspec_ruby = prettyify_array(gemspec_ruby, :files) gemspec_ruby = prettyify_array(gemspec_ruby, :test_files) gemspec_ruby = prettyify_array(gemspec_ruby, :extra_rdoc_files) file.write gemspec_ruby end puts "Wrote gemspec to rack-test.gemspec" read_gemspec.validate end desc "build", "Build a rack-test gem" def build sh "gem build rack-test.gemspec" FileUtils.mkdir_p "pkg" FileUtils.mv read_gemspec.file_name, "pkg" end desc "install", "Install the latest built gem" def install sh "gem install --local pkg/#{read_gemspec.file_name}" end desc "release", "Release the current branch to GitHub and Gemcutter" def release gemspec build Release.new.tag Release.new.gem end end class Release < Thor include GemHelpers desc "tag", "Tag the gem on the origin server" def tag release_tag = "v#{read_gemspec.version}" sh "git tag -a #{release_tag} -m 'Tagging #{release_tag}'" sh "git push origin #{release_tag}" end desc "gem", "Push the gem to Gemcutter" def gem sh "gem push pkg/#{read_gemspec.file_name}" end endrack-test-0.6.2/spec/0000755000004100000410000000000012055434046014401 5ustar www-datawww-datarack-test-0.6.2/spec/rack/0000755000004100000410000000000012055434046015321 5ustar www-datawww-datarack-test-0.6.2/spec/rack/test/0000755000004100000410000000000012055434046016300 5ustar www-datawww-datarack-test-0.6.2/spec/rack/test/multipart_spec.rb0000644000004100000410000001135312055434046021663 0ustar www-datawww-data# encoding: UTF-8 require "spec_helper" describe Rack::Test::Session do def test_file_path File.dirname(__FILE__) + "/../../fixtures/foo.txt" end def second_test_file_path File.dirname(__FILE__) + "/../../fixtures/bar.txt" end def uploaded_file Rack::Test::UploadedFile.new(test_file_path) end def second_uploaded_file Rack::Test::UploadedFile.new(second_test_file_path) end context "uploading a file" do it "sends the multipart/form-data content type" do post "/", "photo" => uploaded_file last_request.env["CONTENT_TYPE"].should include("multipart/form-data;") end it "sends regular params" do post "/", "photo" => uploaded_file, "foo" => "bar" last_request.POST["foo"].should == "bar" end it "sends nested params" do post "/", "photo" => uploaded_file, "foo" => {"bar" => "baz"} last_request.POST["foo"]["bar"].should == "baz" end it "sends multiple nested params" do post "/", "photo" => uploaded_file, "foo" => {"bar" => {"baz" => "bop"}} last_request.POST["foo"]["bar"]["baz"].should == "bop" end it "sends params with arrays" do post "/", "photo" => uploaded_file, "foo" => ["1", "2"] last_request.POST["foo"].should == ["1", "2"] end it "sends params with encoding sensitive values" do post "/", "photo" => uploaded_file, "foo" => "bar? baz" last_request.POST["foo"].should == "bar? baz" end it "sends params encoded as ISO-8859-1" do post "/", "photo" => uploaded_file, "foo" => "bar", "utf8" => "☃" last_request.POST["foo"].should == "bar" if Rack::Test.encoding_aware_strings? last_request.POST["utf8"].should == "☃" else last_request.POST["utf8"].should == "\xE2\x98\x83" end end it "sends params with parens in names" do post "/", "photo" => uploaded_file, "foo(1i)" => "bar" last_request.POST["foo(1i)"].should == "bar" end it "sends params with encoding sensitive names" do post "/", "photo" => uploaded_file, "foo bar" => "baz" last_request.POST["foo bar"].should == "baz" end it "sends files with the filename" do post "/", "photo" => uploaded_file last_request.POST["photo"][:filename].should == "foo.txt" end it "sends files with the text/plain MIME type by default" do post "/", "photo" => uploaded_file last_request.POST["photo"][:type].should == "text/plain" end it "sends files with the right name" do post "/", "photo" => uploaded_file last_request.POST["photo"][:name].should == "photo" end it "allows overriding the content type" do post "/", "photo" => Rack::Test::UploadedFile.new(test_file_path, "image/jpeg") last_request.POST["photo"][:type].should == "image/jpeg" end it "sends files with a Content-Length in the header" do post "/", "photo" => uploaded_file last_request.POST["photo"][:head].should include("Content-Length: 4") end it "sends files as Tempfiles" do post "/", "photo" => uploaded_file last_request.POST["photo"][:tempfile].should be_a(::Tempfile) end end context "uploading two files" do it "sends the multipart/form-data content type" do post "/", "photos" => [uploaded_file, second_uploaded_file] last_request.env["CONTENT_TYPE"].should include("multipart/form-data;") end it "sends files with the filename" do post "/", "photos" => [uploaded_file, second_uploaded_file] last_request.POST["photos"].collect{|photo| photo[:filename]}.should == ["foo.txt", "bar.txt"] end it "sends files with the text/plain MIME type by default" do post "/", "photos" => [uploaded_file, second_uploaded_file] last_request.POST["photos"].collect{|photo| photo[:type]}.should == ["text/plain", "text/plain"] end it "sends files with the right names" do post "/", "photos" => [uploaded_file, second_uploaded_file] last_request.POST["photos"].all?{|photo| photo[:name].should == "photos[]" } end it "allows mixed content types" do image_file = Rack::Test::UploadedFile.new(test_file_path, "image/jpeg") post "/", "photos" => [uploaded_file, image_file] last_request.POST["photos"].collect{|photo| photo[:type]}.should == ["text/plain", "image/jpeg"] end it "sends files with a Content-Length in the header" do post "/", "photos" => [uploaded_file, second_uploaded_file] last_request.POST["photos"].all?{|photo| photo[:head].should include("Content-Length: 4") } end it "sends both files as Tempfiles" do post "/", "photos" => [uploaded_file, second_uploaded_file] last_request.POST["photos"].all?{|photo| photo[:tempfile].should be_a(::Tempfile) } end end end rack-test-0.6.2/spec/rack/test/utils_spec.rb0000644000004100000410000001026212055434046021000 0ustar www-datawww-datarequire "spec_helper" describe Rack::Test::Utils do include Rack::Test::Utils describe "build_nested_query" do it "converts empty strings to =" do build_nested_query("").should == "=" end it "converts nil to an empty string" do build_nested_query(nil).should == "" end it "converts hashes with nil values" do build_nested_query(:a => nil).should == "a" end it "converts hashes" do build_nested_query(:a => 1).should == "a=1" end it "converts hashes with multiple keys" do hash = { :a => 1, :b => 2 } ["a=1&b=2", "b=2&a=1"].should include(build_nested_query(hash)) end it "converts arrays with one element" do build_nested_query(:a => [1]).should == "a[]=1" end it "converts arrays with multiple elements" do build_nested_query(:a => [1, 2]).should == "a[]=1&a[]=2" end it "converts arrays with brackets '[]' in the name" do build_nested_query("a[]" => [1, 2]).should == "a%5B%5D=1&a%5B%5D=2" end it "converts nested hashes" do build_nested_query(:a => { :b => 1 }).should == "a[b]=1" end it "converts arrays nested in a hash" do build_nested_query(:a => { :b => [1, 2] }).should == "a[b][]=1&a[b][]=2" end it "converts arrays of hashes" do build_nested_query(:a => [{ :b => 2}, { :c => 3}]).should == "a[][b]=2&a[][c]=3" end end describe "build_multipart" do it "builds multipart bodies" do files = Rack::Test::UploadedFile.new(multipart_file("foo.txt")) data = build_multipart("submit-name" => "Larry", "files" => files) options = { "CONTENT_TYPE" => "multipart/form-data; boundary=#{Rack::Test::MULTIPART_BOUNDARY}", "CONTENT_LENGTH" => data.length.to_s, :input => StringIO.new(data) } env = Rack::MockRequest.env_for("/", options) params = Rack::Utils::Multipart.parse_multipart(env) check params["submit-name"].should == "Larry" check params["files"][:filename].should == "foo.txt" params["files"][:tempfile].read.should == "bar\n" end it "builds multipart bodies from array of files" do files = [Rack::Test::UploadedFile.new(multipart_file("foo.txt")), Rack::Test::UploadedFile.new(multipart_file("bar.txt"))] data = build_multipart("submit-name" => "Larry", "files" => files) options = { "CONTENT_TYPE" => "multipart/form-data; boundary=#{Rack::Test::MULTIPART_BOUNDARY}", "CONTENT_LENGTH" => data.length.to_s, :input => StringIO.new(data) } env = Rack::MockRequest.env_for("/", options) params = Rack::Utils::Multipart.parse_multipart(env) check params["submit-name"].should == "Larry" check params["files"][0][:filename].should == "foo.txt" params["files"][0][:tempfile].read.should == "bar\n" check params["files"][1][:filename].should == "bar.txt" params["files"][1][:tempfile].read.should == "baz\n" end it "builds nested multipart bodies" do files = Rack::Test::UploadedFile.new(multipart_file("foo.txt")) data = build_multipart("people" => [{"submit-name" => "Larry", "files" => files}], "foo" => ['1', '2']) options = { "CONTENT_TYPE" => "multipart/form-data; boundary=#{Rack::Test::MULTIPART_BOUNDARY}", "CONTENT_LENGTH" => data.length.to_s, :input => StringIO.new(data) } env = Rack::MockRequest.env_for("/", options) params = Rack::Utils::Multipart.parse_multipart(env) check params["people"][0]["submit-name"].should == "Larry" check params["people"][0]["files"][:filename].should == "foo.txt" params["people"][0]["files"][:tempfile].read.should == "bar\n" check params["foo"].should == ["1", "2"] end it "returns nil if no UploadedFiles were used" do data = build_multipart("people" => [{"submit-name" => "Larry", "files" => "contents"}]) data.should be_nil end it "raises ArgumentErrors if params is not a Hash" do lambda { build_multipart("foo=bar") }.should raise_error(ArgumentError, "value must be a Hash") end def multipart_file(name) File.join(File.dirname(__FILE__), "..", "..", "fixtures", name.to_s) end end end rack-test-0.6.2/spec/rack/test/uploaded_file_spec.rb0000644000004100000410000000123712055434046022436 0ustar www-datawww-datarequire "spec_helper" describe Rack::Test::UploadedFile do def test_file_path File.dirname(__FILE__) + "/../../fixtures/foo.txt" end it "responds to things that Tempfile responds to" do uploaded_file = Rack::Test::UploadedFile.new(test_file_path) uploaded_file.should respond_to(:close) uploaded_file.should respond_to(:close!) uploaded_file.should respond_to(:delete) uploaded_file.should respond_to(:length) uploaded_file.should respond_to(:open) uploaded_file.should respond_to(:path) uploaded_file.should respond_to(:size) uploaded_file.should respond_to(:unlink) uploaded_file.should respond_to(:read) end end rack-test-0.6.2/spec/rack/test/cookie_spec.rb0000644000004100000410000001571512055434046021121 0ustar www-datawww-datarequire "spec_helper" describe Rack::Test::Session do context "cookies" do it "keeps a cookie jar" do get "/cookies/show" check last_request.cookies.should == {} get "/cookies/set", "value" => "1" get "/cookies/show" last_request.cookies.should == { "value" => "1" } end it "doesn't send expired cookies" do get "/cookies/set", "value" => "1" now = Time.now Time.stub!(:now => now + 60) get "/cookies/show" last_request.cookies.should == {} end it "cookie path defaults to the uri of the document that was requested" do pending "See issue rack-test github issue #50" do post "/cookies/default-path", "value" => "cookie" get "/cookies/default-path" check last_request.cookies.should == { "simple"=>"cookie" } get "/cookies/show" check last_request.cookies.should == { } end end it "escapes cookie values" do jar = Rack::Test::CookieJar.new jar["value"] = "foo;abc" jar["value"].should == "foo;abc" end it "deletes cookies directly from the CookieJar" do jar = Rack::Test::CookieJar.new jar["abcd"] = "1234" jar["abcd"].should == "1234" jar.delete("abcd") jar["abcd"].should == nil end it "doesn't send cookies with the wrong domain" do get "http://www.example.com/cookies/set", "value" => "1" get "http://www.other.example/cookies/show" last_request.cookies.should == {} end it "doesn't send cookies with the wrong path" do get "/cookies/set", "value" => "1" get "/not-cookies/show" last_request.cookies.should == {} end it "persists cookies across requests that don't return any cookie headers" do get "/cookies/set", "value" => "1" get "/void" get "/cookies/show" last_request.cookies.should == { "value" => "1" } end it "deletes cookies" do get "/cookies/set", "value" => "1" get "/cookies/delete" get "/cookies/show" last_request.cookies.should == { } end it "respects cookie domains when no domain is explicitly set" do pending "FIXME: www.example.org should not get the first cookie" do request("http://example.org/cookies/count").should have_body("1") request("http://www.example.org/cookies/count").should have_body("1") request("http://example.org/cookies/count").should have_body("2") request("http://www.example.org/cookies/count").should have_body("2") end end it "treats domains case insensitively" do get "http://example.com/cookies/set", "value" => "1" get "http://EXAMPLE.COM/cookies/show" last_request.cookies.should == { "value" => "1" } end it "treats paths case sensitively" do get "/cookies/set", "value" => "1" get "/COOKIES/show" last_request.cookies.should == {} end it "prefers more specific cookies" do get "http://example.com/cookies/set", "value" => "domain" get "http://sub.example.com/cookies/set", "value" => "sub" get "http://sub.example.com/cookies/show" check last_request.cookies.should == { "value" => "sub" } get "http://example.com/cookies/show" last_request.cookies.should == { "value" => "domain" } end it "treats cookie names case insensitively" do get "/cookies/set", "value" => "lowercase" get "/cookies/set-uppercase", "value" => "UPPERCASE" get "/cookies/show" last_request.cookies.should == { "VALUE" => "UPPERCASE" } end it "defaults the domain to the request domain" do get "http://example.com/cookies/set-simple", "value" => "cookie" get "http://example.com/cookies/show" check last_request.cookies.should == { "simple" => "cookie" } get "http://other.example/cookies/show" last_request.cookies.should == {} end it "defaults the domain to the request path up to the last slash" do get "/cookies/set-simple", "value" => "1" get "/not-cookies/show" last_request.cookies.should == {} end it "supports secure cookies" do get "https://example.com/cookies/set-secure", "value" => "set" get "http://example.com/cookies/show" check last_request.cookies.should == {} get "https://example.com/cookies/show" last_request.cookies.should == { "secure-cookie" => "set" } rack_mock_session.cookie_jar['secure-cookie'].should == 'set' end it "keeps separate cookie jars for different domains" do get "http://example.com/cookies/set", "value" => "example" get "http://example.com/cookies/show" check last_request.cookies.should == { "value" => "example" } get "http://other.example/cookies/set", "value" => "other" get "http://other.example/cookies/show" check last_request.cookies.should == { "value" => "other" } get "http://example.com/cookies/show" last_request.cookies.should == { "value" => "example" } end it "keeps one cookie jar for domain and its subdomains" do get "http://example.org/cookies/subdomain" get "http://example.org/cookies/subdomain" last_request.cookies.should == { "count" => "1" } get "http://foo.example.org/cookies/subdomain" last_request.cookies.should == { "count" => "2" } end it "allows cookies to be cleared" do get "/cookies/set", "value" => "1" clear_cookies get "/cookies/show" last_request.cookies.should == {} end it "allow cookies to be set" do set_cookie "value=10" get "/cookies/show" last_request.cookies.should == { "value" => "10" } end it "allows an array of cookies to be set" do set_cookie ["value=10", "foo=bar"] get "/cookies/show" last_request.cookies.should == { "value" => "10", "foo" => "bar" } end it "skips emtpy string cookies" do set_cookie "value=10\n\nfoo=bar" get "/cookies/show" last_request.cookies.should == { "value" => "10", "foo" => "bar" } end it "parses multiple cookies properly" do get "/cookies/set-multiple" get "/cookies/show" last_request.cookies.should == { "key1" => "value1", "key2" => "value2" } end it "supports multiple sessions" do with_session(:first) do get "/cookies/set", "value" => "1" get "/cookies/show" last_request.cookies.should == { "value" => "1" } end with_session(:second) do get "/cookies/show" last_request.cookies.should == { } end end it "uses :default as the default session name" do get "/cookies/set", "value" => "1" get "/cookies/show" check last_request.cookies.should == { "value" => "1" } with_session(:default) do get "/cookies/show" last_request.cookies.should == { "value" => "1" } end end it "accepts explicitly provided cookies" do request "/cookies/show", :cookie => "value=1" last_request.cookies.should == { "value" => "1" } end end end rack-test-0.6.2/spec/rack/test/digest_auth_spec.rb0000644000004100000410000000223012055434046022134 0ustar www-datawww-datarequire "spec_helper" describe Rack::Test::Session do context "HTTP Digest authentication" do def app app = Rack::Auth::Digest::MD5.new(Rack::Test::FakeApp.new) do |username| { 'alice' => 'correct-password' }[username] end app.realm = 'WallysWorld' app.opaque = 'this-should-be-secret' app end it 'incorrectly authenticates GETs' do digest_authorize 'foo', 'bar' get '/' last_response.should be_challenge end it "correctly authenticates GETs" do digest_authorize "alice", "correct-password" response = get "/" response.should be_ok end it "correctly authenticates GETs with params" do digest_authorize "alice", "correct-password" response = get "/", "foo" => "bar" response.should be_ok end it "correctly authenticates POSTs" do digest_authorize "alice", "correct-password" response = post "/" response.should be_ok end it "returns a re-challenge if authenticating incorrectly" do digest_authorize "alice", "incorrect-password" response = get "/" response.should be_challenge end end end rack-test-0.6.2/spec/rack/test_spec.rb0000644000004100000410000003232512055434046017644 0ustar www-datawww-datarequire "spec_helper" describe Rack::Test::Session do describe "initialization" do it "supports being initialized with a Rack::MockSession app" do session = Rack::Test::Session.new(Rack::MockSession.new(app)) session.request("/").should be_ok end it "supports being initialized with an app" do session = Rack::Test::Session.new(app) session.request("/").should be_ok end end describe "#request" do it "requests the URI using GET by default" do request "/" last_request.should be_get last_response.should be_ok end it "returns a response" do request("/").should be_ok end it "uses the provided env" do request "/", "X-Foo" => "bar" last_request.env["X-Foo"].should == "bar" end it "allows HTTP_HOST to be set" do request "/", "HTTP_HOST" => "www.example.ua" last_request.env['HTTP_HOST'].should == "www.example.ua" end it "sets HTTP_HOST with port for non-default ports" do request "http://foo.com:8080" last_request.env["HTTP_HOST"].should == "foo.com:8080" request "https://foo.com:8443" last_request.env["HTTP_HOST"].should == "foo.com:8443" end it "sets HTTP_HOST without port for default ports" do request "http://foo.com" last_request.env["HTTP_HOST"].should == "foo.com" request "http://foo.com:80" last_request.env["HTTP_HOST"].should == "foo.com" request "https://foo.com:443" last_request.env["HTTP_HOST"].should == "foo.com" end it "defaults to GET" do request "/" last_request.env["REQUEST_METHOD"].should == "GET" end it "defaults the REMOTE_ADDR to 127.0.0.1" do request "/" last_request.env["REMOTE_ADDR"].should == "127.0.0.1" end it "sets rack.test to true in the env" do request "/" last_request.env["rack.test"].should == true end it "defaults to port 80" do request "/" last_request.env["SERVER_PORT"].should == "80" end it "defaults to example.org" do request "/" last_request.env["SERVER_NAME"].should == "example.org" end it "yields the response to a given block" do request "/" do |response| response.should be_ok end end it "supports sending :params" do request "/", :params => { "foo" => "bar" } last_request.GET["foo"].should == "bar" end it "doesn't follow redirects by default" do request "/redirect" last_response.should be_redirect last_response.body.should be_empty end it "allows passing :input in for POSTs" do request "/", :method => :post, :input => "foo" last_request.env["rack.input"].read.should == "foo" end it "converts method names to a uppercase strings" do request "/", :method => :put last_request.env["REQUEST_METHOD"].should == "PUT" end it "prepends a slash to the URI path" do request "foo" last_request.env["PATH_INFO"].should == "/foo" end it "accepts params and builds query strings for GET requests" do request "/foo?baz=2", :params => {:foo => {:bar => "1"}} last_request.GET.should == { "baz" => "2", "foo" => { "bar" => "1" }} end it "parses query strings with repeated variable names correctly" do request "/foo?bar=2&bar=3" last_request.GET.should == { "bar" => "3" } end it "accepts raw input in params for GET requests" do request "/foo?baz=2", :params => "foo[bar]=1" last_request.GET.should == { "baz" => "2", "foo" => { "bar" => "1" }} end it "does not rewrite a GET query string when :params is not supplied" do request "/foo?a=1&b=2&c=3&e=4&d=5" last_request.query_string.should == "a=1&b=2&c=3&e=4&d=5" end it "accepts params and builds url encoded params for POST requests" do request "/foo", :method => :post, :params => {:foo => {:bar => "1"}} last_request.env["rack.input"].read.should == "foo[bar]=1" end it "accepts raw input in params for POST requests" do request "/foo", :method => :post, :params => "foo[bar]=1" last_request.env["rack.input"].read.should == "foo[bar]=1" end context "when the response body responds_to?(:close)" do class CloseableBody def initialize @closed = false end def each return if @closed yield "Hello, World!" end def close @closed = true end end it "closes response's body" do body = CloseableBody.new body.should_receive(:close) app = lambda do |env| [200, {"Content-Type" => "text/html", "Content-Length" => "13"}, body] end session = Rack::Test::Session.new(Rack::MockSession.new(app)) session.request("/") end it "closes response's body after iteration" do app = lambda do |env| [200, {"Content-Type" => "text/html", "Content-Length" => "13"}, CloseableBody.new] end session = Rack::Test::Session.new(Rack::MockSession.new(app)) session.request("/") session.last_response.body.should == "Hello, World!" end end context "when input is given" do it "sends the input" do request "/", :method => "POST", :input => "foo" last_request.env["rack.input"].read.should == "foo" end it "does not send a multipart request" do request "/", :method => "POST", :input => "foo" last_request.env["CONTENT_TYPE"].should_not == "application/x-www-form-urlencoded" end end context "for a POST specified with :method" do it "uses application/x-www-form-urlencoded as the CONTENT_TYPE" do request "/", :method => "POST" last_request.env["CONTENT_TYPE"].should == "application/x-www-form-urlencoded" end end context "for a POST specified with REQUEST_METHOD" do it "uses application/x-www-form-urlencoded as the CONTENT_TYPE" do request "/", "REQUEST_METHOD" => "POST" last_request.env["CONTENT_TYPE"].should == "application/x-www-form-urlencoded" end end context "when CONTENT_TYPE is specified in the env" do it "does not overwrite the CONTENT_TYPE" do request "/", "CONTENT_TYPE" => "application/xml" last_request.env["CONTENT_TYPE"].should == "application/xml" end end context "when the URL is https://" do it "sets rack.url_scheme to https" do get "https://example.org/" last_request.env["rack.url_scheme"].should == "https" end it "sets SERVER_PORT to 443" do get "https://example.org/" last_request.env["SERVER_PORT"].should == "443" end it "sets HTTPS to on" do get "https://example.org/" last_request.env["HTTPS"].should == "on" end end context "for a XHR" do it "sends XMLHttpRequest for the X-Requested-With header" do request "/", :xhr => true last_request.env["HTTP_X_REQUESTED_WITH"].should == "XMLHttpRequest" last_request.should be_xhr end end end describe "#header" do it "sets a header to be sent with requests" do header "User-Agent", "Firefox" request "/" last_request.env["HTTP_USER_AGENT"].should == "Firefox" end it "sets a Content-Type to be sent with requests" do header "Content-Type", "application/json" request "/" last_request.env["CONTENT_TYPE"].should == "application/json" end it "sets a Host to be sent with requests" do header "Host", "www.example.ua" request "/" last_request.env["HTTP_HOST"].should == "www.example.ua" end it "persists across multiple requests" do header "User-Agent", "Firefox" request "/" request "/" last_request.env["HTTP_USER_AGENT"].should == "Firefox" end it "overwrites previously set headers" do header "User-Agent", "Firefox" header "User-Agent", "Safari" request "/" last_request.env["HTTP_USER_AGENT"].should == "Safari" end it "can be used to clear a header" do header "User-Agent", "Firefox" header "User-Agent", nil request "/" last_request.env.should_not have_key("HTTP_USER_AGENT") end it "is overridden by headers sent during the request" do header "User-Agent", "Firefox" request "/", "HTTP_USER_AGENT" => "Safari" last_request.env["HTTP_USER_AGENT"].should == "Safari" end end describe "#authorize" do it "sets the HTTP_AUTHORIZATION header" do authorize "bryan", "secret" request "/" last_request.env["HTTP_AUTHORIZATION"].should == "Basic YnJ5YW46c2VjcmV0\n" end it "includes the header for subsequent requests" do basic_authorize "bryan", "secret" request "/" request "/" last_request.env["HTTP_AUTHORIZATION"].should == "Basic YnJ5YW46c2VjcmV0\n" end end describe "follow_redirect!" do it "follows redirects" do get "/redirect" follow_redirect! last_response.should_not be_redirect last_response.body.should == "You've been redirected" last_request.env["HTTP_REFERER"].should eql("http://example.org/redirect") end it "does not include params when following the redirect" do get "/redirect", { "foo" => "bar" } follow_redirect! last_request.GET.should == {} end it "raises an error if the last_response is not set" do lambda { follow_redirect! }.should raise_error(Rack::Test::Error) end it "raises an error if the last_response is not a redirect" do get "/" lambda { follow_redirect! }.should raise_error(Rack::Test::Error) end end describe "#last_request" do it "returns the most recent request" do request "/" last_request.env["PATH_INFO"].should == "/" end it "raises an error if no requests have been issued" do lambda { last_request }.should raise_error(Rack::Test::Error) end end describe "#last_response" do it "returns the most recent response" do request "/" last_response["Content-Type"].should == "text/html;charset=utf-8" end it "raises an error if no requests have been issued" do lambda { last_response }.should raise_error end end describe "after_request" do it "runs callbacks after each request" do ran = false rack_mock_session.after_request do ran = true end get "/" ran.should == true end it "runs multiple callbacks" do count = 0 2.times do rack_mock_session.after_request do count += 1 end end get "/" count.should == 2 end end describe "#get" do it_should_behave_like "any #verb methods" def verb "get" end it "uses the provided params hash" do get "/", :foo => "bar" last_request.GET.should == { "foo" => "bar" } end it "sends params with parens in names" do get "/", "foo(1i)" => "bar" last_request.GET["foo(1i)"].should == "bar" end it "supports params with encoding sensitive names" do get "/", "foo bar" => "baz" last_request.GET["foo bar"].should == "baz" end it "supports params with nested encoding sensitive names" do get "/", "boo" => {"foo bar" => "baz"} last_request.GET.should == {"boo" => {"foo bar" => "baz"}} end it "accepts params in the path" do get "/?foo=bar" last_request.GET.should == { "foo" => "bar" } end end describe "#head" do it_should_behave_like "any #verb methods" def verb "head" end end describe "#post" do it_should_behave_like "any #verb methods" def verb "post" end it "uses the provided params hash" do post "/", :foo => "bar" last_request.POST.should == { "foo" => "bar" } end it "supports params with encoding sensitive names" do post "/", "foo bar" => "baz" last_request.POST["foo bar"].should == "baz" end it "uses application/x-www-form-urlencoded as the CONTENT_TYPE" do post "/" last_request.env["CONTENT_TYPE"].should == "application/x-www-form-urlencoded" end it "accepts a body" do post "/", "Lobsterlicious!" last_request.body.read.should == "Lobsterlicious!" end context "when CONTENT_TYPE is specified in the env" do it "does not overwrite the CONTENT_TYPE" do post "/", {}, { "CONTENT_TYPE" => "application/xml" } last_request.env["CONTENT_TYPE"].should == "application/xml" end end end describe "#put" do it_should_behave_like "any #verb methods" def verb "put" end it "accepts a body" do put "/", "Lobsterlicious!" last_request.body.read.should == "Lobsterlicious!" end end describe "#patch" do it_should_behave_like "any #verb methods" def verb "patch" end it "accepts a body" do patch "/", "Lobsterlicious!" last_request.body.read.should == "Lobsterlicious!" end end describe "#delete" do it_should_behave_like "any #verb methods" def verb "delete" end end describe "#options" do it_should_behave_like "any #verb methods" def verb "options" end end end rack-test-0.6.2/spec/spec_helper.rb0000644000004100000410000000277312055434046017230 0ustar www-datawww-datarequire "rubygems" require "bundler/setup" require "rack" require "rspec" Dir[File.dirname(__FILE__) + "/support/**/*.rb"].each {|f| require f} require "rack/test" require File.dirname(__FILE__) + "/fixtures/fake_app" RSpec.configure do |config| config.mock_with :rspec config.include Rack::Test::Methods def app Rack::Lint.new(Rack::Test::FakeApp.new) end def check(*args) end end shared_examples_for "any #verb methods" do it "requests the URL using VERB" do send(verb, "/") check last_request.env["REQUEST_METHOD"].should == verb.upcase last_response.should be_ok end it "uses the provided env" do send(verb, "/", {}, { "HTTP_USER_AGENT" => "Rack::Test" }) last_request.env["HTTP_USER_AGENT"].should == "Rack::Test" end it "yields the response to a given block" do yielded = false send(verb, "/") do |response| response.should be_ok yielded = true end yielded.should be_true end it "sets the HTTP_HOST header with port" do send(verb, "http://example.org:8080/uri") last_request.env["HTTP_HOST"].should == "example.org:8080" end it "sets the HTTP_HOST header without port" do send(verb, "/uri") last_request.env["HTTP_HOST"].should == "example.org" end context "for a XHR" do it "sends XMLHttpRequest for the X-Requested-With header" do send(verb, "/", {}, { :xhr => true }) last_request.env["HTTP_X_REQUESTED_WITH"].should == "XMLHttpRequest" last_request.should be_xhr end end end rack-test-0.6.2/spec/fixtures/0000755000004100000410000000000012055434046016252 5ustar www-datawww-datarack-test-0.6.2/spec/fixtures/bar.txt0000644000004100000410000000000412055434046017551 0ustar www-datawww-databaz rack-test-0.6.2/spec/fixtures/foo.txt0000644000004100000410000000000412055434046017570 0ustar www-datawww-databar rack-test-0.6.2/spec/fixtures/fake_app.rb0000644000004100000410000000571212055434046020352 0ustar www-datawww-datarequire "rubygems" require "sinatra/base" module Rack module Test class FakeApp < Sinatra::Base head "/" do "meh" end options "/" do [200, {}, ""] end get "/" do "Hello, GET: #{params.inspect}" end get "/redirect" do redirect "/redirected" end get "/redirected" do "You've been redirected" end get "/void" do [200, {}, ""] end get "/cookies/show" do request.cookies.inspect end get "/COOKIES/show" do request.cookies.inspect end get "/not-cookies/show" do request.cookies.inspect end get "/cookies/set-secure" do raise if params["value"].nil? response.set_cookie("secure-cookie", :value => params["value"], :secure => true) "Set" end get "/cookies/set-simple" do raise if params["value"].nil? response.set_cookie "simple", params["value"] "Set" end post "/cookies/default-path" do raise if params["value"].nil? response.set_cookie "simple", params["value"] "Set" end get "/cookies/default-path" do response.cookies.inspect end get "/cookies/delete" do response.delete_cookie "value" end get "/cookies/count" do old_value = request.cookies["count"].to_i || 0 new_value = (old_value + 1).to_s response.set_cookie("count", :value => new_value) new_value end get "/cookies/set" do raise if params["value"].nil? response.set_cookie("value", { :value => params["value"], :path => "/cookies", :expires => Time.now + 10 }) "Set" end get "/cookies/domain" do old_value = request.cookies["count"].to_i || 0 new_value = (old_value + 1).to_s response.set_cookie("count", :value => new_value, :domain => "localhost.com") new_value end get "/cookies/subdomain" do old_value = request.cookies["count"].to_i || 0 new_value = (old_value + 1).to_s response.set_cookie("count", :value => new_value, :domain => ".example.org") new_value end get "/cookies/set-uppercase" do raise if params["value"].nil? response.set_cookie("VALUE", { :value => params["value"], :path => "/cookies", :expires => Time.now + 10 }) "Set" end get "/cookies/set-multiple" do response.set_cookie("key1", :value => "value1") response.set_cookie("key2", :value => "value2") "Set" end post "/" do "Hello, POST: #{params.inspect}" end put "/" do "Hello, PUT: #{params.inspect}" end patch "/" do "Hello, PUT: #{params.inspect}" end delete "/" do "Hello, DELETE: #{params.inspect}" end end end end rack-test-0.6.2/spec/fixtures/config.ru0000644000004100000410000000005412055434046020066 0ustar www-datawww-datarequire "fake_app" run Rack::Test::FakeApp rack-test-0.6.2/spec/support/0000755000004100000410000000000012055434046016115 5ustar www-datawww-datarack-test-0.6.2/spec/support/matchers/0000755000004100000410000000000012055434046017723 5ustar www-datawww-datarack-test-0.6.2/spec/support/matchers/challenge.rb0000644000004100000410000000041412055434046022171 0ustar www-datawww-dataRSpec::Matchers.define :be_challenge do match do |actual_response| actual_response.status == 401 && actual_response['WWW-Authenticate'] =~ /^Digest / && actual_response.body.empty? end description do "a HTTP Digest challenge response" end end rack-test-0.6.2/spec/support/matchers/body.rb0000644000004100000410000000026112055434046021204 0ustar www-datawww-dataRSpec::Matchers.define :have_body do |expected| match do |response| response.body.should == expected end description do "have body #{expected.inspect}" end end rack-test-0.6.2/.document0000644000004100000410000000006412055434046015266 0ustar www-datawww-dataREADME.rdoc lib/**/*.rb History.txt MIT-LICENSE.txt rack-test-0.6.2/MIT-LICENSE.txt0000644000004100000410000000207112055434046015721 0ustar www-datawww-dataCopyright (c) 2008-2009 Bryan Helmkamp, Engine Yard 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. rack-test-0.6.2/metadata.yml0000644000004100000410000000516412055434046015760 0ustar www-datawww-data--- !ruby/object:Gem::Specification name: rack-test version: !ruby/object:Gem::Version version: 0.6.2 prerelease: platform: ruby authors: - Bryan Helmkamp autorequire: bindir: bin cert_chain: [] date: 2012-09-27 00:00:00.000000000 Z dependencies: - !ruby/object:Gem::Dependency name: rack requirement: !ruby/object:Gem::Requirement none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: '1.0' type: :runtime prerelease: false version_requirements: !ruby/object:Gem::Requirement none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: '1.0' description: ! 'Rack::Test is a small, simple testing API for Rack apps. It can be used on its own or as a reusable starting point for Web frameworks and testing libraries to build on. Most of its initial functionality is an extraction of Merb 1.0''s request helpers feature.' email: bryan@brynary.com executables: [] extensions: [] extra_rdoc_files: - README.rdoc - MIT-LICENSE.txt files: - .document - .gitignore - Gemfile - Gemfile.lock - History.txt - MIT-LICENSE.txt - README.rdoc - Rakefile - Thorfile - lib/rack/mock_session.rb - lib/rack/test.rb - lib/rack/test/cookie_jar.rb - lib/rack/test/methods.rb - lib/rack/test/mock_digest_request.rb - lib/rack/test/uploaded_file.rb - lib/rack/test/utils.rb - rack-test.gemspec - spec/fixtures/bar.txt - spec/fixtures/config.ru - spec/fixtures/fake_app.rb - spec/fixtures/foo.txt - spec/rack/test/cookie_spec.rb - spec/rack/test/digest_auth_spec.rb - spec/rack/test/multipart_spec.rb - spec/rack/test/uploaded_file_spec.rb - spec/rack/test/utils_spec.rb - spec/rack/test_spec.rb - spec/spec_helper.rb - spec/support/matchers/body.rb - spec/support/matchers/challenge.rb homepage: http://github.com/brynary/rack-test licenses: [] post_install_message: rdoc_options: [] require_paths: - lib required_ruby_version: !ruby/object:Gem::Requirement none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: '0' required_rubygems_version: !ruby/object:Gem::Requirement none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: '0' requirements: [] rubyforge_project: rack-test rubygems_version: 1.8.23 signing_key: specification_version: 3 summary: Simple testing API built on Rack test_files: - spec/fixtures/fake_app.rb - spec/rack/test/cookie_spec.rb - spec/rack/test/digest_auth_spec.rb - spec/rack/test/multipart_spec.rb - spec/rack/test/uploaded_file_spec.rb - spec/rack/test/utils_spec.rb - spec/rack/test_spec.rb - spec/spec_helper.rb - spec/support/matchers/body.rb - spec/support/matchers/challenge.rb rack-test-0.6.2/Gemfile0000644000004100000410000000010212055434046014733 0ustar www-datawww-datasource :rubygems gem 'rspec' gem "rack" gem "sinatra" gem 'rake' rack-test-0.6.2/.gitignore0000644000004100000410000000004612055434046015437 0ustar www-datawww-datapkg doc coverage VERSION *.rbc .bundlerack-test-0.6.2/lib/0000755000004100000410000000000012055434046014215 5ustar www-datawww-datarack-test-0.6.2/lib/rack/0000755000004100000410000000000012055434046015135 5ustar www-datawww-datarack-test-0.6.2/lib/rack/test/0000755000004100000410000000000012055434046016114 5ustar www-datawww-datarack-test-0.6.2/lib/rack/test/mock_digest_request.rb0000644000004100000410000000070312055434046022501 0ustar www-datawww-datamodule Rack module Test class MockDigestRequest # :nodoc: def initialize(params) @params = params end def method_missing(sym) if @params.has_key? k = sym.to_s return @params[k] end super end def method @params['method'] end def response(password) Rack::Auth::Digest::MD5.new(nil).send :digest, self, password end end end end rack-test-0.6.2/lib/rack/test/utils.rb0000644000004100000410000000674712055434046017617 0ustar www-datawww-datamodule Rack module Test module Utils # :nodoc: include Rack::Utils def build_nested_query(value, prefix = nil) case value when Array value.map do |v| unless unescape(prefix) =~ /\[\]$/ prefix = "#{prefix}[]" end build_nested_query(v, "#{prefix}") end.join("&") when Hash value.map do |k, v| build_nested_query(v, prefix ? "#{prefix}[#{escape(k)}]" : escape(k)) end.join("&") when NilClass prefix.to_s else "#{prefix}=#{escape(value)}" end end module_function :build_nested_query def build_multipart(params, first = true) if first unless params.is_a?(Hash) raise ArgumentError, "value must be a Hash" end multipart = false query = lambda { |value| case value when Array value.each(&query) when Hash value.values.each(&query) when UploadedFile multipart = true end } params.values.each(&query) return nil unless multipart end flattened_params = Hash.new params.each do |key, value| k = first ? key.to_s : "[#{key}]" case value when Array value.map do |v| if (v.is_a?(Hash)) build_multipart(v, false).each { |subkey, subvalue| flattened_params["#{k}[]#{subkey}"] = subvalue } else flattened_params["#{k}[]"] = value end end when Hash build_multipart(value, false).each { |subkey, subvalue| flattened_params[k + subkey] = subvalue } else flattened_params[k] = value end end if first build_parts(flattened_params) else flattened_params end end module_function :build_multipart private def build_parts(parameters) parameters.map { |name, value| if value.respond_to?(:original_filename) build_file_part(name, value) elsif value.is_a?(Array) and value.all? { |v| v.respond_to?(:original_filename) } value.map do |v| build_file_part(name, v) end.join else primitive_part = build_primitive_part(name, value) Rack::Test.encoding_aware_strings? ? primitive_part.force_encoding('BINARY') : primitive_part end }.join + "--#{MULTIPART_BOUNDARY}--\r" end def build_primitive_part(parameter_name, value) unless value.is_a? Array value = [value] end value.map do |v| <<-EOF --#{MULTIPART_BOUNDARY}\r Content-Disposition: form-data; name="#{parameter_name}"\r \r #{v}\r EOF end.join end def build_file_part(parameter_name, uploaded_file) ::File.open(uploaded_file.path, "rb") do |physical_file| physical_file.set_encoding(Encoding::BINARY) if physical_file.respond_to?(:set_encoding) <<-EOF --#{MULTIPART_BOUNDARY}\r Content-Disposition: form-data; name="#{parameter_name}"; filename="#{escape(uploaded_file.original_filename)}"\r Content-Type: #{uploaded_file.content_type}\r Content-Length: #{::File.stat(uploaded_file.path).size}\r \r #{physical_file.read}\r EOF end end end end end rack-test-0.6.2/lib/rack/test/methods.rb0000644000004100000410000000373112055434046020110 0ustar www-datawww-datarequire "forwardable" module Rack module Test # This module serves as the primary integration point for using Rack::Test # in a testing environment. It depends on an app method being defined in the # same context, and provides the Rack::Test API methods (see Rack::Test::Session # for their documentation). # # Example: # # class HomepageTest < Test::Unit::TestCase # include Rack::Test::Methods # # def app # MyApp.new # end # end module Methods extend Forwardable def rack_mock_session(name = :default) # :nodoc: return build_rack_mock_session unless name @_rack_mock_sessions ||= {} @_rack_mock_sessions[name] ||= build_rack_mock_session end def build_rack_mock_session # :nodoc: Rack::MockSession.new(app) end def rack_test_session(name = :default) # :nodoc: return build_rack_test_session(name) unless name @_rack_test_sessions ||= {} @_rack_test_sessions[name] ||= build_rack_test_session(name) end def build_rack_test_session(name) # :nodoc: Rack::Test::Session.new(rack_mock_session(name)) end def current_session # :nodoc: rack_test_session(_current_session_names.last) end def with_session(name) # :nodoc: _current_session_names.push(name) yield rack_test_session(name) _current_session_names.pop end def _current_session_names # :nodoc: @_current_session_names ||= [:default] end METHODS = [ :request, :get, :post, :put, :patch, :delete, :options, :head, :follow_redirect!, :header, :set_cookie, :clear_cookies, :authorize, :basic_authorize, :digest_authorize, :last_response, :last_request ] def_delegators :current_session, *METHODS end end end rack-test-0.6.2/lib/rack/test/cookie_jar.rb0000644000004100000410000001025212055434046020546 0ustar www-datawww-datarequire "uri" require "time" module Rack module Test class Cookie # :nodoc: include Rack::Utils # :api: private attr_reader :name, :value # :api: private def initialize(raw, uri = nil, default_host = DEFAULT_HOST) @default_host = default_host uri ||= default_uri # separate the name / value pair from the cookie options @name_value_raw, options = raw.split(/[;,] */n, 2) @name, @value = parse_query(@name_value_raw, ';').to_a.first @options = parse_query(options, ';') @options["domain"] ||= (uri.host || default_host) @options["path"] ||= uri.path.sub(/\/[^\/]*\Z/, "") end def replaces?(other) [name.downcase, domain, path] == [other.name.downcase, other.domain, other.path] end # :api: private def raw @name_value_raw end # :api: private def empty? @value.nil? || @value.empty? end # :api: private def domain @options["domain"] end def secure? @options.has_key?("secure") end # :api: private def path @options["path"].strip || "/" end # :api: private def expires Time.parse(@options["expires"]) if @options["expires"] end # :api: private def expired? expires && expires < Time.now end # :api: private def valid?(uri) uri ||= default_uri if uri.host.nil? uri.host = @default_host end real_domain = domain =~ /^\./ ? domain[1..-1] : domain (!secure? || (secure? && uri.scheme == "https")) && uri.host =~ Regexp.new("#{Regexp.escape(real_domain)}$", Regexp::IGNORECASE) && uri.path =~ Regexp.new("^#{Regexp.escape(path)}") end # :api: private def matches?(uri) ! expired? && valid?(uri) end # :api: private def <=>(other) # Orders the cookies from least specific to most [name, path, domain.reverse] <=> [other.name, other.path, other.domain.reverse] end protected def default_uri URI.parse("//" + @default_host + "/") end end class CookieJar # :nodoc: # :api: private def initialize(cookies = [], default_host = DEFAULT_HOST) @default_host = default_host @cookies = cookies @cookies.sort! end def [](name) cookies = hash_for(nil) # TODO: Should be case insensitive cookies[name] && cookies[name].value end def []=(name, value) merge("#{name}=#{Rack::Utils.escape(value)}") end def delete(name) @cookies.reject! do |cookie| cookie.name == name end end def merge(raw_cookies, uri = nil) return unless raw_cookies if raw_cookies.is_a? String raw_cookies = raw_cookies.split("\n") raw_cookies.reject!{|c| c.empty? } end raw_cookies.each do |raw_cookie| cookie = Cookie.new(raw_cookie, uri, @default_host) self << cookie if cookie.valid?(uri) end end def <<(new_cookie) @cookies.reject! do |existing_cookie| new_cookie.replaces?(existing_cookie) end @cookies << new_cookie @cookies.sort! end # :api: private def for(uri) hash_for(uri).values.map { |c| c.raw }.join(';') end def to_hash cookies = {} hash_for(nil).each do |name, cookie| cookies[name] = cookie.value end return cookies end protected def hash_for(uri = nil) cookies = {} # The cookies are sorted by most specific first. So, we loop through # all the cookies in order and add it to a hash by cookie name if # the cookie can be sent to the current URI. It's added to the hash # so that when we are done, the cookies will be unique by name and # we'll have grabbed the most specific to the URI. @cookies.each do |cookie| cookies[cookie.name] = cookie if !uri || cookie.matches?(uri) end return cookies end end end end rack-test-0.6.2/lib/rack/test/uploaded_file.rb0000644000004100000410000000257712055434046021250 0ustar www-datawww-datarequire "tempfile" require "fileutils" module Rack module Test # Wraps a Tempfile with a content type. Including one or more UploadedFile's # in the params causes Rack::Test to build and issue a multipart request. # # Example: # post "/photos", "file" => Rack::Test::UploadedFile.new("me.jpg", "image/jpeg") class UploadedFile # The filename, *not* including the path, of the "uploaded" file attr_reader :original_filename # The content type of the "uploaded" file attr_accessor :content_type def initialize(path, content_type = "text/plain", binary = false) raise "#{path} file does not exist" unless ::File.exist?(path) @content_type = content_type @original_filename = ::File.basename(path) @tempfile = Tempfile.new(@original_filename) @tempfile.set_encoding(Encoding::BINARY) if @tempfile.respond_to?(:set_encoding) @tempfile.binmode if binary FileUtils.copy_file(path, @tempfile.path) end def path @tempfile.path end alias_method :local_path, :path def method_missing(method_name, *args, &block) #:nodoc: @tempfile.__send__(method_name, *args, &block) end def respond_to?(method_name, include_private = false) #:nodoc: @tempfile.respond_to?(method_name, include_private) || super end end end end rack-test-0.6.2/lib/rack/test.rb0000644000004100000410000002277312055434046016454 0ustar www-datawww-datarequire "uri" require "rack" require "rack/mock_session" require "rack/test/cookie_jar" require "rack/test/mock_digest_request" require "rack/test/utils" require "rack/test/methods" require "rack/test/uploaded_file" module Rack module Test VERSION = "0.6.2" DEFAULT_HOST = "example.org" MULTIPART_BOUNDARY = "----------XnJLe9ZIbbGUYtzPQJ16u1" # The common base class for exceptions raised by Rack::Test class Error < StandardError; end # This class represents a series of requests issued to a Rack app, sharing # a single cookie jar # # Rack::Test::Session's methods are most often called through Rack::Test::Methods, # which will automatically build a session when it's first used. class Session extend Forwardable include Rack::Test::Utils def_delegators :@rack_mock_session, :clear_cookies, :set_cookie, :last_response, :last_request # Creates a Rack::Test::Session for a given Rack app or Rack::MockSession. # # Note: Generally, you won't need to initialize a Rack::Test::Session directly. # Instead, you should include Rack::Test::Methods into your testing context. # (See README.rdoc for an example) def initialize(mock_session) @headers = {} if mock_session.is_a?(MockSession) @rack_mock_session = mock_session else @rack_mock_session = MockSession.new(mock_session) end @default_host = @rack_mock_session.default_host end # Issue a GET request for the given URI with the given params and Rack # environment. Stores the issues request object in #last_request and # the app's response in #last_response. Yield #last_response to a block # if given. # # Example: # get "/" def get(uri, params = {}, env = {}, &block) env = env_for(uri, env.merge(:method => "GET", :params => params)) process_request(uri, env, &block) end # Issue a POST request for the given URI. See #get # # Example: # post "/signup", "name" => "Bryan" def post(uri, params = {}, env = {}, &block) env = env_for(uri, env.merge(:method => "POST", :params => params)) process_request(uri, env, &block) end # Issue a PUT request for the given URI. See #get # # Example: # put "/" def put(uri, params = {}, env = {}, &block) env = env_for(uri, env.merge(:method => "PUT", :params => params)) process_request(uri, env, &block) end # Issue a PATCH request for the given URI. See #get # # Example: # patch "/" def patch(uri, params = {}, env = {}, &block) env = env_for(uri, env.merge(:method => "PATCH", :params => params)) process_request(uri, env, &block) end # Issue a DELETE request for the given URI. See #get # # Example: # delete "/" def delete(uri, params = {}, env = {}, &block) env = env_for(uri, env.merge(:method => "DELETE", :params => params)) process_request(uri, env, &block) end # Issue an OPTIONS request for the given URI. See #get # # Example: # options "/" def options(uri, params = {}, env = {}, &block) env = env_for(uri, env.merge(:method => "OPTIONS", :params => params)) process_request(uri, env, &block) end # Issue a HEAD request for the given URI. See #get # # Example: # head "/" def head(uri, params = {}, env = {}, &block) env = env_for(uri, env.merge(:method => "HEAD", :params => params)) process_request(uri, env, &block) end # Issue a request to the Rack app for the given URI and optional Rack # environment. Stores the issues request object in #last_request and # the app's response in #last_response. Yield #last_response to a block # if given. # # Example: # request "/" def request(uri, env = {}, &block) env = env_for(uri, env) process_request(uri, env, &block) end # Set a header to be included on all subsequent requests through the # session. Use a value of nil to remove a previously configured header. # # In accordance with the Rack spec, headers will be included in the Rack # environment hash in HTTP_USER_AGENT form. # # Example: # header "User-Agent", "Firefox" def header(name, value) if value.nil? @headers.delete(name) else @headers[name] = value end end # Set the username and password for HTTP Basic authorization, to be # included in subsequent requests in the HTTP_AUTHORIZATION header. # # Example: # basic_authorize "bryan", "secret" def basic_authorize(username, password) encoded_login = ["#{username}:#{password}"].pack("m*") header('Authorization', "Basic #{encoded_login}") end alias_method :authorize, :basic_authorize # Set the username and password for HTTP Digest authorization, to be # included in subsequent requests in the HTTP_AUTHORIZATION header. # # Example: # digest_authorize "bryan", "secret" def digest_authorize(username, password) @digest_username = username @digest_password = password end # Rack::Test will not follow any redirects automatically. This method # will follow the redirect returned (including setting the Referer header # on the new request) in the last response. If the last response was not # a redirect, an error will be raised. def follow_redirect! unless last_response.redirect? raise Error.new("Last response was not a redirect. Cannot follow_redirect!") end get(last_response["Location"], {}, { "HTTP_REFERER" => last_request.url }) end private def env_for(path, env) uri = URI.parse(path) uri.path = "/#{uri.path}" unless uri.path[0] == ?/ uri.host ||= @default_host env = default_env.merge(env) env["HTTP_HOST"] ||= [uri.host, (uri.port if uri.port != uri.default_port)].compact.join(":") env.update("HTTPS" => "on") if URI::HTTPS === uri env["HTTP_X_REQUESTED_WITH"] = "XMLHttpRequest" if env[:xhr] # TODO: Remove this after Rack 1.1 has been released. # Stringifying and upcasing methods has be commit upstream env["REQUEST_METHOD"] ||= env[:method] ? env[:method].to_s.upcase : "GET" if env["REQUEST_METHOD"] == "GET" # merge :params with the query string if params = env[:params] params = parse_nested_query(params) if params.is_a?(String) params.update(parse_nested_query(uri.query)) uri.query = build_nested_query(params) end elsif !env.has_key?(:input) env["CONTENT_TYPE"] ||= "application/x-www-form-urlencoded" if env[:params].is_a?(Hash) if data = build_multipart(env[:params]) env[:input] = data env["CONTENT_LENGTH"] ||= data.length.to_s env["CONTENT_TYPE"] = "multipart/form-data; boundary=#{MULTIPART_BOUNDARY}" else env[:input] = params_to_string(env[:params]) end else env[:input] = env[:params] end end env.delete(:params) if env.has_key?(:cookie) set_cookie(env.delete(:cookie), uri) end Rack::MockRequest.env_for(uri.to_s, env) end def process_request(uri, env) uri = URI.parse(uri) uri.host ||= @default_host @rack_mock_session.request(uri, env) if retry_with_digest_auth?(env) auth_env = env.merge({ "HTTP_AUTHORIZATION" => digest_auth_header, "rack-test.digest_auth_retry" => true }) auth_env.delete('rack.request') process_request(uri.path, auth_env) else yield last_response if block_given? last_response end end def digest_auth_header challenge = last_response["WWW-Authenticate"].split(" ", 2).last params = Rack::Auth::Digest::Params.parse(challenge) params.merge!({ "username" => @digest_username, "nc" => "00000001", "cnonce" => "nonsensenonce", "uri" => last_request.fullpath, "method" => last_request.env["REQUEST_METHOD"], }) params["response"] = MockDigestRequest.new(params).response(@digest_password) "Digest #{params}" end def retry_with_digest_auth?(env) last_response.status == 401 && digest_auth_configured? && !env["rack-test.digest_auth_retry"] end def digest_auth_configured? @digest_username end def default_env { "rack.test" => true, "REMOTE_ADDR" => "127.0.0.1" }.merge(headers_for_env) end def headers_for_env converted_headers = {} @headers.each do |name, value| env_key = name.upcase.gsub("-", "_") env_key = "HTTP_" + env_key unless "CONTENT_TYPE" == env_key converted_headers[env_key] = value end converted_headers end def params_to_string(params) case params when Hash then build_nested_query(params) when nil then "" else params end end end def self.encoding_aware_strings? defined?(Encoding) && "".respond_to?(:encode) end end end rack-test-0.6.2/lib/rack/mock_session.rb0000644000004100000410000000331112055434046020154 0ustar www-datawww-datamodule Rack class MockSession # :nodoc: attr_writer :cookie_jar attr_reader :default_host def initialize(app, default_host = Rack::Test::DEFAULT_HOST) @app = app @after_request = [] @default_host = default_host @last_request = nil @last_response = nil end def after_request(&block) @after_request << block end def clear_cookies @cookie_jar = Rack::Test::CookieJar.new([], @default_host) end def set_cookie(cookie, uri = nil) cookie_jar.merge(cookie, uri) end def request(uri, env) env["HTTP_COOKIE"] ||= cookie_jar.for(uri) @last_request = Rack::Request.new(env) status, headers, body = @app.call(@last_request.env) @last_response = MockResponse.new(status, headers, body, env["rack.errors"].flush) body.close if body.respond_to?(:close) cookie_jar.merge(last_response.headers["Set-Cookie"], uri) @after_request.each { |hook| hook.call } if @last_response.respond_to?(:finish) @last_response.finish else @last_response end end # Return the last request issued in the session. Raises an error if no # requests have been sent yet. def last_request raise Rack::Test::Error.new("No request yet. Request a page first.") unless @last_request @last_request end # Return the last response received in the session. Raises an error if # no requests have been sent yet. def last_response raise Rack::Test::Error.new("No response yet. Request a page first.") unless @last_response @last_response end def cookie_jar @cookie_jar ||= Rack::Test::CookieJar.new([], @default_host) end end end rack-test-0.6.2/Gemfile.lock0000644000004100000410000000105012055434046015665 0ustar www-datawww-dataGEM remote: http://rubygems.org/ specs: diff-lcs (1.1.3) rack (1.4.0) rack-protection (1.2.0) rack rake (0.9.2) rspec (2.8.0) rspec-core (~> 2.8.0) rspec-expectations (~> 2.8.0) rspec-mocks (~> 2.8.0) rspec-core (2.8.0) rspec-expectations (2.8.0) diff-lcs (~> 1.1.2) rspec-mocks (2.8.0) sinatra (1.3.2) rack (~> 1.3, >= 1.3.6) rack-protection (~> 1.2) tilt (~> 1.3, >= 1.3.3) tilt (1.3.3) PLATFORMS java ruby DEPENDENCIES rack rake rspec sinatra