artifice 0.5
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.
- data/LICENSE +22 -0
- data/lib/artifice.rb +131 -0
- metadata +76 -0
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2010 Yehuda Katz
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person
|
4
|
+
obtaining a copy of this software and associated documentation
|
5
|
+
files (the "Software"), to deal in the Software without
|
6
|
+
restriction, including without limitation the rights to use,
|
7
|
+
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
8
|
+
copies of the Software, and to permit persons to whom the
|
9
|
+
Software is furnished to do so, subject to the following
|
10
|
+
conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be
|
13
|
+
included in all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
17
|
+
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
19
|
+
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
20
|
+
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
21
|
+
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
22
|
+
OTHER DEALINGS IN THE SOFTWARE.
|
data/lib/artifice.rb
ADDED
@@ -0,0 +1,131 @@
|
|
1
|
+
require "rack/test"
|
2
|
+
require "net/http"
|
3
|
+
require "net/https"
|
4
|
+
|
5
|
+
module Artifice
|
6
|
+
NET_HTTP = ::Net::HTTP
|
7
|
+
|
8
|
+
# Activate Artifice with a particular Rack endpoint.
|
9
|
+
#
|
10
|
+
# Calling this method will replace the Net::HTTP system
|
11
|
+
# with a replacement that routes all requests to the
|
12
|
+
# Rack endpoint.
|
13
|
+
#
|
14
|
+
# @param [#call] endpoint A valid Rack endpoint
|
15
|
+
# @yield An optional block that uses Net::HTTP
|
16
|
+
# In this case, Artifice will be used only for
|
17
|
+
# the duration of the block
|
18
|
+
def self.activate_with(endpoint)
|
19
|
+
Net::HTTP.endpoint = endpoint
|
20
|
+
replace_net_http(Artifice::Net::HTTP)
|
21
|
+
|
22
|
+
if block_given?
|
23
|
+
yield
|
24
|
+
deactivate
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
# Deactivate the Artifice replacement.
|
29
|
+
def self.deactivate
|
30
|
+
replace_net_http(NET_HTTP)
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
def self.replace_net_http(value)
|
35
|
+
::Net.class_eval do
|
36
|
+
remove_const(:HTTP)
|
37
|
+
const_set(:HTTP, value)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
module Net
|
42
|
+
# This is an internal object that can receive Rack requests
|
43
|
+
# to the application using the Rack::Test API
|
44
|
+
class RackRequest
|
45
|
+
include Rack::Test::Methods
|
46
|
+
attr_reader :app
|
47
|
+
|
48
|
+
def initialize(app)
|
49
|
+
@app = app
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
class HTTP < ::Net::HTTP
|
54
|
+
class << self
|
55
|
+
attr_accessor :endpoint
|
56
|
+
end
|
57
|
+
|
58
|
+
# Net::HTTP uses a @newimpl instance variable to decide whether
|
59
|
+
# to use a legacy implementation. Since we are subclassing
|
60
|
+
# Net::HTTP, we must set it
|
61
|
+
@newimpl = true
|
62
|
+
|
63
|
+
# We don't need to connect, so blank out this method
|
64
|
+
def connect
|
65
|
+
end
|
66
|
+
|
67
|
+
# Replace the Net::HTTP request method with a method
|
68
|
+
# that converts the request into a Rack request and
|
69
|
+
# dispatches it to the Rack endpoint.
|
70
|
+
#
|
71
|
+
# @param [Net::HTTPRequest] req A Net::HTTPRequest
|
72
|
+
# object, or one if its subclasses
|
73
|
+
# @param [optional, String, #read] body This should
|
74
|
+
# be sent as "rack.input". If it's a String, it will
|
75
|
+
# be converted to a StringIO.
|
76
|
+
# @return [Net::HTTPResponse]
|
77
|
+
#
|
78
|
+
# @yield [Net::HTTPResponse] If a block is provided,
|
79
|
+
# this method will yield the Net::HTTPResponse to
|
80
|
+
# it after the body is read.
|
81
|
+
def request(req, body = nil, &block)
|
82
|
+
rack_request = RackRequest.new(self.class.endpoint)
|
83
|
+
|
84
|
+
req.each_header do |header, value|
|
85
|
+
rack_request.header(header, value)
|
86
|
+
end
|
87
|
+
|
88
|
+
scheme = use_ssl? ? "https" : "http"
|
89
|
+
prefix = "#{scheme}://#{addr_port}"
|
90
|
+
|
91
|
+
response = rack_request.request("#{prefix}#{req.path}",
|
92
|
+
{:method => req.method, :input => body})
|
93
|
+
|
94
|
+
make_net_http_response(response, &block)
|
95
|
+
end
|
96
|
+
|
97
|
+
private
|
98
|
+
|
99
|
+
# This method takes a Rack response and creates a Net::HTTPResponse
|
100
|
+
# Instead of trying to mock HTTPResponse directly, we just convert
|
101
|
+
# the Rack response into a String that looks like a normal HTTP
|
102
|
+
# response and call Net::HTTPResponse.read_new
|
103
|
+
#
|
104
|
+
# @param [Array(#to_i, Hash, #each)] response a Rack response
|
105
|
+
# @return [Net::HTTPResponse]
|
106
|
+
# @yield [Net::HTTPResponse] If a block is provided, yield the
|
107
|
+
# response to it after the body is read
|
108
|
+
def make_net_http_response(response)
|
109
|
+
status, headers, body = response.status, response.headers, response.body
|
110
|
+
|
111
|
+
response_string = []
|
112
|
+
response_string << "HTTP/1.1 #{status} #{Rack::Utils::HTTP_STATUS_CODES[status]}"
|
113
|
+
|
114
|
+
headers.each do |header, value|
|
115
|
+
response_string << "#{header}: #{value}"
|
116
|
+
end
|
117
|
+
|
118
|
+
response_string << "" << body
|
119
|
+
|
120
|
+
response_io = ::Net::BufferedIO.new(StringIO.new(response_string.join("\n")))
|
121
|
+
res = ::Net::HTTPResponse.read_new(response_io)
|
122
|
+
|
123
|
+
res.reading_body(response_io, true) do
|
124
|
+
yield res if block_given?
|
125
|
+
end
|
126
|
+
|
127
|
+
res
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
metadata
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: artifice
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 5
|
8
|
+
version: "0.5"
|
9
|
+
platform: ruby
|
10
|
+
authors:
|
11
|
+
- Yehuda Katz
|
12
|
+
autorequire:
|
13
|
+
bindir: bin
|
14
|
+
cert_chain: []
|
15
|
+
|
16
|
+
date: 2010-03-24 00:00:00 -07:00
|
17
|
+
default_executable:
|
18
|
+
dependencies:
|
19
|
+
- !ruby/object:Gem::Dependency
|
20
|
+
name: rack-test
|
21
|
+
prerelease: false
|
22
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
segments:
|
27
|
+
- 0
|
28
|
+
version: "0"
|
29
|
+
type: :runtime
|
30
|
+
version_requirements: *id001
|
31
|
+
description: Replaces Net::HTTP with a subclass that routes all requests to a Rack application
|
32
|
+
email: wycats@gmail.com
|
33
|
+
executables: []
|
34
|
+
|
35
|
+
extensions: []
|
36
|
+
|
37
|
+
extra_rdoc_files: []
|
38
|
+
|
39
|
+
files:
|
40
|
+
- LICENSE
|
41
|
+
- lib/artifice.rb
|
42
|
+
has_rdoc: true
|
43
|
+
homepage: http://www.yehudakatz.com
|
44
|
+
licenses: []
|
45
|
+
|
46
|
+
post_install_message:
|
47
|
+
rdoc_options:
|
48
|
+
- --exclude
|
49
|
+
- .
|
50
|
+
require_paths:
|
51
|
+
- lib
|
52
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
53
|
+
requirements:
|
54
|
+
- - ">="
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
segments:
|
57
|
+
- 1
|
58
|
+
- 8
|
59
|
+
- 6
|
60
|
+
version: 1.8.6
|
61
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
62
|
+
requirements:
|
63
|
+
- - ">="
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
segments:
|
66
|
+
- 0
|
67
|
+
version: "0"
|
68
|
+
requirements: []
|
69
|
+
|
70
|
+
rubyforge_project: artifice
|
71
|
+
rubygems_version: 1.3.6
|
72
|
+
signing_key:
|
73
|
+
specification_version: 3
|
74
|
+
summary: Use a Rack application for mock HTTP requests
|
75
|
+
test_files: []
|
76
|
+
|