http_capture 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +15 -0
- data/.gitignore +18 -0
- data/.rspec +5 -0
- data/.travis.yml +13 -0
- data/CHANGELOG.md +14 -0
- data/Gemfile +3 -0
- data/LICENSE +21 -0
- data/README.md +48 -0
- data/Rakefile +20 -0
- data/VERSION +1 -0
- data/http_capture.gemspec +32 -0
- data/lib/http_capture.rb +99 -0
- data/lib/http_capture/version.rb +3 -0
- data/lib/httparty/capture.rb +4 -0
- data/lib/httpclient/capture.rb +53 -0
- data/lib/mechanize/capture.rb +4 -0
- data/lib/net/http/capture.rb +39 -0
- data/lib/rack/test/capture.rb +35 -0
- data/spec/capture_spec.rb +68 -0
- data/spec/httparty/capture_spec.rb +10 -0
- data/spec/httpclient/capture_spec.rb +11 -0
- data/spec/mechanize/capture_spec.rb +11 -0
- data/spec/net/http/capture_spec.rb +13 -0
- data/spec/rack/test/capture_spec.rb +16 -0
- data/spec/spec_helper.rb +59 -0
- metadata +189 -0
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
MzNhYzU1NDc2OWRlNjI1YjVlMTNjZDE3YTQ4NWZmMDQ5MWUxZTU1Mw==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
M2JkOWFhNWU0MmJjOGYzZGZkMDE0ZmQ2OTdjODI3MDI1ZDc5YTcyNw==
|
7
|
+
SHA512:
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
YjhkMjI0Y2M5NjRjYWFkZWU1OWMxMTk1MzRlZWQ4YzM3YjkwM2EwNGVkMDNh
|
10
|
+
ZDRjOGFhN2M0ZmVkODBjNTFlNWY5OTkzZGIzODJmMWIwZTNhMTQ1Mzk5MDEz
|
11
|
+
MTk3MjA0MGZhZGVkOGY3NTk3OWQzZjAwYjE4ZDZiNTFmMTAxMmE=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
ZmYxZjBlZDE4N2Y4MjI3MWMzYjhhZTE5MDNkZjc0OWYzMDI5NDc3ZThlMGZh
|
14
|
+
N2E5YTAxYTkzNGEwY2JkYTQ4YTQ1NjAwN2ZhMWViNTAyODEzOTNjMTU3YjFh
|
15
|
+
ODc1OGY1NDhhNTk5MWE3OTBkYjhlOTE4MmIxY2IzZWQzZWMwYjM=
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
language: ruby
|
2
|
+
rvm:
|
3
|
+
- 2.0.0
|
4
|
+
- 2.1.2
|
5
|
+
deploy:
|
6
|
+
provider: rubygems
|
7
|
+
api_key:
|
8
|
+
secure: G2rk3KCBDCD0QDbKJtTXsdtWlfSewvBImu90oaBBlVW97v423GfQ+xRWH2amHBIw0UYwgqDDnMAG38oAovKcYgFe3dHNwKIrwLsZDEL7syOa68P5swOsYaGLboZjSFcfjFWqfp6UcrBNeVjzdaXcbIJK8c+UTCpt/zUnDYFj/zo=
|
9
|
+
gem: http_capture
|
10
|
+
on:
|
11
|
+
repo: blinkboxbooks/http_capture.rb
|
12
|
+
rvm: 2.1.2
|
13
|
+
branch: master
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
# Change log
|
2
|
+
|
3
|
+
## 0.2.0 2014-07-01 10:05:00
|
4
|
+
|
5
|
+
Manually bumped version when going to Artifactory
|
6
|
+
|
7
|
+
## 0.0.1 ([#7](https://git.mobcastdev.com/TEST/http_capture/pull/7) 2014-06-30 16:51:38)
|
8
|
+
|
9
|
+
Artifactory
|
10
|
+
|
11
|
+
### Improvement
|
12
|
+
|
13
|
+
- Move to the use of artifactory
|
14
|
+
|
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2015 blinkbox Books Ltd.
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
# HTTP Capture
|
2
|
+
|
3
|
+
Allows access to the responses from a wide range of ruby HTTP libraries. This is super helpful for testing (especially with Cucumber).
|
4
|
+
|
5
|
+
Currently supports:
|
6
|
+
|
7
|
+
* [Net::HTTP](http://ruby-doc.org/stdlib-2.0/libdoc/net/http/rdoc/Net/HTTP.html) (and anything that uses it, specifically including:)
|
8
|
+
* [Mechanize](http://mechanize.rubyforge.org/)
|
9
|
+
* [HTTParty](http://httparty.rubyforge.org/rdoc/)
|
10
|
+
* [HTTPClient](http://rubydoc.info/gems/httpclient/2.1.5.2/HTTPClient)
|
11
|
+
* [Rack::Test](http://rdoc.info/github/brynary/rack-test/master/frames)
|
12
|
+
|
13
|
+
They can all be used by requiring `<library folder space>/capture` from your code, eg:
|
14
|
+
|
15
|
+
require 'net/http/capture'
|
16
|
+
require 'mechanize/capture'
|
17
|
+
require 'httparty/capture'
|
18
|
+
require 'httpclient/capture'
|
19
|
+
require 'rack/test/capture'
|
20
|
+
|
21
|
+
## Install
|
22
|
+
|
23
|
+
Install the usual way:
|
24
|
+
|
25
|
+
$ gem install http_capture
|
26
|
+
|
27
|
+
Or require it from within your gemspec and use `bundle`.
|
28
|
+
|
29
|
+
## Usage
|
30
|
+
|
31
|
+
Because it's beneficial to use a number of different HTTP libraries during our testing I've written a small script to capture the HTTP response information from each of the supported libraries so they can be examined after-the-fact. For example:
|
32
|
+
|
33
|
+
require 'httpclient'
|
34
|
+
# Include the relevant capture library
|
35
|
+
require 'httpclient/capture'
|
36
|
+
|
37
|
+
# Perform a request, as usual
|
38
|
+
clnt = HTTPClient.new
|
39
|
+
clnt.get_content("http://google.com") # => "<html>..."
|
40
|
+
|
41
|
+
# Now you can retrieve all the captured responses:
|
42
|
+
HttpCapture::RESPONSES.last.status # => 200
|
43
|
+
HttpCapture::RESPONSES.last['Content-Length'] # => 12345
|
44
|
+
HttpCapture::RESPONSES.last.body # => "<html>..."
|
45
|
+
HttpCapture::RESPONSES.last.response # => <HTTPClient::Response>
|
46
|
+
|
47
|
+
The objects in the `HttpCapture::RESPONSES` array contain the exact objects, wrapped by helper functions which expose three methods: `code` for the status code, `[](key)` for accessing headers and `body` for reading the body of the document.
|
48
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'bundler/gem_tasks'
|
3
|
+
|
4
|
+
task :default => :build
|
5
|
+
task :build => :test
|
6
|
+
task :test => :spec
|
7
|
+
|
8
|
+
desc "Run all rspec tests"
|
9
|
+
begin
|
10
|
+
require 'rspec/core/rake_task'
|
11
|
+
|
12
|
+
RSpec::Core::RakeTask.new(:spec) do |t|
|
13
|
+
t.pattern = 'spec/**/*_spec.rb'
|
14
|
+
end
|
15
|
+
rescue LoadError => e
|
16
|
+
raise e
|
17
|
+
task :spec do
|
18
|
+
$stderr.puts "Please install rspec: `gem install rspec`"
|
19
|
+
end
|
20
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.2.0
|
@@ -0,0 +1,32 @@
|
|
1
|
+
($LOAD_PATH << File.expand_path("../lib", __FILE__)).uniq!
|
2
|
+
require "http_capture/version"
|
3
|
+
|
4
|
+
Gem::Specification.new do |s|
|
5
|
+
s.name = "http_capture"
|
6
|
+
s.version = HttpCapture::VERSION
|
7
|
+
s.summary = "Captures http responses from a number of libraries for testing."
|
8
|
+
s.description = "Captures the Response objects from HTTParty, Mechanize, Net::HTTP, HTTPClient and Rack::Test and abstracts them for use in testing libraries."
|
9
|
+
s.author = "blinkbox books"
|
10
|
+
s.email = "jphastings@blinkbox.com"
|
11
|
+
s.homepage = "http://www.blinkboxbooks.com"
|
12
|
+
s.license = "MIT"
|
13
|
+
|
14
|
+
s.files = `git ls-files`.split($/)
|
15
|
+
s.executables = s.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
16
|
+
s.test_files = s.files.grep(%r{^(test|spec|features)/})
|
17
|
+
s.require_paths = ["lib"]
|
18
|
+
s.extra_rdoc_files = ["README.md"]
|
19
|
+
|
20
|
+
s.post_install_message = ":: Coded for blinkbox books :: Love books, love code? Get in touch ::"
|
21
|
+
|
22
|
+
# These are the supported libraries.
|
23
|
+
s.add_development_dependency "rack-test", "~> 0.6"
|
24
|
+
s.add_development_dependency "mechanize", "~> 2.7"
|
25
|
+
s.add_development_dependency "httpclient", "~> 2.3"
|
26
|
+
s.add_development_dependency "httparty", "~> 0.11"
|
27
|
+
|
28
|
+
s.add_development_dependency "bundler", "~> 1.3"
|
29
|
+
s.add_development_dependency "rake", "~> 10.1"
|
30
|
+
s.add_development_dependency "rspec", "~> 2.99"
|
31
|
+
s.add_development_dependency "sinatra"
|
32
|
+
end
|
data/lib/http_capture.rb
ADDED
@@ -0,0 +1,99 @@
|
|
1
|
+
require 'http_capture/version'
|
2
|
+
|
3
|
+
# Contains functionality to capture HTTP traffic from a variety of libraries.
|
4
|
+
module HttpCapture
|
5
|
+
RESPONSES = []
|
6
|
+
|
7
|
+
# Represents a captured request.
|
8
|
+
class Request
|
9
|
+
def initialize(real_request)
|
10
|
+
@real_request = real_request
|
11
|
+
end
|
12
|
+
|
13
|
+
# The request method as an upper-case string.
|
14
|
+
def method
|
15
|
+
if @real_request.respond_to?(:request_method)
|
16
|
+
@real_request.request_method.to_s.upcase
|
17
|
+
else
|
18
|
+
@real_request.method.to_s.upcase
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
# The request path.
|
23
|
+
def path
|
24
|
+
@real_request.path
|
25
|
+
end
|
26
|
+
|
27
|
+
# The complete request URI.
|
28
|
+
def uri
|
29
|
+
uri = if @real_request.respond_to?(:uri)
|
30
|
+
@real_request.uri
|
31
|
+
else
|
32
|
+
@real_request.url
|
33
|
+
end
|
34
|
+
uri = URI.parse(uri.to_s) unless uri.is_a?(URI)
|
35
|
+
uri
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
# Represents a captured response.
|
40
|
+
class Response
|
41
|
+
include Enumerable
|
42
|
+
|
43
|
+
# The request that this is a response to.
|
44
|
+
attr_reader :request
|
45
|
+
|
46
|
+
# The duration of the request in seconds.
|
47
|
+
attr_reader :duration
|
48
|
+
|
49
|
+
def initialize(real_response, request: nil, duration: nil)
|
50
|
+
@real_response = real_response
|
51
|
+
@request = request
|
52
|
+
@duration = duration
|
53
|
+
end
|
54
|
+
|
55
|
+
# Provides access to the response headers.
|
56
|
+
def [](key)
|
57
|
+
if @real_response.respond_to?(:[])
|
58
|
+
@real_response[key]
|
59
|
+
elsif @real_response.respond_to?(:headers)
|
60
|
+
@real_response.headers[key]
|
61
|
+
elsif @real_response.respond_to?(:header)
|
62
|
+
@real_response.header[key]
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def each(&block)
|
67
|
+
# some of the libraries return just header names in the each method; others return the header name and value
|
68
|
+
# as an array. some downcase the header name but others leave them as they were. this adapts them to the most
|
69
|
+
# useful and consistent which is an array of [name, value] with the name in lower case.
|
70
|
+
action = Proc.new { |item| block.(item.is_a?(String) ? [item.downcase, self[item]] : item) }
|
71
|
+
if @real_response.respond_to?(:each)
|
72
|
+
@real_response.each &action
|
73
|
+
elsif @real_response.respond_to?(:headers)
|
74
|
+
@real_response.headers.each &action
|
75
|
+
elsif @real_response.respond_to?(:header)
|
76
|
+
@real_response.header.each &action
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
# The default status code accessor
|
81
|
+
def status
|
82
|
+
if @real_response.respond_to?(:code)
|
83
|
+
@real_response.code.to_i
|
84
|
+
else
|
85
|
+
@real_response.status.to_i
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
# The default body accessor
|
90
|
+
def body
|
91
|
+
@real_response.body
|
92
|
+
end
|
93
|
+
|
94
|
+
# Whether the request was successful.
|
95
|
+
def successful?
|
96
|
+
status >= 200 && status < 300
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'httpclient'
|
2
|
+
require 'http_capture'
|
3
|
+
|
4
|
+
class HTTPClient
|
5
|
+
alias :old_do_request :do_request
|
6
|
+
def do_request(method, uri, query, body, header, &block)
|
7
|
+
start_time = Time.now.to_f
|
8
|
+
real_response = old_do_request(method, uri, query, body, header, &block)
|
9
|
+
duration = Time.now.to_f - start_time
|
10
|
+
|
11
|
+
captured_request = HttpCapture::HTTPClientRequest.new(method, uri, query)
|
12
|
+
captured_response = HttpCapture::HTTPClientResponse.new(real_response, request: captured_request, duration: duration)
|
13
|
+
HttpCapture::RESPONSES.push(captured_response)
|
14
|
+
|
15
|
+
real_response
|
16
|
+
end
|
17
|
+
|
18
|
+
alias :old_get_content :get_content
|
19
|
+
def get_content(uri, *args, &block)
|
20
|
+
query, header = keyword_argument(args, :query, :header)
|
21
|
+
success_content(follow_redirect(:get, uri, query, nil, header || {}, &block))
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
# Modifications of the base class to work with HTTPClient
|
26
|
+
module HttpCapture
|
27
|
+
class HTTPClientRequest < Request
|
28
|
+
attr_reader :method, :path, :uri
|
29
|
+
|
30
|
+
def initialize(method, uri, query)
|
31
|
+
super(nil)
|
32
|
+
@method = method.to_s.upcase
|
33
|
+
@path = uri
|
34
|
+
if query
|
35
|
+
query = Rack::Utils.build_query(query) unless query.is_a?(String)
|
36
|
+
@uri = URI.parse("#{uri}?#{query}")
|
37
|
+
else
|
38
|
+
@uri = uri.is_a?(URI) ? uri : URI.parse(uri)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
class HTTPClientResponse < Response
|
44
|
+
# def each
|
45
|
+
# @real_response.headers.each { |array| yield array.join(", ") }
|
46
|
+
# end
|
47
|
+
|
48
|
+
# Body access
|
49
|
+
def body
|
50
|
+
@real_response.content
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
require 'http_capture'
|
3
|
+
|
4
|
+
module Net
|
5
|
+
class HTTP
|
6
|
+
alias :old_request :request
|
7
|
+
def request(req, body = nil, &block)
|
8
|
+
start_time = Time.now.to_f
|
9
|
+
real_response = old_request(req, body, &block)
|
10
|
+
duration = Time.now.to_f - start_time
|
11
|
+
|
12
|
+
captured_request = HttpCapture::Request.new(req)
|
13
|
+
captured_response = HttpCapture::NetHTTPResponse.new(real_response, request: captured_request, duration: duration)
|
14
|
+
HttpCapture::RESPONSES.push(captured_response)
|
15
|
+
|
16
|
+
real_response
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
class ReadAdapter
|
21
|
+
attr_reader :stored_body
|
22
|
+
|
23
|
+
alias :old_write_to :<<
|
24
|
+
# If a block is used to process the incoming body data, ensure we're keeping it for inspection later too
|
25
|
+
def <<(str)
|
26
|
+
(@stored_body ||= '') << str
|
27
|
+
old_write_to(str)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
module HttpCapture
|
33
|
+
class NetHTTPResponse < HttpCapture::Response
|
34
|
+
def body
|
35
|
+
return @real_response.body.stored_body if @real_response.body.respond_to? :stored_body
|
36
|
+
@real_response.body
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'rack/test'
|
2
|
+
require 'http_capture'
|
3
|
+
|
4
|
+
module Rack
|
5
|
+
class MockSession
|
6
|
+
# I *do not* like replicating functionality (this is a copy of the code from within rack/test's `Rack::MockSession`)
|
7
|
+
# but for some reason this method pushes out an array, not the expected `@last_response` if I just call it with the
|
8
|
+
# usual `alias` method. This works, let's leave it at that for now!
|
9
|
+
def request(uri, env)
|
10
|
+
env["HTTP_COOKIE"] ||= cookie_jar.for(uri)
|
11
|
+
|
12
|
+
@last_request = Rack::Request.new(env)
|
13
|
+
start_time = Time.now.to_f
|
14
|
+
status, headers, body = @app.call(@last_request.env)
|
15
|
+
duration = Time.now.to_f - start_time
|
16
|
+
|
17
|
+
@last_response = MockResponse.new(status, headers, body, env["rack.errors"].flush)
|
18
|
+
captured_request = HttpCapture::Request.new(@last_request)
|
19
|
+
captured_response = HttpCapture::Response.new(@last_response, request: captured_request, duration: duration)
|
20
|
+
HttpCapture::RESPONSES.push(captured_response)
|
21
|
+
|
22
|
+
body.close if body.respond_to?(:close)
|
23
|
+
|
24
|
+
cookie_jar.merge(last_response.headers["Set-Cookie"], uri)
|
25
|
+
|
26
|
+
@after_request.each { |hook| hook.call }
|
27
|
+
|
28
|
+
if @last_response.respond_to?(:finish)
|
29
|
+
@last_response.finish
|
30
|
+
else
|
31
|
+
@last_response
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'net/http/capture'
|
2
|
+
|
3
|
+
shared_examples "capturing HTTP responses" do
|
4
|
+
before :each do
|
5
|
+
# Clear the captured requests
|
6
|
+
HttpCapture::RESPONSES.clear
|
7
|
+
end
|
8
|
+
|
9
|
+
it 'should capture a HTTP GET request' do
|
10
|
+
# Do the request
|
11
|
+
perform_get(make_test_uri())
|
12
|
+
|
13
|
+
# Really I should check that it has exactly 1 item, but for now we're happy that something comes through.
|
14
|
+
HttpCapture::RESPONSES.length.should > 0
|
15
|
+
end
|
16
|
+
|
17
|
+
context 'last captured response wrapper' do
|
18
|
+
before :all do
|
19
|
+
HttpCapture::RESPONSES.clear
|
20
|
+
perform_get(make_test_uri(200, "text"))
|
21
|
+
@it = HttpCapture::RESPONSES.last
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'should capture the request that triggered the response' do
|
25
|
+
expect(@it.request).to_not be_nil
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'should record the time it took to get the response with the #duration method' do
|
29
|
+
expect(@it.duration).to be > 0
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'should return headers with the #[](key) method' do
|
33
|
+
expect(@it['Content-Length']).to be_a_kind_of(String)
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'should support enumerating the headers with the #each method' do
|
37
|
+
@it.each { |item| expect(item).to be_a_kind_of(Array) }
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'should return the status with the #status method' do
|
41
|
+
expect(@it.status).to eq(200)
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'should return the body with the #body method' do
|
45
|
+
expect(@it.body).to eq("text")
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
context('last captured request wrapper') do
|
50
|
+
before :all do
|
51
|
+
HttpCapture::RESPONSES.clear
|
52
|
+
perform_get(make_test_uri(200, "text"))
|
53
|
+
@it = HttpCapture::RESPONSES.last.request
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'should return the method with the #method method' do
|
57
|
+
expect(@it.method).to eq("GET")
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'should return the path with the #path method' do
|
61
|
+
expect(@it.path).to_not be_nil # TODO: This should be a stronger check...
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'should return the full URI with the #uri method' do
|
65
|
+
expect(@it.uri).to be_a_kind_of(URI)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'rack/test'
|
2
|
+
require 'rack/test/capture'
|
3
|
+
|
4
|
+
describe Rack::Test do
|
5
|
+
include_examples "capturing HTTP responses"
|
6
|
+
include Rack::Test::Methods
|
7
|
+
|
8
|
+
# This spins up an in-process version of the app for testing with rack-test
|
9
|
+
def app
|
10
|
+
TestingApp.new
|
11
|
+
end
|
12
|
+
|
13
|
+
def perform_get(uri)
|
14
|
+
get(uri)
|
15
|
+
end
|
16
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'webrick'
|
2
|
+
require 'sinatra/base'
|
3
|
+
require 'uri'
|
4
|
+
require 'logger'
|
5
|
+
|
6
|
+
# This app allows us to make real HTTP responses from tests
|
7
|
+
class TestingApp < Sinatra::Base
|
8
|
+
# Call this with /?body=the_body&code=200&headers[Content-Type]=text/plain
|
9
|
+
get '/' do
|
10
|
+
halt params['code'].to_i, params['body']
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
# Windows requires a different descriptor for "ignore the logs"
|
15
|
+
dev_null = case RUBY_PLATFORM
|
16
|
+
when /cygwin|mswin|mingw|bccwin|wince|emx/
|
17
|
+
"nul"
|
18
|
+
else
|
19
|
+
"/dev/null"
|
20
|
+
end
|
21
|
+
|
22
|
+
# Start the real server on any open port
|
23
|
+
$server = ::WEBrick::HTTPServer.new({
|
24
|
+
:BindAddress => '127.0.0.1',
|
25
|
+
:Port => 0,
|
26
|
+
:OutputBufferSize => 5,
|
27
|
+
:Logger => WEBrick::Log.new(dev_null),
|
28
|
+
:AccessLog => []
|
29
|
+
})
|
30
|
+
|
31
|
+
# Mount the testing app for the tests to hit
|
32
|
+
$server.mount "/", Rack::Handler::WEBrick, TestingApp.new
|
33
|
+
|
34
|
+
# Ensure we don't start the tests until the server is ready
|
35
|
+
$ready = false
|
36
|
+
$server.config[:StartCallback] = Proc.new{ $ready = true }
|
37
|
+
|
38
|
+
$server.config[:Logger].level = Logger::ERROR
|
39
|
+
|
40
|
+
# Start the server in another thread
|
41
|
+
Thread.new do
|
42
|
+
$server.start
|
43
|
+
end
|
44
|
+
|
45
|
+
# Wait for the server to be ready
|
46
|
+
while not $ready
|
47
|
+
end
|
48
|
+
|
49
|
+
# TODO: Enclose this somewhere useful
|
50
|
+
def make_test_uri(code = 200, body = '', headers = {})
|
51
|
+
u = URI.parse("http://127.0.0.1:#{$server.config[:Port]}/")
|
52
|
+
|
53
|
+
u.query = "code=#{code.to_i.to_s}&body=#{URI.encode(body)}"
|
54
|
+
headers.each_pair do |key, value|
|
55
|
+
u.query << "&headers[#{URI.encode(key)}]=#{URI.encode(value)}"
|
56
|
+
end
|
57
|
+
|
58
|
+
u.to_s
|
59
|
+
end
|
metadata
ADDED
@@ -0,0 +1,189 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: http_capture
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- blinkbox books
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-01-29 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rack-test
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0.6'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0.6'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: mechanize
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ~>
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '2.7'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ~>
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '2.7'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: httpclient
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ~>
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '2.3'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ~>
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '2.3'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: httparty
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0.11'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ~>
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0.11'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: bundler
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ~>
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '1.3'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ~>
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '1.3'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rake
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ~>
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '10.1'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ~>
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '10.1'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: rspec
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ~>
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '2.99'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ~>
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '2.99'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: sinatra
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ! '>='
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ! '>='
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
description: Captures the Response objects from HTTParty, Mechanize, Net::HTTP, HTTPClient
|
126
|
+
and Rack::Test and abstracts them for use in testing libraries.
|
127
|
+
email: jphastings@blinkbox.com
|
128
|
+
executables: []
|
129
|
+
extensions: []
|
130
|
+
extra_rdoc_files:
|
131
|
+
- README.md
|
132
|
+
files:
|
133
|
+
- .gitignore
|
134
|
+
- .rspec
|
135
|
+
- .travis.yml
|
136
|
+
- CHANGELOG.md
|
137
|
+
- Gemfile
|
138
|
+
- LICENSE
|
139
|
+
- README.md
|
140
|
+
- Rakefile
|
141
|
+
- VERSION
|
142
|
+
- http_capture.gemspec
|
143
|
+
- lib/http_capture.rb
|
144
|
+
- lib/http_capture/version.rb
|
145
|
+
- lib/httparty/capture.rb
|
146
|
+
- lib/httpclient/capture.rb
|
147
|
+
- lib/mechanize/capture.rb
|
148
|
+
- lib/net/http/capture.rb
|
149
|
+
- lib/rack/test/capture.rb
|
150
|
+
- spec/capture_spec.rb
|
151
|
+
- spec/httparty/capture_spec.rb
|
152
|
+
- spec/httpclient/capture_spec.rb
|
153
|
+
- spec/mechanize/capture_spec.rb
|
154
|
+
- spec/net/http/capture_spec.rb
|
155
|
+
- spec/rack/test/capture_spec.rb
|
156
|
+
- spec/spec_helper.rb
|
157
|
+
homepage: http://www.blinkboxbooks.com
|
158
|
+
licenses:
|
159
|
+
- MIT
|
160
|
+
metadata: {}
|
161
|
+
post_install_message: ':: Coded for blinkbox books :: Love books, love code? Get in
|
162
|
+
touch ::'
|
163
|
+
rdoc_options: []
|
164
|
+
require_paths:
|
165
|
+
- lib
|
166
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
167
|
+
requirements:
|
168
|
+
- - ! '>='
|
169
|
+
- !ruby/object:Gem::Version
|
170
|
+
version: '0'
|
171
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
172
|
+
requirements:
|
173
|
+
- - ! '>='
|
174
|
+
- !ruby/object:Gem::Version
|
175
|
+
version: '0'
|
176
|
+
requirements: []
|
177
|
+
rubyforge_project:
|
178
|
+
rubygems_version: 2.4.5
|
179
|
+
signing_key:
|
180
|
+
specification_version: 4
|
181
|
+
summary: Captures http responses from a number of libraries for testing.
|
182
|
+
test_files:
|
183
|
+
- spec/capture_spec.rb
|
184
|
+
- spec/httparty/capture_spec.rb
|
185
|
+
- spec/httpclient/capture_spec.rb
|
186
|
+
- spec/mechanize/capture_spec.rb
|
187
|
+
- spec/net/http/capture_spec.rb
|
188
|
+
- spec/rack/test/capture_spec.rb
|
189
|
+
- spec/spec_helper.rb
|