Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Refactors Perfection, every test, and adds Guard

  • Loading branch information...
commit aa5fc01626098e2dc24134b86d76455aa50a8331 1 parent 0d48a8b
Alexander Kern authored
Showing with 1,622 additions and 1,208 deletions.
  1. +0 −5 .autotest
  2. +5 −0 Gemfile
  3. +5 −0 Guardfile
  4. +1 −1  Rakefile
  5. +8 −8 lib/webbed/generic_message.rb
  6. +2 −0  lib/webbed/headers.rb
  7. +12 −12 lib/webbed/helpers/entity_headers_helper.rb
  8. +2 −2 lib/webbed/helpers/rack_request_helper.rb
  9. +4 −2 lib/webbed/helpers/rack_response_helper.rb
  10. +12 −12 lib/webbed/helpers/request_headers_helper.rb
  11. +9 −9 lib/webbed/helpers/response_headers_helper.rb
  12. +8 −11 lib/webbed/http_version.rb
  13. +18 −20 lib/webbed/media_type.rb
  14. +8 −7 lib/webbed/method.rb
  15. +24 −29 lib/webbed/request.rb
  16. +23 −25 lib/webbed/response.rb
  17. +14 −14 lib/webbed/status_code.rb
  18. +17 −0 test/support/assertions.rb
  19. +326 −0 test/support/runner.rb
  20. +8 −1 test/test_helper.rb
  21. +44 −0 test/webbed/generic_message_test.rb
  22. +31 −0 test/webbed/headers_test.rb
  23. +68 −0 test/webbed/helpers/entity_headers_helper_test.rb
  24. +151 −0 test/webbed/helpers/method_helper_test.rb
  25. +48 −0 test/webbed/helpers/rack_request_helper_test.rb
  26. +26 −0 test/webbed/helpers/rack_response_helper_test.rb
  27. +57 −0 test/webbed/helpers/request_headers_helper_test.rb
  28. +32 −0 test/webbed/helpers/request_uri_helper_test.rb
  29. +46 −0 test/webbed/helpers/response_headers_helper_test.rb
  30. +28 −0 test/webbed/helpers/scheme_helper_test.rb
  31. +0 −64 test/webbed/helpers/test_entity_headers_helper.rb
  32. +0 −147 test/webbed/helpers/test_method_helper.rb
  33. +0 −44 test/webbed/helpers/test_rack_request_helper.rb
  34. +0 −22 test/webbed/helpers/test_rack_response_helper.rb
  35. +0 −53 test/webbed/helpers/test_request_headers_helper.rb
  36. +0 −28 test/webbed/helpers/test_request_uri_helper.rb
  37. +0 −42 test/webbed/helpers/test_response_headers_helper.rb
  38. +0 −24 test/webbed/helpers/test_scheme_helper.rb
  39. +52 −0 test/webbed/http_version_test.rb
  40. +100 −0 test/webbed/media_type_test.rb
  41. +160 −0 test/webbed/method_test.rb
  42. +74 −0 test/webbed/request_test.rb
  43. +86 −0 test/webbed/response_test.rb
  44. +105 −0 test/webbed/status_code_test.rb
  45. +0 −42 test/webbed/test_generic_message.rb
  46. +0 −29 test/webbed/test_headers.rb
  47. +0 −47 test/webbed/test_http_version.rb
  48. +0 −98 test/webbed/test_media_type.rb
  49. +0 −158 test/webbed/test_method.rb
  50. +0 −70 test/webbed/test_request.rb
  51. +0 −72 test/webbed/test_response.rb
  52. +0 −106 test/webbed/test_status_code.rb
  53. +8 −4 webbed.gemspec
View
5 .autotest
@@ -1,5 +0,0 @@
-require 'bundler/setup'
-
-Autotest.add_hook :initialize do |at|
- at.testlib = 'minitest/unit'
-end
View
5 Gemfile
@@ -1,2 +1,7 @@
source :gemcutter
+
+# This is temporary until guard-minitest accepts my patch.
+gem 'guard-minitest', :git => 'git://github.com/CapnKernul/guard-minitest.git'
+gem 'rb-fsevent'
+
gemspec
View
5 Guardfile
@@ -0,0 +1,5 @@
+guard 'minitest', :notify => true do
+ watch(/^test\/(.*)_test.rb/)
+ watch(/^lib\/(.*)\.rb/) { |m| "test/#{m[1]}_test.rb" }
+ watch(/^test\/test_helper.rb/) { 'test' }
+end
View
2  Rakefile
@@ -7,5 +7,5 @@ require 'rake/testtask'
Rake::TestTask.new do |t|
t.ruby_opts += ['-rubygems']
t.libs << 'test'
- t.pattern = 'test/**/test_*.rb'
+ t.pattern = 'test/**/*_test.rb'
end
View
16 lib/webbed/generic_message.rb
@@ -1,9 +1,9 @@
module Webbed
- # Generic methods used for both {Request}'s and {Response}'s
+ # Generic methods used for both {Request}'s and {Response}'s.
#
# @abstract Include and implement `#status_line`.
module GenericMessage
- # The HTTP-Version of the message
+ # The HTTP-Version of the message.
#
# The method automatically converts the new value to an instance of
# {HTTPVersion} if it is not already one.
@@ -11,11 +11,11 @@ module GenericMessage
# @return [HTTPVersion]
attr_reader :http_version
- def http_version=(new_http_version)
- @http_version = Webbed::HTTPVersion.new(new_http_version)
+ def http_version=(http_version)
+ @http_version = Webbed::HTTPVersion.new(http_version)
end
- # The Headers of the message
+ # The Headers of the message.
#
# The method automatically converts the new value to an instance of
# {Headers} if it is not already one.
@@ -23,11 +23,11 @@ def http_version=(new_http_version)
# @return [Headers]
attr_reader :headers
- def headers=(new_headers)
- @headers = Webbed::Headers.new(new_headers)
+ def headers=(headers)
+ @headers = Webbed::Headers.new(headers)
end
- # The Entity Body of the message
+ # The Entity Body of the message.
#
# @return [#to_s]
attr_accessor :entity_body
View
2  lib/webbed/headers.rb
@@ -1,4 +1,6 @@
module Webbed
+ # Representation of HTTP headers.
+ #
# This class is stolen directly from Rack.
class Headers < Hash
def self.new(hash={})
View
24 lib/webbed/helpers/entity_headers_helper.rb
@@ -11,9 +11,9 @@ def content_length
# Sets the Content-Length of the Entity (as defined in the Content-Length Header).
#
- # @param [#to_s] new_content_length
- def content_length=(new_content_length)
- headers['Content-Length'] = new_content_length.to_s
+ # @param [#to_s] content_length
+ def content_length=(content_length)
+ headers['Content-Length'] = content_length.to_s
end
# The Content-Location of the Entity (as defined in the Content-Location Header).
@@ -25,9 +25,9 @@ def content_location
# Sets the Content-Location of the Entity (as defined in the Content-Location Header).
#
- # @param [#to_s] new_content_location
- def content_location=(new_content_location)
- headers['Content-Location'] = new_content_location.to_s
+ # @param [#to_s] content_location
+ def content_location=(content_location)
+ headers['Content-Location'] = content_location.to_s
end
# The Content-MD5 of the Entity (as defined in the Content-MD5 Header).
@@ -39,9 +39,9 @@ def content_md5
# Sets the Content-MD5 of the Entity (as defined in the Content-MD5 Header).
#
- # @param [String] new_content_md5
- def content_md5=(new_content_md5)
- headers['Content-MD5'] = new_content_md5
+ # @param [String] content_md5
+ def content_md5=(content_md5)
+ headers['Content-MD5'] = content_md5
end
# The Content-Type of the Entity (as defined in the Content-Type Header).
@@ -53,9 +53,9 @@ def content_type
# Sets the Content-Type of the Entity (as defined in the Content-Type Header).
#
- # @param [#to_s] new_content_type
- def content_type=(new_content_type)
- headers['Content-Type'] = new_content_type.to_s
+ # @param [#to_s] content_type
+ def content_type=(content_type)
+ headers['Content-Type'] = content_type.to_s
end
end
end
View
4 lib/webbed/helpers/rack_request_helper.rb
@@ -29,7 +29,7 @@ def from_rack(rack_env)
headers['Content-Type'] = env.delete('CONTENT_TYPE')
headers['Content-Length'] = env.delete('CONTENT_LENGTH')
- request = new([method, request_uri, headers, entity_body], {
+ request = new(method, request_uri, headers, entity_body, {
:http_version => http_version,
:scheme => scheme
})
@@ -55,4 +55,4 @@ def self.included(base)
end
end
end
-end
+end
View
6 lib/webbed/helpers/rack_response_helper.rb
@@ -19,8 +19,10 @@ def to_rack
# Converts the Response to an array
#
- # The array has the same format as the one that you use in order to create
- # a Response.
+ # The array has a similar format to the format defined in the Rack specification with some modifications:
+ #
+ # 1. The Reason Phrase is included with the Status Code.
+ # 2. The Entity Body does not need to respond to `#each`.
#
# @return [Array]
# @note This will *not* return a Rack-compatible response array.
View
24 lib/webbed/helpers/request_headers_helper.rb
@@ -11,9 +11,9 @@ def host
# Sets the Host of the Request (as defined in the Host Header)
#
- # @param [String] new_host
- def host=(new_host)
- headers['Host'] = new_host
+ # @param [String] host
+ def host=(host)
+ headers['Host'] = host
end
# The From email of the Request (as defined in the From Header)
@@ -25,9 +25,9 @@ def from
# Sets the From email of the Request (as defined in the From Header)
#
- # @param [String] new_from
- def from=(new_from)
- headers['From'] = new_from
+ # @param [String] from
+ def from=(from)
+ headers['From'] = from
end
# The Max-Forwards of the Request (as defined in the Max-Forwards Header)
@@ -39,9 +39,9 @@ def max_forwards
# Sets the Max-Forwards of the Request (as defined in the Max-Forwards Header)
#
- # @param [#to_s] new_max_forwards
- def max_forwards=(new_max_forwards)
- headers['Max-Forwards'] = new_max_forwards.to_s
+ # @param [#to_s] max_forwards
+ def max_forwards=(max_forwards)
+ headers['Max-Forwards'] = max_forwards.to_s
end
# The Referer of the Request (as defined in the Referer Header)
@@ -53,9 +53,9 @@ def referer
# Sets the Referer of the Request (as defined in the Referer Header)
#
- # @param [#to_s] new_referer
- def referer=(new_referer)
- headers['Referer'] = new_referer.to_s
+ # @param [#to_s] referer
+ def referer=(referer)
+ headers['Referer'] = referer.to_s
end
end
end
View
18 lib/webbed/helpers/response_headers_helper.rb
@@ -11,9 +11,9 @@ def etag
# Sets the ETag of the Response (as defined in the ETag Header)
#
- # @param [String] new_etag
- def etag=(new_etag)
- headers['ETag'] = new_etag
+ # @param [String] etag
+ def etag=(etag)
+ headers['ETag'] = etag
end
# The Age of the Response (as defined in the Age Header)
@@ -25,9 +25,9 @@ def age
# Sets the Age of the Response (as defined in the Age Header)
#
- # @param [#to_s] new_age
- def age=(new_age)
- headers['Age'] = new_age.to_s
+ # @param [#to_s] age
+ def age=(age)
+ headers['Age'] = age.to_s
end
# The Location of the Response (as defined in the Location Header)
@@ -39,9 +39,9 @@ def location
# Sets the Location of the Response (as defined in the Location Header)
#
- # @param [#to_s] new_location
- def location=(new_location)
- headers['Location'] = new_location.to_s
+ # @param [#to_s] location
+ def location=(location)
+ headers['Location'] = location.to_s
end
end
end
View
19 lib/webbed/http_version.rb
@@ -1,4 +1,6 @@
module Webbed
+ # Representation of an HTTP HTTP Version.
+ #
# Webbed supports both primary versions of HTTP, HTTP/1.0 and HTTP/1.1.
# Although the use of HTTP/1.1 has been strongly encouraged since its creation
# in 1999, it remains relatively common for older command line tools (such as
@@ -20,11 +22,9 @@ module Webbed
class HTTPVersion
include Comparable
- # Regular expression for retrieving the major and minor version numbers from
- # an HTTP-Version
REGEX = /^HTTP\/(\d+)\.(\d+)$/
- # Creates a new HTTP-Version
+ # Creates a new HTTP-Version.
#
# Only HTTP/1.0 and HTTP/1.1 versions are cached. All other versions will be
# created at runtime each time this method is called.
@@ -42,7 +42,7 @@ def initialize(http_version)
end
end
- # Converts the HTTP-Version to a string according to RFC 2616
+ # Converts the HTTP-Version to a string according to RFC 2616.
#
# @example
# version = Webbed::HTTPVersion.new(1.1)
@@ -53,7 +53,7 @@ def to_s
@http_version
end
- # Converts the HTTP-Version to a float
+ # Converts the HTTP-Version to a float.
#
# @example
# version = Webbed::HTTPVersion.new('HTTP/1.1')
@@ -65,7 +65,7 @@ def to_f
"#{$1}.#{$2}".to_f
end
- # Compares the HTTP-Version to another HTTP-Version
+ # Compares the HTTP-Version to another HTTP-Version.
#
# @example
# version_1_1 = Webbed::HTTPVersion.new(1.1)
@@ -80,7 +80,7 @@ def <=>(other_http_version)
to_f <=> other_http_version.to_f
end
- # The major HTTP-Version number
+ # The major HTTP-Version number.
#
# @example
# version = Webbed::HTTPVersion.new('HTTP/6.9')
@@ -92,7 +92,7 @@ def major
$1.to_i
end
- # The minor HTTP-Version number
+ # The minor HTTP-Version number.
#
# @example
# version = Webbed::HTTPVersion.new('HTTP/4.2')
@@ -104,10 +104,7 @@ def minor
$2.to_i
end
- # HTTP/1.1
ONE_POINT_ONE = HTTPVersion.new(1.1)
-
- # HTTP/1.0
ONE_POINT_OH = HTTPVersion.new(1.0)
end
end
View
38 lib/webbed/media_type.rb
@@ -1,6 +1,10 @@
module Webbed
+ # Representation of an HTTP Media Type.
class MediaType
- # The type of the MIME type
+ MIME_TYPE_REGEX = /^([-\w.+]+)\/([-\w.+]*)$/
+ PARAMETERS_REGEX = /=|\s*;\s*/
+
+ # The type of the MIME type.
#
# According to RFC 2616, this is the part *before* the slash.
#
@@ -11,7 +15,7 @@ class MediaType
# @return [String]
attr_accessor :type
- # The subtype of the MIME type
+ # The subtype of the MIME type.
#
# According to RFC 2616, this is the *after* before the slash.
#
@@ -22,7 +26,7 @@ class MediaType
# @return [String]
attr_accessor :subtype
- # The parameters of the Media Type
+ # The parameters of the Media Type.
#
# According to RFC 2616, parameters are separated from the MIME type and
# each other using a semicolon.
@@ -34,13 +38,7 @@ class MediaType
# @return [Hash{String => String}]
attr_accessor :parameters
- # Regular expression for parsing the type and subtype of a MIME type
- MIME_TYPE_REGEX = /^([-\w.+]+)\/([-\w.+]*)$/
-
- # Regular expression for parsing the parameters of a Media Type
- PARAMETERS_REGEX = /=|\s*;\s*/
-
- # Creates a new Media Type
+ # Creates a new Media Type.
#
# @example Create a MediaType without parameters
# media_type = Webbed::MediaType.new('text/html')
@@ -58,23 +56,23 @@ def initialize(media_type)
self.parameters = Hash[*parameters] || {}
end
- # The MIME type of the Media Type
+ # The MIME type of the Media Type.
#
# @return [String]
def mime_type
"#{type}/#{subtype}"
end
- # Sets the MIME type of the Media Type
+ # Sets the MIME type of the Media Type.
#
- # @param [String] new_mime_type
- def mime_type=(new_mime_type)
- MIME_TYPE_REGEX =~ new_mime_type
+ # @param [String] mime_type
+ def mime_type=(mime_type)
+ MIME_TYPE_REGEX =~ mime_type
self.type = $1
self.subtype = $2
end
- # Converts the Media Type to a string
+ # Converts the Media Type to a string.
#
# @return [String]
def to_s
@@ -86,7 +84,7 @@ def to_s
end
end
- # Whether or not the Media Type is vendor-specific
+ # Whether or not the Media Type is vendor-specific.
#
# The method uses the `vnd.` prefix convention to determine whether or not
# it was created for a specific vendor.
@@ -103,7 +101,7 @@ def vendor_specific?
subtype[0..3] == 'vnd.'
end
- # The suffix of the MIME type
+ # The suffix of the MIME type.
#
# Suffixes follow the convention set forth by the Atom specification:
# separated from the rest of the MIME Type by a `+`.
@@ -126,7 +124,7 @@ def suffix
end
end
- # Compares the Media Type to another Media Type
+ # Compares the Media Type to another Media Type.
#
# Two Media Types are equal if their `#mime_type`'s are equal.
#
@@ -136,7 +134,7 @@ def ==(other_media_type)
mime_type == other_media_type.mime_type
end
- # The MIME types that the Media Type can be interpreted as
+ # The MIME types that the Media Type can be interpreted as.
#
# This uses the suffix to generate a list of MIME types that can be used to
# interpret the Media Type. It's useful if you need to be able to parse XML
View
15 lib/webbed/method.rb
@@ -1,4 +1,5 @@
module Webbed
+ # Representation of an HTTP Method.
class Method
DEFAULTS = {
:safe => false,
@@ -6,14 +7,14 @@ class Method
:allowable_entities => [:request, :response]
}
- # The allowable entities of a message
+ # The allowable entities of a message.
#
# It can contain any combination of `:request` and `:response`.
#
# @return [Array<:request, :response>]
attr_reader :allowable_entities
- # Checks for a cached Method or creates a new one
+ # Checks for a cached Method or creates a new one.
#
# It caches the standard HTTP Methods that are in RFC 2616 as well as the
# new method `PATCH`. If the Method cannot be found, it calls `#initialize`.
@@ -32,7 +33,7 @@ def self.new(value, options = {})
end
end
- # Creates a new Method
+ # Creates a new Method.
#
# @param [String] name the name of the Method to create
# @param [Hash] options the options to create the Method with
@@ -49,28 +50,28 @@ def initialize(name, options = {})
@allowable_entities = options[:allowable_entities]
end
- # Whether or not the Method is safe
+ # Whether or not the Method is safe.
#
# @return [Boolean]
def safe?
@safe
end
- # Whether or not the Method is idempotent
+ # Whether or not the Method is idempotent.
#
# @return [Boolean]
def idempotent?
@idempotent
end
- # Converts the Method to a string
+ # Converts the Method to a string.
#
# @return [String]
def to_s
@name
end
- # Compares the Method to another Method
+ # Compares the Method to another Method.
#
# Two Methods are equal if they have the same name.
#
View
53 lib/webbed/request.rb
@@ -1,14 +1,14 @@
require 'addressable/uri'
module Webbed
- # Representation of an HTTP Request
+ # Representation of an HTTP Request.
#
# This class contains the absolute minimum for accessing the different parts
# of an HTTP Request. Helper modules provide far more functionality.
class Request
include GenericMessage
- # The Request-URI of the Request
+ # The Request-URI of the Request.
#
# The method automatically converts the new value to an instance of
# `Addressable::URI` if it is not already one.
@@ -17,46 +17,41 @@ class Request
# @note {Helpers::RequestURIHelper} aliases this method to `#request_url`.
attr_reader :request_uri
- def request_uri=(new_request_uri)
- @request_uri = Addressable::URI.parse(new_request_uri)
+ def request_uri=(request_uri)
+ @request_uri = Addressable::URI.parse(request_uri)
end
- # The scheme of the Request
+ # The scheme of the Request.
#
# @return ['http', 'https']
attr_accessor :scheme
- # Creates a new Request
- #
- # The attributes of the Request are passed in as an array. In order, they
- # go:
- #
- # 1. Method
- # 2. Request-URI
- # 3. Headers
- # 4. Entity Body
+ # Creates a new Request.
#
# The method converts the values passed in to their proper types.
#
# @example
- # Webbed::Request.new(['GET', 'http://example.com', {}, ''])
+ # Webbed::Request.new('GET', 'http://example.com', {}, '')
#
- # @param [Array] request_array
+ # @param [Method, String] method
+ # @param [Addressable::URI, String] request_uri
+ # @param [Headers, Hash] headers
+ # @param [#to_s] entity_body
# @param [Array] options the options to create the Request with
# @option options [#to_s] :http_version (1.1) the HTTP-Version of the
# Request
# @option options ['http', 'https'] :scheme ('http') the scheme of the
# Request
- def initialize(request_array, options = {})
- self.method = request_array[0]
- self.request_uri = request_array[1]
- self.headers = request_array[2]
- self.entity_body = request_array[3]
- self.http_version = options.delete(:http_version) || 1.1
- self.scheme = options.delete(:scheme) || 'http'
+ def initialize(method, request_uri, headers, entity_body, options = {})
+ self.method = method
+ self.request_uri = request_uri
+ self.headers = headers
+ self.entity_body = entity_body
+ self.http_version = options[:http_version] || 1.1
+ self.scheme = options[:scheme] || 'http'
end
- # The {Method} of the Request
+ # The Method of the Request.
#
# @return [Method]
def method(*args)
@@ -64,14 +59,14 @@ def method(*args)
@method
end
- # Sets the {Method} of the Request
+ # Sets the Method of the Request.
#
- # @param [Method] new_method
- def method=(new_method)
- @method = Webbed::Method.new(new_method)
+ # @param [Method] method
+ def method=(method)
+ @method = Webbed::Method.new(method)
end
- # The Request-Line of the Request as defined in RFC 2616
+ # The Request-Line of the Request as defined in RFC 2616.
#
# @example
# request = Webbed::Request.new(['GET', 'http://example.com', {}, ''])
View
48 lib/webbed/response.rb
@@ -1,15 +1,14 @@
module Webbed
- # Representation of an HTTP Response
+ # Representation of an HTTP Response.
#
# This class contains the absolute minimum for accessing the different parts
# of an HTTP Response. Helper modules provide far more functionality.
class Response
include GenericMessage
- # Regular expression for separating a Status Code and a Reason Phrase
STATUS_CODE_REGEX = /^(\d{3}) (.*)$/
- # The Status Code of the Response
+ # The Status Code of the Response.
#
# The method automatically converts the new value to an instance of
# {StatusCode} if it is not already one.
@@ -21,52 +20,51 @@ def status_code=(status_code)
@status_code = Webbed::StatusCode.new(status_code)
end
- # The Reason Phrase of the Response
+ # The Reason Phrase of the Response.
#
# The method returns the Status Code's default reason phrase if the Reason
# Phrase has not already been set.
#
# @return [String]
def reason_phrase
- @reason_phrase || @status_code.default_reason_phrase
+ defined?(@reason_phrase) ? @reason_phrase : @status_code.default_reason_phrase
end
attr_writer :reason_phrase
- # Creates a new Response
+ # Creates a new Response.
#
- # The attributes of the Response are passed in as an array. In order, they
- # go:
- #
- # 1. Status Code (and Reason Phrase if a string)
- # 2. Headers
- # 3. Entity Body
+ # The Status Code may be passed in as a string with a Reason Phrase or just
+ # a number. If a number is provided, the default Reason Phrase for that
+ # Status Code is used.
#
# The method converts the values passed in to their proper types.
#
# @example
- # Webbed::Response.new([200, {}, ''])
- # Webbed::Response.new(['404 Missing File', {}, ''])
+ # Webbed::Response.new(200, {}, '')
+ # Webbed::Response.new('404 Missing File', {}, '')
#
- # @param [Array] response_array
- # @param [Array] options the options to create the Response with
- # @option options [#to_s] :http_version (1.1) the HTTP-Version of the
+ # @param [Fixnum, String] status_code
+ # @param [Headers, Hash] headers
+ # @param [#to_s] entity_body
+ # @param [Array] options the options to create the Response with @option
+ # @options options [#to_s] :http_version (1.1) the HTTP-Version of the
# Response
- def initialize(response_array, options = {})
- self.http_version = options.delete(:http_version) || 1.1
-
- if STATUS_CODE_REGEX =~ response_array[0].to_s
+ def initialize(status_code, headers, entity_body, options = {})
+ if STATUS_CODE_REGEX =~ status_code.to_s
self.status_code = $1
self.reason_phrase = $2
else
- self.status_code = response_array[0]
+ self.status_code = status_code
end
- self.headers = response_array[1]
- self.entity_body = response_array[2]
+ self.headers = headers
+ self.entity_body = entity_body
+
+ self.http_version = options.delete(:http_version) || 1.1
end
- # The Status-Line of the Response
+ # The Status-Line of the Response.
#
# @example
# response = Webbed::Response.new([200, {}, ''])
View
28 lib/webbed/status_code.rb
@@ -1,5 +1,5 @@
module Webbed
- # Representation of HTTP Status Codes
+ # Representation of an HTTP Status Code.
class StatusCode
include Comparable
@@ -49,12 +49,12 @@ class StatusCode
@@cached = {}
- # The default Reason Phrase of the Status Code
+ # The default Reason Phrase of the Status Code.
#
# @return [String]
attr_reader :default_reason_phrase
- # Retrieves a Status Code from the cache or creates a new one
+ # Retrieves a Status Code from the cache or creates a new one.
#
# All created Status Codes are cached forever.
#
@@ -66,7 +66,7 @@ def self.new(status_code)
@@cached[status_code] ||= super(status_code)
end
- # Creates a new Status Code
+ # Creates a new Status Code.
#
# @param [Fixnum] status_code
def initialize(status_code)
@@ -74,7 +74,7 @@ def initialize(status_code)
@default_reason_phrase = REASON_PHRASES[@status_code] || UNKNOWN_REASON_PHRASE
end
- # Comparse the Status Code to another Status Code
+ # Comparse the Status Code to another Status Code.
#
# @param [#to_i] other_status_code the other Status Code
# @return [Fixnum] the sign of the comparison (either `1`, `0`, or `-1`)
@@ -82,21 +82,21 @@ def <=>(other_status_code)
@status_code <=> other_status_code.to_i
end
- # Converts the Status Code to an integer
+ # Converts the Status Code to an integer.
#
# @return [Fixnum]
def to_i
@status_code
end
- # Converts the Status Code to a string
+ # Converts the Status Code to a string.
#
# @return [String]
def to_s
@status_code.to_s
end
- # Whether or not the Status Code is informational
+ # Whether or not the Status Code is informational.
#
# According to RFC 2616, informational status codes are in the range of 100
# to 199, inclusive.
@@ -106,7 +106,7 @@ def informational?
(100...200).include?(@status_code)
end
- # Whether or not the Status Code is successful
+ # Whether or not the Status Code is successful.
#
# According to RFC 2616, successful status codes are in the range of 200 to
# 299, inclusive.
@@ -116,7 +116,7 @@ def successful?
(200...300).include?(@status_code)
end
- # Whether or not the Status Code is a redirection
+ # Whether or not the Status Code is a redirection.
#
# According to RFC 2616, redirection status codes are in the range of 300 to
# 399, inclusive.
@@ -126,7 +126,7 @@ def redirection?
(300...400).include?(@status_code)
end
- # Whether or not the Status Code is a client error
+ # Whether or not the Status Code is a client error.
#
# According to RFC 2616, client error status codes are in the range of 400
# to 499, inclusive.
@@ -136,7 +136,7 @@ def client_error?
(400...500).include?(@status_code)
end
- # Whether or not the Status Code is a server error
+ # Whether or not the Status Code is a server error.
#
# According to RFC 2616, server error status codes are in the range of 500
# to 599, inclusive.
@@ -146,7 +146,7 @@ def server_error?
(500...600).include?(@status_code)
end
- # Whether or not the Status Code is unknown
+ # Whether or not the Status Code is unknown.
#
# According to RFC 2616, the only defined Status Code ranges are from 100 to
# 599, inclusive. Anything outside that range is an unknown Status Code.
@@ -156,7 +156,7 @@ def unknown?
!(100...600).include?(@status_code)
end
- # Whether or not the Status Code is an error
+ # Whether or not the Status Code is an error.
#
# According to RFC 2616, Status Codes that signify errors are in the range
# of 400 to 599, inclusive.
View
17 test/support/assertions.rb
@@ -0,0 +1,17 @@
+module WebbedTest
+ module Assertions
+ def assert_comparable(smaller, larger)
+ assert_operator smaller, :<, larger
+ assert_operator smaller, :<=, larger
+
+ refute_operator larger, :<, smaller
+ refute_operator larger, :<=, smaller
+
+ assert_operator larger, :>, smaller
+ assert_operator larger, :>=, smaller
+
+ refute_operator smaller, :>, larger
+ refute_operator smaller, :>=, larger
+ end
+ end
+end
View
326 test/support/runner.rb
@@ -0,0 +1,326 @@
+require 'minitest/unit'
+require 'ansi'
+require 'progressbar'
+
+# Code has been borrowed and modified from MiniTest, written by Ryan Davis of
+# Seattle.rb. MiniTest is licensed under the MIT License, and can be found on
+# GitHub at https://github.com/seattlerb/minitest.
+#
+# This code is also heavily based upon these gists as well:
+# * https://gist.github.com/356945
+# * https://gist.github.com/960669
+#
+# TODO: Add documentation to everything.
+
+module Perfection
+ class Reporter
+ def runner
+ Perfection::Runner.runner
+ end
+
+ def print(*args)
+ runner.output.print(*args)
+ end
+
+ def puts(*args)
+ runner.output.puts(*args)
+ end
+
+ def before_suites(suites); end
+ def after_suites(suites); end
+ def before_suite(suite); end
+ def after_suite(suite); end
+ def before_test(suite, test); end
+ def pass(suite, test); end
+ def skip(suite, test, e); end
+ def failure(suite, test, e); end
+ def error(suite, test, e); end
+ end
+
+ # Takes a signficant amount of code from Jef Kreefmeijer's Fuubar. Fuubar is
+ # licensed under the MIT License and can be found at:
+ # https://github.com/jeffkreeftmeijer/fuubar.
+ class ProgressReporter < Reporter
+ include ANSI::Code
+
+ INFO_PADDING = 2
+
+ def before_suites(suites)
+ puts 'Started'
+ puts
+
+ @color = GREEN
+ @finished_count = 0
+ @progress = ProgressBar.new("0/#{runner.test_count}", runner.test_count, runner.output)
+ @progress.bar_mark = '='
+ end
+
+ def increment
+ with_color do
+ @finished_count += 1
+ @progress.instance_variable_set('@title', "#{@finished_count}/#{runner.test_count}")
+ @progress.inc
+ end
+ end
+
+ def pass(suite, test)
+ increment
+ end
+
+ def skip(suite, test, e)
+ @color = YELLOW unless @color == RED
+ print(yellow { 'SKIP' })
+ print_test_with_time(suite, test)
+ puts
+ puts
+ increment
+ end
+
+ def failure(suite, test, e)
+ @color = RED
+ print(red { 'FAIL' })
+ print_test_with_time(suite, test)
+ puts
+ print_info(e)
+ puts
+ increment
+ end
+
+ def error(suite, test, e)
+ @color = RED
+ print(red { 'ERROR' })
+ print_test_with_time(suite, test)
+ puts
+ print_info(e)
+ puts
+ increment
+ end
+
+ def after_suites(suites)
+ with_color { @progress.finish }
+
+ total_time = Time.now - runner.start_time
+
+ puts
+ puts('Finished in %.5fs' % total_time)
+ print('%d tests, %d assertions, ' % [runner.test_count, runner.assertion_count])
+ print(red { '%d failures, %d errors, ' } % [runner.failures, runner.errors])
+ print(yellow { '%d skips' } % runner.skips)
+ puts
+ end
+
+ private
+
+ def print_test_with_time(suite, test)
+ total_time = Time.now - runner.test_start_time
+ print(" #{suite}##{test} (%.2fs)#{clr}" % total_time)
+ end
+
+ def print_info(e)
+ e.message.each_line { |line| puts pad(line) }
+
+ trace = MiniTest.filter_backtrace(e.backtrace)
+ trace.each { |line| puts pad(line) }
+ end
+
+ def pad(str)
+ ' ' * INFO_PADDING + str
+ end
+
+ def with_color
+ print @color
+ yield
+ print CLEAR
+ end
+ end
+
+ class SpecReporter < Reporter
+ include ANSI::Code
+
+ TEST_PADDING = 2
+ INFO_PADDING = 8
+ MARK_SIZE = 5
+
+ def before_suites(suites)
+ puts 'Started'
+ puts
+ end
+
+ def after_suites(suites)
+ total_time = Time.now - runner.start_time
+
+ puts('Finished in %.5fs' % total_time)
+ print('%d tests, %d assertions, ' % [runner.test_count, runner.assertion_count])
+ print(red { '%d failures, %d errors, ' } % [runner.failures, runner.errors])
+ print(yellow { '%d skips' } % runner.skips)
+ puts
+ end
+
+ def before_suite(suite)
+ puts suite
+ end
+
+ def after_suite(suite)
+ puts
+ end
+
+ def pass(suite, test)
+ print(green { pad_mark('PASS') })
+ print_test_with_time(test)
+ puts
+ end
+
+ def skip(suite, test, e)
+ print(yellow { pad_mark('SKIP') })
+ print_test_with_time(test)
+ puts
+ end
+
+ def failure(suite, test, e)
+ print(red { pad_mark('FAIL') })
+ print_test_with_time(test)
+ puts
+ print_info(e)
+ puts
+ end
+
+ def error(suite, test, e)
+ print(red { pad_mark('ERROR') })
+ print_test_with_time(test)
+ puts
+ print_info(e)
+ puts
+ end
+
+ private
+
+ def print_test_with_time(test)
+ total_time = Time.now - runner.test_start_time
+ print(" #{test} (%.2fs)" % total_time)
+ end
+
+ def print_info(e)
+ e.message.each_line { |line| puts pad(line, INFO_PADDING) }
+
+ trace = MiniTest.filter_backtrace(e.backtrace)
+ trace.each { |line| puts pad(line, INFO_PADDING) }
+ end
+
+ def pad(str, size)
+ ' ' * size + str
+ end
+
+ def pad_mark(str)
+ pad("%#{MARK_SIZE}s" % str, TEST_PADDING)
+ end
+ end
+
+ class Runner < MiniTest::Unit
+ class << self
+ attr_writer :reporter
+
+ def reporter
+ @reporter ||= ProgressReporter.new
+ end
+ end
+
+ attr_accessor :suite_start_time, :test_start_time
+
+ def reporter
+ self.class.reporter
+ end
+
+ def puke(suite, method, e)
+ case e
+ when MiniTest::Skip then
+ @skips += 1
+ [:skip, e]
+ when MiniTest::Assertion then
+ @failures += 1
+ [:failure, e]
+ else
+ @errors += 1
+ [:error, e]
+ end
+ end
+
+ def _run_anything(type)
+ suites = TestCase.send("#{type}_suites")
+ return if suites.empty?
+
+ @test_count = suites.inject(0) { |acc, suite| acc + suite.send("#{type}_methods").length }
+ @assertion_count = 0
+
+ @start_time = Time.now
+ reporter.before_suites(suites)
+ fix_sync { _run_suites(suites, type) }
+ reporter.after_suites(suites)
+ end
+
+ def _run_suites(suites, type)
+ suites.each { |suite| _run_suite(suite, type) }
+ end
+
+ def _run_suite(suite, type)
+ run_suite_header(suite, type)
+
+ filter = options[:filter] || '/./'
+ filter = Regexp.new($1) if filter =~ /\/(.*)\//
+
+ tests = suite.send("#{type}_methods").grep(filter)
+
+ unless tests.empty?
+ @suite_start_time = Time.now
+ reporter.before_suite(suite)
+ _run_tests(suite, tests)
+ reporter.after_suite(suite)
+ end
+ end
+
+ private
+
+ def run_suite_header(suite, type)
+ header_method = "#{type}_suite_header"
+ send(header_method, suite) if respond_to?(header_method)
+ end
+
+ def _run_tests(suite, tests)
+ suite.startup if suite.respond_to?(:startup)
+ tests.each { |test| _run_test(suite, test) }
+ ensure
+ suite.shutdown if suite.respond_to?(:shutdown)
+ end
+
+ def _run_test(suite, test)
+ @test_start_time = Time.now
+ reporter.before_test(suite, test)
+
+ suite_instance = suite.new(test)
+ suite_instance._assertions = 0
+
+ result = fix_result(suite_instance.run(self))
+ @assertion_count += suite_instance._assertions
+
+ case result[0]
+ when :pass then reporter.pass(suite, test)
+ when :skip then reporter.skip(suite, test, result[1])
+ when :failure then reporter.failure(suite, test, result[1])
+ else reporter.error(suite, test, result[1])
+ end
+ end
+
+ def fix_result(result)
+ result == '.' ? [:pass, nil] : result
+ end
+
+ def fix_sync
+ sync = output.respond_to?(:'sync=') # stupid emacs
+ old_sync, output.sync = output.sync, true if sync
+ yield
+ output.sync = old_sync if sync
+ end
+ end
+end
+
+Perfection::Runner.runner = Perfection::Runner.new
+Perfection::Runner.reporter = Perfection::ProgressReporter.new
View
9 test/test_helper.rb
@@ -1,6 +1,13 @@
require 'bundler/setup'
require 'minitest/autorun'
require 'mocha'
+require 'test_declarative'
require 'webbed'
-Dir[File.dirname(__FILE__) + '/support/**/*.rb'].each { |f| require f }
+Dir[File.dirname(__FILE__) + '/support/**/*.rb'].each { |f| require f }
+
+module WebbedTest
+ class TestCase < MiniTest::Unit::TestCase
+ include Assertions
+ end
+end
View
44 test/webbed/generic_message_test.rb
@@ -0,0 +1,44 @@
+require 'test_helper'
+
+module WebbedTest
+ class GenericMessageTest < TestCase
+ def setup
+ @klass = Class.new
+ @klass.instance_eval { include Webbed::GenericMessage }
+ @message = @klass.new
+ end
+
+ test '#initialize' do
+ assert_nil @message.http_version
+ assert_nil @message.headers
+ assert_nil @message.entity_body
+ end
+
+ test '#http_version' do
+ @message.http_version = 'HTTP/1.0'
+
+ assert_instance_of Webbed::HTTPVersion, @message.http_version
+ assert_equal 1.0, @message.http_version
+ end
+
+ test '#headers' do
+ @message.headers = { 'Host' => 'foo.com' }
+
+ assert_instance_of Webbed::Headers, @message.headers
+ assert_equal 'foo.com', @message.headers['Host']
+ end
+
+ test '#entity_body' do
+ @message.entity_body = 'foo'
+ assert_equal 'foo', @message.entity_body
+ end
+
+ test '#to_s' do
+ @message.expects(:start_line).returns("Start Line\r\n")
+ @message.expects(:headers).returns("Headers\r\n")
+ @message.expects(:entity_body).returns('Entity Body')
+
+ assert_equal "Start Line\r\nHeaders\r\n\r\nEntity Body", @message.to_s
+ end
+ end
+end
View
31 test/webbed/headers_test.rb
@@ -0,0 +1,31 @@
+require 'test_helper'
+
+# TODO: Add more tests to this. Since it was stolen from Rack, I'm pretty darn
+# sure that it works correctly. Still, as a matter of principle, it should have
+# all the necessary tests to make sure it works correctly when it changes. But
+# yeah, very low priority at the moment.
+module WebbedTest
+ class HeadersTest < TestCase
+ test '#initialize without headers' do
+ assert Webbed::Headers.new.empty?
+ end
+
+ test '#initialize with headers' do
+ headers = Webbed::Headers.new({ 'Host' => 'foo.com' })
+
+ refute headers.empty?
+ assert_equal 'foo.com', headers['Host']
+ assert_equal 'foo.com', headers['host']
+ assert_equal 'foo.com', headers['HOST']
+ end
+
+ test '#to_s' do
+ headers = Webbed::Headers.new({
+ 'Content-Type' => 'application/json',
+ 'Host' => 'foo.com'
+ })
+
+ assert_equal "Content-Type: application/json\r\nHost: foo.com\r\n", headers.to_s
+ end
+ end
+end
View
68 test/webbed/helpers/entity_headers_helper_test.rb
@@ -0,0 +1,68 @@
+require 'test_helper'
+
+module WebbedTest
+ module HelperTest
+ class EntityHeadersHelperTest < TestCase
+ def setup
+ @request = Webbed::Request.new('GET', '*', {}, '')
+ @response = Webbed::Response.new(200, {}, '')
+ end
+
+ test '#content_length' do
+ [@request, @response].each do |message|
+ assert_nil message.content_length
+
+ message.headers['Content-Length'] = 9876
+ assert_equal 9876, message.content_length
+
+ message.content_length = 123
+ assert_equal 123, message.content_length
+ assert_equal '123', message.headers['Content-Length']
+ end
+ end
+
+ test '#content_location' do
+ [@request, @response].each do |message|
+ assert_nil message.content_location
+
+ message.headers['Content-Location'] = 'http://google.com'
+ assert_instance_of Addressable::URI, message.content_location
+ assert_equal 'http://google.com', message.content_location.to_s
+
+ message.content_location = 'http://example.com/testing'
+ assert_instance_of Addressable::URI, message.content_location
+ assert_equal 'http://example.com/testing', message.content_location.to_s
+ assert_equal 'http://example.com/testing', message.headers['Content-Location']
+ end
+ end
+
+ test '#content_md5' do
+ [@request, @response].each do |message|
+ assert_nil message.content_md5
+
+ message.headers['Content-MD5'] = 'asdfasdf'
+ assert_equal 'asdfasdf', message.content_md5
+
+ message.content_md5 = ';lkj;lkj'
+ assert_equal ';lkj;lkj', message.content_md5
+ assert_equal ';lkj;lkj', message.headers['Content-MD5']
+ end
+ end
+
+ test '#content_type' do
+ [@request, @response].each do |message|
+ assert_nil message.content_type
+
+ message.headers['Content-Type'] = 'text/html'
+ assert_instance_of Webbed::MediaType, message.content_type
+ assert_equal 'text/html', message.content_type.to_s
+
+ message.content_type = 'application/json'
+ assert_instance_of Webbed::MediaType, message.content_type
+ assert_equal 'application/json', message.content_type.to_s
+ assert_equal 'application/json', message.headers['Content-Type']
+ end
+ end
+ end
+ end
+end
View
151 test/webbed/helpers/method_helper_test.rb
@@ -0,0 +1,151 @@
+require 'test_helper'
+
+module WebbedTest
+ module HelperTest
+ class MethodHelperTest < TestCase
+ test '#options?' do
+ request = Webbed::Request.new('OPTIONS', '*', {}, '')
+
+ assert request.options?
+ refute request.get?
+ refute request.head?
+ refute request.post?
+ refute request.put?
+ refute request.delete?
+ refute request.trace?
+ refute request.connect?
+ refute request.patch?
+ assert request.safe?
+ assert request.idempotent?
+ end
+
+ test '#get?' do
+ request = Webbed::Request.new('GET', '*', {}, '')
+
+ refute request.options?
+ assert request.get?
+ refute request.head?
+ refute request.post?
+ refute request.put?
+ refute request.delete?
+ refute request.trace?
+ refute request.connect?
+ refute request.patch?
+ assert request.safe?
+ assert request.idempotent?
+ end
+
+ test '#head?' do
+ request = Webbed::Request.new('HEAD', '*', {}, '')
+
+ refute request.options?
+ refute request.get?
+ assert request.head?
+ refute request.post?
+ refute request.put?
+ refute request.delete?
+ refute request.trace?
+ refute request.connect?
+ refute request.patch?
+ assert request.safe?
+ assert request.idempotent?
+ end
+
+ test '#post?' do
+ request = Webbed::Request.new('POST', '*', {}, '')
+
+ refute request.options?
+ refute request.get?
+ refute request.head?
+ assert request.post?
+ refute request.put?
+ refute request.delete?
+ refute request.trace?
+ refute request.connect?
+ refute request.patch?
+ refute request.safe?
+ refute request.idempotent?
+ end
+
+ test '#put?' do
+ request = Webbed::Request.new('PUT', '*', {}, '')
+
+ refute request.options?
+ refute request.get?
+ refute request.head?
+ refute request.post?
+ assert request.put?
+ refute request.delete?
+ refute request.trace?
+ refute request.connect?
+ refute request.patch?
+ refute request.safe?
+ assert request.idempotent?
+ end
+
+ test '#delete?' do
+ request = Webbed::Request.new('DELETE', '*', {}, '')
+
+ refute request.options?
+ refute request.get?
+ refute request.head?
+ refute request.post?
+ refute request.put?
+ assert request.delete?
+ refute request.trace?
+ refute request.connect?
+ refute request.patch?
+ refute request.safe?
+ assert request.idempotent?
+ end
+
+ test '#trace?' do
+ request = Webbed::Request.new('TRACE', '*', {}, '')
+
+ refute request.options?
+ refute request.get?
+ refute request.head?
+ refute request.post?
+ refute request.put?
+ refute request.delete?
+ assert request.trace?
+ refute request.connect?
+ refute request.patch?
+ assert request.safe?
+ assert request.idempotent?
+ end
+
+ test '#connect?' do
+ request = Webbed::Request.new('CONNECT', '*', {}, '')
+
+ refute request.options?
+ refute request.get?
+ refute request.head?
+ refute request.post?
+ refute request.put?
+ refute request.delete?
+ refute request.trace?
+ assert request.connect?
+ refute request.patch?
+ refute request.safe?
+ refute request.idempotent?
+ end
+
+ test '#patch?' do
+ request = Webbed::Request.new('PATCH', '*', {}, '')
+
+ refute request.options?
+ refute request.get?
+ refute request.head?
+ refute request.post?
+ refute request.put?
+ refute request.delete?
+ refute request.trace?
+ refute request.connect?
+ assert request.patch?
+ refute request.safe?
+ refute request.idempotent?
+ end
+ end
+ end
+end
View
48 test/webbed/helpers/rack_request_helper_test.rb
@@ -0,0 +1,48 @@
+require 'test_helper'
+
+module WebbedTest
+ module HelperTest
+ class RackRequestHelperTest < TestCase
+ test '.from_rack' do
+ rack_env = {
+ 'REQUEST_METHOD' => 'GET',
+ 'SCRIPT_NAME' => '',
+ 'PATH_INFO' => '/test',
+ 'QUERY_STRING' => 'foo=bar',
+ 'HTTP_HOST' => 'google.com',
+ 'HTTP_ACCEPT' => '*/*',
+ 'CONTENT_TYPE' => 'text/plain',
+ 'CONTENT_LENGTH' => '0',
+ 'HTTP_VERSION' => 'HTTP/1.0',
+ 'rack.url_scheme' => 'https',
+ 'rack.input' => StringIO.new('Foobar')
+ }
+
+ request = Webbed::Request.from_rack(rack_env)
+
+ assert_equal Webbed::Method::GET, request.method
+ assert_equal Addressable::URI.parse('/test?foo=bar'), request.request_uri
+ assert_equal 'google.com', request.headers['Host']
+ assert_equal '*/*', request.headers['Accept']
+ assert_equal 'text/plain', request.headers['Content-Type']
+ assert_equal '0', request.headers['Content-Length']
+ assert_equal 'https', request.scheme
+ assert_equal 'Foobar', request.entity_body.gets
+ assert_equal Webbed::HTTPVersion::ONE_POINT_OH, request.http_version
+ assert_same rack_env, request.rack_env
+ end
+
+ test '.from_rack without an HTTP Version' do
+ request = Webbed::Request.from_rack({
+ 'REQUEST_METHOD' => 'GET',
+ 'SCRIPT_NAME' => '',
+ 'PATH_INFO' => '/test',
+ 'QUERY_STRING' => 'foo=bar',
+ 'HTTP_HOST' => 'google.com'
+ })
+
+ assert_equal Webbed::HTTPVersion::ONE_POINT_ONE, request.http_version
+ end
+ end
+ end
+end
View
26 test/webbed/helpers/rack_response_helper_test.rb
@@ -0,0 +1,26 @@
+require 'test_helper'
+
+module WebbedTest
+ module HelperTest
+ class RackResponseHelperTest < TestCase
+ test '#to_rack' do
+ response = Webbed::Response.new(200, {}, '')
+
+ if ''.respond_to?(:each)
+ assert_equal [200, {}, ''], response.to_rack
+ else
+ assert_equal [200, {}, ['']], response.to_rack
+ end
+
+ string_io = StringIO.new
+ response = Webbed::Response.new(200, {}, string_io)
+ assert_equal [200, {}, string_io], response.to_rack
+ end
+
+ test '#to_a' do
+ response = Webbed::Response.new(200, {}, '')
+ assert_equal ['200 OK', {}, ''], response.to_a
+ end
+ end
+ end
+end
View
57 test/webbed/helpers/request_headers_helper_test.rb
@@ -0,0 +1,57 @@
+require 'test_helper'
+
+module WebbedTest
+ module HelperTest
+ class RequestHeadersHelper < TestCase
+ def setup
+ @request = Webbed::Request.new('GET', '*', {}, '')
+ end
+
+ test '#host' do
+ assert_nil @request.host
+
+ @request.headers['Host'] = 'example.com'
+ assert_equal 'example.com', @request.host
+
+ @request.host = 'test.com'
+ assert_equal 'test.com', @request.host
+ assert_equal 'test.com', @request.headers['Host']
+ end
+
+ test '#from' do
+ assert_nil @request.from
+
+ @request.headers['From'] = 'test@example.com'
+ assert_equal 'test@example.com', @request.from
+
+ @request.from = 'foo@bar.com'
+ assert_equal 'foo@bar.com', @request.from
+ assert_equal 'foo@bar.com', @request.headers['From']
+ end
+
+ test '#max_forwards' do
+ assert_nil @request.max_forwards
+
+ @request.headers['Max-Forwards'] = '56'
+ assert_equal 56, @request.max_forwards
+
+ @request.max_forwards = 1234
+ assert_equal 1234, @request.max_forwards
+ assert_equal '1234', @request.headers['Max-Forwards']
+ end
+
+ test '#referer' do
+ assert_nil @request.referer
+
+ @request.headers['Referer'] = 'http://foo.com'
+ assert_instance_of Addressable::URI, @request.referer
+ assert_equal Addressable::URI.parse('http://foo.com'), @request.referer
+
+ @request.referer = 'http://example.com'
+ assert_instance_of Addressable::URI, @request.referer
+ assert_equal Addressable::URI.parse('http://example.com'), @request.referer
+ assert_equal 'http://example.com', @request.headers['Referer']
+ end
+ end
+ end
+end
View
32 test/webbed/helpers/request_uri_helper_test.rb
@@ -0,0 +1,32 @@
+require 'test_helper'
+
+module WebbedTest
+ module HelperTest
+ class RequestURIHelperTest < TestCase
+ test '#request_url' do
+ request = Webbed::Request.new('GET', '/foo', { 'Host' => 'example.com' }, '')
+ assert_equal request.request_uri, request.request_url
+ end
+
+ test '#uri and #url' do
+ no_host = Webbed::Request.new('GET', '/foo', {}, '')
+ assert_instance_of Addressable::URI, no_host.uri
+ assert_instance_of Addressable::URI, no_host.url
+ assert_equal no_host.request_uri, no_host.uri
+ assert_equal no_host.request_uri, no_host.url
+
+ request_uri_with_host = Webbed::Request.new('GET', 'http://example2.com/foo', { 'Host' => 'example.com' }, '')
+ assert_instance_of Addressable::URI, request_uri_with_host.uri
+ assert_instance_of Addressable::URI, request_uri_with_host.url
+ assert_equal request_uri_with_host.request_uri, request_uri_with_host.uri
+ assert_equal request_uri_with_host.request_uri, request_uri_with_host.url
+
+ request_uri_without_host = Webbed::Request.new('GET', '/foo', { 'Host' => 'example.com' }, '')
+ assert_instance_of Addressable::URI, request_uri_without_host.uri
+ assert_instance_of Addressable::URI, request_uri_without_host.url
+ assert_equal Addressable::URI.parse('http://example.com/foo'), request_uri_without_host.uri
+ assert_equal Addressable::URI.parse('http://example.com/foo'), request_uri_without_host.url
+ end
+ end
+ end
+end
View
46 test/webbed/helpers/response_headers_helper_test.rb
@@ -0,0 +1,46 @@
+require 'test_helper'
+
+module WebbedTest
+ module HelperTest
+ class ResponseHeadersHelperTest < TestCase
+ def setup
+ @response = Webbed::Response.new(200, {}, '')
+ end
+
+ test '#etag' do
+ assert_nil @response.etag
+
+ @response.headers['ETag'] = 'asdf'
+ assert_equal 'asdf', @response.etag
+
+ @response.etag = 'foo'
+ assert_equal 'foo', @response.etag
+ assert_equal 'foo', @response.headers['ETag']
+ end
+
+ test '#age' do
+ assert_nil @response.age
+
+ @response.headers['Age'] = '123'
+ assert_equal 123, @response.age
+
+ @response.age = 456
+ assert_equal 456, @response.age
+ assert_equal '456', @response.headers['Age']
+ end
+
+ test '#location' do
+ assert_nil @response.location
+
+ @response.headers['Location'] = 'http://example.com/test'
+ assert_instance_of Addressable::URI, @response.location
+ assert_equal Addressable::URI.parse('http://example.com/test'), @response.location
+
+ @response.location = 'http://test.com/foo'
+ assert_instance_of Addressable::URI, @response.location
+ assert_equal Addressable::URI.parse('http://test.com/foo'), @response.location
+ assert_equal 'http://test.com/foo', @response.headers['Location']
+ end
+ end
+ end
+end
View
28 test/webbed/helpers/scheme_helper_test.rb
@@ -0,0 +1,28 @@
+require 'test_helper'
+
+module WebbedTest
+ module HelperTest
+ class SchemeHelperTest < TestCase
+ test 'HTTP scheme' do
+ request = Webbed::Request.new('GET', '*', {}, '', :scheme => 'http')
+
+ refute request.secure?
+ assert_equal 80, request.default_port
+ end
+
+ test 'HTTPS scheme' do
+ request = Webbed::Request.new('GET', '*', {}, '', :scheme => 'https')
+
+ assert request.secure?
+ assert_equal 443, request.default_port
+ end
+
+ test 'unknown scheme' do
+ request = Webbed::Request.new('GET', '*', {}, '', :scheme => 'foo')
+
+ refute request.secure?
+ assert_nil request.default_port
+ end
+ end
+ end
+end
View
64 test/webbed/helpers/test_entity_headers_helper.rb
@@ -1,64 +0,0 @@
-require 'test_helper'
-
-class TestEntityHeadersHelper < MiniTest::Unit::TestCase
- def setup
- @request = Webbed::Request.new(['GET', '*', {}, ''])
- @response = Webbed::Response.new([200, {}, ''])
- end
-
- def test_content_length
- [@request, @response].each do |message|
- assert_nil message.content_length
-
- message.headers['Content-Length'] = 9876
- assert_equal 9876, message.content_length
-
- message.content_length = 123
- assert_equal 123, message.content_length
- assert_equal '123', message.headers['Content-Length']
- end
- end
-
- def test_content_location
- [@request, @response].each do |message|
- assert_nil message.content_location
-
- message.headers['Content-Location'] = 'http://google.com'
- assert_instance_of Addressable::URI, message.content_location
- assert_equal Addressable::URI.parse('http://google.com'), message.content_location
-
- message.content_location = 'http://example.com/testing'
- assert_instance_of Addressable::URI, message.content_location
- assert_equal Addressable::URI.parse('http://example.com/testing'), message.content_location
- assert_equal 'http://example.com/testing', message.headers['Content-Location']
- end
- end
-
- def test_content_md5
- [@request, @response].each do |message|
- assert_nil message.content_md5
-
- message.headers['Content-MD5'] = 'asdfasdf'
- assert_equal 'asdfasdf', message.content_md5
-
- message.content_md5 = ';lkj;lkj'
- assert_equal ';lkj;lkj', message.content_md5
- assert_equal ';lkj;lkj', message.headers['Content-MD5']
- end
- end
-
- def test_content_type
- [@request, @response].each do |message|
- assert_nil message.content_type
-
- message.headers['Content-Type'] = 'text/html'
- assert_instance_of Webbed::MediaType, message.content_type
- assert_equal Webbed::MediaType.new('text/html'), message.content_type
-
- message.content_type = 'application/json'
- assert_instance_of Webbed::MediaType, message.content_type
- assert_equal Webbed::MediaType.new('application/json'), message.content_type
- assert_equal 'application/json', message.headers['Content-Type']
- end
- end
-end
View
147 test/webbed/helpers/test_method_helper.rb
@@ -1,147 +0,0 @@
-require 'test_helper'
-
-class TestMethodHelper < MiniTest::Unit::TestCase
- def test_options
- request = Webbed::Request.new(['OPTIONS', '*', {}, ''])
-
- assert request.options?
- refute request.get?
- refute request.head?
- refute request.post?
- refute request.put?
- refute request.delete?
- refute request.trace?
- refute request.connect?
- refute request.patch?
- assert request.safe?
- assert request.idempotent?
- end
-
- def test_get
- request = Webbed::Request.new(['GET', '*', {}, ''])
-
- refute request.options?
- assert request.get?
- refute request.head?
- refute request.post?
- refute request.put?
- refute request.delete?
- refute request.trace?
- refute request.connect?
- refute request.patch?
- assert request.safe?
- assert request.idempotent?
- end
-
- def test_head
- request = Webbed::Request.new(['HEAD', '*', {}, ''])
-
- refute request.options?
- refute request.get?
- assert request.head?
- refute request.post?
- refute request.put?
- refute request.delete?
- refute request.trace?
- refute request.connect?
- refute request.patch?
- assert request.safe?
- assert request.idempotent?
- end
-
- def test_post
- request = Webbed::Request.new(['POST', '*', {}, ''])
-
- refute request.options?
- refute request.get?
- refute request.head?
- assert request.post?
- refute request.put?
- refute request.delete?
- refute request.trace?
- refute request.connect?
- refute request.patch?
- refute request.safe?
- refute request.idempotent?
- end
-
- def test_put
- request = Webbed::Request.new(['PUT', '*', {}, ''])
-
- refute request.options?
- refute request.get?
- refute request.head?
- refute request.post?
- assert request.put?
- refute request.delete?
- refute request.trace?
- refute request.connect?
- refute request.patch?
- refute request.safe?
- assert request.idempotent?
- end
-
- def test_delete
- request = Webbed::Request.new(['DELETE', '*', {}, ''])
-
- refute request.options?
- refute request.get?
- refute request.head?
- refute request.post?
- refute request.put?
- assert request.delete?
- refute request.trace?
- refute request.connect?
- refute request.patch?
- refute request.safe?
- assert request.idempotent?
- end
-
- def test_trace
- request = Webbed::Request.new(['TRACE', '*', {}, ''])
-
- refute request.options?
- refute request.get?
- refute request.head?
- refute request.post?
- refute request.put?
- refute request.delete?
- assert request.trace?
- refute request.connect?
- refute request.patch?
- assert request.safe?
- assert request.idempotent?
- end
-
- def test_connect
- request = Webbed::Request.new(['CONNECT', '*', {}, ''])
-
- refute request.options?
- refute request.get?
- refute request.head?
- refute request.post?
- refute request.put?
- refute request.delete?
- refute request.trace?
- assert request.connect?
- refute request.patch?
- refute request.safe?
- refute request.idempotent?
- end
-
- def test_patch
- request = Webbed::Request.new(['PATCH', '*', {}, ''])
-
- refute request.options?
- refute request.get?
- refute request.head?
- refute request.post?
- refute request.put?
- refute request.delete?
- refute request.trace?
- refute request.connect?
- assert request.patch?
- refute request.safe?
- refute request.idempotent?
- end
-end
View
44 test/webbed/helpers/test_rack_request_helper.rb
@@ -1,44 +0,0 @@
-require 'test_helper'
-
-class TestRackRequestHelper < MiniTest::Unit::TestCase
- def test_from_rack
- rack_env = {
- 'REQUEST_METHOD' => 'GET',
- 'SCRIPT_NAME' => '',
- 'PATH_INFO' => '/test',
- 'QUERY_STRING' => 'foo=bar',
- 'HTTP_HOST' => 'google.com',
- 'HTTP_ACCEPT' => '*/*',
- 'CONTENT_TYPE' => 'text/plain',
- 'CONTENT_LENGTH' => '0',
- 'HTTP_VERSION' => 'HTTP/1.0',
- 'rack.url_scheme' => 'https',
- 'rack.input' => StringIO.new('Foobar')
- }
-
- request = Webbed::Request.from_rack(rack_env)
-
- assert_equal Webbed::Method::GET, request.method
- assert_equal Addressable::URI.parse('/test?foo=bar'), request.request_uri
- assert_equal 'google.com', request.headers['Host']
- assert_equal '*/*', request.headers['Accept']
- assert_equal 'text/plain', request.headers['Content-Type']
- assert_equal '0', request.headers['Content-Length']
- assert_equal 'https', request.scheme
- assert_equal 'Foobar', request.entity_body.gets
- assert_equal Webbed::HTTPVersion::ONE_POINT_OH, request.http_version
- assert_same rack_env, request.rack_env
- end
-
- def test_from_rack_without_http_version
- request = Webbed::Request.from_rack({
- 'REQUEST_METHOD' => 'GET',
- 'SCRIPT_NAME' => '',
- 'PATH_INFO' => '/test',
- 'QUERY_STRING' => 'foo=bar',
- 'HTTP_HOST' => 'google.com'
- })
-
- assert_equal Webbed::HTTPVersion::ONE_POINT_ONE, request.http_version
- end
-end
View
22 test/webbed/helpers/test_rack_response_helper.rb
@@ -1,22 +0,0 @@
-require 'test_helper'
-
-class TestRackResponseHelper < MiniTest::Unit::TestCase
- def test_to_rack
- if ''.respond_to?(:each)
- response = Webbed::Response.new([200, {}, ''])
- assert_equal [200, {}, ''], response.to_rack
- else
- response = Webbed::Response.new([200, {}, ''])
- assert_equal [200, {}, ['']], response.to_rack
- end
-
- string_io = StringIO.new
- response = Webbed::Response.new([200, {}, string_io])
- assert_equal [200, {}, string_io], response.to_rack
- end
-
- def test_to_a
- response = Webbed::Response.new([200, {}, ''])
- assert_equal ['200 OK', {}, ''], response.to_a
- end
-end
View
53 test/webbed/helpers/test_request_headers_helper.rb
@@ -1,53 +0,0 @@
-require 'test_helper'
-
-class TestRequestHeadersHelper < MiniTest::Unit::TestCase
- def setup
- @request = Webbed::Request.new(['GET', '*', {}, ''])
- end
-
- def test_host
- assert_nil @request.host
-
- @request.headers['Host'] = 'example.com'
- assert_equal 'example.com', @request.host
-
- @request.host = 'test.com'
- assert_equal 'test.com', @request.host
- assert_equal 'test.com', @request.headers['Host']
- end
-
- def test_from
- assert_nil @request.from
-
- @request.headers['From'] = 'test@example.com'
- assert_equal 'test@example.com', @request.from
-
- @request.from = 'foo@bar.com'
- assert_equal 'foo@bar.com', @request.from
- assert_equal 'foo@bar.com', @request.headers['From']
- end
-
- def test_max_forwards
- assert_nil @request.max_forwards
-
- @request.headers['Max-Forwards'] = '56'
- assert_equal 56, @request.max_forwards
-
- @request.max_forwards = 1234
- assert_equal 1234, @request.max_forwards
- assert_equal '1234', @request.headers['Max-Forwards']
- end
-
- def test_referer
- assert_nil @request.referer
-
- @request.headers['Referer'] = 'http://foo.com'
- assert_instance_of Addressable::URI, @request.referer
- assert_equal Addressable::URI.parse('http://foo.com'), @request.referer
-
- @request.referer = 'http://example.com'
- assert_instance_of Addressable::URI, @request.referer
- assert_equal Addressable::URI.parse('http://example.com'), @request.referer
- assert_equal 'http://example.com', @request.headers['Referer']
- end
-end
View
28 test/webbed/helpers/test_request_uri_helper.rb
@@ -1,28 +0,0 @@
-require 'test_helper'
-
-class TestRequestURIHelper < MiniTest::Unit::TestCase
- def test_request_url
- request = Webbed::Request.new(['GET', '/foo', { 'Host' => 'example.com' }, ''])
- assert_equal request.request_uri, request.request_url
- end
-
- def test_uri_and_url
- no_host = Webbed::Request.new(['GET', '/foo', {}, ''])
- assert_instance_of Addressable::URI, no_host.uri
- assert_instance_of Addressable::URI, no_host.url
- assert_equal no_host.request_uri, no_host.uri
- assert_equal no_host.request_uri, no_host.url
-
- request_uri_with_host = Webbed::Request.new(['GET', 'http://example2.com/foo', { 'Host' => 'example.com' }, ''])
- assert_instance_of Addressable::URI, request_uri_with_host.uri
- assert_instance_of Addressable::URI, request_uri_with_host.url
- assert_equal request_uri_with_host.request_uri, request_uri_with_host.uri
- assert_equal request_uri_with_host.request_uri, request_uri_with_host.url
-
- request_uri_without_host = Webbed::Request.new(['GET', '/foo', { 'Host' => 'example.com' }, ''])
- assert_instance_of Addressable::URI, request_uri_without_host.uri
- assert_instance_of Addressable::URI, request_uri_without_host.url
- assert_equal Addressable::URI.parse('http://example.com/foo'), request_uri_without_host.uri
- assert_equal Addressable::URI.parse('http://example.com/foo'), request_uri_without_host.url
- end
-end
View
42 test/webbed/helpers/test_response_headers_helper.rb
@@ -1,42 +0,0 @@
-require 'test_helper'
-