hatetepe 0.5.2 → 0.6.0.pre
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +7 -0
- data/.rspec +3 -0
- data/.travis.yml +4 -0
- data/.yardopts +1 -0
- data/Gemfile +9 -4
- data/Gemfile.devtools +55 -0
- data/LICENSE.txt +22 -0
- data/README.md +39 -192
- data/Rakefile +3 -2
- data/bin/hatetepe +35 -2
- data/config/devtools.yml +2 -0
- data/config/flay.yml +3 -0
- data/config/flog.yml +2 -0
- data/config/mutant.yml +3 -0
- data/config/reek.yml +103 -0
- data/config/rubocop.yml +58 -0
- data/config/yardstick.yml +2 -0
- data/hatetepe.gemspec +23 -27
- data/lib/hatetepe/client/keep_alive.rb +59 -0
- data/lib/hatetepe/client/timeouts.rb +19 -0
- data/lib/hatetepe/client.rb +54 -302
- data/lib/hatetepe/connection/eventmachine.rb +61 -0
- data/lib/hatetepe/connection/status.rb +28 -0
- data/lib/hatetepe/errors.rb +7 -0
- data/lib/hatetepe/promise.rb +86 -0
- data/lib/hatetepe/request.rb +15 -39
- data/lib/hatetepe/response.rb +82 -22
- data/lib/hatetepe/serializer/encoding.rb +58 -0
- data/lib/hatetepe/serializer.rb +61 -0
- data/lib/hatetepe/server/keep_alive.rb +53 -13
- data/lib/hatetepe/server/timeouts.rb +17 -0
- data/lib/hatetepe/server.rb +37 -85
- data/lib/hatetepe/support/handlers.rb +19 -0
- data/lib/hatetepe/support/keep_alive.rb +14 -0
- data/lib/hatetepe/support/message.rb +40 -0
- data/lib/hatetepe/version.rb +3 -1
- data/lib/hatetepe.rb +29 -7
- data/spec/integration/error_handling_spec.rb +7 -0
- data/spec/integration/keep_alive_spec.rb +106 -0
- data/spec/integration/smoke_spec.rb +21 -0
- data/spec/integration/streaming_spec.rb +61 -0
- data/spec/integration/timeouts_spec.rb +82 -0
- data/spec/shared/integration/server_client_pair.rb +26 -0
- data/spec/spec_helper.rb +41 -10
- data/spec/support/handler.rb +55 -0
- data/spec/support/helper.rb +74 -0
- data/spec/unit/client_spec.rb +115 -156
- data/spec/unit/connection/eventmachine_spec.rb +146 -0
- data/spec/unit/request_spec.rb +35 -0
- data/spec/unit/response_spec.rb +42 -0
- data/spec/unit/server_spec.rb +65 -100
- data/spec/unit/support/keep_alive_spec.rb +52 -0
- data/spec/unit/support/message_spec.rb +41 -0
- metadata +68 -103
- data/Gemfile.lock +0 -46
- data/LICENSE +0 -19
- data/Procfile +0 -1
- data/config.ru +0 -7
- data/examples/parallel_requests.rb +0 -32
- data/lib/hatetepe/body.rb +0 -182
- data/lib/hatetepe/builder.rb +0 -171
- data/lib/hatetepe/cli.rb +0 -61
- data/lib/hatetepe/connection.rb +0 -73
- data/lib/hatetepe/events.rb +0 -35
- data/lib/hatetepe/message.rb +0 -13
- data/lib/hatetepe/parser.rb +0 -83
- data/lib/hatetepe/server/pipeline.rb +0 -20
- data/lib/hatetepe/server/rack_app.rb +0 -39
- data/lib/rack/handler/hatetepe.rb +0 -33
- data/spec/integration/cli/start_spec.rb +0 -113
- data/spec/integration/client/keep_alive_spec.rb +0 -23
- data/spec/integration/client/timeout_spec.rb +0 -97
- data/spec/integration/server/keep_alive_spec.rb +0 -27
- data/spec/integration/server/timeout_spec.rb +0 -51
- data/spec/unit/body_spec.rb +0 -205
- data/spec/unit/builder_spec.rb +0 -372
- data/spec/unit/connection_spec.rb +0 -62
- data/spec/unit/events_spec.rb +0 -96
- data/spec/unit/parser_spec.rb +0 -209
- data/spec/unit/rack_handler_spec.rb +0 -60
data/spec/unit/client_spec.rb
CHANGED
@@ -1,211 +1,170 @@
|
|
1
|
-
|
2
|
-
require "hatetepe/client"
|
1
|
+
# encoding: utf-8
|
3
2
|
|
4
|
-
|
5
|
-
let :config do
|
6
|
-
{
|
7
|
-
:host => "127.0.0.1",
|
8
|
-
:port => 4242
|
9
|
-
}
|
10
|
-
end
|
3
|
+
require 'spec_helper'
|
11
4
|
|
12
|
-
|
13
|
-
|
14
|
-
client.extend(Hatetepe::Client)
|
15
|
-
client.stub(:send_data)
|
16
|
-
client.stub(:comm_inactivity_timeout=)
|
17
|
-
client.stub(:pending_connect_timeout=)
|
18
|
-
client.stub(:send_request) { response }
|
5
|
+
describe Hatetepe::Client do
|
6
|
+
let(:client) { described_class.new(config) }
|
19
7
|
|
20
|
-
|
21
|
-
|
22
|
-
|
8
|
+
let(:config) do
|
9
|
+
{ address: localhost, port: random_port, handlers: [handler_class] }
|
10
|
+
end
|
11
|
+
let(:connection) do
|
12
|
+
double('connection', parse: nil,
|
13
|
+
closed: double('closed', then: nil),
|
14
|
+
serialize: nil,
|
15
|
+
close: nil)
|
23
16
|
end
|
17
|
+
let(:handler_class) { double('handler_class', new: handler) }
|
18
|
+
let(:handler) { double('handler', post_init: nil, receive: nil) }
|
24
19
|
|
25
|
-
|
26
|
-
|
27
|
-
EM.should_receive(:connect).
|
28
|
-
with(config[:host], config[:port], Hatetepe::Client, config).
|
29
|
-
and_return(client)
|
30
|
-
Hatetepe::Client.start(config).should equal(client)
|
31
|
-
end
|
20
|
+
before do
|
21
|
+
allow(EM).to receive(:connect) { connection }
|
32
22
|
end
|
33
23
|
|
34
|
-
describe
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
24
|
+
describe '#initialize' do
|
25
|
+
subject! { client }
|
26
|
+
|
27
|
+
its(:config) { should be(config) }
|
28
|
+
|
29
|
+
specify do
|
30
|
+
expect(EM).to have_received(:connect)
|
31
|
+
.with(config[:address], config[:port],
|
32
|
+
Hatetepe::Connection::EventMachine)
|
33
|
+
expect(connection).to have_received(:parse)
|
34
|
+
.with(subject.method(:receive))
|
35
|
+
expect(connection.closed).to have_received(:then)
|
36
|
+
.with(subject.method(:teardown))
|
39
37
|
end
|
40
|
-
end
|
41
38
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
39
|
+
specify do
|
40
|
+
expect(handler_class).to have_received(:new)
|
41
|
+
.with(config, subject, connection)
|
42
|
+
expect(handler).to have_received(:post_init)
|
46
43
|
end
|
47
44
|
end
|
48
45
|
|
49
|
-
describe
|
50
|
-
let
|
51
|
-
|
46
|
+
describe '#request' do
|
47
|
+
let(:request) do
|
48
|
+
double('request', finished: double('finished', fulfill: nil),
|
49
|
+
served: double('served', sync: response))
|
52
50
|
end
|
51
|
+
let(:response) { double('response') }
|
53
52
|
|
54
53
|
before do
|
55
|
-
|
56
|
-
client
|
57
|
-
client << requests[1]
|
58
|
-
end
|
59
|
-
|
60
|
-
it "waits for all requests to finish" do
|
61
|
-
returned = false
|
62
|
-
Fiber.new do
|
63
|
-
client.wait
|
64
|
-
returned = true
|
65
|
-
end.resume
|
66
|
-
|
67
|
-
returned.should be_false
|
68
|
-
|
69
|
-
requests.each(&:succeed)
|
70
|
-
returned.should be_true
|
54
|
+
allow(Hatetepe::Request).to receive(:new) { request }
|
55
|
+
allow(client).to receive(:perform)
|
71
56
|
end
|
72
|
-
end
|
73
57
|
|
74
|
-
|
75
|
-
let(:client) { double("client", request: res, stop: nil) }
|
76
|
-
let(:headers) { double("headers") }
|
77
|
-
let(:body) { double("body") }
|
78
|
-
let(:res) { double("response") }
|
79
|
-
let(:response) { Hatetepe::Client.request(:put, "/test", headers, body) }
|
58
|
+
subject! { client.request(:head, '/wat') }
|
80
59
|
|
81
|
-
|
60
|
+
specify do
|
61
|
+
expect(Hatetepe::Request).to have_received(:new).with(:head, '/wat')
|
62
|
+
expect(request.finished).to have_received(:fulfill)
|
63
|
+
expect(client).to have_received(:perform).with(request)
|
82
64
|
|
83
|
-
|
84
|
-
client.should_receive(:request).with(:put, URI("/test"), headers, body)
|
85
|
-
response.should equal(res)
|
65
|
+
expect(subject).to be(response)
|
86
66
|
end
|
87
67
|
end
|
88
68
|
|
89
|
-
describe
|
90
|
-
let(:
|
91
|
-
let(:headers) { { "Content-Type" => "text/plain" } }
|
92
|
-
let(:request) { double("request") }
|
93
|
-
let(:response) { double("response") }
|
69
|
+
describe '#perform' do
|
70
|
+
let(:request) { double('request') }
|
94
71
|
|
95
72
|
before do
|
96
|
-
|
97
|
-
|
73
|
+
@fibers = []
|
74
|
+
allow(handler).to receive(:perform) { @fibers << Fiber.current }
|
75
|
+
allow(connection).to receive(:serialize) { @fibers << Fiber.current }
|
98
76
|
end
|
99
77
|
|
100
|
-
|
101
|
-
Hatetepe::Request.should_receive(:new) do |verb, uri, headers, body|
|
102
|
-
verb.should eq(:head)
|
103
|
-
uri.path.should eq("/test")
|
104
|
-
uri.query.should eq("key=value")
|
105
|
-
headers["Content-Type"].should eq("text/plain")
|
106
|
-
Enumerator.new(body).to_a.join.should eq("Hello, world!")
|
107
|
-
|
108
|
-
request
|
109
|
-
end
|
110
|
-
|
111
|
-
client.should_receive(:<<).with(request)
|
112
|
-
EM::Synchrony.should_receive(:sync).with(request)
|
78
|
+
subject! { client.perform(request) }
|
113
79
|
|
114
|
-
|
115
|
-
|
80
|
+
specify do
|
81
|
+
expect(handler).to have_received(:perform).with(request)
|
82
|
+
expect(connection).to have_received(:serialize).with(request)
|
116
83
|
|
117
|
-
|
118
|
-
|
119
|
-
client.request(:get, "/").should equal(response)
|
84
|
+
expect(@fibers).not_to include(Fiber.current)
|
85
|
+
expect(@fibers.uniq).to be_one
|
120
86
|
end
|
121
87
|
end
|
122
88
|
|
123
|
-
describe
|
124
|
-
subject
|
125
|
-
|
89
|
+
describe '#close' do
|
90
|
+
subject! { client.close }
|
91
|
+
|
92
|
+
specify do
|
93
|
+
expect(connection).to have_received(:close)
|
126
94
|
end
|
95
|
+
end
|
127
96
|
|
128
|
-
|
129
|
-
let(:
|
97
|
+
describe '#receive' do
|
98
|
+
let(:request) { default_request }
|
99
|
+
let(:response) { default_response }
|
130
100
|
|
131
|
-
|
132
|
-
client.
|
133
|
-
end
|
101
|
+
describe 'with outstanding request' do
|
102
|
+
before { client.perform(request) }
|
134
103
|
|
135
|
-
|
136
|
-
subject.call.should eq(response)
|
137
|
-
end
|
104
|
+
subject! { client.receive(response) }
|
138
105
|
|
139
|
-
|
140
|
-
|
106
|
+
it 'correlates response with request, and notifies handlers' do
|
107
|
+
expect(request.served).to be_fulfilled
|
108
|
+
expect(request.served.value).to be(response)
|
141
109
|
|
142
|
-
|
143
|
-
subject.should raise_error(Hatetepe::ClientError)
|
110
|
+
expect(handler).to have_received(:receive).with(request, response)
|
144
111
|
end
|
145
112
|
end
|
146
113
|
|
147
|
-
describe
|
148
|
-
|
114
|
+
describe 'without outstanding request' do
|
115
|
+
subject { client.receive(response) }
|
149
116
|
|
150
|
-
it
|
151
|
-
subject.
|
117
|
+
it 'fails' do
|
118
|
+
expect { subject }.to raise_error(Hatetepe::ClientError, /correlate/)
|
152
119
|
end
|
153
120
|
end
|
154
121
|
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
122
|
+
[:fulfill, :reject].each do |action|
|
123
|
+
describe "after #{action}ed response" do
|
124
|
+
let(:request) { WeakRef.new(finished_request) }
|
125
|
+
let(:response) { WeakRef.new(default_response) }
|
126
|
+
|
127
|
+
before do
|
128
|
+
client.perform(request.__getobj__)
|
129
|
+
client.receive(response.__getobj__)
|
130
|
+
end
|
131
|
+
|
132
|
+
subject do
|
133
|
+
response.finished.send(action)
|
134
|
+
tick
|
135
|
+
RSpec::Mocks.teardown
|
136
|
+
GC.start
|
137
|
+
end
|
138
|
+
|
139
|
+
it 'cleans up' do
|
140
|
+
if RUBY_VERSION == '1.9.3' && RUBY_PATCHLEVEL == 392
|
141
|
+
expect { subject }.to change { request.weakref_alive? }.to(false)
|
142
|
+
else
|
143
|
+
pending
|
144
|
+
end
|
145
|
+
end
|
159
146
|
end
|
160
147
|
end
|
161
148
|
end
|
162
149
|
|
163
|
-
describe
|
164
|
-
let
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
describe "if the response is a success" do
|
169
|
-
let(:response) { Hatetepe::Response.new(307) }
|
150
|
+
describe '#teardown' do
|
151
|
+
let(:requests) { [finished_request, finished_request] }
|
152
|
+
let(:responses) { [default_response] }
|
153
|
+
let(:reason) { double }
|
170
154
|
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
end
|
176
|
-
|
177
|
-
describe "if the response is a failure" do
|
178
|
-
let(:response) { Hatetepe::Response.new(502) }
|
179
|
-
|
180
|
-
it "fails the request" do
|
181
|
-
request.should_receive(:fail).with(response)
|
182
|
-
client << request
|
183
|
-
end
|
155
|
+
before do
|
156
|
+
client.perform(requests[0])
|
157
|
+
client.perform(requests[1])
|
158
|
+
client.receive(responses[0])
|
184
159
|
end
|
185
160
|
|
186
|
-
|
187
|
-
let(:response) { nil }
|
161
|
+
subject! { client.teardown(reason) }
|
188
162
|
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
163
|
+
it 'rejects outstanding requests and responses' do
|
164
|
+
expect(responses[0].finished).to be_rejected
|
165
|
+
expect(responses[0].finished.reason).to be(reason)
|
166
|
+
expect(requests[1].served).to be_rejected
|
167
|
+
expect(requests[1].served.reason).to be(reason)
|
193
168
|
end
|
194
169
|
end
|
195
170
|
end
|
196
|
-
|
197
|
-
describe Hatetepe::Client, "(EventMachine API)" do
|
198
|
-
describe "#initialize"
|
199
|
-
|
200
|
-
describe "#post_init"
|
201
|
-
|
202
|
-
describe "#receive_data"
|
203
|
-
|
204
|
-
describe "#unbind"
|
205
|
-
end
|
206
|
-
|
207
|
-
describe Hatetepe::Client, "(private API)" do
|
208
|
-
describe "#send_request"
|
209
|
-
|
210
|
-
describe "#receive_response"
|
211
|
-
end
|
@@ -0,0 +1,146 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe Hatetepe::Connection::EventMachine do
|
6
|
+
let(:connection) { described_class.allocate }
|
7
|
+
let(:callback) { double('callback', call: nil) }
|
8
|
+
let(:parser) { double('parser', :<< => nil) }
|
9
|
+
let(:serializer) { double('serializer', serialize: nil) }
|
10
|
+
let(:message) { default_request }
|
11
|
+
|
12
|
+
before do
|
13
|
+
allow(connection).to receive(:close_connection_after_writing)
|
14
|
+
allow(HTTP::Parser).to receive(:new) { parser }
|
15
|
+
allow(Hatetepe::Serializer).to receive(:new) { serializer }
|
16
|
+
allow(Hatetepe::Support::Message).to receive(:build) { message }
|
17
|
+
|
18
|
+
connection.instance_variable_set(:@signature, 123)
|
19
|
+
|
20
|
+
# initialize separately, EM::Connection overloads .new
|
21
|
+
# this smell tells us that we should decouple from EM::Connection
|
22
|
+
connection.send(:initialize, callback)
|
23
|
+
end
|
24
|
+
|
25
|
+
describe '#initialize' do
|
26
|
+
subject! { connection }
|
27
|
+
|
28
|
+
it 'creates parser' do
|
29
|
+
expect(HTTP::Parser).to have_received(:new).with(connection)
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'calls back' do
|
33
|
+
expect(callback).to have_received(:call).with(connection)
|
34
|
+
end
|
35
|
+
|
36
|
+
describe 'without callback' do
|
37
|
+
let(:connection) { described_class.allocate }
|
38
|
+
|
39
|
+
subject! { connection.send(:initialize) }
|
40
|
+
|
41
|
+
it 'is happy as well' do
|
42
|
+
expect(connection).to be_a(described_class)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe '#serialize' do
|
48
|
+
let(:writer) { connection.method(:send_data) }
|
49
|
+
|
50
|
+
subject! { connection.serialize(message) }
|
51
|
+
|
52
|
+
it 'feeds a serializer' do
|
53
|
+
expect(Hatetepe::Serializer).to have_received(:new).with(message, writer)
|
54
|
+
expect(serializer).to have_received(:serialize)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
describe '#close' do
|
59
|
+
subject! { connection.close }
|
60
|
+
|
61
|
+
it 'closes the connection' do
|
62
|
+
expect(connection).to have_received(:close_connection_after_writing)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
describe '#receive_data' do
|
67
|
+
let(:data) { double }
|
68
|
+
|
69
|
+
subject! { connection.receive_data(data) }
|
70
|
+
|
71
|
+
it 'feeds the parser' do
|
72
|
+
expect(parser).to have_received(:<<).with(data)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
describe '#unbind' do
|
77
|
+
let(:reason) { double('reason') }
|
78
|
+
|
79
|
+
describe 'following #close' do
|
80
|
+
before { connection.close }
|
81
|
+
|
82
|
+
subject! { connection.unbind(reason) }
|
83
|
+
|
84
|
+
it 'fulfills the promise' do
|
85
|
+
expect(connection.closed).to be_fulfilled
|
86
|
+
expect(connection.closed.value).to be(:self)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
describe 'following remote termination' do
|
91
|
+
subject! { connection.unbind(reason) }
|
92
|
+
|
93
|
+
it 'fulfills the promise' do
|
94
|
+
expect(connection.closed).to be_fulfilled
|
95
|
+
expect(connection.closed.value).to be(reason)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
describe '#on_headers_complete' do
|
101
|
+
let(:parse) { double('parse', call: nil) }
|
102
|
+
|
103
|
+
before { connection.parse(parse) }
|
104
|
+
|
105
|
+
subject! { connection.on_headers_complete(nil) }
|
106
|
+
|
107
|
+
it 'builds the message and passes it on' do
|
108
|
+
expect(Hatetepe::Support::Message).to have_received(:build).with(parser)
|
109
|
+
expect(parse).to have_received(:call).with(message)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
describe '#on_body' do
|
114
|
+
let(:progress) { [] }
|
115
|
+
let(:chunks) { %w[body chunk] }
|
116
|
+
|
117
|
+
before do
|
118
|
+
connection.parse(proc {})
|
119
|
+
connection.on_headers_complete(nil)
|
120
|
+
end
|
121
|
+
|
122
|
+
subject! do
|
123
|
+
message.finished.on_progress { |chunk| progress << chunk }
|
124
|
+
connection.on_body(chunks[0])
|
125
|
+
connection.on_body(chunks[1])
|
126
|
+
end
|
127
|
+
|
128
|
+
it 'passes chunk to message body' do
|
129
|
+
expect(message.body).to eq(chunks.join)
|
130
|
+
expect(progress).to eq(chunks)
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
describe '#on_message_complete' do
|
135
|
+
before do
|
136
|
+
connection.parse(proc {})
|
137
|
+
connection.on_headers_complete(nil)
|
138
|
+
end
|
139
|
+
|
140
|
+
subject! { connection.on_message_complete }
|
141
|
+
|
142
|
+
it 'fulfills the promise' do
|
143
|
+
expect(message.finished).to be_fulfilled
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe Hatetepe::Request do
|
6
|
+
describe '#initialize' do
|
7
|
+
subject do
|
8
|
+
Hatetepe::Request.new(:get, '/', { 'Key' => 'value' }, 'hello').freeze
|
9
|
+
end
|
10
|
+
|
11
|
+
its(:http_method) { should be(:get) }
|
12
|
+
its(:uri) { should eq('/') }
|
13
|
+
its(:headers) { should eq('Key' => 'value') }
|
14
|
+
its(:body) { should eq('hello') }
|
15
|
+
|
16
|
+
its(:finished) { should be_a(Hatetepe::Promise) }
|
17
|
+
its(:served) { should be_a(Hatetepe::Promise) }
|
18
|
+
|
19
|
+
describe 'defaults' do
|
20
|
+
subject { Hatetepe::Request.new(:get, '/') }
|
21
|
+
|
22
|
+
its(:headers) { should eq({}) }
|
23
|
+
its(:body) { should eq('') }
|
24
|
+
its(:http_version) { should eq(1.1) }
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe '#http_version=' do
|
29
|
+
subject { Hatetepe::Request.new(:get, '/') }
|
30
|
+
|
31
|
+
before { subject.http_version = 1.0 }
|
32
|
+
|
33
|
+
its(:http_version) { should eq(1.0) }
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe Hatetepe::Response do
|
6
|
+
describe '#initialize' do
|
7
|
+
subject do
|
8
|
+
Hatetepe::Response.new(200, { 'Key' => 'value' }, 'hello').freeze
|
9
|
+
end
|
10
|
+
|
11
|
+
its(:status) { should be(200) }
|
12
|
+
its(:headers) { should eq('Key' => 'value') }
|
13
|
+
its(:body) { should eq('hello') }
|
14
|
+
|
15
|
+
its(:finished) { should be_a(Hatetepe::Promise) }
|
16
|
+
|
17
|
+
its(:status_name) { should eq('OK') }
|
18
|
+
|
19
|
+
describe 'defaults' do
|
20
|
+
subject { Hatetepe::Response.new(200) }
|
21
|
+
|
22
|
+
its(:headers) { should eq({}) }
|
23
|
+
its(:body) { should eq('') }
|
24
|
+
its(:http_version) { should eq(1.1) }
|
25
|
+
end
|
26
|
+
|
27
|
+
describe 'unknown status' do
|
28
|
+
subject { Hatetepe::Response.new(-1) }
|
29
|
+
|
30
|
+
its(:status) { should be(-1) }
|
31
|
+
its(:status_name) { should eq('Unknown Status') }
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe '#http_version=' do
|
36
|
+
subject { Hatetepe::Response.new(200) }
|
37
|
+
|
38
|
+
before { subject.http_version = 1.0 }
|
39
|
+
|
40
|
+
its(:http_version) { should eq(1.0) }
|
41
|
+
end
|
42
|
+
end
|