pax_global_header 0000666 0000000 0000000 00000000064 12137770550 0014521 g ustar 00root root 0000000 0000000 52 comment=e30f210d408462576da8d960d93e6f01f32fbac3
ruby-sham-rack-1.3.6/ 0000775 0000000 0000000 00000000000 12137770550 0014355 5 ustar 00root root 0000000 0000000 ruby-sham-rack-1.3.6/CHANGES.markdown 0000664 0000000 0000000 00000002074 12137770550 0017174 0 ustar 00root root 0000000 0000000 ## 1-May-2012 [mdub@dogbiscuit.org]
* Validate arguments to `ShamRack#mount`.
* Update for compatibility with patron-0.4.x.
## 18-Oct-2010 [mdub@dogbiscuit.org]
* Add support for Patron.
## 02-Sep-2010 [mdub@dogbiscuit.org]
* Fixes to support Ruby-1.9.x.
## 08-Jul-2010 [jyurek@thoughtbot.com]
* Add support for Mechanize.
## 11-Mar-2010 [mdub@dogbiscuit.org]
* Added generic `StubWebService`.
## 15-Jan-2010 [jeremy.burks@gmail.com]
* Fix an incompatibility with rest-client 1.2.0.
## 27-Nov-2009 [mdub@dogbiscuit.org]
* Change of approach: extend rather than reimplement `Net:HTTP`. This should improve coverage of all the weird and wonderful ways of using the `Net:HTTP` API.
## 5-Jun-2009 [mdub@dogbiscuit.org]
* Add support for `Net::HTTP.get_response`.
* Pass back headers provided by Rack app in the `HTTPResponse`.
## 3-Jun-2009 [mdub@dogbiscuit.org]
* Introduced `ShamRack#at` to simplify registration of apps.
## 13-May-2009 [mdub@dogbiscuit.org]
* Added accessors on HTTP object for address, port and rack_app.
* Added accessors to imitate "net/https".
ruby-sham-rack-1.3.6/README.markdown 0000664 0000000 0000000 00000006730 12137770550 0017064 0 ustar 00root root 0000000 0000000 ShamRack
========
ShamRack plumbs HTTP requests into [Rack][rack].
What's it for, again?
---------------------
Well, it makes it easy to _stub out external (HTTP) services_, which is handy in development and testing environments, or when you want to _test your HTTP client code_.
You can also use it to _test your Rack application_ (or Sinatra, or Rails, or Merb) using a variety of HTTP client libraries, to check interoperability. For instance, you could test your app using:
* [`rest-client`][rest-client]
* [`httparty`][httparty]
* [`oauth`][oauth]
all without having to boot it in a server.
Installing it
-------------
gem install sham_rack
Using it
--------
### A simple inline application
require 'sham_rack'
ShamRack.at("www.greetings.com") do |env|
["200 OK", { "Content-type" => "text/plain" }, ["Hello, world!"]]
end
require 'open-uri'
open("http://www.greetings.com/").read #=> "Hello, world!"
### Sinatra integration
ShamRack.at("sinatra.xyz").sinatra do
get "/hello/:subject" do
"Hello, #{params[:subject]}"
end
end
open("http://sinatra.xyz/hello/stranger").read #=> "Hello, stranger"
### Rackup support
ShamRack.at("rackup.xyz").rackup do
use Some::Middleware
use Some::Other::Middleware
run MyApp.new
end
### Any old Rack app
ShamRack.at("google.com").mount(my_google_stub)
### General-purpose stubbing
@stub_app = ShamRack.at("stubbed.com").stub
@stub_app.register_resource("/greeting", "Hello, world!", "text/plain")
open("http://stubbed.com/greeting").read #=> "Hello, world!"
@stub_app.last_request.path #=> "/greeting"
Or, just use Sinatra, as described above ... it's almost as succinct, and heaps more powerful.
### When you're done testing
ShamRack.unmount_all
open("http://stubbed.com/greeting").read #=> OpenURI::HTTPError
Supported HTTP client libraries
-------------------------------
### Net::HTTP and friends
ShamRack supports requests made using Net::HTTP, or any of the numerous APIs built on top of it:
uri = URI.parse("http://www.greetings.com/")
Net::HTTP.get_response(uri).body #=> "Hello, world!"
require 'open-uri'
open("http://www.greetings.com/").read #=> "Hello, world!"
require 'restclient'
RestClient.get("http://www.greetings.com/").to_s #=> "Hello, world!"
require 'mechanize'
Mechanize.new.get("http://www.greetings.com/").body #=> "Hello, world!"
### Patron (experimental)
We've recently added support for [Patron][patron]:
require 'sham_rack/patron'
patron = Patron::Session.new
patron.get("http://www.greetings.com/").body #=> "Hello, world!"
What's the catch?
-----------------
* Your Rack request-handling code runs in the same Ruby VM, in fact the same Thread, as your request.
Thanks to
---------
* Blaine Cook for [FakeWeb][fakeweb], which was an inspiration for ShamRack.
* Perryn Fowler for his efforts plumbing Net::HTTP into ActionController::TestProcess.
* Christian Neukirchen et al for the chewy goodness that is [Rack][rack].
[rack]: http://rack.rubyforge.org/
[sinatra]: http://www.sinatrarb.com/
[rest-client]: http://github.com/adamwiggins/rest-client
[httparty]: http://github.com/jnunemaker/httparty
[oauth]: http://oauth.rubyforge.org/
[fakeweb]: http://fakeweb.rubyforge.org/
[mechanize]: http://mechanize.rubyforge.org
[patron]: http://github.com/toland/Patron
ruby-sham-rack-1.3.6/Rakefile 0000664 0000000 0000000 00000000337 12137770550 0016025 0 ustar 00root root 0000000 0000000 require "rubygems"
require "rake"
task "default" => "spec"
require "rspec/core/rake_task"
RSpec::Core::RakeTask.new do |t|
t.rspec_opts = ["--format", "nested"]
end
require 'bundler'
Bundler::GemHelper.install_tasks
ruby-sham-rack-1.3.6/benchmark/ 0000775 0000000 0000000 00000000000 12137770550 0016307 5 ustar 00root root 0000000 0000000 ruby-sham-rack-1.3.6/benchmark/benchmark.rb 0000664 0000000 0000000 00000002125 12137770550 0020566 0 ustar 00root root 0000000 0000000 require "rubygems"
require "pathname"
dir = Pathname(__FILE__).parent
$LOAD_PATH.unshift(dir.parent + "lib")
require dir + "hello_app"
require "sham_rack"
require "restclient"
# mount an instance of the app using ShamRack
ShamRack.mount(HelloApp.new, "hello.sham")
# run another instance in a separate process
server_pid = fork do
puts "Starting HTTP server on port 3333"
$stdout = File.new('/dev/null', 'w')
HelloApp.run!(:port => 3333)
end
at_exit do
puts "Killing HTTP server"
Process.kill("TERM", server_pid)
Process.wait(server_pid)
end
puts "Waiting for server to come up"
begin
puts RestClient.get("http://localhost:3333/hello/stranger")
rescue SystemCallError => e
retry
end
iterations = (ARGV.shift || 1000).to_i
%w(hello.sham localhost:3333).each do |site|
start = Time.now
iterations.times do
x = RestClient.get("http://#{site}/hello/stranger").to_s
end
elapsed_time = (Time.now - start)
requests_per_second = iterations / elapsed_time.to_f
printf "%-20s #{iterations} requests in %f; %f per second\n", site, elapsed_time, requests_per_second
end
ruby-sham-rack-1.3.6/benchmark/hello_app.rb 0000664 0000000 0000000 00000000234 12137770550 0020576 0 ustar 00root root 0000000 0000000 require "rubygems"
require "sinatra/base"
class HelloApp < Sinatra::Base
get "/hello/:subject" do
"Hello, #{params[:subject]}"
end
end
ruby-sham-rack-1.3.6/checksums.yaml.gz 0000664 0000000 0000000 00000000651 12137770550 0017647 0 ustar 00root root 0000000 0000000 ‹ +r^Q‘±ŽÛ0†÷<…{{
[q–2ä Åp Rp@Å 67)ìÈV‡C ÇB¾¼:(Ðâ ’ÿŸ\¯×«/ßn?º÷%{qùðÍn÷òºÊ²øýÞ]»{÷µO¯Ùï’ŸkÉd™®ÄÖ(¨Î‡}îµÙZ
†ãi ™¨ßB€¨)9šö»4?‘÷îýïX3{=Ý0Œ%¤úá:r‹“§&±òƒmòú õF³z,yìÌòO¨kt9¹mkÅÔÏœ#´&qêsl“%ØH¾Ä0DNcéR ¹åSk…+[5…Õ{eµy°™
¨sð¡Þ@0¹Óäu³e2¥Ô.¨yóÈÇì
Ûž‚¯üÍìJ9…QT…CDU+¤}‰ '™ú°tùý-VsÉtž°:HECi5¢c@íf«]¢ÍëCô/L—«ãøÀsæ˜ÛÊ ¦äžè%‰ÆÀÔ(‰ŠÃ)ÚŠåX|„Ò’+>z
dÔl±©y@Ú'ß²<ó¤I÷Vµ»Õ/ñãp„ ruby-sham-rack-1.3.6/lib/ 0000775 0000000 0000000 00000000000 12137770550 0015123 5 ustar 00root root 0000000 0000000 ruby-sham-rack-1.3.6/lib/sham_rack.rb 0000664 0000000 0000000 00000000447 12137770550 0017405 0 ustar 00root root 0000000 0000000 require "sham_rack/net_http"
require "sham_rack/registration"
require "sham_rack/version"
# ShamRack allows access to Rack applications using Net::Http, but without network traffic.
#
# For more detail, see http://github.com/mdub/sham_rack
#
module ShamRack
extend ShamRack::Registration
end
ruby-sham-rack-1.3.6/lib/sham_rack/ 0000775 0000000 0000000 00000000000 12137770550 0017053 5 ustar 00root root 0000000 0000000 ruby-sham-rack-1.3.6/lib/sham_rack/net_http.rb 0000664 0000000 0000000 00000005011 12137770550 0021222 0 ustar 00root root 0000000 0000000 require "net/http"
require "rack"
class << Net::HTTP
alias :new_without_sham_rack :new
def new(address, port = nil, *proxy_args)
port ||= Net::HTTP.default_port
rack_app = ShamRack.application_for(address, port)
http_object = new_without_sham_rack(address, port, *proxy_args)
if rack_app
http_object.extend(ShamRack::NetHttp::Extensions)
http_object.rack_app = rack_app
end
http_object
end
end
module ShamRack
module NetHttp
module Extensions
attr_accessor :rack_app
def start
if block_given?
yield self
else
self
end
end
def request(request, body = nil)
rack_response = @rack_app.call(rack_env(request, body))
net_http_response = build_response(rack_response)
yield net_http_response if block_given?
return net_http_response
end
private
def rack_env(request, body)
rack_env = request_env(request, body)
rack_env.merge!(header_env(request))
rack_env.merge!(server_env)
end
def server_env
{
"SERVER_NAME" => @address,
"SERVER_PORT" => @port.to_s
}
end
def header_env(request)
env = {}
request.each_header do |header, content|
key = header.upcase.gsub('-', '_')
key = "HTTP_" + key unless key =~ /^CONTENT_(TYPE|LENGTH)$/
env[key] = content
end
env
end
def request_env(request, body)
body ||= request.body || ""
Rack::MockRequest.env_for(request.path, :method => request.method, :input => body.to_s)
end
def build_response(rack_response)
status, headers, body = rack_response
code, message = status.to_s.split(" ", 2)
message ||= Rack::Utils::HTTP_STATUS_CODES[code.to_i]
response = Net::HTTPResponse.send(:response_class, code).new("Sham", code, message)
response.instance_variable_set(:@body, assemble_body(body))
response.instance_variable_set(:@read, true)
headers.each do |k,v|
response.add_field(k, v)
end
response.extend ShamRack::NetHttp::ResponseExtensions
return response
end
def assemble_body(body)
content = ""
body.each { |fragment| content << fragment }
content
end
end
module ResponseExtensions
def read_body(dest = nil)
yield @body if block_given?
dest << @body if dest
return @body
end
end
end
end
ruby-sham-rack-1.3.6/lib/sham_rack/patron.rb 0000664 0000000 0000000 00000003316 12137770550 0020706 0 ustar 00root root 0000000 0000000 require "patron"
require "sham_rack"
require "uri"
module Patron
class Session
alias :handle_request_without_sham_rack :handle_request
def handle_request(patron_request)
uri = URI.parse(patron_request.url)
rack_app = ShamRack.application_for(uri.host, uri.port)
if rack_app
handle_request_with_rack(patron_request, rack_app)
else
handle_request_without_sham_rack(patron_request)
end
end
private
def handle_request_with_rack(patron_request, rack_app)
env = rack_env_for(patron_request)
rack_response = rack_app.call(env)
patron_response(rack_response)
end
def rack_env_for(patron_request)
env = Rack::MockRequest.env_for(patron_request.url, :method => patron_request.action, :input => patron_request.upload_data)
env.merge!(header_env(patron_request))
env
end
def patron_response(rack_response)
status, headers, body = rack_response
Patron::Response.new("", status.to_i, 0, assemble_headers(status, headers), assemble_body(body))
end
def header_env(patron_request)
env = {}
patron_request.headers.each do |header, content|
key = header.upcase.gsub('-', '_')
key = "HTTP_" + key unless key =~ /^CONTENT_(TYPE|LENGTH)$/
env[key] = content
end
env
end
def assemble_headers(status, headers)
status_code = Rack::Utils::HTTP_STATUS_CODES[status.to_i]
content = "HTTP/1.1 #{status} #{status_code}\r\n"
headers.each do |k, v|
content << "#{k}: #{v}\r\n"
end
content
end
def assemble_body(body)
content = ""
body.each { |fragment| content << fragment }
content
end
end
end
ruby-sham-rack-1.3.6/lib/sham_rack/registration.rb 0000664 0000000 0000000 00000002713 12137770550 0022115 0 ustar 00root root 0000000 0000000 module ShamRack
module Registration
ADDRESS_PATTERN = /^[a-z0-9-]+(\.[a-z0-9-]+)*$/i
def unmount_all
registry.clear
end
def at(address, port = nil, &app_block)
mount_point = mount_point_for(address, port)
if app_block
mount_point.mount(app_block)
else
mount_point
end
end
def application_for(address, port = nil)
mount_point_for(address, port).app
end
def mount(app, address, port = nil)
at(address, port).mount(app)
end
private
def mount_point_for(address, port)
registry[mount_key(address, port)]
end
def registry
@registry ||= Hash.new do |hash, key|
hash[key] = MountPoint.new
end
end
def mount_key(address, port)
unless address =~ ADDRESS_PATTERN
raise ArgumentError, "invalid address"
end
port ||= Net::HTTP.default_port
port = Integer(port)
[address, port]
end
end
class MountPoint
attr_reader :app
def mount(app)
@app = app
end
def unmount
@app = nil
end
def rackup(&block)
require "rack"
mount(Rack::Builder.new(&block).to_app)
end
def sinatra(&block)
require "sinatra/base"
sinatra_app = Class.new(Sinatra::Base)
sinatra_app.class_eval(&block)
mount(sinatra_app.new)
end
def stub
require "sham_rack/stub_web_service"
mount(StubWebService.new)
end
end
end
ruby-sham-rack-1.3.6/lib/sham_rack/stub_web_service.rb 0000664 0000000 0000000 00000002016 12137770550 0022731 0 ustar 00root root 0000000 0000000 require "rack"
module ShamRack
# A simple Rack app that stubs out a web service, for testing.
class StubWebService
def initialize
@handlers = []
end
def last_request
@request
end
def call(env)
@request = Rack::Request.new(env)
@handlers.each do |handler|
response = handler.call(@request)
return response if response
end
return default_response
end
def handle(&block)
@handlers.unshift(block)
end
def register_resource(path, content, content_type = "application/xml", status = 200)
handle do |request|
request_path = request.path_info
unless request.query_string.to_s.empty?
request_path += "?" + request.query_string
end
[status, {"Content-Type" => content_type}, [content]] if request_path == path
end
end
def reset
@handlers.clear
end
protected
def default_response
[404, {"Content-Type" => "text/plain"}, ["Not found"]]
end
end
end
ruby-sham-rack-1.3.6/lib/sham_rack/version.rb 0000664 0000000 0000000 00000000050 12137770550 0021060 0 ustar 00root root 0000000 0000000 module ShamRack
VERSION = "1.3.6"
end
ruby-sham-rack-1.3.6/metadata.yml 0000664 0000000 0000000 00000003522 12137770550 0016662 0 ustar 00root root 0000000 0000000 --- !ruby/object:Gem::Specification
name: sham_rack
version: !ruby/object:Gem::Version
version: 1.3.6
platform: ruby
authors:
- Mike Williams
autorequire:
bindir: bin
cert_chain: []
date: 2013-04-05 00:00:00.000000000 Z
dependencies:
- !ruby/object:Gem::Dependency
prerelease: false
version_requirements: !ruby/object:Gem::Requirement
requirements:
- - ! '>='
- !ruby/object:Gem::Version
version: '0'
name: rack
requirement: !ruby/object:Gem::Requirement
requirements:
- - ! '>='
- !ruby/object:Gem::Version
version: '0'
type: :runtime
description: ShamRack plumbs Net::HTTP directly into Rack, for quick and easy HTTP
testing.
email: mdub@dogbiscuit.org
executables: []
extensions: []
extra_rdoc_files: []
files:
- lib/sham_rack/net_http.rb
- lib/sham_rack/patron.rb
- lib/sham_rack/registration.rb
- lib/sham_rack/stub_web_service.rb
- lib/sham_rack/version.rb
- lib/sham_rack.rb
- README.markdown
- CHANGES.markdown
- spec/sham_rack/stub_web_service_spec.rb
- spec/sham_rack_spec.rb
- spec/spec_helper.rb
- spec/test_apps.rb
- Rakefile
- benchmark/benchmark.rb
- benchmark/hello_app.rb
homepage: http://github.com/mdub/sham_rack
licenses: []
metadata: {}
post_install_message:
rdoc_options: []
require_paths:
- lib
required_ruby_version: !ruby/object:Gem::Requirement
requirements:
- - ! '>='
- !ruby/object:Gem::Version
version: '0'
required_rubygems_version: !ruby/object:Gem::Requirement
requirements:
- - ! '>='
- !ruby/object:Gem::Version
version: '0'
requirements: []
rubyforge_project: shamrack
rubygems_version: 2.0.0
signing_key:
specification_version: 4
summary: Net::HTTP-to-Rack plumbing
test_files:
- spec/sham_rack/stub_web_service_spec.rb
- spec/sham_rack_spec.rb
- spec/spec_helper.rb
- spec/test_apps.rb
- Rakefile
- benchmark/benchmark.rb
- benchmark/hello_app.rb
ruby-sham-rack-1.3.6/spec/ 0000775 0000000 0000000 00000000000 12137770550 0015307 5 ustar 00root root 0000000 0000000 ruby-sham-rack-1.3.6/spec/sham_rack/ 0000775 0000000 0000000 00000000000 12137770550 0017237 5 ustar 00root root 0000000 0000000 ruby-sham-rack-1.3.6/spec/sham_rack/stub_web_service_spec.rb 0000664 0000000 0000000 00000004204 12137770550 0024130 0 ustar 00root root 0000000 0000000 require "spec_helper"
require "sham_rack/stub_web_service"
require "rack/test"
describe ShamRack::StubWebService do
include Rack::Test::Methods
attr_reader :app
before(:each) do
@app = ShamRack::StubWebService.new
end
describe "#last_request" do
it "returns the last request" do
get '/foo/bar'
@app.last_request.path_info.should == "/foo/bar"
end
end
describe "with no handlers registered" do
describe "any request" do
before do
get "/foo/456"
end
it "returns a 404" do
last_response.status.should == 404
end
end
end
describe "with two handlers registered" do
before(:each) do
@app.handle do |request|
[200, {}, ["response from first handler"]] if request.get?
end
@app.handle do |request|
[200, {}, ["response from second handler"]] if request.path_info == "/stuff"
end
end
describe "a request matching the first handler" do
before do
get "/foo/456"
end
it "receives a response from the first handler" do
last_response.body.should == "response from first handler"
end
end
describe "a request matching the second handler" do
before do
post "/stuff"
end
it "receives a response from the second handler" do
last_response.body.should == "response from second handler"
end
end
describe "a request matching both handlers" do
before do
get "/stuff"
end
it "receives a response from the second handler" do
last_response.body.should == "response from second handler"
end
end
end
describe ".register_resource" do
before do
@app.register_resource("/stuff?foo=bar", "STUFF", "text/plain", 202)
get "/stuff?foo=bar"
end
it "sets body" do
last_response.body.should == "STUFF"
end
it "sets content-type" do
last_response.content_type.should == "text/plain"
end
it "sets status code" do
last_response.status.should == 202
end
end
end
ruby-sham-rack-1.3.6/spec/sham_rack_spec.rb 0000664 0000000 0000000 00000020504 12137770550 0020577 0 ustar 00root root 0000000 0000000 require "spec_helper"
require "sham_rack"
require "sham_rack/patron"
require "open-uri"
require "restclient"
require "mechanize"
require "rack"
describe ShamRack do
class NetHttpProhibited < StandardError; end
before do
any_instance_of(Net::HTTP) do |http|
stub(http).start do
raise NetHttpProhibited, "real network calls are not allowed"
end
end
end
after(:each) do
ShamRack.unmount_all
end
describe "mounted Rack application" do
before(:each) do
ShamRack.mount(GreetingApp.new, "www.greetings.com")
end
it "can be accessed using Net::HTTP" do
response = Net::HTTP.start("www.greetings.com") do |http|
http.request(Net::HTTP::Get.new("/"))
end
response.body.should == "Hello, world"
end
it "can be accessed using Net::HTTP#get_response" do
response = Net::HTTP.get_response(URI.parse("http://www.greetings.com/"))
response.body.should == "Hello, world"
end
it "can be accessed using open-uri" do
response = open("http://www.greetings.com")
response.status.should == ["200", "OK"]
response.read.should == "Hello, world"
end
it "can be accessed using RestClient" do
response = RestClient.get("http://www.greetings.com")
response.code.should == 200
response.to_s.should == "Hello, world"
end
it "can be accessed using Mechanize" do
response = Mechanize.new.get("http://www.greetings.com")
response.body.should == "Hello, world"
end
it "can be accessed using Patron" do
patron = Patron::Session.new
response = patron.get("http://www.greetings.com/foo/bar")
response.body.should == "Hello, world"
end
end
describe ".at" do
context "with a block" do
it "mounts associated block as an app" do
ShamRack.at("simple.xyz") do |env|
["200 OK", { "Content-type" => "text/plain" }, ["Easy, huh?"]]
end
open("http://simple.xyz").read.should == "Easy, huh?"
end
end
context "with a URL" do
it "raises an ArgumentError" do
lambda do
ShamRack.at("http://www.greetings.com")
end.should raise_error(ArgumentError, "invalid address")
end
end
describe "#mount" do
it "mounts an app" do
ShamRack.at("hello.xyz").mount(GreetingApp.new)
open("http://hello.xyz").read.should == "Hello, world"
end
end
describe "#unmount" do
it "deregisters a mounted app" do
ShamRack.at("gone.xyz").mount(GreetingApp.new)
ShamRack.at("gone.xyz").unmount
lambda do
open("http://gone.xyz").read
end.should raise_error(NetHttpProhibited)
end
end
describe "#rackup" do
before do
@return_value = ShamRack.at("rackup.xyz").rackup do
use UpcaseBody
run GreetingApp.new
end
end
it "mounts an app created using Rack::Builder" do
open("http://rackup.xyz").read.should == "HELLO, WORLD"
end
it "returns the app" do
@return_value.should respond_to(:call)
end
end
describe "#sinatra" do
before do
@return_value = ShamRack.at("sinatra.xyz").sinatra do
get "/hello/:subject" do
"Hello, #{params[:subject]}"
end
end
end
it "mounts associated block as a Sinatra app" do
open("http://sinatra.xyz/hello/stranger").read.should == "Hello, stranger"
end
it "returns the app" do
@return_value.should respond_to(:call)
end
end
describe "#stub" do
before do
@return_value = ShamRack.at("stubbed.xyz").stub
end
it "mounts a StubWebService" do
ShamRack.application_for("stubbed.xyz").should be_kind_of(ShamRack::StubWebService)
end
it "returns the StubWebService" do
@return_value.should == ShamRack.application_for("stubbed.xyz")
end
end
end
describe ".mount" do
it "is deprecated, but still works" do
ShamRack.mount(GreetingApp.new, "hello.xyz")
open("http://hello.xyz").read.should == "Hello, world"
end
end
describe "response" do
before(:each) do
ShamRack.at("www.greetings.com") do
[
"456 Foo Bar",
{ "Content-Type" => "text/plain", "X-Foo" => "bar" },
["BODY"]
]
end
end
let(:response) { Net::HTTP.get_response(URI.parse("http://www.greetings.com/")) }
it "has status returned by app" do
response.code.should == "456"
end
it "has status message returned by app" do
response.message.should == "Foo Bar"
end
it "has body returned by app" do
response.body.should == "BODY"
end
it "has Content-Type returned by app" do
response.content_type.should == "text/plain"
end
it "has other headers returned by app" do
response["x-foo"].should =="bar"
end
context "when the app returns a numeric status" do
before(:each) do
ShamRack.at("www.greetings.com") do
[
201,
{ "Content-Type" => "text/plain" },
["BODY"]
]
end
@response = Net::HTTP.get_response(URI.parse("http://www.greetings.com/"))
end
it "has status returned by app" do
response.code.should == "201"
end
it "derives a status message" do
response.message.should == "Created"
end
end
end
describe "Rack environment" do
before(:each) do
@env_recorder = recorder = EnvRecorder.new(GreetingApp.new)
ShamRack.at("env.xyz").rackup do
use Rack::Lint
run recorder
end
end
def env
@env_recorder.last_env
end
it "is valid" do
open("http://env.xyz/blah?q=abc")
env["REQUEST_METHOD"].should == "GET"
env["SCRIPT_NAME"].should == ""
env["PATH_INFO"].should == "/blah"
env["QUERY_STRING"].should == "q=abc"
env["SERVER_NAME"].should == "env.xyz"
env["SERVER_PORT"].should == "80"
env["rack.version"].should be_kind_of(Array)
env["rack.url_scheme"].should == "http"
env["rack.multithread"].should == true
env["rack.multiprocess"].should == true
env["rack.run_once"].should == false
end
it "provides request headers" do
Net::HTTP.start("env.xyz") do |http|
request = Net::HTTP::Get.new("/")
request["Foo-bar"] = "baz"
http.request(request)
end
env["HTTP_FOO_BAR"].should == "baz"
end
it "supports POST" do
RestClient.post("http://env.xyz/resource", "q" => "rack")
env["REQUEST_METHOD"].should == "POST"
env["CONTENT_TYPE"].should == "application/x-www-form-urlencoded"
env["rack.input"].read.should == "q=rack"
end
it "supports POST using Net::HTTP" do
Net::HTTP.start("env.xyz") do |http|
http.post("/resource", "q=rack")
end
env["REQUEST_METHOD"].should == "POST"
env["rack.input"].read.should == "q=rack"
end
it "supports POST using Patron" do
patron = Patron::Session.new
response = patron.post("http://env.xyz/resource", "", "Content-Type" => "application/xml")
response.status.should == 200
env["REQUEST_METHOD"].should == "POST"
env["rack.input"].read.should == ""
env["CONTENT_TYPE"].should == "application/xml"
end
it "supports PUT" do
RestClient.put("http://env.xyz/thing1", "stuff", :content_type => "text/plain")
env["REQUEST_METHOD"].should == "PUT"
env["CONTENT_TYPE"].should == "text/plain"
env["rack.input"].read.should == "stuff"
end
it "supports PUT using Patron" do
patron = Patron::Session.new
response = patron.put("http://env.xyz/resource", "stuff", "Content-Type" => "text/plain")
env["REQUEST_METHOD"].should == "PUT"
env["CONTENT_TYPE"].should == "text/plain"
env["rack.input"].read.should == "stuff"
end
it "supports DELETE" do
RestClient.delete("http://env.xyz/thing/1")
env["REQUEST_METHOD"].should == "DELETE"
env["PATH_INFO"].should == "/thing/1"
end
it "supports DELETE using Patron" do
patron = Patron::Session.new
response = patron.delete("http://env.xyz/resource")
env["REQUEST_METHOD"].should == "DELETE"
env["PATH_INFO"].should == "/resource"
end
end
end
ruby-sham-rack-1.3.6/spec/spec_helper.rb 0000664 0000000 0000000 00000000216 12137770550 0020124 0 ustar 00root root 0000000 0000000 require "rubygems"
require "rspec"
require "rr"
RSpec.configure do |config|
config.mock_with RR::Adapters::RSpec2
end
require "test_apps"
ruby-sham-rack-1.3.6/spec/test_apps.rb 0000664 0000000 0000000 00000001414 12137770550 0017636 0 ustar 00root root 0000000 0000000 require "rack"
class GreetingApp
include Rack::Utils
def call(env)
params = parse_nested_query(env["QUERY_STRING"])
salutation = params[:salutation] || "Hello"
subject = params[:subject] || "world"
message = "#{salutation}, #{subject}"
[
"200 OK",
{ "Content-Type" => "text/plain", "Content-Length" => message.length.to_s },
[message]
]
end
end
class EnvRecorder
def initialize(app)
@app = app
end
def call(env)
@last_env = env
@app.call(env)
end
attr_reader :last_env
end
class UpcaseBody
def initialize(app)
@app = app
end
def call(env)
status, headers, body = @app.call(env)
upcased_body = Array(body).map { |x| x.upcase }
[status, headers, upcased_body]
end
end