@luvio/adapter-test-library 0.137.4 → 0.138.0
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.
- package/dist/es/es2018/adapterRoundtrip.d.ts +35 -0
- package/dist/es/es2018/customMatchers.d.ts +10 -0
- package/dist/es/es2018/jest.setup.d.ts +1 -0
- package/dist/es/es2018/main.d.ts +4 -1
- package/dist/es/es2018/test-library.js +200 -49
- package/dist/es/es2018/utils.d.ts +15 -0
- package/dist/umd/es2018/adapterRoundtrip.d.ts +35 -0
- package/dist/umd/es2018/customMatchers.d.ts +10 -0
- package/dist/umd/es2018/jest.setup.d.ts +1 -0
- package/dist/umd/es2018/main.d.ts +4 -1
- package/dist/umd/es2018/test-library.js +207 -52
- package/dist/umd/es2018/utils.d.ts +15 -0
- package/dist/umd/es5/adapterRoundtrip.d.ts +35 -0
- package/dist/umd/es5/customMatchers.d.ts +10 -0
- package/dist/umd/es5/jest.setup.d.ts +1 -0
- package/dist/umd/es5/main.d.ts +4 -1
- package/dist/umd/es5/test-library.js +236 -52
- package/dist/umd/es5/utils.d.ts +15 -0
- package/matcher-types.d.ts +10 -0
- package/package.json +3 -3
- package/src/adapterRoundtrip.ts +100 -0
- package/src/customMatchers.ts +17 -0
- package/src/jest.setup.ts +4 -0
- package/src/main.ts +8 -1
- package/src/utils.ts +150 -0
- package/tsconfig.json +1 -1
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { AdapterFactory, NetworkAdapter } from '@luvio/engine';
|
|
2
|
+
import { Luvio } from '@luvio/engine';
|
|
3
|
+
import type { MockPayload } from './network';
|
|
4
|
+
export declare function buildLuvioInstance(mockNetworkAdapter: NetworkAdapter): Luvio;
|
|
5
|
+
declare type AdapterRoundtripTestParams<C, D> = AdapterNetworkRoundtripTestParams<C, D> | AdapterNetworkRoundtripWithLuvioTestParams<C, D> | AdapterCacheHitRoundtripTestParams<C, D>;
|
|
6
|
+
declare type AdapterTest<C, D> = {
|
|
7
|
+
adapterFactory: AdapterFactory<C, D>;
|
|
8
|
+
adapterConfig: C;
|
|
9
|
+
privateProperties?: string[];
|
|
10
|
+
};
|
|
11
|
+
declare type AdapterTestWithInjectedLuvio<C, D> = AdapterTest<C, D> & {
|
|
12
|
+
luvio: Luvio;
|
|
13
|
+
expectedData: D;
|
|
14
|
+
};
|
|
15
|
+
declare type NetworkConfig = {
|
|
16
|
+
request: MockPayload['networkArgs'];
|
|
17
|
+
response: any;
|
|
18
|
+
};
|
|
19
|
+
declare type AdapterNetworkRoundtripTestParams<C, D> = AdapterTest<C, D> & {
|
|
20
|
+
type: 'network';
|
|
21
|
+
network: NetworkConfig;
|
|
22
|
+
expectedData?: D;
|
|
23
|
+
};
|
|
24
|
+
declare type AdapterNetworkRoundtripWithLuvioTestParams<C, D> = AdapterTestWithInjectedLuvio<C, D> & {
|
|
25
|
+
type: 'injectedLuvioNetwork';
|
|
26
|
+
};
|
|
27
|
+
declare type AdapterCacheHitRoundtripTestParams<C, D> = AdapterTestWithInjectedLuvio<C, D> & {
|
|
28
|
+
type: 'cache';
|
|
29
|
+
};
|
|
30
|
+
export declare function testAdapterCompletesRoundtrip<C = any, D = any>(params: AdapterRoundtripTestParams<C, D>): Promise<void>;
|
|
31
|
+
export declare function buildLuvioWithNetwork(networkConfig: NetworkConfig): {
|
|
32
|
+
luvio: Luvio;
|
|
33
|
+
networkAdapter: NetworkAdapter;
|
|
34
|
+
};
|
|
35
|
+
export {};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { FetchResponse } from '@luvio/engine';
|
|
2
|
+
export interface LuvioCustomMatchers<R> {
|
|
3
|
+
toEqualFulfilledSnapshotWithData: (expected: any, privateProperties?: string[]) => R;
|
|
4
|
+
toEqualStaleSnapshotWithData: (expected: any, privateProperties?: string[]) => R;
|
|
5
|
+
toEqualErrorSnapshot: (expectedStatus?: number) => R;
|
|
6
|
+
toEqualOfflineErrorSnapshot: () => R;
|
|
7
|
+
toHaveBeenHitTimes: (expected: Number) => R;
|
|
8
|
+
toHaveBeenHitOnce: () => R;
|
|
9
|
+
toEqualFetchResponse: (expected: FetchResponse<unknown>) => R;
|
|
10
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function setupCustomLuvioMatchers(): void;
|
package/dist/es/es2018/main.d.ts
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
export { MockPayload, ConnectivityState, buildMockNetworkAdapter, resetMockNetworkAdapter, getMockNetworkAdapterCallCount, buildSuccessMockPayload, buildErrorMockPayload, setMockNetworkPayloads, setNetworkConnectivity, buildFetchResponse, overrideMockNetworkResponses, flushPendingNetworkRequests, } from './network';
|
|
2
2
|
export { verifyImmutable, isImmutable } from './verification';
|
|
3
3
|
export { getMockLuvioWithFulfilledSnapshot, getMockFulfilledSnapshot } from './mocks';
|
|
4
|
-
export { stripProperties } from './utils';
|
|
4
|
+
export { stripProperties, customMatchers } from './utils';
|
|
5
|
+
export { setupCustomLuvioMatchers } from './jest.setup';
|
|
5
6
|
export { MockDurableStore } from './MockDurableStore';
|
|
6
7
|
export { MemoryDurableStorePersistence, DurableStorePersistence } from './durableStorePersistence';
|
|
8
|
+
export { testAdapterCompletesRoundtrip, buildLuvioWithNetwork, buildLuvioInstance, } from './adapterRoundtrip';
|
|
9
|
+
export { LuvioCustomMatchers } from './customMatchers';
|
|
@@ -1,4 +1,52 @@
|
|
|
1
1
|
import sinon from 'sinon';
|
|
2
|
+
import { InMemoryStore, Environment, Luvio } from '@luvio/engine';
|
|
3
|
+
|
|
4
|
+
function isImmutable(value) {
|
|
5
|
+
return !doesThrow(() => {
|
|
6
|
+
// if verifyImmutable does not throw then the object is immutable
|
|
7
|
+
verifyImmutable(value, '$');
|
|
8
|
+
});
|
|
9
|
+
}
|
|
10
|
+
function verifyImmutable(value, path) {
|
|
11
|
+
if (typeof value !== 'object' || value === null) {
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
if (Array.isArray(value)) {
|
|
15
|
+
if (doesThrow(() => {
|
|
16
|
+
const len = value.length;
|
|
17
|
+
value.push('__test');
|
|
18
|
+
if (len === value.length) {
|
|
19
|
+
throw new Error('IE11 does not throw when mutating a frozen object');
|
|
20
|
+
}
|
|
21
|
+
}) === false) {
|
|
22
|
+
throw new Error(`Unexpected mutable property found at ${path}: Array is extensible!`);
|
|
23
|
+
}
|
|
24
|
+
value.forEach((item, index) => {
|
|
25
|
+
verifyImmutable(item, `${path}.${index}`);
|
|
26
|
+
});
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
if (doesThrow(() => {
|
|
30
|
+
value['__test_____'] = true;
|
|
31
|
+
if (value['__test_____'] !== true) {
|
|
32
|
+
throw new Error('IE11 does not throw when mutating a frozen object');
|
|
33
|
+
}
|
|
34
|
+
}) === false) {
|
|
35
|
+
throw new Error(`Unexpected mutable property found at ${path}: Object is extensible!`);
|
|
36
|
+
}
|
|
37
|
+
Object.keys(value).forEach((key) => {
|
|
38
|
+
if (doesThrow(() => {
|
|
39
|
+
const old = value[key];
|
|
40
|
+
value[key] = '_______foo';
|
|
41
|
+
if (value[key] === old) {
|
|
42
|
+
throw new Error('IE11 does not throw when mutating a frozen object');
|
|
43
|
+
}
|
|
44
|
+
}) === false) {
|
|
45
|
+
throw new Error(`Unexpected mutable property found at ${path}: "${path}.${key}" is mutable!`);
|
|
46
|
+
}
|
|
47
|
+
verifyImmutable(value[key], `${path}.${key}`);
|
|
48
|
+
});
|
|
49
|
+
}
|
|
2
50
|
|
|
3
51
|
/**
|
|
4
52
|
* Clone an object
|
|
@@ -51,7 +99,108 @@ function doesThrow(predicate) {
|
|
|
51
99
|
}
|
|
52
100
|
function flushPromises() {
|
|
53
101
|
return new Promise((resolve) => setTimeout(resolve, 0));
|
|
54
|
-
}
|
|
102
|
+
}
|
|
103
|
+
// Copied from engine to avoid build time dependency
|
|
104
|
+
// BEGIN OF COPY BLOCK
|
|
105
|
+
var SnapshotState;
|
|
106
|
+
(function (SnapshotState) {
|
|
107
|
+
SnapshotState["Fulfilled"] = "Fulfilled";
|
|
108
|
+
SnapshotState["Unfulfilled"] = "Unfulfilled";
|
|
109
|
+
SnapshotState["Error"] = "Error";
|
|
110
|
+
SnapshotState["Pending"] = "Pending";
|
|
111
|
+
SnapshotState["Stale"] = "Stale";
|
|
112
|
+
})(SnapshotState || (SnapshotState = {}));
|
|
113
|
+
function isErrorSnapshot(snapshot) {
|
|
114
|
+
return snapshot.state === SnapshotState.Error;
|
|
115
|
+
}
|
|
116
|
+
function isFulfilledSnapshot(snapshot) {
|
|
117
|
+
return snapshot.state === SnapshotState.Fulfilled;
|
|
118
|
+
}
|
|
119
|
+
function isStaleSnapshot(snapshot) {
|
|
120
|
+
return snapshot.state === SnapshotState.Stale;
|
|
121
|
+
}
|
|
122
|
+
// END OF COPY BLOCK
|
|
123
|
+
const customMatchers = {
|
|
124
|
+
toEqualFulfilledSnapshotWithData: (snapshot, expected, privateProperties) => {
|
|
125
|
+
if (isFulfilledSnapshot(snapshot)) {
|
|
126
|
+
const expectedWithoutPrivateProperties = stripProperties(expected, privateProperties || []);
|
|
127
|
+
expect(snapshot.data).toEqual(expectedWithoutPrivateProperties);
|
|
128
|
+
expect(isImmutable(snapshot.data)).toBe(true);
|
|
129
|
+
return { pass: true, message: () => 'Snapshot is a FulfilledSnapshot' };
|
|
130
|
+
}
|
|
131
|
+
return {
|
|
132
|
+
pass: false,
|
|
133
|
+
message: () => 'Actual Snapshot is not a FulfilledSnapshot.',
|
|
134
|
+
};
|
|
135
|
+
},
|
|
136
|
+
toEqualStaleSnapshotWithData: (snapshot, expected, privateProperties) => {
|
|
137
|
+
if (isStaleSnapshot(snapshot)) {
|
|
138
|
+
const expectedWithoutPrivateProperties = stripProperties(expected, privateProperties || []);
|
|
139
|
+
expect(snapshot.data).toEqual(expectedWithoutPrivateProperties);
|
|
140
|
+
expect(isImmutable(snapshot.data)).toBe(true);
|
|
141
|
+
return { pass: true, message: () => 'Snapshot is a StaleSnapshot' };
|
|
142
|
+
}
|
|
143
|
+
return {
|
|
144
|
+
pass: false,
|
|
145
|
+
message: () => 'Actual Snapshot is not a StaleSnapshot.',
|
|
146
|
+
};
|
|
147
|
+
},
|
|
148
|
+
toEqualErrorSnapshot: (actual, expectedStatus) => {
|
|
149
|
+
if (isErrorSnapshot(actual)) {
|
|
150
|
+
expect(isImmutable(actual.error)).toBe(true);
|
|
151
|
+
expect(actual.data).toBeUndefined();
|
|
152
|
+
if (expectedStatus !== undefined) {
|
|
153
|
+
expect(actual.error.status).toBe(expectedStatus);
|
|
154
|
+
}
|
|
155
|
+
return { pass: true, message: () => 'Snapshot is an ErrorSnapshot' };
|
|
156
|
+
}
|
|
157
|
+
return {
|
|
158
|
+
pass: false,
|
|
159
|
+
message: () => 'Actual Snapshot is not a ErrorSnapshot.',
|
|
160
|
+
};
|
|
161
|
+
},
|
|
162
|
+
toEqualOfflineErrorSnapshot: (actual) => {
|
|
163
|
+
if (isErrorSnapshot(actual)) {
|
|
164
|
+
expect(isImmutable(actual.error)).toBe(true);
|
|
165
|
+
expect(actual.data).toBeUndefined();
|
|
166
|
+
expect(actual.error).toBeInstanceOf(Error);
|
|
167
|
+
expect(actual.error.errorType).toBe('networkAdapterError');
|
|
168
|
+
return {
|
|
169
|
+
pass: true,
|
|
170
|
+
message: () => 'Snapshot is an ErrorSnapshot',
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
return {
|
|
174
|
+
pass: false,
|
|
175
|
+
message: () => 'Actual Snapshot is not a ErrorSnapshot.',
|
|
176
|
+
};
|
|
177
|
+
},
|
|
178
|
+
toHaveBeenHitTimes: (mockNetworkAdapter, expected) => {
|
|
179
|
+
const callCount = getMockNetworkAdapterCallCount(mockNetworkAdapter);
|
|
180
|
+
if (callCount !== expected) {
|
|
181
|
+
return {
|
|
182
|
+
pass: false,
|
|
183
|
+
message: () => `Number of network calls made are different. Actual ${callCount}, Expected ${expected}.`,
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
return { pass: true, message: () => `Network calls were made ${expected} times.` };
|
|
187
|
+
},
|
|
188
|
+
toHaveBeenHitOnce: (mockNetworkAdapter) => {
|
|
189
|
+
const callCount = getMockNetworkAdapterCallCount(mockNetworkAdapter);
|
|
190
|
+
if (callCount !== 1) {
|
|
191
|
+
return {
|
|
192
|
+
pass: false,
|
|
193
|
+
message: () => `Number of network calls was not 1. Actual ${callCount}.`,
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
return { pass: true, message: () => 'Number of network calls was 1' };
|
|
197
|
+
},
|
|
198
|
+
toEqualFetchResponse: (actual, expected) => {
|
|
199
|
+
expect(actual).toEqual({ ...expected, errorType: 'fetchResponse' });
|
|
200
|
+
expect(isImmutable(actual)).toBe(true);
|
|
201
|
+
return { pass: true, message: () => 'Actual response equals expected response' };
|
|
202
|
+
},
|
|
203
|
+
};
|
|
55
204
|
|
|
56
205
|
const networkConnectivityStateMap = new WeakMap();
|
|
57
206
|
var ConnectivityState;
|
|
@@ -213,53 +362,6 @@ function buildErrorMockPayload(networkArgs, body, errorStatusCode, errorStatusTe
|
|
|
213
362
|
return mockPayload;
|
|
214
363
|
}
|
|
215
364
|
|
|
216
|
-
function isImmutable(value) {
|
|
217
|
-
return !doesThrow(() => {
|
|
218
|
-
// if verifyImmutable does not throw then the object is immutable
|
|
219
|
-
verifyImmutable(value, '$');
|
|
220
|
-
});
|
|
221
|
-
}
|
|
222
|
-
function verifyImmutable(value, path) {
|
|
223
|
-
if (typeof value !== 'object' || value === null) {
|
|
224
|
-
return;
|
|
225
|
-
}
|
|
226
|
-
if (Array.isArray(value)) {
|
|
227
|
-
if (doesThrow(() => {
|
|
228
|
-
const len = value.length;
|
|
229
|
-
value.push('__test');
|
|
230
|
-
if (len === value.length) {
|
|
231
|
-
throw new Error('IE11 does not throw when mutating a frozen object');
|
|
232
|
-
}
|
|
233
|
-
}) === false) {
|
|
234
|
-
throw new Error(`Unexpected mutable property found at ${path}: Array is extensible!`);
|
|
235
|
-
}
|
|
236
|
-
value.forEach((item, index) => {
|
|
237
|
-
verifyImmutable(item, `${path}.${index}`);
|
|
238
|
-
});
|
|
239
|
-
return;
|
|
240
|
-
}
|
|
241
|
-
if (doesThrow(() => {
|
|
242
|
-
value['__test_____'] = true;
|
|
243
|
-
if (value['__test_____'] !== true) {
|
|
244
|
-
throw new Error('IE11 does not throw when mutating a frozen object');
|
|
245
|
-
}
|
|
246
|
-
}) === false) {
|
|
247
|
-
throw new Error(`Unexpected mutable property found at ${path}: Object is extensible!`);
|
|
248
|
-
}
|
|
249
|
-
Object.keys(value).forEach((key) => {
|
|
250
|
-
if (doesThrow(() => {
|
|
251
|
-
const old = value[key];
|
|
252
|
-
value[key] = '_______foo';
|
|
253
|
-
if (value[key] === old) {
|
|
254
|
-
throw new Error('IE11 does not throw when mutating a frozen object');
|
|
255
|
-
}
|
|
256
|
-
}) === false) {
|
|
257
|
-
throw new Error(`Unexpected mutable property found at ${path}: "${path}.${key}" is mutable!`);
|
|
258
|
-
}
|
|
259
|
-
verifyImmutable(value[key], `${path}.${key}`);
|
|
260
|
-
});
|
|
261
|
-
}
|
|
262
|
-
|
|
263
365
|
const mockFulfilledSnapshot = { state: 'Fulfilled' };
|
|
264
366
|
const mockFulfilledSnapshotPromise = {
|
|
265
367
|
then() {
|
|
@@ -287,6 +389,10 @@ function getMockFulfilledSnapshot() {
|
|
|
287
389
|
return mockFulfilledSnapshot;
|
|
288
390
|
}
|
|
289
391
|
|
|
392
|
+
function setupCustomLuvioMatchers() {
|
|
393
|
+
expect.extend(customMatchers);
|
|
394
|
+
}
|
|
395
|
+
|
|
290
396
|
class MemoryDurableStorePersistence {
|
|
291
397
|
constructor() {
|
|
292
398
|
this.store = {};
|
|
@@ -418,4 +524,49 @@ class MockDurableStore {
|
|
|
418
524
|
}
|
|
419
525
|
}
|
|
420
526
|
|
|
421
|
-
|
|
527
|
+
// Use this util if you want to configure multiple network mocks in your test code.
|
|
528
|
+
// If you're only mocking one, we suggest you use buildLuvioWithNetwork instead.
|
|
529
|
+
function buildLuvioInstance(mockNetworkAdapter) {
|
|
530
|
+
const store = new InMemoryStore();
|
|
531
|
+
const env = new Environment(store, mockNetworkAdapter);
|
|
532
|
+
return new Luvio(env);
|
|
533
|
+
}
|
|
534
|
+
async function testAdapterCompletesRoundtrip(params) {
|
|
535
|
+
const adapterSetup = setupAdapter(params);
|
|
536
|
+
const result = await callAdapter(adapterSetup, params);
|
|
537
|
+
expect(result.data).toBeDefined();
|
|
538
|
+
expect(result).toEqualFulfilledSnapshotWithData(params.type === 'network'
|
|
539
|
+
? params.expectedData || params.network.response
|
|
540
|
+
: params.expectedData, params.privateProperties);
|
|
541
|
+
}
|
|
542
|
+
function setupAdapter(params) {
|
|
543
|
+
const luvio = params.type === 'network' ? buildLuvioWithNetwork(params.network).luvio : params.luvio;
|
|
544
|
+
return params.adapterFactory(luvio);
|
|
545
|
+
}
|
|
546
|
+
// Returns a tuple of the Luvio instance and network adapter so the test author may expect a number expected calls to the network.
|
|
547
|
+
function buildLuvioWithNetwork(networkConfig) {
|
|
548
|
+
// TODO: handle alternative expected network calls, errors and etc
|
|
549
|
+
const expectedNetwork = [
|
|
550
|
+
buildSuccessMockPayload(networkConfig.request, networkConfig.response),
|
|
551
|
+
];
|
|
552
|
+
const mockNetworkAdapter = buildMockNetworkAdapter(expectedNetwork);
|
|
553
|
+
return { luvio: buildLuvioInstance(mockNetworkAdapter), networkAdapter: mockNetworkAdapter };
|
|
554
|
+
}
|
|
555
|
+
async function callAdapter(adapter, params) {
|
|
556
|
+
const snapshotOrPromise = adapter(params.adapterConfig);
|
|
557
|
+
if (snapshotOrPromise === null) {
|
|
558
|
+
throw new Error('Result of calling the adapter was null. Is the adapter config valid?');
|
|
559
|
+
}
|
|
560
|
+
// Cache Miss - Check that the network call was right.
|
|
561
|
+
if (params.type === 'injectedLuvioNetwork' || params.type === 'network') {
|
|
562
|
+
expect(snapshotOrPromise).toBeInstanceOf(Promise);
|
|
563
|
+
return snapshotOrPromise;
|
|
564
|
+
}
|
|
565
|
+
else {
|
|
566
|
+
// Cache hit
|
|
567
|
+
expect(snapshotOrPromise).not.toBeInstanceOf(Promise); // Expect cache hit to be synchronous
|
|
568
|
+
return Promise.resolve(snapshotOrPromise);
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
export { ConnectivityState, MemoryDurableStorePersistence, MockDurableStore, buildErrorMockPayload, buildFetchResponse, buildLuvioInstance, buildLuvioWithNetwork, buildMockNetworkAdapter, buildSuccessMockPayload, customMatchers, flushPendingNetworkRequests, getMockFulfilledSnapshot, getMockLuvioWithFulfilledSnapshot, getMockNetworkAdapterCallCount, isImmutable, overrideMockNetworkResponses, resetMockNetworkAdapter, setMockNetworkPayloads, setNetworkConnectivity, setupCustomLuvioMatchers, stripProperties, testAdapterCompletesRoundtrip, verifyImmutable };
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { FetchResponse, NetworkAdapter, Snapshot } from '@luvio/engine';
|
|
1
2
|
/**
|
|
2
3
|
* Clone an object
|
|
3
4
|
*
|
|
@@ -20,3 +21,17 @@ export declare function stripProperties(obj: {
|
|
|
20
21
|
}, props: string[]): any;
|
|
21
22
|
export declare function doesThrow(predicate: () => void): boolean;
|
|
22
23
|
export declare function flushPromises(): Promise<unknown>;
|
|
24
|
+
declare type MatcherResult = {
|
|
25
|
+
pass: boolean;
|
|
26
|
+
message: () => string;
|
|
27
|
+
};
|
|
28
|
+
export declare const customMatchers: {
|
|
29
|
+
toEqualFulfilledSnapshotWithData: (snapshot: Snapshot<unknown, unknown>, expected: any, privateProperties?: string[] | undefined) => MatcherResult;
|
|
30
|
+
toEqualStaleSnapshotWithData: (snapshot: Snapshot<unknown, unknown>, expected: any, privateProperties?: string[] | undefined) => MatcherResult;
|
|
31
|
+
toEqualErrorSnapshot: (actual: Snapshot<unknown, unknown>, expectedStatus?: number | undefined) => MatcherResult;
|
|
32
|
+
toEqualOfflineErrorSnapshot: (actual: Snapshot<unknown, unknown>) => MatcherResult;
|
|
33
|
+
toHaveBeenHitTimes: (mockNetworkAdapter: NetworkAdapter, expected: Number) => MatcherResult;
|
|
34
|
+
toHaveBeenHitOnce: (mockNetworkAdapter: NetworkAdapter) => MatcherResult;
|
|
35
|
+
toEqualFetchResponse: (actual: FetchResponse<unknown>, expected: FetchResponse<unknown>) => MatcherResult;
|
|
36
|
+
};
|
|
37
|
+
export {};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { AdapterFactory, NetworkAdapter } from '@luvio/engine';
|
|
2
|
+
import { Luvio } from '@luvio/engine';
|
|
3
|
+
import type { MockPayload } from './network';
|
|
4
|
+
export declare function buildLuvioInstance(mockNetworkAdapter: NetworkAdapter): Luvio;
|
|
5
|
+
declare type AdapterRoundtripTestParams<C, D> = AdapterNetworkRoundtripTestParams<C, D> | AdapterNetworkRoundtripWithLuvioTestParams<C, D> | AdapterCacheHitRoundtripTestParams<C, D>;
|
|
6
|
+
declare type AdapterTest<C, D> = {
|
|
7
|
+
adapterFactory: AdapterFactory<C, D>;
|
|
8
|
+
adapterConfig: C;
|
|
9
|
+
privateProperties?: string[];
|
|
10
|
+
};
|
|
11
|
+
declare type AdapterTestWithInjectedLuvio<C, D> = AdapterTest<C, D> & {
|
|
12
|
+
luvio: Luvio;
|
|
13
|
+
expectedData: D;
|
|
14
|
+
};
|
|
15
|
+
declare type NetworkConfig = {
|
|
16
|
+
request: MockPayload['networkArgs'];
|
|
17
|
+
response: any;
|
|
18
|
+
};
|
|
19
|
+
declare type AdapterNetworkRoundtripTestParams<C, D> = AdapterTest<C, D> & {
|
|
20
|
+
type: 'network';
|
|
21
|
+
network: NetworkConfig;
|
|
22
|
+
expectedData?: D;
|
|
23
|
+
};
|
|
24
|
+
declare type AdapterNetworkRoundtripWithLuvioTestParams<C, D> = AdapterTestWithInjectedLuvio<C, D> & {
|
|
25
|
+
type: 'injectedLuvioNetwork';
|
|
26
|
+
};
|
|
27
|
+
declare type AdapterCacheHitRoundtripTestParams<C, D> = AdapterTestWithInjectedLuvio<C, D> & {
|
|
28
|
+
type: 'cache';
|
|
29
|
+
};
|
|
30
|
+
export declare function testAdapterCompletesRoundtrip<C = any, D = any>(params: AdapterRoundtripTestParams<C, D>): Promise<void>;
|
|
31
|
+
export declare function buildLuvioWithNetwork(networkConfig: NetworkConfig): {
|
|
32
|
+
luvio: Luvio;
|
|
33
|
+
networkAdapter: NetworkAdapter;
|
|
34
|
+
};
|
|
35
|
+
export {};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { FetchResponse } from '@luvio/engine';
|
|
2
|
+
export interface LuvioCustomMatchers<R> {
|
|
3
|
+
toEqualFulfilledSnapshotWithData: (expected: any, privateProperties?: string[]) => R;
|
|
4
|
+
toEqualStaleSnapshotWithData: (expected: any, privateProperties?: string[]) => R;
|
|
5
|
+
toEqualErrorSnapshot: (expectedStatus?: number) => R;
|
|
6
|
+
toEqualOfflineErrorSnapshot: () => R;
|
|
7
|
+
toHaveBeenHitTimes: (expected: Number) => R;
|
|
8
|
+
toHaveBeenHitOnce: () => R;
|
|
9
|
+
toEqualFetchResponse: (expected: FetchResponse<unknown>) => R;
|
|
10
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function setupCustomLuvioMatchers(): void;
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
export { MockPayload, ConnectivityState, buildMockNetworkAdapter, resetMockNetworkAdapter, getMockNetworkAdapterCallCount, buildSuccessMockPayload, buildErrorMockPayload, setMockNetworkPayloads, setNetworkConnectivity, buildFetchResponse, overrideMockNetworkResponses, flushPendingNetworkRequests, } from './network';
|
|
2
2
|
export { verifyImmutable, isImmutable } from './verification';
|
|
3
3
|
export { getMockLuvioWithFulfilledSnapshot, getMockFulfilledSnapshot } from './mocks';
|
|
4
|
-
export { stripProperties } from './utils';
|
|
4
|
+
export { stripProperties, customMatchers } from './utils';
|
|
5
|
+
export { setupCustomLuvioMatchers } from './jest.setup';
|
|
5
6
|
export { MockDurableStore } from './MockDurableStore';
|
|
6
7
|
export { MemoryDurableStorePersistence, DurableStorePersistence } from './durableStorePersistence';
|
|
8
|
+
export { testAdapterCompletesRoundtrip, buildLuvioWithNetwork, buildLuvioInstance, } from './adapterRoundtrip';
|
|
9
|
+
export { LuvioCustomMatchers } from './customMatchers';
|