-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
144 lines (132 loc) · 4.56 KB
/
index.js
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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
/**
* @fileOverview This file contains the main class of the package,
* which mocks the default fetch.
*
* @module PseudoFetch
*/
import parse from 'url-parse';
import Server from './core/server';
/**
* A simple object holding all our registered servers.
*
* @type {Object}
*/
let serverStore = {};
/**
* Variable containing the original fetch-method we "mock away".
* We keep this stored, to make sure we can restore it at some point.
*
* @type {Function}
*/
let originalFetch = undefined;
/**
* Creates a hash we can use to store a server from the
* urlConfig parameters of the server.
*
* @param {Object} urlConfig The urlconfig of a host.
* @return {string} The hash of the urlConfig
*/
export function createUrlConfigHash(urlConfig) {
const defaultResponse = 'host:|port:|protocol:';
if (!urlConfig) {
return defaultResponse;
}
return `host:${urlConfig.host||''}|`
+`port:${urlConfig.port||''}|`
+`protocol:${urlConfig.protocol||''}`;
}
/**
* The mock-fetch function we use. The method simply invokes
* the correct server with the url and config parameters.
*
* @param {string} url The url to fetch.
* @param {Object} config The config of the request.
* @return {Promise} A Promise which should resolve with the response of a server.
* If no server exists, a Connection Refused Error will be thrown.
*/
export function fetch(url, config) {
const parsedUrl = parse(url);
const urlHash = createUrlConfigHash(parsedUrl);
const registeredServer = serverStore[urlHash];
if (!registeredServer) {
throw new Error(`Connection refused, no server listening on ${JSON.stringify(urlHash)}`);
}
return registeredServer._call(parsedUrl.pathname, config);
}
/**
* When invoked, this method will mock the global fetch-method.
*/
export function mock() {
if (typeof window !== 'undefined') {
originalFetch = window.fetch;
window.fetch = fetch;
} else if (typeof global !== 'undefined') {
originalFetch = global.fetch;
global.fetch = fetch;
} else {
throw Error('Unable to find fetch, what environment are you running in?');
}
}
/**
* Restore the original global.fetch method.
*/
export function restore() {
if (typeof window !== 'undefined') {
window.fetch = originalFetch;
} else if(typeof global !== 'undefined') {
global.fetch = originalFetch;
}
}
/**
* Overloads a set of config-arguments.
*
* @param {null|undefined|string|Object} arg0 The first argument, either a full config,
* or a hostname, or undefined or null.
* @param {null|undefined|string} arg1 The second argument. Either undefined or null or a port as a string.
* @param {null|undefined|string} arg2 The third argument. Either undefined, null or a string representing
* the protocol.
* @return {Object} A resulting urlConfig object.
*/
export function overloadUrlconfig(arg0, arg1, arg2) {
const defaultResponse = {host: '', port: '', protocol: ''};
if (arg0 === undefined || arg0 === null) {
return defaultResponse;
}
// Assume arg0 is the host, and arg1 is the port
if (typeof arg0 === 'string') {
return {
host: arg0,
port: arg1 || '',
protocol: arg2 || '',
};
// Assume all info is in the object
} else if (arg0.constructor === Object) {
return arg0;
} else {
return defaultResponse;
}
}
/**
* The default export for this module. And the main entry-point
* for creating new pseudo-servers.
*
* @param {undefined|null|string|Object} arg0 The first argument, either a full config, or a hostname.
* @param {undefined|null|string} arg1 The second argument, possibly a port.
* @param {undefined|null|string} arg2 The third argument. Either undefined, null or a string representing
* the protocol.
* @return {Server} A Server instance.
*/
export default function(arg0, arg1, arg2) {
const urlConfig = overloadUrlconfig(arg0, arg1, arg2);
const pseudoServer = new Server(urlConfig);
serverStore[createUrlConfigHash(urlConfig)] = pseudoServer;
// We automatically mock if we haven't mocked before.
// This makes our API easier, as we can just create a new Server instance,
// and everything is taken care for us.
// Note that originalFetch will never be undefined after the first mock, so for every
// restore() after this call, one has to call mock() explicitly.
if (originalFetch === undefined) {
mock();
}
return pseudoServer;
}