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
@@ -1,113 +0,0 @@
|
|
1
|
-
require "spec_helper"
|
2
|
-
require "hatetepe/cli"
|
3
|
-
require "hatetepe/server"
|
4
|
-
require "hatetepe/version"
|
5
|
-
require "rack/builder"
|
6
|
-
|
7
|
-
describe Hatetepe::CLI do
|
8
|
-
let :rackup do
|
9
|
-
[ proc {|*| }, {} ]
|
10
|
-
end
|
11
|
-
|
12
|
-
before do
|
13
|
-
file = File.expand_path("config.ru")
|
14
|
-
Rack::Builder.stub(:parse_file).with(file) { rackup }
|
15
|
-
|
16
|
-
$stdout, $stderr = StringIO.new, StringIO.new
|
17
|
-
@old_env = ENV.delete("RACK_ENV")
|
18
|
-
end
|
19
|
-
|
20
|
-
after do
|
21
|
-
$stdout, $stderr = STDOUT, STDERR
|
22
|
-
ENV["RACK_ENV"] = @old_env
|
23
|
-
end
|
24
|
-
|
25
|
-
describe "#version" do
|
26
|
-
it "prints Hatetepe's version" do
|
27
|
-
Hatetepe::CLI.start([ "version" ])
|
28
|
-
$stdout.rewind
|
29
|
-
$stdout.read.should include(Hatetepe::VERSION)
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
describe "#start" do
|
34
|
-
it "starts a server running the default configuration" do
|
35
|
-
Hatetepe::Server.should_receive(:start) do |config|
|
36
|
-
config[:host].should == "127.0.0.1"
|
37
|
-
config[:port].should equal(3000)
|
38
|
-
config[:timeout].should be_nil
|
39
|
-
|
40
|
-
config[:app].should equal(rackup[0])
|
41
|
-
ENV["RACK_ENV"].should == "development"
|
42
|
-
end
|
43
|
-
Hatetepe::CLI.start([])
|
44
|
-
end
|
45
|
-
|
46
|
-
it "writes stuff to stderr" do
|
47
|
-
Hatetepe::CLI.start([])
|
48
|
-
$stderr.rewind
|
49
|
-
$stderr.read.should include("config.ru", "127.0.0.1:3000", "development")
|
50
|
-
end
|
51
|
-
|
52
|
-
it "starts an EventMachine reactor" do
|
53
|
-
EM.should_receive(:synchrony)
|
54
|
-
Hatetepe::CLI.start([])
|
55
|
-
end
|
56
|
-
|
57
|
-
it "enables epoll" do
|
58
|
-
EM.should_receive(:epoll)
|
59
|
-
Hatetepe::CLI.start([])
|
60
|
-
end
|
61
|
-
|
62
|
-
it "doesn't overwrite RACK_ENV" do
|
63
|
-
ENV["RACK_ENV"] = "foobar"
|
64
|
-
Hatetepe::CLI.start([])
|
65
|
-
ENV["RACK_ENV"].should == "foobar"
|
66
|
-
end
|
67
|
-
|
68
|
-
describe "with --bind option" do
|
69
|
-
it "passes the :host option to Server.start" do
|
70
|
-
Hatetepe::Server.should_receive(:start) do |config|
|
71
|
-
config[:host].should == "127.0.5.1"
|
72
|
-
end
|
73
|
-
Hatetepe::CLI.start([ "--bind", "127.0.5.1" ])
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
describe "with --port option" do
|
78
|
-
it "passes the :port option to Server.start" do
|
79
|
-
Hatetepe::Server.should_receive(:start) do |config|
|
80
|
-
config[:port].should == 5234
|
81
|
-
end
|
82
|
-
Hatetepe::CLI.start([ "--port", "5234" ])
|
83
|
-
end
|
84
|
-
end
|
85
|
-
|
86
|
-
describe "with --timeout option" do
|
87
|
-
it "passes the :timeout option to Server.start" do
|
88
|
-
Hatetepe::Server.should_receive(:start) do |config|
|
89
|
-
config[:timeout].should == 123.4
|
90
|
-
end
|
91
|
-
Hatetepe::CLI.start([ "--timeout", "123.4" ])
|
92
|
-
end
|
93
|
-
end
|
94
|
-
|
95
|
-
describe "with --rackup option" do
|
96
|
-
it "boots from the specified RackUp file" do
|
97
|
-
file = File.expand_path("./other_config.ru")
|
98
|
-
Rack::Builder.should_receive(:parse_file).with(file) { rackup }
|
99
|
-
Hatetepe::Server.should_receive(:start) do |config|
|
100
|
-
config[:app].should equal(rackup[0])
|
101
|
-
end
|
102
|
-
Hatetepe::CLI.start([ "--rackup", "other_config.ru" ])
|
103
|
-
end
|
104
|
-
end
|
105
|
-
|
106
|
-
describe "with --env option" do
|
107
|
-
it "sets RACK_ENV to the specified value" do
|
108
|
-
Hatetepe::CLI.start([ "--env", "production" ])
|
109
|
-
ENV["RACK_ENV"].should == "production"
|
110
|
-
end
|
111
|
-
end
|
112
|
-
end
|
113
|
-
end
|
@@ -1,23 +0,0 @@
|
|
1
|
-
require "hatetepe/cli"
|
2
|
-
require "hatetepe/client"
|
3
|
-
require "spec_helper"
|
4
|
-
require "stringio"
|
5
|
-
require "yaml"
|
6
|
-
|
7
|
-
describe Hatetepe::Client, "with Keep-Alive" do
|
8
|
-
let :client do
|
9
|
-
Hatetepe::Client.start :host => "127.0.0.1", :port => 30001
|
10
|
-
end
|
11
|
-
|
12
|
-
it "keeps the connection open"
|
13
|
-
|
14
|
-
it "sends Connection: keep-alive"
|
15
|
-
|
16
|
-
describe "and an obviously single request" do
|
17
|
-
it "sends Connection: close"
|
18
|
-
|
19
|
-
it "closes the connection immediately after the response"
|
20
|
-
end
|
21
|
-
|
22
|
-
it "closes the connection if the server tells it to"
|
23
|
-
end
|
@@ -1,97 +0,0 @@
|
|
1
|
-
require "spec_helper"
|
2
|
-
require "hatetepe/client"
|
3
|
-
require "hatetepe/server"
|
4
|
-
|
5
|
-
describe Hatetepe::Client do
|
6
|
-
let :options do
|
7
|
-
{ host: "127.0.0.1", port: 3123 }
|
8
|
-
end
|
9
|
-
|
10
|
-
let :options2 do
|
11
|
-
{ host: "1.2.3.4", port: 3123}
|
12
|
-
end
|
13
|
-
|
14
|
-
let :client do
|
15
|
-
Hatetepe::Client.start(options)
|
16
|
-
end
|
17
|
-
|
18
|
-
before do
|
19
|
-
if defined?(RUBY_ENGINE) && RUBY_ENGINE == "jruby"
|
20
|
-
pending "EventMachine timeouts are not available on JRuby"
|
21
|
-
end
|
22
|
-
|
23
|
-
Hatetepe::Server.start(options.merge(timeout: 0))
|
24
|
-
end
|
25
|
-
|
26
|
-
it "times out after 5 seconds of connection inactivity" do
|
27
|
-
# only verify that 5 seconds is the default, but actually
|
28
|
-
# use a smaller timeout to keep specs fast
|
29
|
-
Hatetepe::Client::CONFIG_DEFAULTS[:timeout].should == 5
|
30
|
-
end
|
31
|
-
|
32
|
-
it "times out after 5 seconds trying to establish a connection" do
|
33
|
-
# only verify that 5 seconds is the default, but actually
|
34
|
-
# use a smaller timeout to keep specs fast
|
35
|
-
Hatetepe::Client::CONFIG_DEFAULTS[:connect_timeout].should == 5
|
36
|
-
end
|
37
|
-
|
38
|
-
describe "with :timeout option" do
|
39
|
-
let :client do
|
40
|
-
Hatetepe::Client.start(options.merge(timeout: 0.5))
|
41
|
-
end
|
42
|
-
|
43
|
-
it "times out after n seconds of connection inactivity" do
|
44
|
-
client.should_not be_closed
|
45
|
-
EM::Synchrony.sleep(0.45)
|
46
|
-
client.should_not be_closed
|
47
|
-
|
48
|
-
EM::Synchrony.sleep(0.1)
|
49
|
-
client.should be_closed
|
50
|
-
client.should be_closed_by_timeout
|
51
|
-
client.should_not be_closed_by_connect_timeout
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
describe "with :timeout set to 0" do
|
56
|
-
let :client do
|
57
|
-
Hatetepe::Client.start(options.merge(timeout: 0))
|
58
|
-
end
|
59
|
-
|
60
|
-
it "never times out" do
|
61
|
-
client.should_not be_closed
|
62
|
-
EM::Synchrony.sleep(0.55)
|
63
|
-
client.should_not be_closed
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
describe "with :connect_timeout option" do
|
68
|
-
let :client do
|
69
|
-
Hatetepe::Client.start(options2.merge(connect_timeout: 0.5))
|
70
|
-
end
|
71
|
-
|
72
|
-
# this example fails if there's no network connection
|
73
|
-
it "times out after n seconds trying to establish a connection" do
|
74
|
-
client.should_not be_closed
|
75
|
-
EM::Synchrony.sleep(0.45)
|
76
|
-
client.should_not be_closed
|
77
|
-
|
78
|
-
EM::Synchrony.sleep(0.1)
|
79
|
-
client.should be_closed
|
80
|
-
client.should be_closed_by_connect_timeout
|
81
|
-
client.should_not be_closed_by_timeout
|
82
|
-
end
|
83
|
-
end
|
84
|
-
|
85
|
-
describe "with :connect_timeout set to 0" do
|
86
|
-
let :client do
|
87
|
-
Hatetepe::Client.start(options2.merge(connect_timeout: 0))
|
88
|
-
end
|
89
|
-
|
90
|
-
# this example fails if there's no network connection
|
91
|
-
it "never times out trying to establish a connection" do
|
92
|
-
client.should_not be_closed
|
93
|
-
EM::Synchrony.sleep(0.55)
|
94
|
-
client.should_not be_closed
|
95
|
-
end
|
96
|
-
end
|
97
|
-
end
|
@@ -1,27 +0,0 @@
|
|
1
|
-
require "spec_helper"
|
2
|
-
require "hatetepe/client"
|
3
|
-
require "hatetepe/server"
|
4
|
-
|
5
|
-
describe Hatetepe::Server, "with Keep-Alive" do
|
6
|
-
describe "and :timeout option" do
|
7
|
-
it "times out the connection after the specified amount of time"
|
8
|
-
end
|
9
|
-
|
10
|
-
describe "and :timeout option set to 0" do
|
11
|
-
it "keeps the connection open until the client closes it"
|
12
|
-
end
|
13
|
-
|
14
|
-
it "closes the connection if the client sends Connection: close"
|
15
|
-
|
16
|
-
it "responds with Connection: keep-alive if the client also sent it"
|
17
|
-
|
18
|
-
["1.0", "0.9"].each do |version|
|
19
|
-
describe "and an HTTP #{version} client" do
|
20
|
-
it "closes the connection after one request" do
|
21
|
-
pending "http_parser.rb doesn't parse HTTP/0.9" if version == "0.9"
|
22
|
-
end
|
23
|
-
|
24
|
-
it "doesn't close the connection if the client sent Connection: Keep-Alive"
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
@@ -1,51 +0,0 @@
|
|
1
|
-
require "spec_helper"
|
2
|
-
require "hatetepe/client"
|
3
|
-
require "hatetepe/server"
|
4
|
-
|
5
|
-
describe Hatetepe::Server do
|
6
|
-
before do
|
7
|
-
if defined?(RUBY_ENGINE) && RUBY_ENGINE == "jruby"
|
8
|
-
pending "EventMachine timeouts are not available on JRuby"
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
12
|
-
let :options do
|
13
|
-
{ host: "127.0.0.1", port: 3123 }
|
14
|
-
end
|
15
|
-
|
16
|
-
let :client do
|
17
|
-
Hatetepe::Client.start(options.merge(timeout: 0))
|
18
|
-
end
|
19
|
-
|
20
|
-
it "times out after 5 seconds of connection inactivity" do
|
21
|
-
# only verify that 5 seconds is the default
|
22
|
-
Hatetepe::Server::CONFIG_DEFAULTS[:timeout].should == 5
|
23
|
-
end
|
24
|
-
|
25
|
-
describe "with :timeout option" do
|
26
|
-
before do
|
27
|
-
Hatetepe::Server.start(options.merge(timeout: 0.5))
|
28
|
-
end
|
29
|
-
|
30
|
-
it "times out after the specified amount of seconds" do
|
31
|
-
client.should_not be_closed
|
32
|
-
EM::Synchrony.sleep(0.45)
|
33
|
-
client.should_not be_closed
|
34
|
-
|
35
|
-
EM::Synchrony.sleep(0.1)
|
36
|
-
client.should be_closed_by_remote
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
describe "with :timeout set to 0" do
|
41
|
-
before do
|
42
|
-
Hatetepe::Server.start(options.merge(timeout: 0))
|
43
|
-
end
|
44
|
-
|
45
|
-
it "never times out" do
|
46
|
-
client.should_not be_closed
|
47
|
-
EM::Synchrony.sleep(0.55)
|
48
|
-
client.should_not be_closed
|
49
|
-
end
|
50
|
-
end
|
51
|
-
end
|
data/spec/unit/body_spec.rb
DELETED
@@ -1,205 +0,0 @@
|
|
1
|
-
require "spec_helper"
|
2
|
-
require "hatetepe/body"
|
3
|
-
|
4
|
-
describe Hatetepe::Body do
|
5
|
-
let(:body) { Hatetepe::Body.new }
|
6
|
-
|
7
|
-
it "is deferrable" do
|
8
|
-
body.should respond_to(:callback)
|
9
|
-
end
|
10
|
-
|
11
|
-
context "#initialize" do
|
12
|
-
it "leaves the IO stream empty" do
|
13
|
-
body.io.length.should be_zero
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
context "#initialize(string)" do
|
18
|
-
let(:body) { Hatetepe::Body.new "herp derp" }
|
19
|
-
|
20
|
-
before { body.close_write }
|
21
|
-
|
22
|
-
it "writes the passed string" do
|
23
|
-
body.length.should equal(9)
|
24
|
-
body.io.read.should == "herp derp"
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
context "#sync" do
|
29
|
-
let(:conn) { double "conn", :paused? => true }
|
30
|
-
|
31
|
-
it "resumes the source connection if any" do
|
32
|
-
body.source = conn
|
33
|
-
|
34
|
-
conn.should_receive :resume
|
35
|
-
Fiber.new { body.succeed }.resume
|
36
|
-
body.sync
|
37
|
-
end
|
38
|
-
|
39
|
-
it "forwards to EM::Synchrony.sync(body)" do
|
40
|
-
EM::Synchrony.should_receive(:sync).with(body)
|
41
|
-
body.sync
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
context "#length" do
|
46
|
-
let(:length) { double "length" }
|
47
|
-
|
48
|
-
it "forwards to io#length" do
|
49
|
-
body.stub :sync
|
50
|
-
body.io.stub :length => length
|
51
|
-
|
52
|
-
body.length.should equal(length)
|
53
|
-
end
|
54
|
-
|
55
|
-
it "waits for the body to succeed" do
|
56
|
-
succeeded = false
|
57
|
-
Fiber.new {
|
58
|
-
body.length
|
59
|
-
succeeded = true
|
60
|
-
}.resume
|
61
|
-
|
62
|
-
succeeded.should be_false
|
63
|
-
|
64
|
-
body.close_write
|
65
|
-
succeeded.should be_true
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
context "#empty?" do
|
70
|
-
it "returns true if length is zero" do
|
71
|
-
body.stub :length => 0
|
72
|
-
body.empty?.should be_true
|
73
|
-
end
|
74
|
-
|
75
|
-
it "returns false if length is non-zero" do
|
76
|
-
body.stub :length => 42
|
77
|
-
body.empty?.should be_false
|
78
|
-
end
|
79
|
-
end
|
80
|
-
|
81
|
-
context "#pos" do
|
82
|
-
let(:pos) { double "pos" }
|
83
|
-
|
84
|
-
it "forwards to io#pos" do
|
85
|
-
body.io.stub :pos => pos
|
86
|
-
body.pos.should equal(pos)
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
90
|
-
context "#rewind" do
|
91
|
-
it "blocks and forwards to io#rewind" do
|
92
|
-
body.should_receive(:sync).ordered
|
93
|
-
body.io.should_receive(:rewind).ordered
|
94
|
-
body.rewind
|
95
|
-
end
|
96
|
-
end
|
97
|
-
|
98
|
-
context "#close_write" do
|
99
|
-
it "forwards to io#close_write" do
|
100
|
-
body.io.should_receive :close_write
|
101
|
-
body.close_write
|
102
|
-
end
|
103
|
-
|
104
|
-
it "succeeds the body" do
|
105
|
-
body.should_receive :succeed
|
106
|
-
body.close_write
|
107
|
-
end
|
108
|
-
end
|
109
|
-
|
110
|
-
context "#closed_write?" do
|
111
|
-
it "forwards to io#closed_write?" do
|
112
|
-
ret = double("return")
|
113
|
-
body.io.should_receive(:closed_write?) { ret }
|
114
|
-
|
115
|
-
body.closed_write?.should equal(ret)
|
116
|
-
end
|
117
|
-
end
|
118
|
-
|
119
|
-
context "#each {|chunk| ... }" do
|
120
|
-
it "yields each written chunk until the body succeeds" do
|
121
|
-
chunks = ["111", "222"]
|
122
|
-
received, succeeded = [], false
|
123
|
-
|
124
|
-
body.write chunks[0]
|
125
|
-
Fiber.new {
|
126
|
-
body.each {|chunk| received << chunk }
|
127
|
-
succeeded = true
|
128
|
-
}.resume
|
129
|
-
received.should == chunks.values_at(0)
|
130
|
-
succeeded.should be_false
|
131
|
-
|
132
|
-
body.write chunks[1]
|
133
|
-
received.should == chunks
|
134
|
-
succeeded.should be_false
|
135
|
-
|
136
|
-
body.succeed
|
137
|
-
succeeded.should be_true
|
138
|
-
end
|
139
|
-
|
140
|
-
it "returns self" do
|
141
|
-
Fiber.new { body.each {}.should == body }.resume
|
142
|
-
body.succeed
|
143
|
-
end
|
144
|
-
|
145
|
-
describe "without a block" do
|
146
|
-
let(:enumerator) { double }
|
147
|
-
|
148
|
-
before { body.stub(:to_enum).with(:each) { enumerator } }
|
149
|
-
|
150
|
-
it "immediately returns an Enumerator" do
|
151
|
-
Fiber.new { body.each.should == enumerator }.resume
|
152
|
-
body.succeed
|
153
|
-
end
|
154
|
-
end
|
155
|
-
end
|
156
|
-
|
157
|
-
context "#read(length, buffer)" do
|
158
|
-
it "waits for the body to succeed" do
|
159
|
-
ret, read = nil, false
|
160
|
-
|
161
|
-
Fiber.new { body.read; read = true }.resume
|
162
|
-
read.should be_false
|
163
|
-
|
164
|
-
body.succeed
|
165
|
-
read.should be_true
|
166
|
-
end
|
167
|
-
|
168
|
-
it "forwards to io#read" do
|
169
|
-
body.succeed
|
170
|
-
args, ret = [double("arg#1"), double("arg#2")], double("ret")
|
171
|
-
|
172
|
-
body.io.should_receive(:read).with(*args) { ret }
|
173
|
-
body.read(*args).should equal(ret)
|
174
|
-
end
|
175
|
-
end
|
176
|
-
|
177
|
-
context "#gets" do
|
178
|
-
it "waits for the body to succeed" do
|
179
|
-
ret, read = nil, false
|
180
|
-
|
181
|
-
Fiber.new { body.gets; read = true }.resume
|
182
|
-
read.should be_false
|
183
|
-
|
184
|
-
body.succeed
|
185
|
-
read.should be_true
|
186
|
-
end
|
187
|
-
|
188
|
-
it "forwards to io#gets" do
|
189
|
-
body.succeed
|
190
|
-
ret = double("ret")
|
191
|
-
|
192
|
-
body.io.should_receive(:gets) { ret }
|
193
|
-
body.gets.should equal(ret)
|
194
|
-
end
|
195
|
-
end
|
196
|
-
|
197
|
-
context "#write(chunk)" do
|
198
|
-
it "forwards to io#write" do
|
199
|
-
arg, ret = double("arg"), double("ret")
|
200
|
-
body.io.should_receive(:write).with(arg) { ret }
|
201
|
-
|
202
|
-
body.write(arg).should equal(ret)
|
203
|
-
end
|
204
|
-
end
|
205
|
-
end
|