Repository navigation
Expand file tree
/
Copy pathtest_helper.rb
More file actions
118 lines (108 loc) · 3.51 KB
/
Copy pathtest_helper.rb
File metadata and controls
118 lines (108 loc) · 3.51 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
require 'em-synchrony'
require 'em-synchrony/em-http'
require 'goliath/server'
require 'rack'
module Goliath
# Methods to help with testing Goliath APIs
#
# @example
# describe Echo do
# include Goliath::TestHelper
#
# let(:err) { Proc.new { fail "API request failed" } }
# it 'returns the echo param' do
# with_api(Echo) do
# get_request({:query => {:echo => 'test'}}, err) do |c|
# b = Yajl::Parser.parse(c.response)
# b['response'].should == 'test'
# end
# end
# end
# end
#
module TestHelper
def self.included(mod)
Goliath.env = 'test'
end
# Builds the rack middleware chain for the given API
#
# @param klass [Class] The API class to build the middlewares for
# @return [Object] The Rack middleware chain
def build_app(klass)
::Rack::Builder.new do
klass.middlewares.each do |mw|
use(*(mw[0..1].compact), &mw[2])
end
run klass.new
end
end
# Launches an instance of a given API server. The server
# will launch on the default settings of localhost port 9000.
#
# @param api [Class] The API class to launch
# @param port [Integer] The port to run the server on
# @return [Nil]
def server(api, port = 9000)
s = Goliath::Server.new
s.logger = mock('log').as_null_object
s.api = api.new
s.app = build_app(api)
s.port = port
s.start
s
end
# Stops the launched API
#
# @return [Nil]
def stop
EM.stop
end
# Wrapper for launching API and executing given code block. This
# will start the EventMachine reactor running.
#
# @param api [Class] The API class to launch
# @param blk [Proc] The code to execute after the server is launched.
# @note This will not return until stop is called.
def with_api(api, &blk)
EM.synchrony do
@api_server = server(api)
blk.call
end
end
# Helper method to setup common callbacks for various request methods.
# The given err and callback handlers will be attached and a callback
# to stop the reactor will be added.
#
# @param req [EM::HttpRequest] The HTTP request to augment
# @param errback [Proc] An error handler to attach
# @param blk [Proc] The callback handler to attach
# @return [Nil]
# @api private
def hookup_request_callbacks(req, errback, &blk)
req.callback &blk
req.callback { stop }
req.errback &errback if errback
req.errback { stop }
end
# Make a GET request the currently launched API.
#
# @param request_data [Hash] Any data to pass to the GET request.
# @param errback [Proc] An error handler to attach
# @param blk [Proc] The callback block to execute
def get_request(request_data = {}, errback = nil, &blk)
path = request_data.delete(:path) || ''
req = EM::HttpRequest.new("http://localhost:9000#{path}").get(request_data)
hookup_request_callbacks(req, errback, &blk)
end
# Make a POST request the currently launched API.
#
# @param request_data [Hash] Any data to pass to the POST request.
# @param errback [Proc] An error handler to attach
# @param blk [Proc] The callback block to execute
def post_request(request_data = {}, errback = nil, &blk)
path = request_data.delete(:path) || ''
req = EM::HttpRequest.new("http://localhost:9000#{path}").post(request_data)
hookup_request_callbacks(req, errback, &blk)
end
end
end