@luvio/adapter-test-library 0.142.2 → 0.142.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/package.json +13 -6
  2. package/babel.config.js +0 -1
  3. package/dist/umd/es2018/test-library.js +0 -600
  4. package/dist/umd/es2018/types/MockDurableStore.d.ts +0 -16
  5. package/dist/umd/es2018/types/adapterRoundtrip.d.ts +0 -35
  6. package/dist/umd/es2018/types/customMatchers.d.ts +0 -10
  7. package/dist/umd/es2018/types/durableStorePersistence.d.ts +0 -13
  8. package/dist/umd/es2018/types/jest.setup.d.ts +0 -1
  9. package/dist/umd/es2018/types/main.d.ts +0 -9
  10. package/dist/umd/es2018/types/mocks.d.ts +0 -17
  11. package/dist/umd/es2018/types/network.d.ts +0 -38
  12. package/dist/umd/es2018/types/utils.d.ts +0 -39
  13. package/dist/umd/es2018/types/verification.d.ts +0 -2
  14. package/dist/umd/es5/test-library.js +0 -818
  15. package/dist/umd/es5/types/MockDurableStore.d.ts +0 -16
  16. package/dist/umd/es5/types/adapterRoundtrip.d.ts +0 -35
  17. package/dist/umd/es5/types/customMatchers.d.ts +0 -10
  18. package/dist/umd/es5/types/durableStorePersistence.d.ts +0 -13
  19. package/dist/umd/es5/types/jest.setup.d.ts +0 -1
  20. package/dist/umd/es5/types/main.d.ts +0 -9
  21. package/dist/umd/es5/types/mocks.d.ts +0 -17
  22. package/dist/umd/es5/types/network.d.ts +0 -38
  23. package/dist/umd/es5/types/utils.d.ts +0 -39
  24. package/dist/umd/es5/types/verification.d.ts +0 -2
  25. package/jest.config.js +0 -16
  26. package/matcher-types.d.ts +0 -10
  27. package/project.json +0 -8
  28. package/rollup.config.js +0 -33
  29. package/src/MockDurableStore.ts +0 -145
  30. package/src/__tests__/MockDurableStore.spec.ts +0 -53
  31. package/src/adapterRoundtrip.ts +0 -101
  32. package/src/customMatchers.ts +0 -17
  33. package/src/durableStorePersistence.ts +0 -34
  34. package/src/jest.setup.ts +0 -4
  35. package/src/main.ts +0 -26
  36. package/src/mocks.ts +0 -31
  37. package/src/network.ts +0 -240
  38. package/src/utils.ts +0 -207
  39. package/src/verification.ts +0 -60
  40. package/tsconfig.json +0 -4
  41. /package/dist/{es/es2018/test-library.js → test-library.js} +0 -0
  42. /package/dist/{es/es2018/types → types}/MockDurableStore.d.ts +0 -0
  43. /package/dist/{es/es2018/types → types}/adapterRoundtrip.d.ts +0 -0
  44. /package/dist/{es/es2018/types → types}/customMatchers.d.ts +0 -0
  45. /package/dist/{es/es2018/types → types}/durableStorePersistence.d.ts +0 -0
  46. /package/dist/{es/es2018/types → types}/jest.setup.d.ts +0 -0
  47. /package/dist/{es/es2018/types → types}/main.d.ts +0 -0
  48. /package/dist/{es/es2018/types → types}/mocks.d.ts +0 -0
  49. /package/dist/{es/es2018/types → types}/network.d.ts +0 -0
  50. /package/dist/{es/es2018/types → types}/utils.d.ts +0 -0
  51. /package/dist/{es/es2018/types → types}/verification.d.ts +0 -0
@@ -1,818 +0,0 @@
1
- (function (global, factory) {
2
- typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('sinon'), require('@luvio/engine')) :
3
- typeof define === 'function' && define.amd ? define(['exports', 'sinon', '@luvio/engine'], factory) :
4
- (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.luvioAdapterTestLibrary = {}, global.sinon, global.engine));
5
- })(this, (function (exports, sinon, engine) { 'use strict';
6
-
7
- /******************************************************************************
8
- Copyright (c) Microsoft Corporation.
9
-
10
- Permission to use, copy, modify, and/or distribute this software for any
11
- purpose with or without fee is hereby granted.
12
-
13
- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
14
- REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
15
- AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
16
- INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
17
- LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
18
- OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19
- PERFORMANCE OF THIS SOFTWARE.
20
- ***************************************************************************** */
21
-
22
- var __assign = function() {
23
- __assign = Object.assign || function __assign(t) {
24
- for (var s, i = 1, n = arguments.length; i < n; i++) {
25
- s = arguments[i];
26
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
27
- }
28
- return t;
29
- };
30
- return __assign.apply(this, arguments);
31
- };
32
-
33
- function __awaiter(thisArg, _arguments, P, generator) {
34
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
35
- return new (P || (P = Promise))(function (resolve, reject) {
36
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
37
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
38
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
39
- step((generator = generator.apply(thisArg, _arguments || [])).next());
40
- });
41
- }
42
-
43
- function __generator(thisArg, body) {
44
- var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
45
- return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
46
- function verb(n) { return function (v) { return step([n, v]); }; }
47
- function step(op) {
48
- if (f) throw new TypeError("Generator is already executing.");
49
- while (g && (g = 0, op[0] && (_ = 0)), _) try {
50
- if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
51
- if (y = 0, t) op = [op[0] & 2, t.value];
52
- switch (op[0]) {
53
- case 0: case 1: t = op; break;
54
- case 4: _.label++; return { value: op[1], done: false };
55
- case 5: _.label++; y = op[1]; op = [0]; continue;
56
- case 7: op = _.ops.pop(); _.trys.pop(); continue;
57
- default:
58
- if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
59
- if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
60
- if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
61
- if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
62
- if (t[2]) _.ops.pop();
63
- _.trys.pop(); continue;
64
- }
65
- op = body.call(thisArg, _);
66
- } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
67
- if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
68
- }
69
- }
70
-
71
- function isImmutable(value) {
72
- return !doesThrow(function () {
73
- // if verifyImmutable does not throw then the object is immutable
74
- verifyImmutable(value, '$');
75
- });
76
- }
77
- function verifyImmutable(value, path) {
78
- if (typeof value !== 'object' || value === null) {
79
- return;
80
- }
81
- if (Array.isArray(value)) {
82
- if (doesThrow(function () {
83
- var len = value.length;
84
- value.push('__test');
85
- if (len === value.length) {
86
- throw new Error('IE11 does not throw when mutating a frozen object');
87
- }
88
- }) === false) {
89
- throw new Error("Unexpected mutable property found at ".concat(path, ": Array is extensible!"));
90
- }
91
- value.forEach(function (item, index) {
92
- verifyImmutable(item, "".concat(path, ".").concat(index));
93
- });
94
- return;
95
- }
96
- if (doesThrow(function () {
97
- value['__test_____'] = true;
98
- if (value['__test_____'] !== true) {
99
- throw new Error('IE11 does not throw when mutating a frozen object');
100
- }
101
- }) === false) {
102
- throw new Error("Unexpected mutable property found at ".concat(path, ": Object is extensible!"));
103
- }
104
- Object.keys(value).forEach(function (key) {
105
- if (doesThrow(function () {
106
- var old = value[key];
107
- value[key] = '_______foo';
108
- if (value[key] === old) {
109
- throw new Error('IE11 does not throw when mutating a frozen object');
110
- }
111
- }) === false) {
112
- throw new Error("Unexpected mutable property found at ".concat(path, ": \"").concat(path, ".").concat(key, "\" is mutable!"));
113
- }
114
- verifyImmutable(value[key], "".concat(path, ".").concat(key));
115
- });
116
- }
117
-
118
- /**
119
- * Clone an object
120
- *
121
- * @param {object} data The object to clone
122
- * @returns {object} The cloned object
123
- */
124
- function clone(data) {
125
- if (data === undefined) {
126
- return undefined;
127
- }
128
- return JSON.parse(JSON.stringify(data));
129
- }
130
- /**
131
- * Strips the given properties from an object. Useful for comparing data payloads
132
- * where the given props may not be present in the data returned from an adapter.
133
- *
134
- * Does not mutate the passed in object.
135
- *
136
- * @param {object} obj The object from which to strip properties
137
- * @param {string[]} props The properties to be removed
138
- * @returns {object} The updated object with the given props stripped out
139
- */
140
- function stripProperties(obj, props) {
141
- // don't mutate the original object
142
- var cloned = clone(obj);
143
- stripPropertiesMutating(cloned, props);
144
- return cloned;
145
- }
146
- // private version of strip properties that mutates
147
- function stripPropertiesMutating(obj, props) {
148
- props.forEach(function (prop) {
149
- delete obj[prop];
150
- });
151
- Object.keys(obj).forEach(function (key) {
152
- var value = obj[key];
153
- if (typeof value === 'object' && value !== null) {
154
- stripPropertiesMutating(value, props);
155
- }
156
- });
157
- }
158
- function doesThrow(predicate) {
159
- try {
160
- predicate();
161
- }
162
- catch (e) {
163
- return true;
164
- }
165
- return false;
166
- }
167
- function flushPromises() {
168
- return new Promise(function (resolve) { return setTimeout(resolve, 0); });
169
- }
170
- // Copied from engine to avoid build time dependency
171
- // BEGIN OF COPY BLOCK
172
- var SnapshotState;
173
- (function (SnapshotState) {
174
- SnapshotState["Fulfilled"] = "Fulfilled";
175
- SnapshotState["Unfulfilled"] = "Unfulfilled";
176
- SnapshotState["Error"] = "Error";
177
- SnapshotState["Pending"] = "Pending";
178
- SnapshotState["Stale"] = "Stale";
179
- })(SnapshotState || (SnapshotState = {}));
180
- function isErrorSnapshot(snapshot) {
181
- return snapshot.state === SnapshotState.Error;
182
- }
183
- function isFulfilledSnapshot(snapshot) {
184
- return snapshot.state === SnapshotState.Fulfilled;
185
- }
186
- function isStaleSnapshot(snapshot) {
187
- return snapshot.state === SnapshotState.Stale;
188
- }
189
- // END OF COPY BLOCK
190
- var customMatchers = {
191
- toEqualFulfilledSnapshotWithData: function (snapshot, expected, privateProperties) {
192
- if (isFulfilledSnapshot(snapshot)) {
193
- var expectedWithoutPrivateProperties = stripProperties(expected, privateProperties || []);
194
- expect(snapshot.data).toEqual(expectedWithoutPrivateProperties);
195
- expect(isImmutable(snapshot.data)).toBe(true);
196
- return { pass: true, message: function () { return 'Snapshot is a FulfilledSnapshot'; } };
197
- }
198
- return {
199
- pass: false,
200
- message: function () { return 'Actual Snapshot is not a FulfilledSnapshot.'; },
201
- };
202
- },
203
- toEqualStaleSnapshotWithData: function (snapshot, expected, privateProperties) {
204
- if (isStaleSnapshot(snapshot)) {
205
- var expectedWithoutPrivateProperties = stripProperties(expected, privateProperties || []);
206
- expect(snapshot.data).toEqual(expectedWithoutPrivateProperties);
207
- expect(isImmutable(snapshot.data)).toBe(true);
208
- return { pass: true, message: function () { return 'Snapshot is a StaleSnapshot'; } };
209
- }
210
- return {
211
- pass: false,
212
- message: function () { return 'Actual Snapshot is not a StaleSnapshot.'; },
213
- };
214
- },
215
- toEqualErrorSnapshot: function (actual, expectedStatus) {
216
- if (isErrorSnapshot(actual)) {
217
- expect(isImmutable(actual.error)).toBe(true);
218
- expect(actual.data).toBeUndefined();
219
- if (expectedStatus !== undefined) {
220
- expect(actual.error.status).toBe(expectedStatus);
221
- }
222
- return { pass: true, message: function () { return 'Snapshot is an ErrorSnapshot'; } };
223
- }
224
- return {
225
- pass: false,
226
- message: function () { return 'Actual Snapshot is not a ErrorSnapshot.'; },
227
- };
228
- },
229
- toEqualOfflineErrorSnapshot: function (actual) {
230
- if (isErrorSnapshot(actual)) {
231
- expect(isImmutable(actual.error)).toBe(true);
232
- expect(actual.data).toBeUndefined();
233
- expect(actual.error).toBeInstanceOf(Error);
234
- expect(actual.error.errorType).toBe('networkAdapterError');
235
- return {
236
- pass: true,
237
- message: function () { return 'Snapshot is an ErrorSnapshot'; },
238
- };
239
- }
240
- return {
241
- pass: false,
242
- message: function () { return 'Actual Snapshot is not a ErrorSnapshot.'; },
243
- };
244
- },
245
- toHaveBeenHitTimes: function (mockNetworkAdapter, expected) {
246
- var callCount = getMockNetworkAdapterCallCount(mockNetworkAdapter);
247
- if (callCount !== expected) {
248
- return {
249
- pass: false,
250
- message: function () {
251
- return "Number of network calls made are different. Actual ".concat(callCount, ", Expected ").concat(expected, ".");
252
- },
253
- };
254
- }
255
- return { pass: true, message: function () { return "Network calls were made ".concat(expected, " times."); } };
256
- },
257
- toHaveBeenHitOnce: function (mockNetworkAdapter) {
258
- var callCount = getMockNetworkAdapterCallCount(mockNetworkAdapter);
259
- if (callCount !== 1) {
260
- return {
261
- pass: false,
262
- message: function () { return "Number of network calls was not 1. Actual ".concat(callCount, "."); },
263
- };
264
- }
265
- return { pass: true, message: function () { return 'Number of network calls was 1'; } };
266
- },
267
- toEqualFetchResponse: function (actual, expected) {
268
- expect(actual).toEqual(__assign(__assign({}, expected), { errorType: 'fetchResponse' }));
269
- expect(isImmutable(actual)).toBe(true);
270
- return { pass: true, message: function () { return 'Actual response equals expected response'; } };
271
- },
272
- };
273
-
274
- var networkConnectivityStateMap = new WeakMap();
275
- exports.ConnectivityState = void 0;
276
- (function (ConnectivityState) {
277
- ConnectivityState[ConnectivityState["Online"] = 0] = "Online";
278
- ConnectivityState[ConnectivityState["Offline"] = 1] = "Offline";
279
- })(exports.ConnectivityState || (exports.ConnectivityState = {}));
280
- var callCountMap = new WeakMap();
281
- var mockPayloadsMap = new WeakMap();
282
- function buildOfflineError() {
283
- return new Error('Failed to fetch, request timeout');
284
- }
285
- function buildMockSetupError() {
286
- return new Error('A mock network response was not setup for this request');
287
- }
288
- /**
289
- * This function sorts two payloads based on number of parameters. It sorts in
290
- * ascending order, meaning a MockPayload with fewer parameters in the networkArgs
291
- * will come before a MockPayload with more parameters in the networkArgs.
292
- *
293
- * Sorting really only matters when a two networkArg objects have all the same
294
- * fields except for uri/query/headers, so this sorting algorithm is simplistic.
295
- * If two networkArg objects have different baseUri or basePath properties, for
296
- * example, then the sinon matcher won't have a collision so sorting doesn't
297
- * matter in that situation.
298
- *
299
- * @param {MockPayload} a
300
- * @param {MockPayload} b
301
- * @returns {number}
302
- */
303
- function sortPayloads(a, b) {
304
- var _a = b.networkArgs, bUrlParams = _a.urlParams, bQueryParams = _a.queryParams, bHeaders = _a.headers;
305
- var _b = a.networkArgs, aUrlParams = _b.urlParams, aQueryParams = _b.queryParams, aHeaders = _b.headers;
306
- var aParams = Object.keys(aUrlParams !== null && aUrlParams !== void 0 ? aUrlParams : {}).length +
307
- Object.keys(aQueryParams !== null && aQueryParams !== void 0 ? aQueryParams : {}).length +
308
- Object.keys(aHeaders !== null && aHeaders !== void 0 ? aHeaders : {}).length;
309
- var bParams = Object.keys(bUrlParams !== null && bUrlParams !== void 0 ? bUrlParams : {}).length +
310
- Object.keys(bQueryParams !== null && bQueryParams !== void 0 ? bQueryParams : {}).length +
311
- Object.keys(bHeaders !== null && bHeaders !== void 0 ? bHeaders : {}).length;
312
- return aParams - bParams;
313
- }
314
- function isOkResponse(status) {
315
- return status >= 200 && status <= 299;
316
- }
317
- /**
318
- * Flushes any pending network requests. Useful for tests that need to ensure all
319
- * un-awaited background refreshes are complete
320
- *
321
- * @param _mockNetworkAdapter {NetworkAdapter} The network adapter instance to flush
322
- */
323
- function flushPendingNetworkRequests(_mockNetworkAdapter) {
324
- return __awaiter(this, void 0, void 0, function () {
325
- return __generator(this, function (_a) {
326
- switch (_a.label) {
327
- case 0:
328
- // since the network mock is actually synchronous (just returns things wrapped
329
- // in Promise.resolve/reject) the only thing necessary to flush any pending
330
- // network activity is to flush the pending microtask queue
331
- return [4 /*yield*/, flushPromises()];
332
- case 1:
333
- // since the network mock is actually synchronous (just returns things wrapped
334
- // in Promise.resolve/reject) the only thing necessary to flush any pending
335
- // network activity is to flush the pending microtask queue
336
- _a.sent();
337
- return [2 /*return*/];
338
- }
339
- });
340
- });
341
- }
342
- function buildMockNetworkAdapter(mockPayloads) {
343
- // any endpoints not setup with a fake will return a rejected promise
344
- var networkAdapter = sinon.stub().rejects(buildMockSetupError());
345
- callCountMap.set(networkAdapter, 0);
346
- mockPayloadsMap.set(networkAdapter, mockPayloads);
347
- setMockNetworkPayloads(networkAdapter, mockPayloads);
348
- return networkAdapter;
349
- }
350
- function setNetworkConnectivity(mockNetworkAdapter, connectivityState) {
351
- var stub = mockNetworkAdapter;
352
- networkConnectivityStateMap.set(stub, connectivityState);
353
- }
354
- function onNetworkStubCalled(stub, response) {
355
- var _a;
356
- var body = response.body, status = response.status, statusText = response.statusText, ok = response.ok, headers = response.headers;
357
- var currentCallCount = callCountMap.get(stub);
358
- callCountMap.set(stub, currentCallCount ? currentCallCount + 1 : 1);
359
- var connectivityState = (_a = networkConnectivityStateMap.get(stub)) !== null && _a !== void 0 ? _a : exports.ConnectivityState.Online;
360
- if (connectivityState === exports.ConnectivityState.Offline) {
361
- return Promise.reject(buildOfflineError());
362
- }
363
- return Promise.resolve({
364
- status: status,
365
- statusText: statusText,
366
- ok: ok,
367
- body: clone(body),
368
- headers: clone(headers),
369
- });
370
- }
371
- function setMockNetworkPayloads(mockNetworkAdapter, mockPayloads) {
372
- var stub = mockNetworkAdapter;
373
- // sort mock payloads so least-specific network args are registered first
374
- mockPayloads.sort(sortPayloads).forEach(function (mockPayload) {
375
- var networkArgs = mockPayload.networkArgs, response = mockPayload.response;
376
- var args = sinon.match(networkArgs);
377
- stub.withArgs(args).callsFake(function () {
378
- return onNetworkStubCalled(stub, response);
379
- });
380
- });
381
- }
382
- /**
383
- * Overrides the mock network adapter responses with the given "responses". Each request to
384
- * the network adapter will "pop" a response from the response array. If more requests
385
- * to the network adapter are made than responses in the given array then an error
386
- * will be returned.
387
- *
388
- * This differs from setMockNetworkPayloads because it does not look at the incoming
389
- * network request args to determine what the response should be, it just returns
390
- * the response based on the request order.
391
- *
392
- * NOTE: this overrides any previously setup MockPayloads for the given network adapter
393
- * until resetMockNetworkAdapter is called.
394
- */
395
- function overrideMockNetworkResponses(mockNetworkAdapter, responses) {
396
- var stub = mockNetworkAdapter;
397
- var index = 0;
398
- stub.withArgs(sinon.match.any).callsFake(function () {
399
- var response = responses[index++];
400
- if (response === undefined) {
401
- // if they have more requests than expected
402
- return Promise.reject(buildMockSetupError());
403
- }
404
- return onNetworkStubCalled(stub, response);
405
- });
406
- }
407
- function resetMockNetworkAdapter(mockNetworkAdapter, newPayloads) {
408
- var stub = mockNetworkAdapter;
409
- // reset stub in case a test modified payload responses
410
- stub.reset();
411
- // reset call count
412
- callCountMap.set(stub, 0);
413
- // set mock payloads up - Allow for the test to provide a different set of payloads
414
- // Default behavior is to reset to the original payloads.
415
- var payloads = newPayloads ? newPayloads : mockPayloadsMap.get(stub);
416
- if (payloads) {
417
- setMockNetworkPayloads(stub, payloads);
418
- }
419
- }
420
- function getMockNetworkAdapterCallCount(mockNetworkAdapter) {
421
- var stub = mockNetworkAdapter;
422
- return callCountMap.get(stub);
423
- }
424
- function buildFetchResponse(body, status, statusText, headers) {
425
- if (status === void 0) { status = 200; }
426
- if (statusText === void 0) { statusText = 'Ok'; }
427
- if (headers === void 0) { headers = {}; }
428
- return {
429
- headers: headers,
430
- body: body,
431
- status: status,
432
- statusText: statusText,
433
- ok: isOkResponse(status),
434
- };
435
- }
436
- function buildSuccessMockPayload(networkArgs, body, headers) {
437
- if (headers === void 0) { headers = {}; }
438
- var mockPayload = {
439
- networkArgs: networkArgs,
440
- response: buildFetchResponse(body, 200, 'Ok', headers),
441
- };
442
- return mockPayload;
443
- }
444
- function buildErrorMockPayload(networkArgs, body, errorStatusCode, errorStatusText, headers) {
445
- if (headers === void 0) { headers = {}; }
446
- var mockPayload = {
447
- networkArgs: networkArgs,
448
- response: buildFetchResponse(body, errorStatusCode, errorStatusText, headers),
449
- };
450
- return mockPayload;
451
- }
452
-
453
- var mockFulfilledSnapshot = { state: 'Fulfilled' };
454
- var mockFulfilledSnapshotPromise = {
455
- then: function () {
456
- return mockFulfilledSnapshot;
457
- },
458
- };
459
- var mockLuvio = {
460
- storeLookup: function () {
461
- return mockFulfilledSnapshot;
462
- },
463
- snapshotAvailable: function () {
464
- return true;
465
- },
466
- dispatchResourceRequest: function () {
467
- return mockFulfilledSnapshotPromise;
468
- },
469
- applyCachePolicy: function () {
470
- return mockFulfilledSnapshot;
471
- },
472
- };
473
- function getMockLuvioWithFulfilledSnapshot() {
474
- return mockLuvio;
475
- }
476
- function getMockFulfilledSnapshot() {
477
- return mockFulfilledSnapshot;
478
- }
479
-
480
- function setupCustomLuvioMatchers() {
481
- expect.extend(customMatchers);
482
- }
483
-
484
- var MemoryDurableStorePersistence = /** @class */ (function () {
485
- function MemoryDurableStorePersistence() {
486
- this.store = {};
487
- }
488
- MemoryDurableStorePersistence.prototype.get = function (key) {
489
- return __awaiter(this, void 0, void 0, function () {
490
- return __generator(this, function (_a) {
491
- return [2 /*return*/, this.store[key]];
492
- });
493
- });
494
- };
495
- MemoryDurableStorePersistence.prototype.set = function (key, value) {
496
- return __awaiter(this, void 0, void 0, function () {
497
- return __generator(this, function (_a) {
498
- switch (_a.label) {
499
- case 0:
500
- // simulate a more realistic durable store by making the write wait a
501
- // tick before actually setting the value
502
- return [4 /*yield*/, flushPromises()];
503
- case 1:
504
- // simulate a more realistic durable store by making the write wait a
505
- // tick before actually setting the value
506
- _a.sent();
507
- this.store[key] = value;
508
- return [2 /*return*/];
509
- }
510
- });
511
- });
512
- };
513
- MemoryDurableStorePersistence.prototype.delete = function (key) {
514
- return __awaiter(this, void 0, void 0, function () {
515
- return __generator(this, function (_a) {
516
- delete this.store[key];
517
- return [2 /*return*/];
518
- });
519
- });
520
- };
521
- MemoryDurableStorePersistence.prototype.flushPendingWork = function () {
522
- return __awaiter(this, void 0, void 0, function () {
523
- return __generator(this, function (_a) {
524
- switch (_a.label) {
525
- case 0:
526
- // since this implementation does actual "IO" synchronously the only
527
- // thing necessary to await any pending IO is to flush the current
528
- // microtask queue
529
- return [4 /*yield*/, flushPromises()];
530
- case 1:
531
- // since this implementation does actual "IO" synchronously the only
532
- // thing necessary to await any pending IO is to flush the current
533
- // microtask queue
534
- _a.sent();
535
- return [2 /*return*/];
536
- }
537
- });
538
- });
539
- };
540
- return MemoryDurableStorePersistence;
541
- }());
542
-
543
- function waitForPromiseSet(set) {
544
- // NOTE: we are building an array from the Set at this point in time. If
545
- // more Promises are added to the Set while this is awaiting it won't
546
- // await the newly-added Promise. That's what we want.
547
- return Promise.all(Array.from(set)).then();
548
- }
549
- var MockDurableStore = /** @class */ (function () {
550
- function MockDurableStore(persistence) {
551
- // for read/write synchronization
552
- this.writePromises = new Set();
553
- this.listeners = new Set();
554
- this.persistence = persistence || new MemoryDurableStorePersistence();
555
- }
556
- MockDurableStore.prototype.getEntries = function (entryIds, segment) {
557
- return __awaiter(this, void 0, void 0, function () {
558
- var entries, returnSource, _i, entryIds_1, entryId, entry;
559
- return __generator(this, function (_a) {
560
- switch (_a.label) {
561
- case 0:
562
- if (!(this.writePromises.size > 0)) return [3 /*break*/, 2];
563
- return [4 /*yield*/, waitForPromiseSet(this.writePromises)];
564
- case 1:
565
- _a.sent();
566
- _a.label = 2;
567
- case 2: return [4 /*yield*/, this.persistence.get(segment)];
568
- case 3:
569
- entries = _a.sent();
570
- if (entries === undefined) {
571
- return [2 /*return*/, undefined];
572
- }
573
- returnSource = Object.create(null);
574
- for (_i = 0, entryIds_1 = entryIds; _i < entryIds_1.length; _i++) {
575
- entryId = entryIds_1[_i];
576
- entry = entries[entryId];
577
- if (entry !== undefined) {
578
- returnSource[entryId] = clone(entry);
579
- }
580
- }
581
- return [2 /*return*/, returnSource];
582
- }
583
- });
584
- });
585
- };
586
- MockDurableStore.prototype.getAllEntries = function (segment) {
587
- return __awaiter(this, void 0, void 0, function () {
588
- var entries;
589
- return __generator(this, function (_a) {
590
- switch (_a.label) {
591
- case 0:
592
- if (!(this.writePromises.size > 0)) return [3 /*break*/, 2];
593
- return [4 /*yield*/, waitForPromiseSet(this.writePromises)];
594
- case 1:
595
- _a.sent();
596
- _a.label = 2;
597
- case 2: return [4 /*yield*/, this.persistence.get(segment)];
598
- case 3:
599
- entries = _a.sent();
600
- return [2 /*return*/, entries];
601
- }
602
- });
603
- });
604
- };
605
- MockDurableStore.prototype.setEntries = function (entries, segment) {
606
- return this.batchOperations([{ entries: entries, segment: segment, type: 'setEntries' }]);
607
- };
608
- MockDurableStore.prototype.evictEntries = function (ids, segment) {
609
- return this.batchOperations([{ ids: ids, segment: segment, type: 'evictEntries' }]);
610
- };
611
- MockDurableStore.prototype.registerOnChangedListener = function (listener) {
612
- var _this = this;
613
- this.listeners.add(listener);
614
- return function () {
615
- _this.listeners.delete(listener);
616
- return Promise.resolve();
617
- };
618
- };
619
- MockDurableStore.prototype.batchOperations = function (operations) {
620
- return __awaiter(this, void 0, void 0, function () {
621
- var changes, writePromise, promises;
622
- var _this = this;
623
- return __generator(this, function (_a) {
624
- switch (_a.label) {
625
- case 0:
626
- if (!(this.writePromises.size > 0)) return [3 /*break*/, 2];
627
- return [4 /*yield*/, waitForPromiseSet(this.writePromises)];
628
- case 1:
629
- _a.sent();
630
- _a.label = 2;
631
- case 2:
632
- changes = [];
633
- writePromise = (function () { return __awaiter(_this, void 0, void 0, function () {
634
- var _i, operations_1, operation, _a, _b;
635
- return __generator(this, function (_c) {
636
- switch (_c.label) {
637
- case 0:
638
- _i = 0, operations_1 = operations;
639
- _c.label = 1;
640
- case 1:
641
- if (!(_i < operations_1.length)) return [3 /*break*/, 4];
642
- operation = operations_1[_i];
643
- _b = (_a = changes).push;
644
- return [4 /*yield*/, this.performOperation(operation)];
645
- case 2:
646
- _b.apply(_a, [_c.sent()]);
647
- _c.label = 3;
648
- case 3:
649
- _i++;
650
- return [3 /*break*/, 1];
651
- case 4: return [2 /*return*/];
652
- }
653
- });
654
- }); })();
655
- this.writePromises.add(writePromise);
656
- _a.label = 3;
657
- case 3:
658
- _a.trys.push([3, , 5, 6]);
659
- return [4 /*yield*/, writePromise];
660
- case 4:
661
- _a.sent();
662
- return [3 /*break*/, 6];
663
- case 5:
664
- this.writePromises.delete(writePromise);
665
- return [7 /*endfinally*/];
666
- case 6:
667
- promises = [];
668
- this.listeners.forEach(function (listener) {
669
- promises.push(listener(changes));
670
- });
671
- return [2 /*return*/, Promise.all(promises).then(function () { return undefined; })];
672
- }
673
- });
674
- });
675
- };
676
- MockDurableStore.prototype.performOperation = function (operation) {
677
- return __awaiter(this, void 0, void 0, function () {
678
- var segment, rawEntries, entries, ids;
679
- return __generator(this, function (_a) {
680
- switch (_a.label) {
681
- case 0:
682
- segment = operation.segment;
683
- return [4 /*yield*/, this.persistence.get(segment)];
684
- case 1:
685
- rawEntries = _a.sent();
686
- entries = rawEntries === undefined ? {} : rawEntries;
687
- ids = [];
688
- switch (operation.type) {
689
- case 'setEntries':
690
- ids = Object.keys(operation.entries);
691
- ids.forEach(function (id) {
692
- entries[id] = clone(operation.entries[id]);
693
- });
694
- break;
695
- case 'evictEntries':
696
- ids = operation.ids;
697
- ids.forEach(function (id) {
698
- delete entries[id];
699
- });
700
- }
701
- return [4 /*yield*/, this.persistence.set(operation.segment, entries)];
702
- case 2:
703
- _a.sent();
704
- return [2 /*return*/, { ids: ids, segment: segment, type: operation.type }];
705
- }
706
- });
707
- });
708
- };
709
- MockDurableStore.prototype.flushPendingOperations = function () {
710
- return __awaiter(this, void 0, void 0, function () {
711
- return __generator(this, function (_a) {
712
- switch (_a.label) {
713
- case 0:
714
- // flush any pending read operations
715
- return [4 /*yield*/, this.persistence.flushPendingWork()];
716
- case 1:
717
- // flush any pending read operations
718
- _a.sent();
719
- _a.label = 2;
720
- case 2:
721
- if (!(this.writePromises.size > 0)) return [3 /*break*/, 4];
722
- return [4 /*yield*/, waitForPromiseSet(this.writePromises)];
723
- case 3:
724
- _a.sent();
725
- return [3 /*break*/, 2];
726
- case 4: return [2 /*return*/];
727
- }
728
- });
729
- });
730
- };
731
- return MockDurableStore;
732
- }());
733
-
734
- // Use this util if you want to configure multiple network mocks in your test code.
735
- // If you're only mocking one, we suggest you use buildLuvioWithNetwork instead.
736
- function buildLuvioInstance(mockNetworkAdapter) {
737
- var store = new engine.InMemoryStore();
738
- var env = new engine.Environment(store, mockNetworkAdapter);
739
- return new engine.Luvio(env);
740
- }
741
- function testAdapterCompletesRoundtrip(params) {
742
- return __awaiter(this, void 0, void 0, function () {
743
- var adapterSetup, result;
744
- return __generator(this, function (_a) {
745
- switch (_a.label) {
746
- case 0:
747
- adapterSetup = setupAdapter(params);
748
- return [4 /*yield*/, callAdapter(adapterSetup, params)];
749
- case 1:
750
- result = _a.sent();
751
- expect(result.data).toBeDefined();
752
- expect(result).toEqualFulfilledSnapshotWithData(params.type === 'network'
753
- ? params.expectedData || params.network.response
754
- : params.expectedData, params.privateProperties);
755
- return [2 /*return*/, result];
756
- }
757
- });
758
- });
759
- }
760
- function setupAdapter(params) {
761
- var luvio = params.type === 'network' ? buildLuvioWithNetwork(params.network).luvio : params.luvio;
762
- return params.adapterFactory(luvio);
763
- }
764
- // Returns a tuple of the Luvio instance and network adapter so the test author may expect a number expected calls to the network.
765
- function buildLuvioWithNetwork(networkConfig) {
766
- // TODO: handle alternative expected network calls, errors and etc
767
- var expectedNetwork = [
768
- buildSuccessMockPayload(networkConfig.request, networkConfig.response),
769
- ];
770
- var mockNetworkAdapter = buildMockNetworkAdapter(expectedNetwork);
771
- return { luvio: buildLuvioInstance(mockNetworkAdapter), networkAdapter: mockNetworkAdapter };
772
- }
773
- function callAdapter(adapter, params) {
774
- return __awaiter(this, void 0, void 0, function () {
775
- var snapshotOrPromise;
776
- return __generator(this, function (_a) {
777
- snapshotOrPromise = adapter(params.adapterConfig);
778
- if (snapshotOrPromise === null) {
779
- throw new Error('Result of calling the adapter was null. Is the adapter config valid?');
780
- }
781
- // Cache Miss - Check that the network call was right.
782
- if (params.type === 'injectedLuvioNetwork' || params.type === 'network') {
783
- expect(snapshotOrPromise).toBeInstanceOf(Promise);
784
- return [2 /*return*/, snapshotOrPromise];
785
- }
786
- else {
787
- // Cache hit
788
- expect(snapshotOrPromise).not.toBeInstanceOf(Promise); // Expect cache hit to be synchronous
789
- return [2 /*return*/, Promise.resolve(snapshotOrPromise)];
790
- }
791
- });
792
- });
793
- }
794
-
795
- exports.MemoryDurableStorePersistence = MemoryDurableStorePersistence;
796
- exports.MockDurableStore = MockDurableStore;
797
- exports.buildErrorMockPayload = buildErrorMockPayload;
798
- exports.buildFetchResponse = buildFetchResponse;
799
- exports.buildLuvioInstance = buildLuvioInstance;
800
- exports.buildLuvioWithNetwork = buildLuvioWithNetwork;
801
- exports.buildMockNetworkAdapter = buildMockNetworkAdapter;
802
- exports.buildSuccessMockPayload = buildSuccessMockPayload;
803
- exports.customMatchers = customMatchers;
804
- exports.flushPendingNetworkRequests = flushPendingNetworkRequests;
805
- exports.getMockFulfilledSnapshot = getMockFulfilledSnapshot;
806
- exports.getMockLuvioWithFulfilledSnapshot = getMockLuvioWithFulfilledSnapshot;
807
- exports.getMockNetworkAdapterCallCount = getMockNetworkAdapterCallCount;
808
- exports.isImmutable = isImmutable;
809
- exports.overrideMockNetworkResponses = overrideMockNetworkResponses;
810
- exports.resetMockNetworkAdapter = resetMockNetworkAdapter;
811
- exports.setMockNetworkPayloads = setMockNetworkPayloads;
812
- exports.setNetworkConnectivity = setNetworkConnectivity;
813
- exports.setupCustomLuvioMatchers = setupCustomLuvioMatchers;
814
- exports.stripProperties = stripProperties;
815
- exports.testAdapterCompletesRoundtrip = testAdapterCompletesRoundtrip;
816
- exports.verifyImmutable = verifyImmutable;
817
-
818
- }));