
== Rack::Auth::Basic
* should challenge correctly when no credentials are specified
* should rechallenge if incorrect credentials are specified
* should return application output if correct credentials are specified
* should return 400 Bad Request if different auth scheme used
* realm as optional constructor arg

== Rack::Auth::Digest::MD5
* should challenge when no credentials are specified
* should return application output if correct credentials given
* should return application output if correct credentials given (hashed passwords)
* should rechallenge if incorrect username given
* should rechallenge if incorrect password given
* should rechallenge with stale parameter if nonce is stale
* should return 400 Bad Request if incorrect qop given
* should return 400 Bad Request if incorrect uri given
* should return 400 Bad Request if different auth scheme used
* should not require credentials for unprotected path
* should challenge when no credentials are specified for protected path
* should return application output if correct credentials given for protected path
* should return application output if correct credentials given for POST
* should return application output if correct credentials given for PUT (using method override of POST)
* realm as optional constructor arg

== Rack::Auth::OpenID
* realm uri should be valid
* should be able to check if a uri is within the realm (empty)
* return_to should be valid
* extensions should have required constants defined
* extensions should have Request and Response defined and inherit from OpenID::Extension

== Rack::Builder
* chains apps by default
* has implicit #to_app
* supports blocks on use
* has explicit #to_app
* apps are initialized once

== Rack::Adapter::Camping
* works with GET
* works with POST

== Rack::Cascade
* should dispatch onward on 404 by default
* should dispatch onward on whatever is passed
* should fail if empty
* should append new app

== Rack::Handler::CGI
* startup (empty)
* should respond
* should be a lighttpd
* should have rack headers
* should have CGI headers on GET
* should have CGI headers on POST
* should support HTTP auth
* should set status
* shutdown

== Rack::Chunked
* chunks responses with no Content-Length
* chunks empty bodies properly
* does not modify response when Content-Length header present
* does not modify response when client is HTTP/1.0
* does not modify response when Transfer-Encoding header already present
* does not modify response when status code is 100
* does not modify response when status code is 204
* does not modify response when status code is 304

== Rack::CommonLogger
* should log to rack.errors by default
* should log to anything with <<

== Rack::ConditionalGet
* should set a 304 status and truncate body when If-Modified-Since hits
* should set a 304 status and truncate body when If-None-Match hits
* should not affect non-GET/HEAD requests

== Rack::ContentLength
* sets Content-Length on String bodies if none is set
* sets Content-Length on Array bodies if none is set
* does not set Content-Length on variable length bodies
* does not change Content-Length if it is already set
* does not set Content-Length on 304 responses
* does not set Content-Length when Transfer-Encoding is chunked

== Rack::ContentType
* sets Content-Type to default text/html if none is set
* sets Content-Type to chosen default if none is set
* does not change Content-Type if it is already set
* case insensitive detection of Content-Type

== Rack::Deflater
* should be able to deflate bodies that respond to each
* should be able to deflate String bodies
* should be able to gzip bodies that respond to each
* should be able to fallback to no deflation
* should be able to skip when there is no response entity body
* should handle the lack of an acceptable encoding
* should handle gzip response with Last-Modified header
* should do nothing when no-transform Cache-Control directive present

== Rack::Directory
* serves directory indices
* passes to app if file found
* serves uri with URL encoded filenames
* does not allow directory traversal
* 404s if it can't find the file

== Rack::Handler::FastCGI
* startup (empty)
* should respond
* should be a lighttpd
* should have rack headers
* should have CGI headers on GET
* should have CGI headers on POST
* should support HTTP auth
* should set status
* shutdown

== Rack::File
* serves files
* sets Last-Modified header
* serves files with URL encoded filenames
* does not allow directory traversal
* does not allow directory traversal with encoded periods
* 404s if it can't find the file
* detects SystemCallErrors
* returns bodies that respond to #to_path

== Rack::Handler
* has registered default handlers
* handler that doesn't exist should raise a NameError
* should get unregistered, but already required, handler by name
* should register custom handler
* should not need registration for properly coded handlers even if not already required

== Rack::Head
* response (empty)
* passes GET, POST, PUT, DELETE, OPTIONS, TRACE requests
* removes body from HEAD requests

== Rack::Lint
* passes valid request
* notices fatal errors
* notices environment errors
* notices input errors
* notices error errors
* notices status errors
* notices header errors
* notices content-type errors
* notices content-length errors
* notices body errors
* notices input handling errors
* notices error handling errors
* notices HEAD errors
* passes valid read calls

== Rack::Lint::InputWrapper
* delegates :size to underlying IO object
* delegates :rewind to underlying IO object

== Rack::Lobster::LambdaLobster
* should be a single lambda
* should look like a lobster
* should be flippable

== Rack::Lobster
* should look like a lobster
* should be flippable
* should provide crashing for testing purposes

== Rack::Lock
* should call synchronize on lock
* should set multithread flag to false
* should reset original multithread flag when exiting lock

== Rack::MethodOverride
* should not affect GET requests
* _method parameter should modify REQUEST_METHOD for POST requests
* X-HTTP-Method-Override header should modify REQUEST_METHOD for POST requests
* should not modify REQUEST_METHOD if the method is unknown
* should not modify REQUEST_METHOD when _method is nil
* should store the original REQUEST_METHOD prior to overriding

== Rack::MockRequest
* should return a MockResponse
* should be able to only return the environment
* should provide sensible defaults
* should allow GET/POST/PUT/DELETE
* should set content length
* should allow posting
* should use all parts of an URL
* should behave valid according to the Rack spec

== Rack::MockResponse
* should provide access to the HTTP status
* should provide access to the HTTP headers
* should provide access to the HTTP body
* should provide access to the Rack errors
* should optionally make Rack errors fatal

== Rack::Handler::Mongrel
* should respond
* should be a Mongrel
* should have rack headers
* should have CGI headers on GET
* should have CGI headers on POST
* should support HTTP auth
* should set status
* should provide a .run
* should provide a .run that maps a hash
* should provide a .run that maps a urlmap
* should provide a .run that maps a urlmap restricting by host
* should stream #each part of the response

== Rack::Recursive
* should allow for subrequests
* should raise error on requests not below the app
* should support forwarding

== Rack::Request
* wraps the rack variables
* can figure out the correct host
* can parse the query string
* can parse POST data
* can parse POST data with explicit content type
* does not parse POST data when media type is not form-data
* rewinds input after parsing POST data
* cleans up Safari's ajax POST body
* can get value by key from params with #[]
* can set value to key on params with #[]=
* values_at answers values by keys in order given
* referrer should be extracted correct
* can cache, but invalidates the cache
* can figure out if called via XHR
* can parse cookies
* parses cookies according to RFC 2109
* provides setters
* provides the original env
* can restore the URL
* can restore the full path
* can handle multiple media type parameters
* can parse multipart form data
* can parse big multipart form data
* can detect invalid multipart form data
* shouldn't try to interpret binary as utf8
* should work around buggy 1.8.* Tempfile equality
* does conform to the Rack spec
* should parse Accept-Encoding correctly
* should provide ip information
* should allow subclass request to be instantiated after parent request
* should allow parent request to be instantiated after subclass request

== Rack::Response
* has sensible default values
* can be written to
* can set and read headers
* can set cookies
* formats the Cookie expiration date accordingly to RFC 2109
* can set secure cookies
* can set http only cookies
* can delete cookies
* can do redirects
* has a useful constructor
* has a constructor that can take a block
* doesn't return invalid responses
* knows if it's empty
* should provide access to the HTTP status
* should provide access to the HTTP headers
* does not add or change Content-Length when #finish()ing
* updates Content-Length when body appended to using #write

== Rack::RewindableInput
=== given an IO object that is already rewindable
* should be able to handle to read()
* should be able to handle to read(nil)
* should be able to handle to read(length)
* should be able to handle to read(length, buffer)
* should be able to handle to read(nil, buffer)
* should rewind to the beginning when #rewind is called
* should be able to handle gets
* should be able to handle each
* should not buffer into a Tempfile if no data has been read yet
* should buffer into a Tempfile when data has been consumed for the first time
* should close the underlying tempfile upon calling #close
* should be possibel to call #close when no data has been buffered yet (empty)
* should be possible to call #close multiple times (empty)
=== given an IO object that is not rewindable
* should be able to handle to read()
* should be able to handle to read(nil)
* should be able to handle to read(length)
* should be able to handle to read(length, buffer)
* should be able to handle to read(nil, buffer)
* should rewind to the beginning when #rewind is called
* should be able to handle gets
* should be able to handle each
* should not buffer into a Tempfile if no data has been read yet
* should buffer into a Tempfile when data has been consumed for the first time
* should close the underlying tempfile upon calling #close
* should be possibel to call #close when no data has been buffered yet (empty)
* should be possible to call #close multiple times (empty)
=== given an IO object whose rewind method raises Errno::ESPIPE
* should be able to handle to read()
* should be able to handle to read(nil)
* should be able to handle to read(length)
* should be able to handle to read(length, buffer)
* should be able to handle to read(nil, buffer)
* should rewind to the beginning when #rewind is called
* should be able to handle gets
* should be able to handle each
* should not buffer into a Tempfile if no data has been read yet
* should buffer into a Tempfile when data has been consumed for the first time
* should close the underlying tempfile upon calling #close
* should be possibel to call #close when no data has been buffered yet (empty)
* should be possible to call #close multiple times (empty)

== Rack::Session::Cookie
* creates a new cookie
* loads from a cookie
* survives broken cookies
* barks on too big cookies
* creates a new cookie with integrity hash
* loads from a cookie wih integrity hash
* ignores tampered with session cookies

== Rack::Session::Memcache
* MemCache can connect to existing server (empty)
* faults on no connection
* creates a new cookie
* determines session from a cookie
* survives nonexistant cookies
* maintains freshness
* deletes cookies with :drop option
* provides new session id with :renew option
* omits cookie with :defer option
* multithread: should cleanly merge sessions (empty)

== Rack::Session::Pool
* creates a new cookie
* determines session from a cookie
* survives nonexistant cookies
* deletes cookies with :drop option
* provides new session id with :renew option
* omits cookie with :defer option
* multithread: should merge sessions (empty)

== Rack::ShowExceptions
* catches exceptions

== Rack::ShowStatus
* should provide a default status message
* should let the app provide additional information
* should not replace existing messages
* should pass on original headers
* should replace existing messages if there is detail

== Rack::Static
* serves files
* 404s if url root is known but it can't find the file
* calls down the chain if url root is not known

== Rack::Handler::Thin
* should respond
* should be a Thin
* should have rack headers
* should have CGI headers on GET
* should have CGI headers on POST
* should support HTTP auth
* should set status

== Rack::URLMap
* dispatches paths correctly
* dispatches hosts correctly
* should be nestable
* should route root apps correctly

== Rack::Utils
* should escape correctly
* should escape correctly for multibyte characters
* should unescape correctly
* should parse query strings correctly
* should parse nested query strings correctly
* should build query strings correctly
* should figure out which encodings are acceptable
* should return the bytesize of String

== Rack::Utils::HeaderHash
* should retain header case
* should check existence of keys case insensitively
* should merge case-insensitively
* should overwrite case insensitively and assume the new key's case
* should be converted to real Hash
* should convert Array values to Strings when converting to Hash
* should be able to delete the given key case-sensitively
* should be able to delete the given key case-insensitively
* should return the deleted value when #delete is called on an existing key
* should return nil when #delete is called on a non-existant key

== Rack::Utils::Context
* should set context correctly
* should alter app on recontexting
* should run different apps

== Rack::Utils::Multipart
* should return nil if content type is not multipart
* should parse multipart upload with text file
* should parse multipart upload with nested parameters
* should parse multipart upload with binary file
* should parse multipart upload with empty file
* should parse multipart upload with filename with semicolons
* should not include file params if no file was selected
* should parse IE multipart upload and clean up filename
* rewinds input after parsing upload

== Rack::Handler::WEBrick
* should respond
* should be a WEBrick
* should have rack headers
* should have CGI headers on GET
* should have CGI headers on POST
* should support HTTP auth
* should set status
* should correctly set cookies
* should provide a .run

335 specifications, 13 empty (1196 requirements), 0 failures
