-
Notifications
You must be signed in to change notification settings - Fork 170
/
Copy pathtest.lua
126 lines (100 loc) · 3.2 KB
/
test.lua
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
119
120
121
122
123
124
125
126
local pairs = pairs
local type = type
local assert = assert
local setmetatable = setmetatable
local getmetatable = getmetatable
local insert = table.insert
local remove = table.remove
local error = error
local format = string.format
local response = require 'resty.http_ng.response'
local url_helper = require('resty.url_helper')
local _M = {}
local function parse_url(url)
local url_obj = url_helper.parse_url(url)
if not url_obj then return end
if url_obj.query then url_obj.query = ngx.decode_args(url_obj.query) end
return url_obj
end
local function contains(expected, actual)
if actual == expected then return true end
local t1,t2 = type(actual), type(expected)
if t1 ~= t2 then
local mt = getmetatable(actual) or {}
if t2 == 'string' and mt.__tostring then
return mt.__tostring(actual) == expected
else
return false, format("can't compare %q with %q", t1, t2)
end
end
if t1 == 'table' then
for k,v in pairs(expected) do
-- compare urls with query params no matter param order
local expected_val = k == 'url' and parse_url(v) or v
local actual_val = k == 'url' and parse_url(actual[k]) or actual[k]
local ok, err = contains(expected_val, actual_val)
if not ok then
return false, format('[%q] %s', k, err)
end
end
return true
end
return false, format('%q does not match %q', actual, expected)
end
_M.expectation = {}
_M.expectation.new = function(request)
assert(request, 'needs expected request')
local expectation = { request = request }
-- chain function to add a response to expectation
local mt = {
respond_with = function(res)
expectation.response = res
end
}
return setmetatable(expectation, {__index = mt})
end
_M.expectation.match = function(expectation, request)
return contains(expectation.request, request)
end
local missing_expectation_mt = {
__tostring = function(t)
local str = [[
Missing expecation to match request. Try following:
test_backend.expect{ url = %q }.
respond_with{ status = 200, body = "" }
]]
return format(str, t.request.url)
end
}
local function missing_expecation(request)
local exception = { request = request }
return setmetatable(exception, missing_expectation_mt)
end
_M.missing_expectation = missing_expecation
_M.new = function()
local requests = {}
local expectations = {}
local backend = {}
backend.expect = function(request)
local expectation = _M.expectation.new(request)
insert(expectations, expectation)
return expectation
end
backend.send = function(_, request)
local expectation = remove(expectations, 1)
if not expectation then error(missing_expecation(request)) end
local match, err = _M.expectation.match(expectation, request)
if not match then error('expectation does not match: ' .. err) end
insert(requests, request)
local res = expectation.response
return response.new(request, res.status, res.headers, res.body or '')
end
backend.verify_no_outstanding_expectations = function()
assert(#expectations == 0, 'has ' .. #expectations .. ' outstanding expectations')
end
backend.get_requests = function()
return requests
end
return backend
end
return _M