Skip to content

Commit

Permalink
Merge branch 'master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
tjschuck authored Apr 26, 2017
2 parents 947d943 + ac30234 commit 4c09c89
Show file tree
Hide file tree
Showing 22 changed files with 538 additions and 263 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
pkg
doc
coverage
Gemfile.lock
VERSION
*.rbc
.bundle
.bundle
16 changes: 16 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
language: ruby
sudo: false
before_install:
- which bundle || gem install bundler
rvm:
- 2.2.7
- 2.3.4
- 2.4.1
- ruby-head
- jruby-9.1.8.0
- jruby-head
matrix:
allow_failures:
- rvm: ruby-head
- rvm: jruby-head
fast_finish: true
2 changes: 2 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,5 @@ gem 'rspec'
gem "rack"
gem "sinatra"
gem 'rake'

gem "codeclimate-test-reporter", group: :test, require: nil
36 changes: 27 additions & 9 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,19 +1,33 @@
GEM
remote: https://rubygems.org/
specs:
diff-lcs (1.2.3)
codeclimate-test-reporter (0.3.0)
simplecov (>= 0.7.1, < 1.0.0)
diff-lcs (1.2.5)
docile (1.1.3)
multi_json (1.9.0)
rack (1.5.2)
rack-protection (1.5.0)
rack
rake (10.0.4)
rspec (2.13.0)
rspec-core (~> 2.13.0)
rspec-expectations (~> 2.13.0)
rspec-mocks (~> 2.13.0)
rspec-core (2.13.1)
rspec-expectations (2.13.0)
diff-lcs (>= 1.1.3, < 2.0)
rspec-mocks (2.13.1)
rspec (3.4.0)
rspec-core (~> 3.4.0)
rspec-expectations (~> 3.4.0)
rspec-mocks (~> 3.4.0)
rspec-core (3.4.3)
rspec-support (~> 3.4.0)
rspec-expectations (3.4.0)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.4.0)
rspec-mocks (3.4.1)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.4.0)
rspec-support (3.4.1)
simplecov (0.8.2)
docile (~> 1.1.0)
multi_json
simplecov-html (~> 0.8.0)
simplecov-html (0.8.0)
sinatra (1.4.2)
rack (~> 1.5, >= 1.5.2)
rack-protection (~> 1.4)
Expand All @@ -25,7 +39,11 @@ PLATFORMS
ruby

DEPENDENCIES
codeclimate-test-reporter
rack
rake
rspec
sinatra

BUNDLED WITH
1.11.2
13 changes: 13 additions & 0 deletions History.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,16 @@
== 0.6.3 / 2015-01-09

* Minor enhancements

* Expose an env helper for persistently configuring the env as needed
(Darío Javier Cravero #80)
* Expose the tempfile of UploadedFile (Sytse Sijbrandij #67)

* Bug fixes

* Improve support for arrays of hashes in multipart forms (Murray Steele #69)
* Improve test for query strings (Paul Grayson #66)

== 0.6.2 / 2012-09-27

* Minor enhancements
Expand Down
8 changes: 4 additions & 4 deletions README.rdoc
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
= Rack::Test {<img src="https://codeclimate.com/badge.png" />}[https://codeclimate.com/github/brynary/rack-test]
= Rack::Test {<img src="https://travis-ci.org/rack-test/rack-test.svg?branch=master" />}[https://travis-ci.org/rack-test/rack-test] {<img src="https://codeclimate.com/github/brynary/rack-test.png" />}[https://codeclimate.com/github/brynary/rack-test] {<img src="https://codeclimate.com/github/brynary/rack-test/coverage.png" />}[https://codeclimate.com/github/brynary/rack-test]

- Code: http://github.com/brynary/rack-test
- Code: http://github.com/rack-test/rack-test

== Description

Expand Down Expand Up @@ -41,7 +41,7 @@ request helpers feature.

If you want to test one app in isolation, you just return that app as shown above. But if you want to test the entire app stack, including middlewares, cascades etc. you need to parse the app defined in config.ru.

OUTER_APP = Rack::Builder.parse_file('config.ru').first
OUTER_APP = Rack::Builder.parse_file("config.ru").first

class TestApp < Test::Unit::TestCase
include Rack::Test::Methods
Expand All @@ -51,7 +51,7 @@ If you want to test one app in isolation, you just return that app as shown abov
end

def test_root
get '/'
get "/"
assert last_response.ok?
end
end
Expand Down
2 changes: 1 addition & 1 deletion Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ require 'rspec/core'
require "rspec/core/rake_task"

RSpec::Core::RakeTask.new do |t|
t.pattern = "./**/*_spec.rb"
t.pattern = "spec/**/*_spec.rb"
t.ruby_opts = "-w"
end

Expand Down
10 changes: 6 additions & 4 deletions lib/rack/test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

module Rack
module Test
VERSION = "0.6.2"
VERSION = "0.6.3"

DEFAULT_HOST = "example.org"
MULTIPART_BOUNDARY = "----------XnJLe9ZIbbGUYtzPQJ16u1"
Expand All @@ -36,6 +36,8 @@ class Session
def initialize(mock_session)
@headers = {}
@env = {}
@digest_username = nil
@digest_password = nil

if mock_session.is_a?(MockSession)
@rack_mock_session = mock_session
Expand Down Expand Up @@ -205,12 +207,12 @@ def env_for(path, env)
# Stringifying and upcasing methods has be commit upstream
env["REQUEST_METHOD"] ||= env[:method] ? env[:method].to_s.upcase : "GET"

if env["REQUEST_METHOD"] == "GET"
if ["GET", "DELETE"].include?(env["REQUEST_METHOD"])
# merge :params with the query string
if params = env[:params]
params = parse_nested_query(params) if params.is_a?(String)
params.update(parse_nested_query(uri.query))
uri.query = build_nested_query(params)

uri.query = [uri.query, build_nested_query(params)].compact.reject { |v| v == '' }.join("&")
end
elsif !env.has_key?(:input)
env["CONTENT_TYPE"] ||= "application/x-www-form-urlencoded"
Expand Down
16 changes: 16 additions & 0 deletions lib/rack/test/cookie_jar.rb
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ def secure?
@options.has_key?("secure")
end

def http_only?
@options.has_key?('HttpOnly')
end

# :api: private
def path
@options["path"].strip || "/"
Expand Down Expand Up @@ -87,6 +91,14 @@ def <=>(other)
# Orders the cookies from least specific to most
[name, path, domain.reverse] <=> [other.name, other.path, other.domain.reverse]
end
def to_h
@options.merge(
'value' => @value,
'HttpOnly' => http_only?,
'secure' => secure?,
)
end
alias_method :to_hash, :to_h

protected

Expand Down Expand Up @@ -115,6 +127,10 @@ def []=(name, value)
merge("#{name}=#{Rack::Utils.escape(value)}")
end

def get_cookie(name)
hash_for(nil).fetch(name,nil)
end

def delete(name)
@cookies.reject! do |cookie|
cookie.name == name
Expand Down
2 changes: 1 addition & 1 deletion lib/rack/test/uploaded_file.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ def initialize(path, content_type = "text/plain", binary = false)
@content_type = content_type
@original_filename = ::File.basename(path)

@tempfile = Tempfile.new(@original_filename)
@tempfile = Tempfile.new([@original_filename, ::File.extname(path)])
@tempfile.set_encoding(Encoding::BINARY) if @tempfile.respond_to?(:set_encoding)
@tempfile.binmode if binary

Expand Down
67 changes: 44 additions & 23 deletions lib/rack/test/utils.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,21 @@ module Test

module Utils # :nodoc:
include Rack::Utils
extend Rack::Utils

def build_nested_query(value, prefix = nil)
case value
when Array
value.map do |v|
unless unescape(prefix) =~ /\[\]$/
prefix = "#{prefix}[]"
end
build_nested_query(v, "#{prefix}")
end.join("&")
if value.empty?
"#{prefix}[]="
else
value.map do |v|
unless unescape(prefix) =~ /\[\]$/
prefix = "#{prefix}[]"
end
build_nested_query(v, "#{prefix}")
end.join("&")
end
when Hash
value.map do |k, v|
build_nested_query(v, prefix ? "#{prefix}[#{escape(k)}]" : escape(k))
Expand All @@ -23,7 +28,6 @@ def build_nested_query(value, prefix = nil)
"#{prefix}=#{escape(value)}"
end
end

module_function :build_nested_query

def build_multipart(params, first = true)
Expand Down Expand Up @@ -57,9 +61,12 @@ def build_multipart(params, first = true)
value.map do |v|

if (v.is_a?(Hash))
nested_params = {}
build_multipart(v, false).each { |subkey, subvalue|
flattened_params["#{k}[]#{subkey}"] = subvalue
nested_params[subkey] = subvalue
}
flattened_params["#{k}[]"] ||= []
flattened_params["#{k}[]"] << nested_params
else
flattened_params["#{k}[]"] = value
end
Expand All @@ -80,46 +87,59 @@ def build_multipart(params, first = true)
flattened_params
end
end

module_function :build_multipart

private
private
def build_parts(parameters)
get_parts(parameters).join + "--#{MULTIPART_BOUNDARY}--\r"
end
module_function :build_parts

def get_parts(parameters)
parameters.map { |name, value|
if value.respond_to?(:original_filename)
build_file_part(name, value)
if name =~ /\[\]\Z/ && value.is_a?(Array) && value.all? {|v| v.is_a?(Hash)}
value.map { |hash|
new_value = {}
hash.each { |k, v| new_value[name+k] = v }
get_parts(new_value).join
}.join
else
if value.respond_to?(:original_filename)
build_file_part(name, value)

elsif value.is_a?(Array) and value.all? { |v| v.respond_to?(:original_filename) }
value.map do |v|
build_file_part(name, v)
end.join
elsif value.is_a?(Array) and value.all? { |v| v.respond_to?(:original_filename) }
value.map do |v|
build_file_part(name, v)
end.join

else
primitive_part = build_primitive_part(name, value)
Rack::Test.encoding_aware_strings? ? primitive_part.force_encoding('BINARY') : primitive_part
else
primitive_part = build_primitive_part(name, value)
Rack::Test.encoding_aware_strings? ? primitive_part.force_encoding('BINARY') : primitive_part
end
end

}.join + "--#{MULTIPART_BOUNDARY}--\r"
}
end
module_function :get_parts

def build_primitive_part(parameter_name, value)
unless value.is_a? Array
value = [value]
end
value.map do |v|
<<-EOF
<<-EOF
--#{MULTIPART_BOUNDARY}\r
Content-Disposition: form-data; name="#{parameter_name}"\r
\r
#{v}\r
EOF
end.join
end
module_function :build_primitive_part

def build_file_part(parameter_name, uploaded_file)
::File.open(uploaded_file.path, "rb") do |physical_file|
physical_file.set_encoding(Encoding::BINARY) if physical_file.respond_to?(:set_encoding)
<<-EOF
<<-EOF
--#{MULTIPART_BOUNDARY}\r
Content-Disposition: form-data; name="#{parameter_name}"; filename="#{escape(uploaded_file.original_filename)}"\r
Content-Type: #{uploaded_file.content_type}\r
Expand All @@ -129,6 +149,7 @@ def build_file_part(parameter_name, uploaded_file)
EOF
end
end
module_function :build_file_part

end

Expand Down
5 changes: 3 additions & 2 deletions rack-test.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@

Gem::Specification.new do |s|
s.name = "rack-test"
s.version = "0.6.2"
s.version = "0.6.3"

s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
s.authors = ["Bryan Helmkamp"]
s.date = "2012-09-27"
s.date = "2015-01-09"
s.description = "Rack::Test is a small, simple testing API for Rack apps. It can be used on its\nown or as a reusable starting point for Web frameworks and testing libraries\nto build on. Most of its initial functionality is an extraction of Merb 1.0's\nrequest helpers feature."
s.email = "bryan@brynary.com"
s.license = 'MIT'
s.extra_rdoc_files = [
"README.rdoc",
"MIT-LICENSE.txt"
Expand Down
21 changes: 21 additions & 0 deletions spec/rack/test/cookie_jar_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
require "spec_helper"

describe Rack::Test::CookieJar do
subject(:jar) { Rack::Test::CookieJar.new }

describe "#get_cookie" do
context "with a populated jar" do
let(:cookie_value) { "foo;abc" }
let(:cookie_name) { "a_cookie_name" }

before do
jar[cookie_name] = cookie_value
end

it "returns full cookie objects" do
cookie = jar.get_cookie(cookie_name)
expect(cookie).to be_a(Rack::Test::Cookie)
end
end
end
end
Loading

0 comments on commit 4c09c89

Please sign in to comment.