3 # test = Faraday::Connection.new do
4 # use Faraday::Adapter::Test do |stub|
5 # stub.get '/nigiri/sake.json' do
6 # [200, {}, 'hi world']
11 # resp = test.get '/nigiri/sake.json'
12 # resp.body # => 'hi world'
14 class Test < Faraday::Adapter
18 class NotFound < StandardError
22 # {:get => [Stub, Stub]}
23 @stack, @consumed = {}, {}
24 yield(self) if block_given?
31 def match(request_method, path, headers, body)
32 return false if !@stack.key?(request_method)
33 stack = @stack[request_method]
34 consumed = (@consumed[request_method] ||= [])
36 if stub = matches?(stack, path, headers, body)
37 consumed << stack.delete(stub)
40 matches?(consumed, path, headers, body)
44 def get(path, headers = {}, &block)
45 new_stub(:get, path, headers, &block)
48 def head(path, headers = {}, &block)
49 new_stub(:head, path, headers, &block)
52 def post(path, body=nil, headers = {}, &block)
53 new_stub(:post, path, headers, body, &block)
56 def put(path, body=nil, headers = {}, &block)
57 new_stub(:put, path, headers, body, &block)
60 def patch(path, body=nil, headers = {}, &block)
61 new_stub(:patch, path, headers, body, &block)
64 def delete(path, headers = {}, &block)
65 new_stub(:delete, path, headers, &block)
68 def options(path, headers = {}, &block)
69 new_stub(:options, path, headers, &block)
72 # Raises an error if any of the stubbed calls have not been made.
73 def verify_stubbed_calls
75 @stack.each do |method, stubs|
76 unless stubs.size == 0
77 failed_stubs.concat(stubs.map {|stub|
78 "Expected #{method} #{stub}."
82 raise failed_stubs.join(" ") unless failed_stubs.size == 0
87 def new_stub(request_method, path, headers = {}, body=nil, &block)
88 normalized_path = Faraday::Utils.normalize_path(path)
89 (@stack[request_method] ||= []) << Stub.new(normalized_path, headers, body, block)
92 def matches?(stack, path, headers, body)
93 stack.detect { |stub| stub.matches?(path, headers, body) }
97 class Stub < Struct.new(:path, :params, :headers, :body, :block)
98 def initialize(full, headers, body, block)
99 path, query = full.split('?')
101 Faraday::Utils.parse_nested_query(query) :
103 super(path, params, headers, body, block)
106 def matches?(request_uri, request_headers, request_body)
107 request_path, request_query = request_uri.split('?')
108 request_params = request_query ?
109 Faraday::Utils.parse_nested_query(request_query) :
111 request_path == path &&
112 params_match?(request_params) &&
113 (body.to_s.size.zero? || request_body == body) &&
114 headers_match?(request_headers)
117 def params_match?(request_params)
118 params.keys.all? do |key|
119 request_params[key] == params[key]
123 def headers_match?(request_headers)
124 headers.keys.all? do |key|
125 request_headers[key] == headers[key]
134 def initialize(app, stubs=nil, &block)
136 @stubs = stubs || Stubs.new
137 configure(&block) if block
146 normalized_path = Faraday::Utils.normalize_path(env[:url])
147 params_encoder = env.request.params_encoder || Faraday::Utils.default_params_encoder
149 if stub = stubs.match(env[:method], normalized_path, env.request_headers, env[:body])
150 env[:params] = (query = env[:url].query) ?
151 params_encoder.decode(query) :
153 status, headers, body = stub.block.call(env)
154 save_response(env, status, body, headers)
156 raise Stubs::NotFound, "no stubbed request for #{env[:method]} #{normalized_path} #{env[:body]}"