This repository was archived by the owner on Feb 20, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathmatcher.ts
83 lines (68 loc) · 2.74 KB
/
matcher.ts
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
import _ from 'lodash';
import {
formatUrl,
ISerializedRequest,
ISerializedRequestResponse,
ISerializedResponse,
} from '../http-serializer';
export type RequestQuery = { [P in keyof ISerializedRequest]?: ISerializedRequest[P] | RegExp };
export type ResponseQuery = { [P in keyof ISerializedResponse]?: ISerializedResponse[P] | RegExp };
export interface ISerializedHttpPartialDeepMatch {
url?: string | RegExp;
request?: RequestQuery;
response?: ResponseQuery;
}
export interface ISerializedRequestResponseToMatch {
request: ISerializedRequest;
response?: ISerializedResponse;
}
export type MatchFn = (serialized: ISerializedRequestResponse) => boolean;
export type UnsafeMatchFn = (serialized: ISerializedRequestResponseToMatch) => boolean;
export type Matcher = ISerializedHttpPartialDeepMatch | MatchFn;
export type HttpFilter = string | RegExp | Matcher;
export const EMPTY_RESPONSE = { body: {}, headers: {}, statusCode: 0 };
/**
* Curried function to determine whether a query matches an intercepted request.
*
* Query objects must be a deep partial match against the intercepted request.
*
* RegEx values are tested for match.
*/
export function match(fnOrPartialMatch: ISerializedHttpPartialDeepMatch | MatchFn): UnsafeMatchFn {
const equalityOrRegExpDeep = (reqResValue: any, queryValue: any): boolean => {
if (queryValue instanceof RegExp) {
return queryValue.test(reqResValue);
} else if (_.isPlainObject(queryValue) || _.isArray(queryValue)) {
// Add a depth limit?
return _.isMatchWith(reqResValue, queryValue, equalityOrRegExpDeep);
} else {
return queryValue === reqResValue;
}
};
const matcher: MatchFn = _.isFunction(fnOrPartialMatch)
? fnOrPartialMatch
: (serialized: ISerializedRequestResponse): boolean => {
const query = fnOrPartialMatch as ISerializedHttpPartialDeepMatch;
let isMatch = true;
if (query.url) {
const matchUrlNoPort = equalityOrRegExpDeep(formatUrl(serialized.request), query.url);
const matchUrlPort = equalityOrRegExpDeep(formatUrl(serialized.request, true), query.url);
isMatch = isMatch && (matchUrlNoPort || matchUrlPort);
}
if (query.request) {
isMatch =
isMatch && _.isMatchWith(serialized.request, query.request, equalityOrRegExpDeep);
}
if (query.response) {
isMatch =
isMatch && _.isMatchWith(serialized.response, query.response, equalityOrRegExpDeep);
}
return isMatch;
};
return (serialized: ISerializedRequestResponseToMatch) =>
matcher({
request: serialized.request,
// Response will be empty if matching against requests
response: serialized.response || EMPTY_RESPONSE,
});
}