sham_rack 1.3.2 → 1.3.3
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/CHANGES.markdown +4 -0
- data/README.markdown +40 -4
- data/Rakefile +5 -1
- data/lib/sham_rack/net_http.rb +26 -51
- data/lib/sham_rack/patron.rb +64 -0
- data/lib/sham_rack/version.rb +1 -1
- data/spec/sham_rack_spec.rb +82 -92
- data/spec/spec_helper.rb +2 -4
- data/spec/test_apps.rb +48 -0
- metadata +22 -6
data/CHANGES.markdown
CHANGED
data/README.markdown
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
ShamRack
|
2
2
|
========
|
3
3
|
|
4
|
-
ShamRack plumbs
|
4
|
+
ShamRack plumbs HTTP requests into [Rack][rack].
|
5
5
|
|
6
6
|
What's it for, again?
|
7
7
|
---------------------
|
8
8
|
|
9
9
|
Well, it makes it easy to _stub out external (HTTP) services_, which is handy in development and testing environments, or when you want to _test your HTTP client code_.
|
10
10
|
|
11
|
-
You can also use it to _test your Rack application_ (or Sinatra, or Rails, or Merb) using
|
11
|
+
You can also use it to _test your Rack application_ (or Sinatra, or Rails, or Merb) using a variety of HTTP client libraries, to check interoperability. For instance, you could test your app using:
|
12
12
|
|
13
13
|
* [`rest-client`][rest-client]
|
14
14
|
* [`httparty`][httparty]
|
@@ -28,12 +28,12 @@ Using it
|
|
28
28
|
|
29
29
|
require 'sham_rack'
|
30
30
|
|
31
|
-
ShamRack.at("www.
|
31
|
+
ShamRack.at("www.greetings.com") do |env|
|
32
32
|
["200 OK", { "Content-type" => "text/plain" }, "Hello, world!"]
|
33
33
|
end
|
34
34
|
|
35
35
|
require 'open-uri'
|
36
|
-
open("http://www.
|
36
|
+
open("http://www.greetings.com/").read #=> "Hello, world!"
|
37
37
|
|
38
38
|
### Sinatra integration
|
39
39
|
|
@@ -67,6 +67,40 @@ Using it
|
|
67
67
|
|
68
68
|
Or, just use Sinatra, as described above ... it's almost as succinct, and heaps more powerful.
|
69
69
|
|
70
|
+
### When you're done testing
|
71
|
+
|
72
|
+
ShamRack.unmount_all
|
73
|
+
|
74
|
+
open("http://stubbed.com/greeting").read #=> OpenURI::HTTPError
|
75
|
+
|
76
|
+
Supported HTTP client libraries
|
77
|
+
-------------------------------
|
78
|
+
|
79
|
+
### Net::HTTP and friends
|
80
|
+
|
81
|
+
ShamRack supports requests made using Net::HTTP, or any of the numerous APIs built on top of it:
|
82
|
+
|
83
|
+
uri = URI.parse("http://www.greetings.com/")
|
84
|
+
Net::HTTP.get_response(uri).body #=> "Hello, world!"
|
85
|
+
|
86
|
+
require 'open-uri'
|
87
|
+
open("http://www.greetings.com/").read #=> "Hello, world!"
|
88
|
+
|
89
|
+
require 'restclient'
|
90
|
+
RestClient.get("http://www.greetings.com/").to_s #=> "Hello, world!"
|
91
|
+
|
92
|
+
require 'mechanize'
|
93
|
+
Mechanize.new.get("http://www.greetings.com/").body #=> "Hello, world!"
|
94
|
+
|
95
|
+
### Patron (experimental)
|
96
|
+
|
97
|
+
We've recently added support for [Patron][patron]:
|
98
|
+
|
99
|
+
require 'sham_rack/patron'
|
100
|
+
|
101
|
+
patron = Patron::Session.new
|
102
|
+
patron.get("http://www.greetings.com/").body #=> "Hello, world!"
|
103
|
+
|
70
104
|
What's the catch?
|
71
105
|
-----------------
|
72
106
|
|
@@ -85,3 +119,5 @@ Thanks to
|
|
85
119
|
[httparty]: http://github.com/jnunemaker/httparty
|
86
120
|
[oauth]: http://oauth.rubyforge.org/
|
87
121
|
[fakeweb]: http://fakeweb.rubyforge.org/
|
122
|
+
[mechanize]: http://mechanize.rubyforge.org
|
123
|
+
[patron]: http://github.com/toland/Patron
|
data/Rakefile
CHANGED
@@ -6,6 +6,10 @@ require "spec/rake/spectask"
|
|
6
6
|
task "default" => "spec"
|
7
7
|
|
8
8
|
Spec::Rake::SpecTask.new do |t|
|
9
|
-
t.spec_opts = ["--colour", "--format", "
|
9
|
+
t.spec_opts = ["--colour", "--format", "nested"]
|
10
10
|
t.spec_files = FileList['spec/**/*_spec.rb']
|
11
11
|
end
|
12
|
+
|
13
|
+
require 'bundler'
|
14
|
+
|
15
|
+
Bundler::GemHelper.install_tasks
|
data/lib/sham_rack/net_http.rb
CHANGED
@@ -33,66 +33,41 @@ module ShamRack
|
|
33
33
|
end
|
34
34
|
end
|
35
35
|
|
36
|
-
def request(
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
env.merge!(io_env(req, body))
|
42
|
-
response = build_response(@rack_app.call(env))
|
43
|
-
yield response if block_given?
|
44
|
-
return response
|
36
|
+
def request(request, body = nil)
|
37
|
+
rack_response = @rack_app.call(rack_env(request, body))
|
38
|
+
net_http_response = build_response(rack_response)
|
39
|
+
yield net_http_response if block_given?
|
40
|
+
return net_http_response
|
45
41
|
end
|
46
42
|
|
47
43
|
private
|
48
44
|
|
49
|
-
def
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
"SERVER_PORT" => @port.to_s,
|
54
|
-
"rack.version" => [0,1],
|
55
|
-
"rack.url_scheme" => "http",
|
56
|
-
"rack.multithread" => true,
|
57
|
-
"rack.multiprocess" => true,
|
58
|
-
"rack.run_once" => false
|
59
|
-
}
|
45
|
+
def rack_env(request, body)
|
46
|
+
rack_env = request_env(request, body)
|
47
|
+
rack_env.merge!(header_env(request))
|
48
|
+
rack_env.merge!(server_env)
|
60
49
|
end
|
61
|
-
|
62
|
-
def
|
50
|
+
|
51
|
+
def server_env
|
63
52
|
{
|
64
|
-
"
|
53
|
+
"SERVER_NAME" => @address,
|
54
|
+
"SERVER_PORT" => @port.to_s
|
65
55
|
}
|
66
56
|
end
|
67
|
-
|
68
|
-
def io_env(request, body)
|
69
|
-
raise(ArgumentError, "both request.body and body argument were provided") if (request.body && body)
|
70
|
-
body ||= request.body || ""
|
71
|
-
body = body.to_s
|
72
|
-
body = body.encode("ASCII-8BIT") if body.respond_to?(:encode)
|
73
|
-
{
|
74
|
-
"rack.input" => StringIO.new(body),
|
75
|
-
"rack.errors" => $stderr
|
76
|
-
}
|
77
|
-
end
|
78
|
-
|
79
|
-
def path_env(path)
|
80
|
-
uri = URI.parse(path)
|
81
|
-
{
|
82
|
-
"PATH_INFO" => uri.path,
|
83
|
-
"QUERY_STRING" => (uri.query || ""),
|
84
|
-
}
|
85
|
-
end
|
86
|
-
|
57
|
+
|
87
58
|
def header_env(request)
|
88
|
-
|
89
|
-
request.
|
90
|
-
|
59
|
+
env = {}
|
60
|
+
request.each_header do |header, content|
|
61
|
+
key = header.upcase.gsub('-', '_')
|
62
|
+
key = "HTTP_" + key unless key =~ /^CONTENT_(TYPE|LENGTH)$/
|
63
|
+
env[key] = content
|
91
64
|
end
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
65
|
+
env
|
66
|
+
end
|
67
|
+
|
68
|
+
def request_env(request, body)
|
69
|
+
body ||= request.body || ""
|
70
|
+
Rack::MockRequest.env_for(request.path, :method => request.method, :input => body.to_s)
|
96
71
|
end
|
97
72
|
|
98
73
|
def build_response(rack_response)
|
@@ -111,7 +86,7 @@ module ShamRack
|
|
111
86
|
def assemble_body(body)
|
112
87
|
content = ""
|
113
88
|
body.each { |fragment| content << fragment }
|
114
|
-
|
89
|
+
content
|
115
90
|
end
|
116
91
|
|
117
92
|
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require "patron"
|
2
|
+
require "sham_rack/registry"
|
3
|
+
require "uri"
|
4
|
+
|
5
|
+
module Patron
|
6
|
+
|
7
|
+
class Session
|
8
|
+
|
9
|
+
alias :handle_request_without_sham_rack :handle_request
|
10
|
+
|
11
|
+
def handle_request(patron_request)
|
12
|
+
uri = URI.parse(patron_request.url)
|
13
|
+
rack_app = ShamRack.application_for(uri.host, uri.port)
|
14
|
+
if rack_app
|
15
|
+
handle_request_with_rack(patron_request, rack_app)
|
16
|
+
else
|
17
|
+
handle_request_without_sham_rack(patron_request)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def handle_request_with_rack(patron_request, rack_app)
|
24
|
+
env = rack_env_for(patron_request)
|
25
|
+
rack_response = rack_app.call(env)
|
26
|
+
patron_response(rack_response)
|
27
|
+
end
|
28
|
+
|
29
|
+
def rack_env_for(patron_request)
|
30
|
+
env = Rack::MockRequest.env_for(patron_request.url, :method => patron_request.action, :input => patron_request.upload_data)
|
31
|
+
env.merge!(header_env(patron_request))
|
32
|
+
env
|
33
|
+
end
|
34
|
+
|
35
|
+
def patron_response(rack_response)
|
36
|
+
status, headers, body = rack_response
|
37
|
+
status_code = Rack::Utils::HTTP_STATUS_CODES[status.to_i]
|
38
|
+
res = Patron::Response.new
|
39
|
+
res.instance_variable_set(:@status, status)
|
40
|
+
res.instance_variable_set(:@status_line, "HTTP/1.1 #{status} #{status_code}")
|
41
|
+
res.instance_variable_set(:@body, assemble_body(body))
|
42
|
+
res.instance_variable_set(:@headers, headers)
|
43
|
+
res
|
44
|
+
end
|
45
|
+
|
46
|
+
def header_env(patron_request)
|
47
|
+
env = {}
|
48
|
+
patron_request.headers.each do |header, content|
|
49
|
+
key = header.upcase.gsub('-', '_')
|
50
|
+
key = "HTTP_" + key unless key =~ /^CONTENT_(TYPE|LENGTH)$/
|
51
|
+
env[key] = content
|
52
|
+
end
|
53
|
+
env
|
54
|
+
end
|
55
|
+
|
56
|
+
def assemble_body(body)
|
57
|
+
content = ""
|
58
|
+
body.each { |fragment| content << fragment }
|
59
|
+
content
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
data/lib/sham_rack/version.rb
CHANGED
data/spec/sham_rack_spec.rb
CHANGED
@@ -1,62 +1,12 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
|
3
3
|
require "sham_rack"
|
4
|
+
require "sham_rack/patron"
|
4
5
|
require "open-uri"
|
5
6
|
require "restclient"
|
6
7
|
require "mechanize"
|
7
8
|
require "rack"
|
8
9
|
|
9
|
-
class PlainTextApp
|
10
|
-
|
11
|
-
def call(env)
|
12
|
-
[
|
13
|
-
"200 OK",
|
14
|
-
{ "Content-Type" => "text/plain", "Content-Length" => message.length.to_s },
|
15
|
-
[message]
|
16
|
-
]
|
17
|
-
end
|
18
|
-
|
19
|
-
end
|
20
|
-
|
21
|
-
class SimpleMessageApp < PlainTextApp
|
22
|
-
|
23
|
-
def initialize(message)
|
24
|
-
@message = message
|
25
|
-
end
|
26
|
-
|
27
|
-
attr_reader :message
|
28
|
-
|
29
|
-
end
|
30
|
-
|
31
|
-
class EnvRecordingApp < PlainTextApp
|
32
|
-
|
33
|
-
def call(env)
|
34
|
-
@last_env = env
|
35
|
-
super
|
36
|
-
end
|
37
|
-
|
38
|
-
attr_reader :last_env
|
39
|
-
|
40
|
-
def message
|
41
|
-
"env stored for later perusal"
|
42
|
-
end
|
43
|
-
|
44
|
-
end
|
45
|
-
|
46
|
-
class UpcaseBody
|
47
|
-
|
48
|
-
def initialize(app)
|
49
|
-
@app = app
|
50
|
-
end
|
51
|
-
|
52
|
-
def call(env)
|
53
|
-
status, headers, body = @app.call(env)
|
54
|
-
upcased_body = Array(body).map { |x| x.upcase }
|
55
|
-
[status, headers, upcased_body]
|
56
|
-
end
|
57
|
-
|
58
|
-
end
|
59
|
-
|
60
10
|
describe ShamRack do
|
61
11
|
|
62
12
|
after(:each) do
|
@@ -66,71 +16,46 @@ describe ShamRack do
|
|
66
16
|
describe "mounted Rack application" do
|
67
17
|
|
68
18
|
before(:each) do
|
69
|
-
ShamRack.mount(
|
19
|
+
ShamRack.mount(GreetingApp.new, "www.greetings.com")
|
70
20
|
end
|
71
21
|
|
72
22
|
it "can be accessed using Net::HTTP" do
|
73
|
-
response = Net::HTTP.start("www.
|
23
|
+
response = Net::HTTP.start("www.greetings.com") do |http|
|
74
24
|
http.request(Net::HTTP::Get.new("/"))
|
75
25
|
end
|
76
26
|
response.body.should == "Hello, world"
|
77
27
|
end
|
78
28
|
|
79
29
|
it "can be accessed using Net::HTTP#get_response" do
|
80
|
-
response = Net::HTTP.get_response(URI.parse("http://www.
|
30
|
+
response = Net::HTTP.get_response(URI.parse("http://www.greetings.com/"))
|
81
31
|
response.body.should == "Hello, world"
|
82
32
|
end
|
83
33
|
|
84
34
|
it "can be accessed using open-uri" do
|
85
|
-
response = open("http://www.
|
35
|
+
response = open("http://www.greetings.com")
|
86
36
|
response.status.should == ["200", "OK"]
|
87
37
|
response.read.should == "Hello, world"
|
88
38
|
end
|
89
39
|
|
90
40
|
it "can be accessed using RestClient" do
|
91
|
-
response = RestClient.get("http://www.
|
41
|
+
response = RestClient.get("http://www.greetings.com")
|
92
42
|
response.code.should == 200
|
93
43
|
response.to_s.should == "Hello, world"
|
94
44
|
end
|
95
45
|
|
96
|
-
it "can be accessed using
|
97
|
-
response = Mechanize.new.get("http://www.
|
46
|
+
it "can be accessed using Mechanize" do
|
47
|
+
response = Mechanize.new.get("http://www.greetings.com")
|
98
48
|
response.body.should == "Hello, world"
|
99
49
|
end
|
100
50
|
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
before(:each) do
|
106
|
-
ShamRack.at("www.test.xyz") do
|
107
|
-
[
|
108
|
-
"201 Created",
|
109
|
-
{ "Content-Type" => "text/plain", "X-Foo" => "bar" },
|
110
|
-
["BODY"]
|
111
|
-
]
|
112
|
-
end
|
113
|
-
@response = Net::HTTP.get_response(URI.parse("http://www.test.xyz/"))
|
114
|
-
end
|
115
|
-
|
116
|
-
it "has status returned by app" do
|
117
|
-
@response.code.should == "201"
|
51
|
+
it "can be accessed using Patron" do
|
52
|
+
patron = Patron::Session.new
|
53
|
+
response = patron.get("http://www.greetings.com/foo/bar")
|
54
|
+
response.body.should == "Hello, world"
|
118
55
|
end
|
119
56
|
|
120
|
-
it "has body returned by app" do
|
121
|
-
@response.body.should == "BODY"
|
122
|
-
end
|
123
|
-
|
124
|
-
it "has Content-Type returned by app" do
|
125
|
-
@response.content_type.should == "text/plain"
|
126
|
-
end
|
127
|
-
|
128
|
-
it "has other headers returned by app" do
|
129
|
-
@response["x-foo"].should =="bar"
|
130
|
-
end
|
131
|
-
|
132
57
|
end
|
133
|
-
|
58
|
+
|
134
59
|
describe ".at" do
|
135
60
|
|
136
61
|
describe "with a block" do
|
@@ -152,12 +77,12 @@ describe ShamRack do
|
|
152
77
|
before do
|
153
78
|
@return_value = ShamRack.at("rackup.xyz").rackup do
|
154
79
|
use UpcaseBody
|
155
|
-
run
|
80
|
+
run GreetingApp.new
|
156
81
|
end
|
157
82
|
end
|
158
83
|
|
159
84
|
it "mounts an app created using Rack::Builder" do
|
160
|
-
open("http://rackup.xyz").read.should == "
|
85
|
+
open("http://rackup.xyz").read.should == "HELLO, WORLD"
|
161
86
|
end
|
162
87
|
|
163
88
|
it "returns the app" do
|
@@ -204,10 +129,41 @@ describe ShamRack do
|
|
204
129
|
|
205
130
|
end
|
206
131
|
|
132
|
+
describe "response" do
|
133
|
+
|
134
|
+
before(:each) do
|
135
|
+
ShamRack.at("www.greetings.com") do
|
136
|
+
[
|
137
|
+
"201 Created",
|
138
|
+
{ "Content-Type" => "text/plain", "X-Foo" => "bar" },
|
139
|
+
["BODY"]
|
140
|
+
]
|
141
|
+
end
|
142
|
+
@response = Net::HTTP.get_response(URI.parse("http://www.greetings.com/"))
|
143
|
+
end
|
144
|
+
|
145
|
+
it "has status returned by app" do
|
146
|
+
@response.code.should == "201"
|
147
|
+
end
|
148
|
+
|
149
|
+
it "has body returned by app" do
|
150
|
+
@response.body.should == "BODY"
|
151
|
+
end
|
152
|
+
|
153
|
+
it "has Content-Type returned by app" do
|
154
|
+
@response.content_type.should == "text/plain"
|
155
|
+
end
|
156
|
+
|
157
|
+
it "has other headers returned by app" do
|
158
|
+
@response["x-foo"].should =="bar"
|
159
|
+
end
|
160
|
+
|
161
|
+
end
|
162
|
+
|
207
163
|
describe "Rack environment" do
|
208
164
|
|
209
165
|
before(:each) do
|
210
|
-
@env_recorder = recorder =
|
166
|
+
@env_recorder = recorder = EnvRecorder.new(GreetingApp.new)
|
211
167
|
ShamRack.at("env.xyz").rackup do
|
212
168
|
use Rack::Lint
|
213
169
|
run recorder
|
@@ -229,7 +185,7 @@ describe ShamRack do
|
|
229
185
|
env["SERVER_NAME"].should == "env.xyz"
|
230
186
|
env["SERVER_PORT"].should == "80"
|
231
187
|
|
232
|
-
env["rack.version"].should
|
188
|
+
env["rack.version"].should be_kind_of(Array)
|
233
189
|
env["rack.url_scheme"].should == "http"
|
234
190
|
|
235
191
|
env["rack.multithread"].should == true
|
@@ -271,6 +227,19 @@ describe ShamRack do
|
|
271
227
|
|
272
228
|
end
|
273
229
|
|
230
|
+
it "supports POST using Patron" do
|
231
|
+
|
232
|
+
patron = Patron::Session.new
|
233
|
+
response = patron.post("http://env.xyz/resource", "<xml/>", "Content-Type" => "application/xml")
|
234
|
+
|
235
|
+
response.status.should == "200 OK"
|
236
|
+
|
237
|
+
env["REQUEST_METHOD"].should == "POST"
|
238
|
+
env["rack.input"].read.should == "<xml/>"
|
239
|
+
env["CONTENT_TYPE"].should == "application/xml"
|
240
|
+
|
241
|
+
end
|
242
|
+
|
274
243
|
it "supports PUT" do
|
275
244
|
|
276
245
|
RestClient.put("http://env.xyz/thing1", "stuff", :content_type => "text/plain")
|
@@ -281,6 +250,17 @@ describe ShamRack do
|
|
281
250
|
|
282
251
|
end
|
283
252
|
|
253
|
+
it "supports PUT using Patron" do
|
254
|
+
|
255
|
+
patron = Patron::Session.new
|
256
|
+
response = patron.put("http://env.xyz/resource", "stuff", "Content-Type" => "text/plain")
|
257
|
+
|
258
|
+
env["REQUEST_METHOD"].should == "PUT"
|
259
|
+
env["CONTENT_TYPE"].should == "text/plain"
|
260
|
+
env["rack.input"].read.should == "stuff"
|
261
|
+
|
262
|
+
end
|
263
|
+
|
284
264
|
it "supports DELETE" do
|
285
265
|
|
286
266
|
RestClient.delete("http://env.xyz/thing/1")
|
@@ -290,6 +270,16 @@ describe ShamRack do
|
|
290
270
|
|
291
271
|
end
|
292
272
|
|
273
|
+
it "supports DELETE using Patron" do
|
274
|
+
|
275
|
+
patron = Patron::Session.new
|
276
|
+
response = patron.delete("http://env.xyz/resource")
|
277
|
+
|
278
|
+
env["REQUEST_METHOD"].should == "DELETE"
|
279
|
+
env["PATH_INFO"].should == "/resource"
|
280
|
+
|
281
|
+
end
|
282
|
+
|
293
283
|
end
|
294
284
|
|
295
285
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -2,10 +2,8 @@ require "rubygems"
|
|
2
2
|
require "spec"
|
3
3
|
require "rr"
|
4
4
|
|
5
|
-
project_root = File.expand_path("#{__FILE__}/../..")
|
6
|
-
$LOAD_PATH << "#{project_root}/lib"
|
7
|
-
$LOAD_PATH << "#{project_root}/spec/support/lib"
|
8
|
-
|
9
5
|
Spec::Runner.configure do |config|
|
10
6
|
config.mock_with RR::Adapters::Rspec
|
11
7
|
end
|
8
|
+
|
9
|
+
require "test_apps"
|
data/spec/test_apps.rb
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
require "rack"
|
2
|
+
|
3
|
+
class GreetingApp
|
4
|
+
|
5
|
+
include Rack::Utils
|
6
|
+
|
7
|
+
def call(env)
|
8
|
+
params = parse_nested_query(env["QUERY_STRING"])
|
9
|
+
salutation = params[:salutation] || "Hello"
|
10
|
+
subject = params[:subject] || "world"
|
11
|
+
message = "#{salutation}, #{subject}"
|
12
|
+
[
|
13
|
+
"200 OK",
|
14
|
+
{ "Content-Type" => "text/plain", "Content-Length" => message.length.to_s },
|
15
|
+
[message]
|
16
|
+
]
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
class EnvRecorder
|
22
|
+
|
23
|
+
def initialize(app)
|
24
|
+
@app = app
|
25
|
+
end
|
26
|
+
|
27
|
+
def call(env)
|
28
|
+
@last_env = env
|
29
|
+
@app.call(env)
|
30
|
+
end
|
31
|
+
|
32
|
+
attr_reader :last_env
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
class UpcaseBody
|
37
|
+
|
38
|
+
def initialize(app)
|
39
|
+
@app = app
|
40
|
+
end
|
41
|
+
|
42
|
+
def call(env)
|
43
|
+
status, headers, body = @app.call(env)
|
44
|
+
upcased_body = Array(body).map { |x| x.upcase }
|
45
|
+
[status, headers, upcased_body]
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sham_rack
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 29
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 1
|
8
8
|
- 3
|
9
|
-
-
|
10
|
-
version: 1.3.
|
9
|
+
- 3
|
10
|
+
version: 1.3.3
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Mike Williams
|
@@ -15,10 +15,23 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2010-
|
18
|
+
date: 2010-12-22 00:00:00 +11:00
|
19
19
|
default_executable:
|
20
|
-
dependencies:
|
21
|
-
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: rack
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 3
|
30
|
+
segments:
|
31
|
+
- 0
|
32
|
+
version: "0"
|
33
|
+
type: :runtime
|
34
|
+
version_requirements: *id001
|
22
35
|
description: ShamRack plumbs Net::HTTP directly into Rack, for quick and easy HTTP testing.
|
23
36
|
email: mdub@dogbiscuit.org
|
24
37
|
executables: []
|
@@ -29,6 +42,7 @@ extra_rdoc_files: []
|
|
29
42
|
|
30
43
|
files:
|
31
44
|
- lib/sham_rack/net_http.rb
|
45
|
+
- lib/sham_rack/patron.rb
|
32
46
|
- lib/sham_rack/registry.rb
|
33
47
|
- lib/sham_rack/stub_web_service.rb
|
34
48
|
- lib/sham_rack/version.rb
|
@@ -38,6 +52,7 @@ files:
|
|
38
52
|
- spec/sham_rack/stub_web_service_spec.rb
|
39
53
|
- spec/sham_rack_spec.rb
|
40
54
|
- spec/spec_helper.rb
|
55
|
+
- spec/test_apps.rb
|
41
56
|
- Rakefile
|
42
57
|
- benchmark/benchmark.rb
|
43
58
|
- benchmark/hello_app.rb
|
@@ -79,6 +94,7 @@ test_files:
|
|
79
94
|
- spec/sham_rack/stub_web_service_spec.rb
|
80
95
|
- spec/sham_rack_spec.rb
|
81
96
|
- spec/spec_helper.rb
|
97
|
+
- spec/test_apps.rb
|
82
98
|
- Rakefile
|
83
99
|
- benchmark/benchmark.rb
|
84
100
|
- benchmark/hello_app.rb
|