ethon 0.15.0 → 0.17.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 +4 -4
- data/CHANGELOG.md +29 -1
- data/README.md +23 -0
- data/ethon.gemspec +6 -3
- data/lib/ethon/curls/classes.rb +12 -2
- data/lib/ethon/curls/codes.rb +3 -2
- data/lib/ethon/curls/options.rb +4 -3
- data/lib/ethon/easy/callbacks.rb +2 -1
- data/lib/ethon/easy/informations.rb +3 -0
- data/lib/ethon/easy/response_callbacks.rb +6 -1
- data/lib/ethon/version.rb +1 -1
- metadata +6 -85
- data/.github/workflows/ruby.yml +0 -41
- data/.gitignore +0 -8
- data/.rspec +0 -3
- data/Gemfile +0 -43
- data/Guardfile +0 -10
- data/Rakefile +0 -40
- data/profile/benchmarks.rb +0 -104
- data/profile/memory_leaks.rb +0 -114
- data/profile/perf_spec_helper.rb +0 -37
- data/profile/support/memory_test_helpers.rb +0 -76
- data/profile/support/os_memory_leak_tracker.rb +0 -48
- data/profile/support/ruby_object_leak_tracker.rb +0 -49
- data/spec/ethon/curl_spec.rb +0 -38
- data/spec/ethon/easy/callbacks_spec.rb +0 -59
- data/spec/ethon/easy/debug_info_spec.rb +0 -54
- data/spec/ethon/easy/features_spec.rb +0 -24
- data/spec/ethon/easy/form_spec.rb +0 -104
- data/spec/ethon/easy/header_spec.rb +0 -79
- data/spec/ethon/easy/http/custom_spec.rb +0 -177
- data/spec/ethon/easy/http/delete_spec.rb +0 -21
- data/spec/ethon/easy/http/get_spec.rb +0 -126
- data/spec/ethon/easy/http/head_spec.rb +0 -80
- data/spec/ethon/easy/http/options_spec.rb +0 -51
- data/spec/ethon/easy/http/patch_spec.rb +0 -51
- data/spec/ethon/easy/http/post_spec.rb +0 -317
- data/spec/ethon/easy/http/put_spec.rb +0 -168
- data/spec/ethon/easy/http_spec.rb +0 -64
- data/spec/ethon/easy/informations_spec.rb +0 -120
- data/spec/ethon/easy/mirror_spec.rb +0 -47
- data/spec/ethon/easy/operations_spec.rb +0 -268
- data/spec/ethon/easy/options_spec.rb +0 -193
- data/spec/ethon/easy/queryable_spec.rb +0 -235
- data/spec/ethon/easy/response_callbacks_spec.rb +0 -152
- data/spec/ethon/easy/util_spec.rb +0 -28
- data/spec/ethon/easy_spec.rb +0 -203
- data/spec/ethon/libc_spec.rb +0 -14
- data/spec/ethon/loggable_spec.rb +0 -22
- data/spec/ethon/multi/operations_spec.rb +0 -298
- data/spec/ethon/multi/options_spec.rb +0 -182
- data/spec/ethon/multi/stack_spec.rb +0 -80
- data/spec/ethon/multi_spec.rb +0 -152
- data/spec/spec_helper.rb +0 -28
- data/spec/support/localhost_server.rb +0 -95
- data/spec/support/server.rb +0 -115
@@ -1,152 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
require 'spec_helper'
|
3
|
-
|
4
|
-
describe Ethon::Easy::ResponseCallbacks do
|
5
|
-
let(:easy) { Ethon::Easy.new }
|
6
|
-
|
7
|
-
[:on_complete, :on_headers, :on_body, :on_progress].each do |callback_type|
|
8
|
-
describe "##{callback_type}" do
|
9
|
-
it "responds" do
|
10
|
-
expect(easy).to respond_to("#{callback_type}")
|
11
|
-
end
|
12
|
-
|
13
|
-
context "when no block given" do
|
14
|
-
it "returns @#{callback_type}" do
|
15
|
-
expect(easy.send("#{callback_type}")).to eq([])
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
context "when block given" do
|
20
|
-
it "stores" do
|
21
|
-
easy.send(callback_type) { p 1 }
|
22
|
-
expect(easy.instance_variable_get("@#{callback_type}").size).to eq(1)
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
context "when multiple blocks given" do
|
27
|
-
it "stores" do
|
28
|
-
easy.send(callback_type) { p 1 }
|
29
|
-
easy.send(callback_type) { p 2 }
|
30
|
-
expect(easy.instance_variable_get("@#{callback_type}").size).to eq(2)
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
describe "#complete" do
|
37
|
-
before do
|
38
|
-
easy.on_complete {|r| String.new(r.url) }
|
39
|
-
end
|
40
|
-
|
41
|
-
it "executes blocks and passes self" do
|
42
|
-
expect(String).to receive(:new).with(easy.url)
|
43
|
-
easy.complete
|
44
|
-
end
|
45
|
-
|
46
|
-
context "when @on_complete nil" do
|
47
|
-
it "doesn't raise" do
|
48
|
-
easy.instance_variable_set(:@on_complete, nil)
|
49
|
-
expect{ easy.complete }.to_not raise_error
|
50
|
-
end
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
describe "#headers" do
|
55
|
-
before do
|
56
|
-
easy.on_headers {|r| String.new(r.url) }
|
57
|
-
end
|
58
|
-
|
59
|
-
it "executes blocks and passes self" do
|
60
|
-
expect(String).to receive(:new).with(easy.url)
|
61
|
-
easy.headers
|
62
|
-
end
|
63
|
-
|
64
|
-
context "when @on_headers nil" do
|
65
|
-
it "doesn't raise" do
|
66
|
-
easy.instance_variable_set(:@on_headers, nil)
|
67
|
-
expect{ easy.headers }.to_not raise_error
|
68
|
-
end
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
describe "#progress" do
|
73
|
-
context "when requesting for realz" do
|
74
|
-
it "executes callback" do
|
75
|
-
post = Ethon::Easy::Http::Post.new("http://localhost:3001", {:body => "bar=fu"})
|
76
|
-
post.setup(easy)
|
77
|
-
@called = false
|
78
|
-
@has_dltotal = false
|
79
|
-
@has_ultotal = false
|
80
|
-
easy.on_progress { @called = true }
|
81
|
-
easy.on_progress { |dltotal, _, _, _| @has_dltotal ||= true }
|
82
|
-
easy.on_progress { |_, _, ultotal, _| @has_ultotal ||= true }
|
83
|
-
easy.perform
|
84
|
-
expect(@called).to be true
|
85
|
-
expect(@has_dltotal).to be true
|
86
|
-
expect(@has_ultotal).to be true
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
90
|
-
context "when pretending" do
|
91
|
-
before do
|
92
|
-
@dltotal = nil
|
93
|
-
@dlnow = nil
|
94
|
-
@ultotal = nil
|
95
|
-
@ulnow = nil
|
96
|
-
easy.on_progress { |dltotal, dlnow, ultotal, ulnow| @dltotal = dltotal ; @dlnow = dlnow; @ultotal = ultotal; @ulnow = ulnow }
|
97
|
-
end
|
98
|
-
|
99
|
-
it "executes blocks and passes dltotal" do
|
100
|
-
easy.progress(1, 2, 3, 4)
|
101
|
-
expect(@dltotal).to eq(1)
|
102
|
-
end
|
103
|
-
|
104
|
-
it "executes blocks and passes dlnow" do
|
105
|
-
easy.progress(1, 2, 3, 4)
|
106
|
-
expect(@dlnow).to eq(2)
|
107
|
-
end
|
108
|
-
|
109
|
-
it "executes blocks and passes ultotal" do
|
110
|
-
easy.progress(1, 2, 3, 4)
|
111
|
-
expect(@ultotal).to eq(3)
|
112
|
-
end
|
113
|
-
|
114
|
-
it "executes blocks and passes ulnow" do
|
115
|
-
easy.progress(1, 2, 3, 4)
|
116
|
-
expect(@ulnow).to eq(4)
|
117
|
-
end
|
118
|
-
|
119
|
-
context "when @on_progress nil" do
|
120
|
-
it "doesn't raise" do
|
121
|
-
easy.instance_variable_set(:@on_progress, nil)
|
122
|
-
expect{ easy.progress(1, 2, 3, 4) }.to_not raise_error
|
123
|
-
end
|
124
|
-
end
|
125
|
-
end
|
126
|
-
end
|
127
|
-
|
128
|
-
describe "#body" do
|
129
|
-
before do
|
130
|
-
@chunk = nil
|
131
|
-
@r = nil
|
132
|
-
easy.on_body { |chunk, r| @chunk = chunk ; @r = r }
|
133
|
-
end
|
134
|
-
|
135
|
-
it "executes blocks and passes self" do
|
136
|
-
easy.body("the chunk")
|
137
|
-
expect(@r).to be(easy)
|
138
|
-
end
|
139
|
-
|
140
|
-
it "executes blocks and passes chunk" do
|
141
|
-
easy.body("the chunk")
|
142
|
-
expect(@chunk).to eq("the chunk")
|
143
|
-
end
|
144
|
-
|
145
|
-
context "when @on_body nil" do
|
146
|
-
it "doesn't raise" do
|
147
|
-
easy.instance_variable_set(:@on_body, nil)
|
148
|
-
expect{ easy.body("the chunk") }.to_not raise_error
|
149
|
-
end
|
150
|
-
end
|
151
|
-
end
|
152
|
-
end
|
@@ -1,28 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
require 'spec_helper'
|
3
|
-
|
4
|
-
describe Ethon::Easy::Util do
|
5
|
-
class Dummy
|
6
|
-
include Ethon::Easy::Util
|
7
|
-
end
|
8
|
-
|
9
|
-
let(:klass) { Dummy.new }
|
10
|
-
|
11
|
-
describe "escape_zero_byte" do
|
12
|
-
context "when value has no zero byte" do
|
13
|
-
let(:value) { "hello world" }
|
14
|
-
|
15
|
-
it "returns same value" do
|
16
|
-
expect(klass.escape_zero_byte(value)).to be(value)
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
context "when value has zero byte" do
|
21
|
-
let(:value) { "hello \0world" }
|
22
|
-
|
23
|
-
it "returns escaped" do
|
24
|
-
expect(klass.escape_zero_byte(value)).to eq("hello \\0world")
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
data/spec/ethon/easy_spec.rb
DELETED
@@ -1,203 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
require 'spec_helper'
|
3
|
-
|
4
|
-
describe Ethon::Easy do
|
5
|
-
let(:easy) { Ethon::Easy.new }
|
6
|
-
|
7
|
-
describe ".new" do
|
8
|
-
it "inits curl" do
|
9
|
-
expect(Ethon::Curl).to receive(:init)
|
10
|
-
easy
|
11
|
-
end
|
12
|
-
|
13
|
-
context "when options are empty" do
|
14
|
-
it "sets only callbacks" do
|
15
|
-
expect_any_instance_of(Ethon::Easy).to receive(:set_callbacks)
|
16
|
-
expect(Ethon::Easy).to receive(:set_option).never
|
17
|
-
easy
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
context "when options not empty" do
|
22
|
-
context "when followlocation is set" do
|
23
|
-
let(:options) { { :followlocation => true } }
|
24
|
-
let(:easy) { Ethon::Easy.new(options) }
|
25
|
-
|
26
|
-
it "sets followlocation" do
|
27
|
-
expect_any_instance_of(Ethon::Easy).to receive(:set_callbacks)
|
28
|
-
expect(Ethon::Curl).to receive(:set_option).with(:followlocation, true, anything)
|
29
|
-
easy
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
describe "#set_attributes" do
|
36
|
-
context "when options are empty" do
|
37
|
-
it "sets only callbacks" do
|
38
|
-
expect_any_instance_of(Ethon::Easy).to receive(:set_callbacks)
|
39
|
-
expect(Ethon::Easy).to receive(:set_option).never
|
40
|
-
easy
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
context "when options aren't empty" do
|
45
|
-
context "when valid key" do
|
46
|
-
it "sets" do
|
47
|
-
expect(easy).to receive(:verbose=).with(true)
|
48
|
-
easy.set_attributes({:verbose => true})
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
context "when invalid key" do
|
53
|
-
it "raises invalid option error" do
|
54
|
-
expect{ easy.set_attributes({:fubar => 1}) }.to raise_error(Ethon::Errors::InvalidOption)
|
55
|
-
end
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
describe "#reset" do
|
61
|
-
before { easy.url = "www.example.com" }
|
62
|
-
|
63
|
-
it "resets url" do
|
64
|
-
easy.reset
|
65
|
-
expect(easy.url).to be_nil
|
66
|
-
end
|
67
|
-
|
68
|
-
it "resets escape?" do
|
69
|
-
easy.escape = false
|
70
|
-
easy.reset
|
71
|
-
expect(easy.escape?).to be_truthy
|
72
|
-
end
|
73
|
-
|
74
|
-
it "resets hash" do
|
75
|
-
easy.reset
|
76
|
-
expect(easy.instance_variable_get(:@hash)).to be_nil
|
77
|
-
end
|
78
|
-
|
79
|
-
it "resets easy handle" do
|
80
|
-
expect(Ethon::Curl).to receive(:easy_reset)
|
81
|
-
easy.reset
|
82
|
-
end
|
83
|
-
|
84
|
-
it "resets on_complete" do
|
85
|
-
easy.on_complete { p 1 }
|
86
|
-
easy.reset
|
87
|
-
expect(easy.on_complete).to be_empty
|
88
|
-
end
|
89
|
-
|
90
|
-
it "resets on_headers" do
|
91
|
-
easy.on_headers { p 1 }
|
92
|
-
easy.reset
|
93
|
-
expect(easy.on_headers).to be_empty
|
94
|
-
end
|
95
|
-
|
96
|
-
it "resets on_body" do
|
97
|
-
easy.on_body { p 1 }
|
98
|
-
easy.reset
|
99
|
-
expect(easy.on_body).to be_empty
|
100
|
-
end
|
101
|
-
end
|
102
|
-
|
103
|
-
describe "#dup" do
|
104
|
-
let!(:easy) do
|
105
|
-
easy = Ethon::Easy.new
|
106
|
-
easy.url = "http://localhost:3001/"
|
107
|
-
easy.on_complete { 'on_complete' }
|
108
|
-
easy.on_headers { 'on_headers' }
|
109
|
-
easy.on_progress { 'on_progress' }
|
110
|
-
easy.response_body = String.new('test_body')
|
111
|
-
easy.response_headers = String.new('test_headers')
|
112
|
-
easy
|
113
|
-
end
|
114
|
-
let!(:e) { easy.dup }
|
115
|
-
|
116
|
-
it "sets a new handle" do
|
117
|
-
expect(e.handle).not_to eq(easy.handle)
|
118
|
-
end
|
119
|
-
|
120
|
-
it "preserves url" do
|
121
|
-
expect(e.url).to eq(easy.url)
|
122
|
-
end
|
123
|
-
|
124
|
-
it "preserves on_complete callback" do
|
125
|
-
expect(e.on_complete).to be(easy.on_complete)
|
126
|
-
end
|
127
|
-
|
128
|
-
it "preserves on_headers callback" do
|
129
|
-
expect(e.on_headers).to be(easy.on_headers)
|
130
|
-
end
|
131
|
-
|
132
|
-
it 'preserves body_write_callback of original handle' do
|
133
|
-
expect { easy.perform }.to change { easy.response_body }
|
134
|
-
expect { easy.perform }.not_to change { e.response_body }
|
135
|
-
end
|
136
|
-
|
137
|
-
it "preserves on_progress callback" do
|
138
|
-
expect(e.on_progress).to be(easy.on_progress)
|
139
|
-
end
|
140
|
-
|
141
|
-
it 'sets new body_write_callback of duplicated handle' do
|
142
|
-
expect { e.perform }.to change { e.response_body }
|
143
|
-
expect { e.perform }.not_to change { easy.response_body }
|
144
|
-
end
|
145
|
-
|
146
|
-
it 'preserves headers_write_callback of original handle' do
|
147
|
-
expect { easy.perform }.to change { easy.response_headers }
|
148
|
-
expect { easy.perform }.not_to change { e.response_headers }
|
149
|
-
end
|
150
|
-
|
151
|
-
it 'sets new headers_write_callback of duplicated handle' do
|
152
|
-
expect { e.perform }.to change { e.response_headers }
|
153
|
-
expect { e.perform }.not_to change { easy.response_headers }
|
154
|
-
end
|
155
|
-
|
156
|
-
it "resets response_body" do
|
157
|
-
expect(e.response_body).to be_empty
|
158
|
-
end
|
159
|
-
|
160
|
-
it "resets response_headers" do
|
161
|
-
expect(e.response_headers).to be_empty
|
162
|
-
end
|
163
|
-
|
164
|
-
it "sets response_body for duplicated Easy" do
|
165
|
-
e.perform
|
166
|
-
expect(e.response_body).not_to be_empty
|
167
|
-
end
|
168
|
-
|
169
|
-
it "sets response_headers for duplicated Easy" do
|
170
|
-
e.perform
|
171
|
-
expect(e.response_headers).not_to be_empty
|
172
|
-
end
|
173
|
-
|
174
|
-
it "preserves response_body for original Easy" do
|
175
|
-
e.perform
|
176
|
-
expect(easy.response_body).to eq('test_body')
|
177
|
-
end
|
178
|
-
|
179
|
-
it "preserves response_headers for original Easy" do
|
180
|
-
e.perform
|
181
|
-
expect(easy.response_headers).to eq('test_headers')
|
182
|
-
end
|
183
|
-
end
|
184
|
-
|
185
|
-
describe "#mirror" do
|
186
|
-
it "returns a Mirror" do
|
187
|
-
expect(easy.mirror).to be_a(Ethon::Easy::Mirror)
|
188
|
-
end
|
189
|
-
|
190
|
-
it "builds from easy" do
|
191
|
-
expect(Ethon::Easy::Mirror).to receive(:from_easy).with(easy)
|
192
|
-
easy.mirror
|
193
|
-
end
|
194
|
-
end
|
195
|
-
|
196
|
-
describe "#log_inspect" do
|
197
|
-
[ :url, :response_code, :return_code, :total_time ].each do |name|
|
198
|
-
it "contains #{name}" do
|
199
|
-
expect(easy.log_inspect).to match name.to_s
|
200
|
-
end
|
201
|
-
end
|
202
|
-
end
|
203
|
-
end
|
data/spec/ethon/libc_spec.rb
DELETED
@@ -1,14 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
require 'spec_helper'
|
3
|
-
|
4
|
-
describe Ethon::Libc do
|
5
|
-
describe "#getdtablesize", :if => !Ethon::Curl.windows? do
|
6
|
-
it "returns an integer" do
|
7
|
-
expect(Ethon::Libc.getdtablesize).to be_a(Integer)
|
8
|
-
end
|
9
|
-
|
10
|
-
it "returns bigger zero", :if => !Ethon::Curl.windows? do
|
11
|
-
expect(Ethon::Libc.getdtablesize).to_not be_zero
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|
data/spec/ethon/loggable_spec.rb
DELETED
@@ -1,22 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
require "spec_helper"
|
3
|
-
|
4
|
-
describe Ethon::Loggable do
|
5
|
-
|
6
|
-
describe "#logger=" do
|
7
|
-
|
8
|
-
let(:logger) do
|
9
|
-
Logger.new($stdout).tap do |log|
|
10
|
-
log.level = Logger::INFO
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
before do
|
15
|
-
Ethon.logger = logger
|
16
|
-
end
|
17
|
-
|
18
|
-
it "sets the logger" do
|
19
|
-
expect(Ethon.logger).to eq(logger)
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
@@ -1,298 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
require 'spec_helper'
|
3
|
-
|
4
|
-
describe Ethon::Multi::Operations do
|
5
|
-
let(:multi) { Ethon::Multi.new }
|
6
|
-
let(:easy) { Ethon::Easy.new }
|
7
|
-
let(:pointer) { FFI::MemoryPointer.new(:int) }
|
8
|
-
|
9
|
-
describe "#handle" do
|
10
|
-
it "returns a pointer" do
|
11
|
-
expect(multi.handle).to be_a(FFI::Pointer)
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
describe "#running_count" do
|
16
|
-
context "when hydra has no easy" do
|
17
|
-
it "returns nil" do
|
18
|
-
expect(multi.send(:running_count)).to be_nil
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
context "when hydra has easy" do
|
23
|
-
before do
|
24
|
-
easy.url = "http://localhost:3001/"
|
25
|
-
multi.add(easy)
|
26
|
-
multi.send(:trigger, pointer)
|
27
|
-
end
|
28
|
-
|
29
|
-
it "returns 1" do
|
30
|
-
expect(multi.send(:running_count)).to eq(1)
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
context "when hydra has more easys" do
|
35
|
-
let(:another_easy) { Ethon::Easy.new }
|
36
|
-
|
37
|
-
before do
|
38
|
-
easy.url = "http://localhost:3001/"
|
39
|
-
another_easy.url = "http://localhost:3001/"
|
40
|
-
multi.add(easy)
|
41
|
-
multi.add(another_easy)
|
42
|
-
multi.send(:trigger, pointer)
|
43
|
-
end
|
44
|
-
|
45
|
-
it "returns 2" do
|
46
|
-
expect(multi.send(:running_count)).to eq(2)
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
describe "#get_timeout" do
|
52
|
-
context "when code ok" do
|
53
|
-
let(:timeout) { 1 }
|
54
|
-
|
55
|
-
before do
|
56
|
-
expect(Ethon::Curl).to receive(:multi_timeout).and_return(:ok)
|
57
|
-
multi.instance_variable_set(:@timeout, double(:read_long => timeout))
|
58
|
-
end
|
59
|
-
|
60
|
-
it "doesn't raise" do
|
61
|
-
expect{ multi.send(:get_timeout) }.to_not raise_error
|
62
|
-
end
|
63
|
-
|
64
|
-
context "when timeout smaller zero" do
|
65
|
-
let(:timeout) { -1 }
|
66
|
-
|
67
|
-
it "returns 1" do
|
68
|
-
expect(multi.send(:get_timeout)).to eq(1)
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
context "when timeout bigger or equal zero" do
|
73
|
-
let(:timeout) { 2 }
|
74
|
-
|
75
|
-
it "returns timeout" do
|
76
|
-
expect(multi.send(:get_timeout)).to eq(timeout)
|
77
|
-
end
|
78
|
-
end
|
79
|
-
end
|
80
|
-
|
81
|
-
context "when code not ok" do
|
82
|
-
before { expect(Ethon::Curl).to receive(:multi_timeout).and_return(:not_ok) }
|
83
|
-
|
84
|
-
it "raises MultiTimeout error" do
|
85
|
-
expect{ multi.send(:get_timeout) }.to raise_error(Ethon::Errors::MultiTimeout)
|
86
|
-
end
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
90
|
-
describe "#set_fds" do
|
91
|
-
let(:timeout) { 1 }
|
92
|
-
let(:max_fd) { 1 }
|
93
|
-
|
94
|
-
context "when code ok" do
|
95
|
-
before { expect(Ethon::Curl).to receive(:multi_fdset).and_return(:ok) }
|
96
|
-
|
97
|
-
it "doesn't raise" do
|
98
|
-
expect{ multi.method(:set_fds).call(timeout) }.to_not raise_error
|
99
|
-
end
|
100
|
-
|
101
|
-
context "when max_fd -1" do
|
102
|
-
let(:max_fd) { -1 }
|
103
|
-
|
104
|
-
before do
|
105
|
-
multi.instance_variable_set(:@max_fd, double(:read_int => max_fd))
|
106
|
-
expect(multi).to receive(:sleep).with(0.001)
|
107
|
-
end
|
108
|
-
|
109
|
-
it "waits 100ms" do
|
110
|
-
multi.method(:set_fds).call(timeout)
|
111
|
-
end
|
112
|
-
end
|
113
|
-
|
114
|
-
context "when max_fd not -1" do
|
115
|
-
context "when code smaller zero" do
|
116
|
-
before { expect(Ethon::Curl).to receive(:select).and_return(-1) }
|
117
|
-
|
118
|
-
it "raises Select error" do
|
119
|
-
expect{ multi.method(:set_fds).call(timeout) }.to raise_error(Ethon::Errors::Select)
|
120
|
-
end
|
121
|
-
end
|
122
|
-
|
123
|
-
context "when code bigger or equal zero" do
|
124
|
-
before { expect(Ethon::Curl).to receive(:select).and_return(0) }
|
125
|
-
|
126
|
-
it "doesn't raise" do
|
127
|
-
expect{ multi.method(:set_fds).call(timeout) }.to_not raise_error
|
128
|
-
end
|
129
|
-
end
|
130
|
-
end
|
131
|
-
end
|
132
|
-
|
133
|
-
context "when code not ok" do
|
134
|
-
before { expect(Ethon::Curl).to receive(:multi_fdset).and_return(:not_ok) }
|
135
|
-
|
136
|
-
it "raises MultiFdset error" do
|
137
|
-
expect{ multi.method(:set_fds).call(timeout) }.to raise_error(Ethon::Errors::MultiFdset)
|
138
|
-
end
|
139
|
-
end
|
140
|
-
end
|
141
|
-
|
142
|
-
describe "#perform" do
|
143
|
-
context "when no easy handles" do
|
144
|
-
it "returns nil" do
|
145
|
-
expect(multi.perform).to be_nil
|
146
|
-
end
|
147
|
-
|
148
|
-
it "logs" do
|
149
|
-
expect(Ethon.logger).to receive(:debug).twice
|
150
|
-
multi.perform
|
151
|
-
end
|
152
|
-
end
|
153
|
-
|
154
|
-
context "when easy handle" do
|
155
|
-
before do
|
156
|
-
easy.url = "http://localhost:3001/"
|
157
|
-
multi.add(easy)
|
158
|
-
end
|
159
|
-
|
160
|
-
it "requests" do
|
161
|
-
multi.perform
|
162
|
-
end
|
163
|
-
|
164
|
-
it "sets easy" do
|
165
|
-
multi.perform
|
166
|
-
expect(easy.response_code).to eq(200)
|
167
|
-
end
|
168
|
-
end
|
169
|
-
|
170
|
-
context "when four easy handles" do
|
171
|
-
let(:easies) do
|
172
|
-
ary = []
|
173
|
-
4.times do
|
174
|
-
ary << another_easy = Ethon::Easy.new
|
175
|
-
another_easy.url = "http://localhost:3001/"
|
176
|
-
end
|
177
|
-
ary
|
178
|
-
end
|
179
|
-
|
180
|
-
before do
|
181
|
-
easies.each { |e| multi.add(e) }
|
182
|
-
multi.perform
|
183
|
-
end
|
184
|
-
|
185
|
-
it "sets response codes" do
|
186
|
-
expect(easies.all?{ |e| e.response_code == 200 }).to be_truthy
|
187
|
-
end
|
188
|
-
end
|
189
|
-
end
|
190
|
-
|
191
|
-
describe "#ongoing?" do
|
192
|
-
context "when easy_handles" do
|
193
|
-
before { multi.easy_handles << 1 }
|
194
|
-
|
195
|
-
context "when running_count not greater 0" do
|
196
|
-
before { multi.instance_variable_set(:@running_count, 0) }
|
197
|
-
|
198
|
-
it "returns true" do
|
199
|
-
expect(multi.method(:ongoing?).call).to be_truthy
|
200
|
-
end
|
201
|
-
end
|
202
|
-
|
203
|
-
context "when running_count greater 0" do
|
204
|
-
before { multi.instance_variable_set(:@running_count, 1) }
|
205
|
-
|
206
|
-
it "returns true" do
|
207
|
-
expect(multi.method(:ongoing?).call).to be_truthy
|
208
|
-
end
|
209
|
-
end
|
210
|
-
end
|
211
|
-
|
212
|
-
context "when no easy_handles" do
|
213
|
-
context "when running_count not greater 0" do
|
214
|
-
before { multi.instance_variable_set(:@running_count, 0) }
|
215
|
-
|
216
|
-
it "returns false" do
|
217
|
-
expect(multi.method(:ongoing?).call).to be_falsey
|
218
|
-
end
|
219
|
-
end
|
220
|
-
|
221
|
-
context "when running_count greater 0" do
|
222
|
-
before { multi.instance_variable_set(:@running_count, 1) }
|
223
|
-
|
224
|
-
it "returns true" do
|
225
|
-
expect(multi.method(:ongoing?).call).to be_truthy
|
226
|
-
end
|
227
|
-
end
|
228
|
-
end
|
229
|
-
end
|
230
|
-
|
231
|
-
describe "#init_vars" do
|
232
|
-
it "sets @timeout" do
|
233
|
-
expect(multi.instance_variable_get(:@timeout)).to be_a(FFI::MemoryPointer)
|
234
|
-
end
|
235
|
-
|
236
|
-
it "sets @timeval" do
|
237
|
-
expect(multi.instance_variable_get(:@timeval)).to be_a(Ethon::Curl::Timeval)
|
238
|
-
end
|
239
|
-
|
240
|
-
it "sets @fd_read" do
|
241
|
-
expect(multi.instance_variable_get(:@fd_read)).to be_a(Ethon::Curl::FDSet)
|
242
|
-
end
|
243
|
-
|
244
|
-
it "sets @fd_write" do
|
245
|
-
expect(multi.instance_variable_get(:@fd_write)).to be_a(Ethon::Curl::FDSet)
|
246
|
-
end
|
247
|
-
|
248
|
-
it "sets @fd_excep" do
|
249
|
-
expect(multi.instance_variable_get(:@fd_excep)).to be_a(Ethon::Curl::FDSet)
|
250
|
-
end
|
251
|
-
|
252
|
-
it "sets @max_fd" do
|
253
|
-
expect(multi.instance_variable_get(:@max_fd)).to be_a(FFI::MemoryPointer)
|
254
|
-
end
|
255
|
-
end
|
256
|
-
|
257
|
-
describe "#reset_fds" do
|
258
|
-
after { multi.method(:reset_fds).call }
|
259
|
-
|
260
|
-
it "resets @fd_read" do
|
261
|
-
expect(multi.instance_variable_get(:@fd_read)).to receive(:clear)
|
262
|
-
end
|
263
|
-
|
264
|
-
it "resets @fd_write" do
|
265
|
-
expect(multi.instance_variable_get(:@fd_write)).to receive(:clear)
|
266
|
-
end
|
267
|
-
|
268
|
-
it "resets @fd_excep" do
|
269
|
-
expect(multi.instance_variable_get(:@fd_excep)).to receive(:clear)
|
270
|
-
end
|
271
|
-
end
|
272
|
-
|
273
|
-
describe "#check" do
|
274
|
-
it { skip("untested") }
|
275
|
-
end
|
276
|
-
|
277
|
-
describe "#run" do
|
278
|
-
it { skip("untested") }
|
279
|
-
end
|
280
|
-
|
281
|
-
describe "#trigger" do
|
282
|
-
it "calls multi perform" do
|
283
|
-
expect(Ethon::Curl).to receive(:multi_perform)
|
284
|
-
multi.send(:trigger, pointer)
|
285
|
-
end
|
286
|
-
|
287
|
-
it "sets running count" do
|
288
|
-
multi.instance_variable_set(:@running_count, nil)
|
289
|
-
multi.send(:trigger, pointer)
|
290
|
-
expect(multi.instance_variable_get(:@running_count)).to_not be_nil
|
291
|
-
end
|
292
|
-
|
293
|
-
it "returns multi perform code" do
|
294
|
-
expect(Ethon::Curl).to receive(:multi_perform).and_return(:ok)
|
295
|
-
expect(multi.send(:trigger, pointer)).to eq(:ok)
|
296
|
-
end
|
297
|
-
end
|
298
|
-
end
|