relay-test-utils-internal 13.1.1 → 14.1.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/consoleError.js.flow +70 -0
- package/consoleErrorsAndWarnings.js.flow +134 -0
- package/consoleWarning.js.flow +70 -0
- package/describeWithFeatureFlags.js.flow +0 -2
- package/getOutputForFixture.js.flow +0 -2
- package/index.js +1 -1
- package/index.js.flow +23 -3
- package/lib/consoleError.js +63 -0
- package/lib/consoleErrorsAndWarnings.js +116 -0
- package/lib/consoleWarning.js +63 -0
- package/lib/describeWithFeatureFlags.js +1 -2
- package/lib/generateTestsFromFixtures.js +1 -1
- package/lib/getOutputForFixture.js +0 -1
- package/lib/index.js +35 -13
- package/lib/printAST.js +1 -2
- package/lib/simpleClone.js +0 -1
- package/lib/testschema.graphql +6 -52
- package/lib/trackRetentionForEnvironment.js +64 -0
- package/lib/warnings.js +19 -63
- package/package.json +2 -2
- package/printAST.js.flow +0 -2
- package/relay-test-utils-internal.js +2 -2
- package/relay-test-utils-internal.min.js +2 -2
- package/simpleClone.js.flow +1 -3
- package/trackRetentionForEnvironment.js.flow +63 -0
- package/warnings.js.flow +28 -61
@@ -0,0 +1,63 @@
|
|
1
|
+
/**
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
3
|
+
*
|
4
|
+
* This source code is licensed under the MIT license found in the
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
6
|
+
*
|
7
|
+
* @flow
|
8
|
+
* @format
|
9
|
+
*/
|
10
|
+
|
11
|
+
'use strict';
|
12
|
+
|
13
|
+
/* global jest */
|
14
|
+
|
15
|
+
import type {IEnvironment} from '../relay-runtime';
|
16
|
+
import type {OperationDescriptor} from '../relay-runtime/store/RelayStoreTypes';
|
17
|
+
|
18
|
+
/**
|
19
|
+
* Takes an environment and augments it with a mock implementation of `retain`
|
20
|
+
* that tracks what operations are currently retained. Also returns the Jest mock
|
21
|
+
* `release` function for backwards-compatibility with existing tests, but you
|
22
|
+
* should use `isOperationRetained` for new tests as it is much less error-prone.
|
23
|
+
*/
|
24
|
+
function trackRetentionForEnvironment(environment: IEnvironment): {
|
25
|
+
release_DEPRECATED: JestMockFn<[mixed], void>,
|
26
|
+
isOperationRetained: OperationDescriptor => boolean,
|
27
|
+
} {
|
28
|
+
const retainCountsByOperation = new Map();
|
29
|
+
|
30
|
+
const release = jest.fn(id => {
|
31
|
+
const existing = retainCountsByOperation.get(id) ?? NaN;
|
32
|
+
if (existing === 1) {
|
33
|
+
retainCountsByOperation.delete(id);
|
34
|
+
} else {
|
35
|
+
retainCountsByOperation.set(id, existing - 1);
|
36
|
+
}
|
37
|
+
});
|
38
|
+
|
39
|
+
// $FlowFixMe[cannot-write] safe to do for mocking
|
40
|
+
environment.retain = jest.fn(operation => {
|
41
|
+
const id = operation.request.identifier;
|
42
|
+
const existing = retainCountsByOperation.get(id) ?? 0;
|
43
|
+
retainCountsByOperation.set(id, existing + 1);
|
44
|
+
let released = false;
|
45
|
+
return {
|
46
|
+
dispose: () => {
|
47
|
+
if (!released) {
|
48
|
+
release(id);
|
49
|
+
}
|
50
|
+
released = true;
|
51
|
+
},
|
52
|
+
};
|
53
|
+
});
|
54
|
+
|
55
|
+
function isOperationRetained(operation: OperationDescriptor) {
|
56
|
+
const id = operation.request.identifier;
|
57
|
+
return (retainCountsByOperation.get(id) ?? 0) > 0;
|
58
|
+
}
|
59
|
+
|
60
|
+
return {release_DEPRECATED: release, isOperationRetained};
|
61
|
+
}
|
62
|
+
|
63
|
+
module.exports = trackRetentionForEnvironment;
|
package/warnings.js.flow
CHANGED
@@ -11,11 +11,27 @@
|
|
11
11
|
|
12
12
|
'use strict';
|
13
13
|
|
14
|
-
/* global jest
|
14
|
+
/* global jest */
|
15
15
|
|
16
|
-
|
17
|
-
|
18
|
-
const
|
16
|
+
import type {WillFireOptions} from './consoleErrorsAndWarnings';
|
17
|
+
|
18
|
+
const {createConsoleInterceptionSystem} = require('./consoleErrorsAndWarnings');
|
19
|
+
|
20
|
+
const warningsSystem = createConsoleInterceptionSystem(
|
21
|
+
'warning',
|
22
|
+
'expectToWarn',
|
23
|
+
impl => {
|
24
|
+
jest.mock('warning', () =>
|
25
|
+
jest.fn((condition, format, ...args) => {
|
26
|
+
if (!condition) {
|
27
|
+
let argIndex = 0;
|
28
|
+
const message = format.replace(/%s/g, () => String(args[argIndex++]));
|
29
|
+
impl(message);
|
30
|
+
}
|
31
|
+
}),
|
32
|
+
);
|
33
|
+
},
|
34
|
+
);
|
19
35
|
|
20
36
|
/**
|
21
37
|
* Mocks the `warning` module to turn warnings into errors. Any expected
|
@@ -25,64 +41,25 @@ const contextualExpectedWarning: Array<string> = [];
|
|
25
41
|
* use `jest.resetModules()` or manually mock `warning`.
|
26
42
|
*/
|
27
43
|
function disallowWarnings(): void {
|
28
|
-
|
29
|
-
throw new Error('`disallowWarnings` should be called at most once');
|
30
|
-
}
|
31
|
-
installed = true;
|
32
|
-
jest.mock('warning', () => {
|
33
|
-
return jest.fn((condition, format, ...args) => {
|
34
|
-
if (!condition) {
|
35
|
-
let argIndex = 0;
|
36
|
-
const message = format.replace(/%s/g, () => String(args[argIndex++]));
|
37
|
-
const index = expectedWarnings.indexOf(message);
|
38
|
-
|
39
|
-
if (
|
40
|
-
contextualExpectedWarning.length > 0 &&
|
41
|
-
contextualExpectedWarning[0] === message
|
42
|
-
) {
|
43
|
-
contextualExpectedWarning.shift();
|
44
|
-
} else if (index >= 0) {
|
45
|
-
expectedWarnings.splice(index, 1);
|
46
|
-
} else {
|
47
|
-
// log to console in case the error gets swallowed somewhere
|
48
|
-
console.error('Unexpected Warning: ' + message);
|
49
|
-
throw new Error('Warning: ' + message);
|
50
|
-
}
|
51
|
-
}
|
52
|
-
});
|
53
|
-
});
|
54
|
-
afterEach(() => {
|
55
|
-
contextualExpectedWarning.length = 0;
|
56
|
-
if (expectedWarnings.length > 0) {
|
57
|
-
const error = new Error(
|
58
|
-
'Some expected warnings where not triggered:\n\n' +
|
59
|
-
Array.from(expectedWarnings, message => ` * ${message}`).join('\n') +
|
60
|
-
'\n',
|
61
|
-
);
|
62
|
-
expectedWarnings.length = 0;
|
63
|
-
throw error;
|
64
|
-
}
|
65
|
-
});
|
44
|
+
warningsSystem.disallowMessages();
|
66
45
|
}
|
67
46
|
|
68
47
|
/**
|
69
48
|
* Expect a warning with the given message. If the message isn't fired in the
|
70
49
|
* current test, the test will fail.
|
71
50
|
*/
|
72
|
-
function expectWarningWillFire(
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
}
|
78
|
-
expectedWarnings.push(message);
|
51
|
+
function expectWarningWillFire(
|
52
|
+
message: string,
|
53
|
+
options?: WillFireOptions,
|
54
|
+
): void {
|
55
|
+
warningsSystem.expectMessageWillFire(message, options);
|
79
56
|
}
|
80
57
|
|
81
58
|
/**
|
82
59
|
* Expect the callback `fn` to trigger the warning message and otherwise fail.
|
83
60
|
*/
|
84
61
|
function expectToWarn<T>(message: string, fn: () => T): T {
|
85
|
-
return
|
62
|
+
return warningsSystem.expectMessage(message, fn);
|
86
63
|
}
|
87
64
|
|
88
65
|
/**
|
@@ -90,17 +67,7 @@ function expectToWarn<T>(message: string, fn: () => T): T {
|
|
90
67
|
* or otherwise fail.
|
91
68
|
*/
|
92
69
|
function expectToWarnMany<T>(messages: Array<string>, fn: () => T): T {
|
93
|
-
|
94
|
-
throw new Error('Cannot nest `expectToWarn()` calls.');
|
95
|
-
}
|
96
|
-
contextualExpectedWarning.push(...messages);
|
97
|
-
const result = fn();
|
98
|
-
if (contextualExpectedWarning.length > 0) {
|
99
|
-
const notFired = contextualExpectedWarning.toString();
|
100
|
-
contextualExpectedWarning.length = 0;
|
101
|
-
throw new Error(`Expected callback to warn: ${notFired}`);
|
102
|
-
}
|
103
|
-
return result;
|
70
|
+
return warningsSystem.expectMessageMany(messages, fn);
|
104
71
|
}
|
105
72
|
|
106
73
|
module.exports = {
|