pauldix-typhoeus 0.0.8
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/ext/typhoeus/Makefile +157 -0
- data/ext/typhoeus/extconf.rb +57 -0
- data/ext/typhoeus/native.c +11 -0
- data/ext/typhoeus/native.h +11 -0
- data/ext/typhoeus/typhoeus_easy.c +206 -0
- data/ext/typhoeus/typhoeus_easy.h +19 -0
- data/ext/typhoeus/typhoeus_multi.c +213 -0
- data/ext/typhoeus/typhoeus_multi.h +16 -0
- data/lib/typhoeus/easy.rb +196 -0
- data/lib/typhoeus/filter.rb +28 -0
- data/lib/typhoeus/multi.rb +21 -0
- data/lib/typhoeus/remote.rb +126 -0
- data/lib/typhoeus/remote_method.rb +107 -0
- data/lib/typhoeus/remote_proxy_object.rb +42 -0
- data/lib/typhoeus/response.rb +12 -0
- data/lib/typhoeus.rb +48 -0
- data/spec/servers/delay_fixture_server.rb +66 -0
- data/spec/servers/method_server.rb +51 -0
- data/spec/spec.opts +2 -0
- data/spec/spec_helper.rb +29 -0
- data/spec/typhoeus/easy_spec.rb +122 -0
- data/spec/typhoeus/filter_spec.rb +35 -0
- data/spec/typhoeus/multi_spec.rb +70 -0
- data/spec/typhoeus/remote_method_spec.rb +141 -0
- data/spec/typhoeus/remote_proxy_object_spec.rb +67 -0
- data/spec/typhoeus/remote_spec.rb +399 -0
- data/spec/typhoeus/response_spec.rb +21 -0
- metadata +80 -0
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
require "rubygems"
|
2
|
+
require "spec"
|
3
|
+
|
4
|
+
# gem install redgreen for colored test output
|
5
|
+
begin require "redgreen" unless ENV['TM_CURRENT_LINE']; rescue LoadError; end
|
6
|
+
|
7
|
+
path = File.expand_path(File.dirname(__FILE__) + "/../lib/")
|
8
|
+
$LOAD_PATH.unshift(path) unless $LOAD_PATH.include?(path)
|
9
|
+
|
10
|
+
require "lib/typhoeus"
|
11
|
+
|
12
|
+
# local servers for running tests
|
13
|
+
require File.dirname(__FILE__) + "/servers/method_server.rb"
|
14
|
+
|
15
|
+
def start_method_server(port, sleep = 0)
|
16
|
+
MethodServer.sleep_time = sleep
|
17
|
+
pid = Process.fork do
|
18
|
+
EventMachine::run {
|
19
|
+
EventMachine.epoll
|
20
|
+
EventMachine::start_server("0.0.0.0", port, MethodServer)
|
21
|
+
}
|
22
|
+
end
|
23
|
+
sleep 0.2
|
24
|
+
pid
|
25
|
+
end
|
26
|
+
|
27
|
+
def stop_method_server(pid)
|
28
|
+
Process.kill("HUP", pid)
|
29
|
+
end
|
@@ -0,0 +1,122 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
|
3
|
+
describe Typhoeus::Easy do
|
4
|
+
before(:all) do
|
5
|
+
@pid = start_method_server(3002)
|
6
|
+
end
|
7
|
+
|
8
|
+
after(:all) do
|
9
|
+
stop_method_server(@pid)
|
10
|
+
end
|
11
|
+
|
12
|
+
describe "options" do
|
13
|
+
it "should allow for following redirects"
|
14
|
+
it "should allow you to set the user agent"
|
15
|
+
it "should provide a timeout in milliseconds" do
|
16
|
+
pid = start_method_server(3001, 5)
|
17
|
+
e = Typhoeus::Easy.new
|
18
|
+
e.url = "http://localhost:3001"
|
19
|
+
e.method = :get
|
20
|
+
e.timeout = 50
|
21
|
+
e.perform
|
22
|
+
puts e.response_code
|
23
|
+
puts e.total_time_taken
|
24
|
+
# e.timed_out?.should == true
|
25
|
+
stop_method_server(pid)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe "get" do
|
30
|
+
it "should perform a get" do
|
31
|
+
easy = Typhoeus::Easy.new
|
32
|
+
easy.url = "http://localhost:3002"
|
33
|
+
easy.method = :get
|
34
|
+
easy.perform
|
35
|
+
easy.response_code.should == 200
|
36
|
+
easy.response_body.should include("REQUEST_METHOD=GET")
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should send a request body" do
|
40
|
+
easy = Typhoeus::Easy.new
|
41
|
+
easy.url = "http://localhost:3002"
|
42
|
+
easy.method = :get
|
43
|
+
easy.request_body = "this is a body!"
|
44
|
+
easy.perform
|
45
|
+
easy.response_code.should == 200
|
46
|
+
easy.response_body.should include("this is a body!")
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
describe "put" do
|
51
|
+
it "should perform a put" do
|
52
|
+
easy = Typhoeus::Easy.new
|
53
|
+
easy.url = "http://localhost:3002"
|
54
|
+
easy.method = :put
|
55
|
+
easy.perform
|
56
|
+
easy.response_code.should == 200
|
57
|
+
easy.response_body.should include("REQUEST_METHOD=PUT")
|
58
|
+
end
|
59
|
+
|
60
|
+
it "should send a request body" do
|
61
|
+
easy = Typhoeus::Easy.new
|
62
|
+
easy.url = "http://localhost:3002"
|
63
|
+
easy.method = :put
|
64
|
+
easy.request_body = "this is a body!"
|
65
|
+
easy.perform
|
66
|
+
easy.response_code.should == 200
|
67
|
+
easy.response_body.should include("this is a body!")
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
describe "post" do
|
72
|
+
it "should perform a post" do
|
73
|
+
easy = Typhoeus::Easy.new
|
74
|
+
easy.url = "http://localhost:3002"
|
75
|
+
easy.method = :post
|
76
|
+
easy.perform
|
77
|
+
easy.response_code.should == 200
|
78
|
+
easy.response_body.should include("REQUEST_METHOD=POST")
|
79
|
+
end
|
80
|
+
|
81
|
+
it "should send a request body" do
|
82
|
+
easy = Typhoeus::Easy.new
|
83
|
+
easy.url = "http://localhost:3002"
|
84
|
+
easy.method = :post
|
85
|
+
easy.request_body = "this is a body!"
|
86
|
+
easy.perform
|
87
|
+
easy.response_code.should == 200
|
88
|
+
easy.response_body.should include("this is a body!")
|
89
|
+
end
|
90
|
+
|
91
|
+
it "should handle params" do
|
92
|
+
easy = Typhoeus::Easy.new
|
93
|
+
easy.url = "http://localhost:3002"
|
94
|
+
easy.method = :post
|
95
|
+
easy.params = {:foo => "bar"}
|
96
|
+
easy.perform
|
97
|
+
easy.response_code.should == 200
|
98
|
+
easy.response_body.should include("foo=bar")
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
describe "delete" do
|
103
|
+
it "should perform a delete" do
|
104
|
+
easy = Typhoeus::Easy.new
|
105
|
+
easy.url = "http://localhost:3002"
|
106
|
+
easy.method = :delete
|
107
|
+
easy.perform
|
108
|
+
easy.response_code.should == 200
|
109
|
+
easy.response_body.should include("REQUEST_METHOD=DELETE")
|
110
|
+
end
|
111
|
+
|
112
|
+
it "should send a request body" do
|
113
|
+
easy = Typhoeus::Easy.new
|
114
|
+
easy.url = "http://localhost:3002"
|
115
|
+
easy.method = :delete
|
116
|
+
easy.request_body = "this is a body!"
|
117
|
+
easy.perform
|
118
|
+
easy.response_code.should == 200
|
119
|
+
easy.response_body.should include("this is a body!")
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
|
3
|
+
describe Typhoeus::Filter do
|
4
|
+
it "should take a method name and optionally take options" do
|
5
|
+
filter = Typhoeus::Filter.new(:bar, :only => :foo)
|
6
|
+
filter = Typhoeus::Filter.new(:bar)
|
7
|
+
end
|
8
|
+
|
9
|
+
describe "#apply_filter?" do
|
10
|
+
it "should return true for any method when :only and :except aren't specified" do
|
11
|
+
filter = Typhoeus::Filter.new(:bar)
|
12
|
+
filter.apply_filter?(:asdf).should be_true
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should return true if a method is in only" do
|
16
|
+
filter = Typhoeus::Filter.new(:bar, :only => :foo)
|
17
|
+
filter.apply_filter?(:foo).should be_true
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should return false if a method isn't in only" do
|
21
|
+
filter = Typhoeus::Filter.new(:bar, :only => :foo)
|
22
|
+
filter.apply_filter?(:bar).should be_false
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should return true if a method isn't in except" do
|
26
|
+
filter = Typhoeus::Filter.new(:bar, :except => :foo)
|
27
|
+
filter.apply_filter?(:bar).should be_true
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should return false if a method is in except" do
|
31
|
+
filter = Typhoeus::Filter.new(:bar, :except => :foo)
|
32
|
+
filter.apply_filter?(:foo).should be_false
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
|
3
|
+
describe Typhoeus::Easy do
|
4
|
+
before(:all) do
|
5
|
+
@pid = start_method_server(3002)
|
6
|
+
end
|
7
|
+
|
8
|
+
after(:all) do
|
9
|
+
stop_method_server(@pid)
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should be reusable" do
|
13
|
+
easy = Typhoeus::Easy.new
|
14
|
+
easy.url = "http://localhost:3002"
|
15
|
+
easy.method = :get
|
16
|
+
|
17
|
+
multi = Typhoeus::Multi.new
|
18
|
+
multi.add(easy)
|
19
|
+
multi.perform
|
20
|
+
easy.response_code.should == 200
|
21
|
+
easy.response_body.should include("METHOD=GET")
|
22
|
+
|
23
|
+
e2 = Typhoeus::Easy.new
|
24
|
+
e2.url = "http://localhost:3002"
|
25
|
+
e2.method = :post
|
26
|
+
multi.add(e2)
|
27
|
+
multi.perform
|
28
|
+
|
29
|
+
e2.response_code.should == 200
|
30
|
+
e2.response_body.should include("METHOD=POST")
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should perform easy handles added after the first one runs" do
|
34
|
+
easy = Typhoeus::Easy.new
|
35
|
+
easy.url = "http://localhost:3002"
|
36
|
+
easy.method = :get
|
37
|
+
multi = Typhoeus::Multi.new
|
38
|
+
multi.add(easy)
|
39
|
+
|
40
|
+
e2 = Typhoeus::Easy.new
|
41
|
+
e2.url = "http://localhost:3002"
|
42
|
+
e2.method = :post
|
43
|
+
easy.on_success do |e|
|
44
|
+
multi.add(e2)
|
45
|
+
end
|
46
|
+
|
47
|
+
multi.perform
|
48
|
+
easy.response_code.should == 200
|
49
|
+
easy.response_body.should include("METHOD=GET")
|
50
|
+
e2.response_code.should == 200
|
51
|
+
e2.response_body.should include("METHOD=POST")
|
52
|
+
end
|
53
|
+
|
54
|
+
# it "should do multiple gets" do
|
55
|
+
# multi = Typhoeus::Multi.new
|
56
|
+
#
|
57
|
+
# handles = []
|
58
|
+
# 5.times do |i|
|
59
|
+
# easy = Typhoeus::Easy.new
|
60
|
+
# easy.url = "http://localhost:3002"
|
61
|
+
# easy.method = :get
|
62
|
+
# easy.on_success {|e| puts "get #{i} succeeded"}
|
63
|
+
# easy.on_failure {|e| puts "get #{i} failed with #{e.response_code}"}
|
64
|
+
# handles << easy
|
65
|
+
# multi.add(easy)
|
66
|
+
# end
|
67
|
+
#
|
68
|
+
# multi.perform
|
69
|
+
# end
|
70
|
+
end
|
@@ -0,0 +1,141 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
|
3
|
+
describe Typhoeus::RemoteMethod do
|
4
|
+
it "should take options" do
|
5
|
+
Typhoeus::RemoteMethod.new(:body => "foo")
|
6
|
+
end
|
7
|
+
|
8
|
+
describe "http_method" do
|
9
|
+
it "should return the http method" do
|
10
|
+
m = Typhoeus::RemoteMethod.new(:method => :put)
|
11
|
+
m.http_method.should == :put
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should default to :get" do
|
15
|
+
m = Typhoeus::RemoteMethod.new
|
16
|
+
m.http_method.should == :get
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should return the options" do
|
21
|
+
m = Typhoeus::RemoteMethod.new(:body => "foo")
|
22
|
+
m.options.should == {:body => "foo"}
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should pull uri out of the options hash" do
|
26
|
+
m = Typhoeus::RemoteMethod.new(:base_uri => "http://pauldix.net")
|
27
|
+
m.base_uri.should == "http://pauldix.net"
|
28
|
+
m.options.should_not have_key(:base_uri)
|
29
|
+
end
|
30
|
+
|
31
|
+
describe "on_success" do
|
32
|
+
it "should return the block" do
|
33
|
+
m = Typhoeus::RemoteMethod.new(:on_success => lambda {:foo})
|
34
|
+
m.on_success.call.should == :foo
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
describe "on_failure" do
|
39
|
+
it "should return method name" do
|
40
|
+
m = Typhoeus::RemoteMethod.new(:on_failure => lambda {:bar})
|
41
|
+
m.on_failure.call.should == :bar
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
describe "path" do
|
46
|
+
it "should pull path out of the options hash" do
|
47
|
+
m = Typhoeus::RemoteMethod.new(:path => "foo")
|
48
|
+
m.path.should == "foo"
|
49
|
+
m.options.should_not have_key(:path)
|
50
|
+
end
|
51
|
+
|
52
|
+
it "should output argument names from the symbols in the path" do
|
53
|
+
m = Typhoeus::RemoteMethod.new(:path => "/posts/:post_id/comments/:comment_id")
|
54
|
+
m.argument_names.should == [:post_id, :comment_id]
|
55
|
+
end
|
56
|
+
|
57
|
+
it "should output an empty string when there are no arguments in path" do
|
58
|
+
m = Typhoeus::RemoteMethod.new(:path => "/default.html")
|
59
|
+
m.argument_names.should == []
|
60
|
+
end
|
61
|
+
|
62
|
+
it "should output and empty string when there is no path specified" do
|
63
|
+
m = Typhoeus::RemoteMethod.new
|
64
|
+
m.argument_names.should == []
|
65
|
+
end
|
66
|
+
|
67
|
+
it "should interpolate a path with arguments" do
|
68
|
+
m = Typhoeus::RemoteMethod.new(:path => "/posts/:post_id/comments/:comment_id")
|
69
|
+
m.interpolate_path_with_arguments(:post_id => 1, :comment_id => "asdf").should == "/posts/1/comments/asdf"
|
70
|
+
end
|
71
|
+
|
72
|
+
it "should provide the path when interpolated called and there is nothing to interpolate" do
|
73
|
+
m = Typhoeus::RemoteMethod.new(:path => "/posts/123")
|
74
|
+
m.interpolate_path_with_arguments(:foo => :bar).should == "/posts/123"
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
describe "#merge_options" do
|
79
|
+
it "should keep the passed in options first" do
|
80
|
+
m = Typhoeus::RemoteMethod.new("User-Agent" => "whatev", :foo => :bar)
|
81
|
+
m.merge_options({"User-Agent" => "http-machine"}).should == {"User-Agent" => "http-machine", :foo => :bar}
|
82
|
+
end
|
83
|
+
|
84
|
+
it "should combine the params" do
|
85
|
+
m = Typhoeus::RemoteMethod.new(:foo => :bar, :params => {:id => :asdf})
|
86
|
+
m.merge_options({:params => {:desc => :jkl}}).should == {:foo => :bar, :params => {:id => :asdf, :desc => :jkl}}
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
describe "memoize_reponses" do
|
91
|
+
before(:each) do
|
92
|
+
@m = Typhoeus::RemoteMethod.new(:memoize_responses => true)
|
93
|
+
@args = ["foo", "bar"]
|
94
|
+
@options = {:asdf => {:jkl => :bar}}
|
95
|
+
end
|
96
|
+
|
97
|
+
it "should store if responses should be memoized" do
|
98
|
+
@m.memoize_responses?.should be_true
|
99
|
+
@m.options.should == {}
|
100
|
+
end
|
101
|
+
|
102
|
+
it "should tell when a method is already called" do
|
103
|
+
@m.already_called?(@args, @options).should be_false
|
104
|
+
@m.calling(@args, @options)
|
105
|
+
@m.already_called?(@args, @options).should be_true
|
106
|
+
@m.already_called?([], {}).should be_false
|
107
|
+
end
|
108
|
+
|
109
|
+
it "should call response blocks and clear the methods that have been called" do
|
110
|
+
response_block_called = mock('response_block')
|
111
|
+
response_block_called.should_receive(:call).exactly(1).times
|
112
|
+
|
113
|
+
@m.add_response_block(lambda {|res| res.should == :foo; response_block_called.call}, @args, @options)
|
114
|
+
@m.calling(@args, @options)
|
115
|
+
@m.call_response_blocks(:foo, @args, @options)
|
116
|
+
@m.already_called?(@args, @options).should be_false
|
117
|
+
@m.call_response_blocks(:asdf, @args, @options) #just to make sure it doesn't actually call that block again
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
describe "cache_reponses" do
|
122
|
+
before(:each) do
|
123
|
+
@m = Typhoeus::RemoteMethod.new(:cache_responses => true)
|
124
|
+
@args = ["foo", "bar"]
|
125
|
+
@options = {:asdf => {:jkl => :bar}}
|
126
|
+
end
|
127
|
+
|
128
|
+
it "should store if responses should be cached" do
|
129
|
+
@m.cache_responses?.should be_true
|
130
|
+
@m.options.should == {}
|
131
|
+
end
|
132
|
+
|
133
|
+
it "should force memoization if caching is enabled" do
|
134
|
+
@m.memoize_responses?.should be_true
|
135
|
+
end
|
136
|
+
|
137
|
+
it "should store cache ttl" do
|
138
|
+
Typhoeus::RemoteMethod.new(:cache_responses => 30).cache_ttl.should == 30
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
|
3
|
+
describe Typhoeus::RemoteProxyObject do
|
4
|
+
before(:each) do
|
5
|
+
@easy = Typhoeus::Easy.new
|
6
|
+
@easy.method = :get
|
7
|
+
@easy.url = "http://localhost:3001"
|
8
|
+
end
|
9
|
+
|
10
|
+
before(:all) do
|
11
|
+
@pid = start_method_server(3001)
|
12
|
+
end
|
13
|
+
|
14
|
+
after(:all) do
|
15
|
+
stop_method_server(@pid)
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should take a caller and call the clear_memoized_proxy_objects" do
|
19
|
+
clear_proxy = lambda {}
|
20
|
+
clear_proxy.should_receive(:call)
|
21
|
+
response = Typhoeus::RemoteProxyObject.new(clear_proxy, @easy)
|
22
|
+
response.code.should == 200
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should take an easy object and return the body when requested" do
|
26
|
+
response = Typhoeus::RemoteProxyObject.new(lambda {}, @easy)
|
27
|
+
@easy.response_code.should == 0
|
28
|
+
response.code.should == 200
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should perform requests only on the first access" do
|
32
|
+
response = Typhoeus::RemoteProxyObject.new(lambda {}, @easy)
|
33
|
+
response.code.should == 200
|
34
|
+
Typhoeus.should_receive(:perform_easy_requests).exactly(0).times
|
35
|
+
response.code.should == 200
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should call the on_success method with an easy object and proxy to the result of on_success" do
|
39
|
+
klass = Class.new do
|
40
|
+
def initialize(r)
|
41
|
+
@response = r
|
42
|
+
end
|
43
|
+
|
44
|
+
def blah
|
45
|
+
@response.code
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
k = Typhoeus::RemoteProxyObject.new(lambda {}, @easy, :on_success => lambda {|e| klass.new(e)})
|
50
|
+
k.blah.should == 200
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should call the on_failure method with an easy object and proxy to the result of on_failure" do
|
54
|
+
klass = Class.new do
|
55
|
+
def initialize(r)
|
56
|
+
@response = r
|
57
|
+
end
|
58
|
+
|
59
|
+
def blah
|
60
|
+
@response.code
|
61
|
+
end
|
62
|
+
end
|
63
|
+
@easy.url = "http://localhost:3002" #bad port
|
64
|
+
k = Typhoeus::RemoteProxyObject.new(lambda {}, @easy, :on_failure => lambda {|e| klass.new(e)})
|
65
|
+
k.blah.should == 0
|
66
|
+
end
|
67
|
+
end
|