repluggable-core 0.0.0-pr351.71 → 0.0.0-pr351.72
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/src/repluggableAppDebug/index.d.ts +1 -1
- package/dist/es/src/repluggableAppDebug/index.d.ts.map +1 -1
- package/dist/es/src/repluggableAppDebug/index.js.map +1 -1
- package/dist/es/src/repluggableAppDebug/repluggableAppDebug.d.ts +0 -20
- package/dist/es/src/repluggableAppDebug/repluggableAppDebug.d.ts.map +1 -1
- package/dist/es/src/repluggableAppDebug/repluggableAppDebug.js +42 -41
- package/dist/es/src/repluggableAppDebug/repluggableAppDebug.js.map +1 -1
- package/dist/es/test/repluggableAppDebug.spec.js +0 -122
- package/dist/es/test/repluggableAppDebug.spec.js.map +1 -1
- package/dist/es/test/testKit.spec.js +5 -16
- package/dist/es/test/testKit.spec.js.map +1 -1
- package/dist/es/testKit/index.d.ts +1 -10
- package/dist/es/testKit/index.d.ts.map +1 -1
- package/dist/es/testKit/index.js +16 -54
- package/dist/es/testKit/index.js.map +1 -1
- package/dist/src/repluggableAppDebug/index.d.ts +1 -1
- package/dist/src/repluggableAppDebug/index.d.ts.map +1 -1
- package/dist/src/repluggableAppDebug/index.js.map +1 -1
- package/dist/src/repluggableAppDebug/repluggableAppDebug.d.ts +0 -20
- package/dist/src/repluggableAppDebug/repluggableAppDebug.d.ts.map +1 -1
- package/dist/src/repluggableAppDebug/repluggableAppDebug.js +42 -41
- package/dist/src/repluggableAppDebug/repluggableAppDebug.js.map +1 -1
- package/dist/test/repluggableAppDebug.spec.js +0 -122
- package/dist/test/repluggableAppDebug.spec.js.map +1 -1
- package/dist/test/testKit.spec.js +4 -15
- package/dist/test/testKit.spec.js.map +1 -1
- package/dist/testKit/index.d.ts +1 -10
- package/dist/testKit/index.d.ts.map +1 -1
- package/dist/testKit/index.js +17 -56
- package/dist/testKit/index.js.map +1 -1
- package/package.json +1 -1
- package/src/repluggableAppDebug/debug.d.ts +1 -16
- package/src/repluggableAppDebug/index.ts +1 -1
- package/src/repluggableAppDebug/repluggableAppDebug.ts +43 -65
- package/test/repluggableAppDebug.spec.ts +0 -150
- package/test/testKit.spec.tsx +6 -19
- package/testKit/index.ts +27 -66
package/dist/testKit/index.js
CHANGED
|
@@ -26,7 +26,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
26
26
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
27
|
};
|
|
28
28
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
-
exports.mockObservable = exports.addMockShell = exports.createAppHostAndWaitForLoading = exports.
|
|
29
|
+
exports.mockObservable = exports.addMockShell = exports.createAppHostAndWaitForLoading = exports.createAppHostWithPacts = exports.getPackagesDependencies = exports.createAppHost = exports.createSignalItemsDataStructure = exports.withThrowOnError = exports.withConsoleErrors = exports.emptyLoggerOptions = exports.createShellLogger = void 0;
|
|
30
30
|
const lodash_1 = __importDefault(require("lodash"));
|
|
31
31
|
const index_1 = require("../src/index");
|
|
32
32
|
const loggers_1 = require("../src/loggers");
|
|
@@ -88,64 +88,33 @@ function createAppHostWithPacts(packages, pacts) {
|
|
|
88
88
|
return (0, exports.createAppHost)([...packages, pactsEntryPoint], Object.assign(Object.assign({}, emptyLoggerOptions_1.emptyLoggerOptions), { disableLayersValidation: true }));
|
|
89
89
|
}
|
|
90
90
|
exports.createAppHostWithPacts = createAppHostWithPacts;
|
|
91
|
-
class AppHostLoadingTimeoutError extends Error {
|
|
92
|
-
constructor(message, report) {
|
|
93
|
-
super(message);
|
|
94
|
-
this.report = report;
|
|
95
|
-
this.name = 'AppHostLoadingTimeoutError';
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
exports.AppHostLoadingTimeoutError = AppHostLoadingTimeoutError;
|
|
99
|
-
const WAIT_FOR_LOADING_PROBE_SHELL = 'Depends on all declared APIs';
|
|
100
|
-
const formatUnreadyReport = (timeout, report) => {
|
|
101
|
-
const { utils } = globalThis.repluggableAppDebug;
|
|
102
|
-
const isProbeShell = (name) => name === WAIT_FOR_LOADING_PROBE_SHELL;
|
|
103
|
-
const header = `createAppHostAndWaitForLoading - host not ready within ${timeout}ms.`;
|
|
104
|
-
const unreadyEntryPoints = report.unreadyEntryPoints.filter(entryPoint => !isProbeShell(entryPoint.name));
|
|
105
|
-
const rootUnreadyEntryPoints = report.rootUnreadyEntryPoints.filter(entryPoint => !isProbeShell(entryPoint.name));
|
|
106
|
-
if (report.probableDependencyCycle) {
|
|
107
|
-
const names = unreadyEntryPoints.map(entryPoint => `"${entryPoint.name}"`).join(', ');
|
|
108
|
-
return `${header}
|
|
109
|
-
No root unready API found while ${unreadyEntryPoints.length} entry points are unready - probable dependency cycle between: ${names}`;
|
|
110
|
-
}
|
|
111
|
-
const roots = report.rootUnreadyAPIs.map((info, index) => {
|
|
112
|
-
const declaredBy = info.declaredBy === 'nobody'
|
|
113
|
-
? 'declared by NO entry point (missing package or pact?)'
|
|
114
|
-
: `declared by "${info.declaredBy.entryPointName}" (installed, but its contribution never completed - hung async contributeAPI?)`;
|
|
115
|
-
const requiredBy = info.requiredBy.filter(name => !isProbeShell(name));
|
|
116
|
-
const lines = [`${index + 1}. "${info.key.name}" - ${declaredBy}`];
|
|
117
|
-
if (requiredBy.length) {
|
|
118
|
-
lines.push(` required by: ${requiredBy.join(', ')}`);
|
|
119
|
-
const tree = utils.visualizeDependencyTree(utils.traceAPIDependency(requiredBy[0], info.key.name));
|
|
120
|
-
lines.push(...tree.split('\n').map(line => ` ${line}`));
|
|
121
|
-
}
|
|
122
|
-
return lines.join('\n');
|
|
123
|
-
});
|
|
124
|
-
return `${header}
|
|
125
|
-
|
|
126
|
-
Root unready APIs (${report.rootUnreadyAPIs.length}):
|
|
127
|
-
${roots.join('\n')}
|
|
128
|
-
|
|
129
|
-
Unready entry points: ${rootUnreadyEntryPoints.length} blocked directly on root APIs, ${unreadyEntryPoints.length} total.`;
|
|
130
|
-
};
|
|
131
91
|
function createAppHostAndWaitForLoading(packages_1, pacts_1) {
|
|
132
|
-
return __awaiter(this, arguments, void 0, function* (packages, pacts,
|
|
92
|
+
return __awaiter(this, arguments, void 0, function* (packages, pacts, timeout = 3000) {
|
|
133
93
|
const appHost = createAppHostWithPacts(packages, pacts);
|
|
134
94
|
const declaredAPIs = (0, lodash_1.default)(packages)
|
|
135
95
|
.flatten()
|
|
136
96
|
.value()
|
|
137
97
|
.flatMap((entryPoint) => (entryPoint.declareAPIs ? entryPoint.declareAPIs() : []));
|
|
138
|
-
let timer;
|
|
139
98
|
const timeoutPromise = new Promise((resolve, reject) => {
|
|
140
|
-
|
|
141
|
-
const
|
|
142
|
-
|
|
99
|
+
setTimeout(() => {
|
|
100
|
+
const readyAPIs = Array.from(globalThis.repluggableAppDebug.readyAPIs);
|
|
101
|
+
const unreadyAPIs = declaredAPIs.filter(api => !readyAPIs.some(readyAPI => readyAPI.name === api.name));
|
|
102
|
+
const unreadyEntryPoints = globalThis.repluggableAppDebug.utils.unReadyEntryPoints();
|
|
103
|
+
const readyNames = new Set(readyAPIs.map(api => api.name));
|
|
104
|
+
const declaredByUnready = new Set(unreadyEntryPoints.flatMap(ep => { var _a; return (((_a = ep.declareAPIs) === null || _a === void 0 ? void 0 : _a.call(ep)) || []).map(key => key.name); }));
|
|
105
|
+
const rootUnreadyAPIs = lodash_1.default.uniqBy(unreadyEntryPoints
|
|
106
|
+
.flatMap(ep => { var _a; return ((_a = ep.getDependencyAPIs) === null || _a === void 0 ? void 0 : _a.call(ep)) || []; })
|
|
107
|
+
.filter(key => !readyNames.has(key.name) && !declaredByUnready.has(key.name)), 'name');
|
|
108
|
+
reject(new Error(`createAppHostAndWaitForLoading - waiting for loading timed out after ${timeout}ms.
|
|
109
|
+
these root unready APIs are most likely the reason - unready entry points require them but nothing declares them (missing entry point or pact?): ${JSON.stringify(rootUnreadyAPIs)}
|
|
110
|
+
|
|
111
|
+
in addition here's the full list of declared APIs that have not been contributed: ${JSON.stringify(unreadyAPIs)}`));
|
|
143
112
|
}, timeout);
|
|
144
113
|
});
|
|
145
114
|
const loadingPromise = new Promise((resolve) => __awaiter(this, void 0, void 0, function* () {
|
|
146
115
|
yield appHost.addShells([
|
|
147
116
|
{
|
|
148
|
-
name:
|
|
117
|
+
name: 'Depends on all declared APIs',
|
|
149
118
|
getDependencyAPIs() {
|
|
150
119
|
return declaredAPIs;
|
|
151
120
|
},
|
|
@@ -155,15 +124,7 @@ function createAppHostAndWaitForLoading(packages_1, pacts_1) {
|
|
|
155
124
|
}
|
|
156
125
|
]);
|
|
157
126
|
}));
|
|
158
|
-
|
|
159
|
-
yield Promise.race([timeoutPromise, loadingPromise]);
|
|
160
|
-
return appHost;
|
|
161
|
-
}
|
|
162
|
-
finally {
|
|
163
|
-
if (timer) {
|
|
164
|
-
clearTimeout(timer);
|
|
165
|
-
}
|
|
166
|
-
}
|
|
127
|
+
return Promise.race([timeoutPromise, loadingPromise]).then(() => appHost);
|
|
167
128
|
});
|
|
168
129
|
}
|
|
169
130
|
exports.createAppHostAndWaitForLoading = createAppHostAndWaitForLoading;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../testKit/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,oDAAsB;AAEtB,wCAAwH;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../testKit/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -23,25 +23,10 @@ export interface DependencyTree {
|
|
|
23
23
|
deps: { api: string; subtree: DependencyTree | null }[]
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
-
export interface RootUnreadyAPIInfo {
|
|
27
|
-
key: AnySlotKey
|
|
28
|
-
declaredBy: 'nobody' | { entryPointName: string }
|
|
29
|
-
requiredBy: string[]
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
export interface UnreadyEntryPointsReport {
|
|
33
|
-
unreadyEntryPoints: EntryPoint[]
|
|
34
|
-
rootUnreadyAPIs: RootUnreadyAPIInfo[]
|
|
35
|
-
rootUnreadyEntryPoints: EntryPoint[]
|
|
36
|
-
probableDependencyCycle: boolean
|
|
37
|
-
}
|
|
38
|
-
|
|
39
26
|
export interface RepluggableDebugUtils {
|
|
40
27
|
apis(): APIDebugInfo[]
|
|
41
28
|
unReadyEntryPoints(): EntryPoint[]
|
|
42
|
-
|
|
43
|
-
/** @deprecated use getUnreadyEntryPointsReport() - this returns only the first of possibly many root unready APIs */
|
|
44
|
-
getRootUnreadyAPI(): SlotKey<any> | undefined
|
|
29
|
+
getRootUnreadyAPI(): SlotKey<any>
|
|
45
30
|
whyEntryPointUnready(name: string): void
|
|
46
31
|
findAPI(name: string): APIDebugInfo[]
|
|
47
32
|
getAPIOrEntryPointsDependencies(
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export { setupDebugInfo
|
|
1
|
+
export { setupDebugInfo } from './repluggableAppDebug'
|
|
@@ -36,74 +36,54 @@ function mapApiToEntryPoint(allPackages: EntryPoint[]) {
|
|
|
36
36
|
return apiToEntryPoint
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
requiredBy: string[]
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
export interface UnreadyEntryPointsReport {
|
|
51
|
-
unreadyEntryPoints: EntryPoint[]
|
|
52
|
-
rootUnreadyAPIs: RootUnreadyAPIInfo[]
|
|
53
|
-
/** unready entry points directly blocked on a root unready API */
|
|
54
|
-
rootUnreadyEntryPoints: EntryPoint[]
|
|
55
|
-
/** true when entry points are unready but no root unready API exists - their dependencies form a cycle */
|
|
56
|
-
probableDependencyCycle: boolean
|
|
39
|
+
/**
|
|
40
|
+
* a function that returns all the entry points in the system with their declared APIs and dependencies
|
|
41
|
+
*/
|
|
42
|
+
const getAllEntryPoints = () => {
|
|
43
|
+
return [
|
|
44
|
+
...globalThis.repluggableAppDebug.utils.unReadyEntryPoints(),
|
|
45
|
+
...[...globalThis.repluggableAppDebug.addedShells].map(([_, shell]) => shell.entryPoint)
|
|
46
|
+
]
|
|
57
47
|
}
|
|
58
48
|
|
|
59
|
-
type UnreadyReportParams = Pick<SetupDebugInfoParams, 'readyAPIs' | 'getOwnSlotKey' | 'getUnreadyEntryPoints' | 'addedShells'>
|
|
60
|
-
|
|
61
49
|
/**
|
|
62
|
-
*
|
|
63
|
-
*
|
|
50
|
+
* this function is used to get the root unready API in case there are too many to understand.
|
|
51
|
+
* for example if you have 200 unready entry points, running this function will give you the first unready API that
|
|
52
|
+
* will unblock the rest of the entry point (note that there might be more than one)
|
|
53
|
+
*
|
|
54
|
+
* this function basically takes the first unready entry point, get its dependencies and iterates over them to find an API that is not ready
|
|
55
|
+
* at this point it follows the same process recursively until it reaced the target API.
|
|
64
56
|
*/
|
|
65
|
-
const
|
|
66
|
-
return ()
|
|
67
|
-
|
|
68
|
-
const
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
const declarerName = declaredByInstalled.get(key.name)
|
|
85
|
-
const info = rootByName.get(key.name) ?? {
|
|
86
|
-
key,
|
|
87
|
-
declaredBy: declarerName ? { entryPointName: declarerName } : ('nobody' as const),
|
|
88
|
-
requiredBy: []
|
|
57
|
+
const getRootUnreadyAPI = (host: AppHost) => {
|
|
58
|
+
return () => {
|
|
59
|
+
// get all unready entry points
|
|
60
|
+
const allEntryPoints = getAllEntryPoints()
|
|
61
|
+
const unReadyAPIsArray = []
|
|
62
|
+
// get the depdenencies of the first unready entry point
|
|
63
|
+
let dependenciesOfUnreadyEntryPoint = allEntryPoints?.[0]?.getDependencyAPIs?.()
|
|
64
|
+
|
|
65
|
+
while (dependenciesOfUnreadyEntryPoint?.length) {
|
|
66
|
+
const currentAPI = dependenciesOfUnreadyEntryPoint.pop()
|
|
67
|
+
|
|
68
|
+
if (!currentAPI) {
|
|
69
|
+
continue
|
|
70
|
+
}
|
|
71
|
+
// try to get the API from this host, we are looking for an API that is not ready
|
|
72
|
+
try {
|
|
73
|
+
const api = host.getAPI(currentAPI as SlotKey<any>)
|
|
74
|
+
if (api) {
|
|
75
|
+
continue
|
|
89
76
|
}
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
entryPoint.getDependencyAPIs?.().some(key => rootAPINames.has(key.name))
|
|
99
|
-
)
|
|
100
|
-
|
|
101
|
-
return {
|
|
102
|
-
unreadyEntryPoints,
|
|
103
|
-
rootUnreadyAPIs,
|
|
104
|
-
rootUnreadyEntryPoints,
|
|
105
|
-
probableDependencyCycle: unreadyEntryPoints.length > 0 && rootUnreadyAPIs.length === 0
|
|
77
|
+
} catch (e) {
|
|
78
|
+
unReadyAPIsArray.push(currentAPI)
|
|
79
|
+
// we found an API that is unready, lets find which entry point declares it
|
|
80
|
+
const declarer = allEntryPoints.find(entryPointData =>
|
|
81
|
+
entryPointData.declareAPIs?.().some(api => currentAPI?.name === api.name)
|
|
82
|
+
)
|
|
83
|
+
dependenciesOfUnreadyEntryPoint = declarer?.getDependencyAPIs?.()
|
|
84
|
+
}
|
|
106
85
|
}
|
|
86
|
+
return unReadyAPIsArray.reverse()[0]
|
|
107
87
|
}
|
|
108
88
|
}
|
|
109
89
|
|
|
@@ -227,9 +207,7 @@ export function setupDebugInfo({
|
|
|
227
207
|
}
|
|
228
208
|
})
|
|
229
209
|
},
|
|
230
|
-
|
|
231
|
-
/** @deprecated use getUnreadyEntryPointsReport() - this returns only the first of possibly many root unready APIs */
|
|
232
|
-
getRootUnreadyAPI: (): AnySlotKey | undefined => utils.getUnreadyEntryPointsReport().rootUnreadyAPIs[0]?.key,
|
|
210
|
+
getRootUnreadyAPI: getRootUnreadyAPI(host),
|
|
233
211
|
unReadyEntryPoints: (): EntryPoint[] => getUnreadyEntryPoints(),
|
|
234
212
|
whyEntryPointUnready: (name: string) => {
|
|
235
213
|
const unreadyEntryPoint = _.find(
|
|
@@ -245,154 +245,4 @@ describe('RepluggableAppDebug', () => {
|
|
|
245
245
|
expect(unreadyAPIs).toEqual({ name: 'unreadyAPI' })
|
|
246
246
|
})
|
|
247
247
|
})
|
|
248
|
-
|
|
249
|
-
describe('getUnreadyEntryPointsReport', () => {
|
|
250
|
-
const getReport = async () => {
|
|
251
|
-
await new Promise(resolve => setTimeout(resolve, 0))
|
|
252
|
-
return globalThis.repluggableAppDebug.utils.getUnreadyEntryPointsReport()
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
it('should report no unready entry points when all are loaded', async () => {
|
|
256
|
-
createAppHost([
|
|
257
|
-
{
|
|
258
|
-
name: 'entryPoint',
|
|
259
|
-
declareAPIs: () => []
|
|
260
|
-
}
|
|
261
|
-
])
|
|
262
|
-
|
|
263
|
-
const report = await getReport()
|
|
264
|
-
|
|
265
|
-
expect(report).toEqual({
|
|
266
|
-
unreadyEntryPoints: [],
|
|
267
|
-
rootUnreadyAPIs: [],
|
|
268
|
-
rootUnreadyEntryPoints: [],
|
|
269
|
-
probableDependencyCycle: false
|
|
270
|
-
})
|
|
271
|
-
})
|
|
272
|
-
|
|
273
|
-
it('should report all root unready APIs of independent unready clusters', async () => {
|
|
274
|
-
createAppHost([
|
|
275
|
-
{
|
|
276
|
-
name: 'entryPoint A',
|
|
277
|
-
getDependencyAPIs: () => [{ name: 'missing A' }]
|
|
278
|
-
},
|
|
279
|
-
{
|
|
280
|
-
name: 'entryPoint B',
|
|
281
|
-
getDependencyAPIs: () => [{ name: 'missing B' }]
|
|
282
|
-
}
|
|
283
|
-
])
|
|
284
|
-
|
|
285
|
-
const report = await getReport()
|
|
286
|
-
|
|
287
|
-
expect(report.rootUnreadyAPIs).toEqual([
|
|
288
|
-
{ key: { name: 'missing A' }, declaredBy: 'nobody', requiredBy: ['entryPoint A'] },
|
|
289
|
-
{ key: { name: 'missing B' }, declaredBy: 'nobody', requiredBy: ['entryPoint B'] }
|
|
290
|
-
])
|
|
291
|
-
expect(report.rootUnreadyEntryPoints.map(entryPoint => entryPoint.name)).toEqual(['entryPoint A', 'entryPoint B'])
|
|
292
|
-
expect(report.probableDependencyCycle).toBe(false)
|
|
293
|
-
})
|
|
294
|
-
|
|
295
|
-
it('should report only the root API of a transitively blocked chain', async () => {
|
|
296
|
-
createAppHost([
|
|
297
|
-
{
|
|
298
|
-
name: 'entryPoint A',
|
|
299
|
-
getDependencyAPIs: () => [{ name: 'API B' }]
|
|
300
|
-
},
|
|
301
|
-
{
|
|
302
|
-
name: 'entryPoint B',
|
|
303
|
-
declareAPIs: () => [{ name: 'API B' }],
|
|
304
|
-
getDependencyAPIs: () => [unreadAPI]
|
|
305
|
-
}
|
|
306
|
-
])
|
|
307
|
-
|
|
308
|
-
const report = await getReport()
|
|
309
|
-
|
|
310
|
-
expect(report.rootUnreadyAPIs).toEqual([{ key: unreadAPI, declaredBy: 'nobody', requiredBy: ['entryPoint B'] }])
|
|
311
|
-
expect(report.rootUnreadyEntryPoints.map(entryPoint => entryPoint.name)).toEqual(['entryPoint B'])
|
|
312
|
-
expect(report.unreadyEntryPoints.map(entryPoint => entryPoint.name)).toEqual(['entryPoint A', 'entryPoint B'])
|
|
313
|
-
})
|
|
314
|
-
|
|
315
|
-
it('should report roots of sibling branches, including APIs declared by an installed shell that never contributed them', async () => {
|
|
316
|
-
createAppHost([
|
|
317
|
-
{
|
|
318
|
-
name: 'entryPoint 0',
|
|
319
|
-
getDependencyAPIs: () => [{ name: 'missing API' }, { name: 'API B' }]
|
|
320
|
-
},
|
|
321
|
-
{
|
|
322
|
-
name: 'entryPoint 1',
|
|
323
|
-
declareAPIs: () => [{ name: 'API B' }]
|
|
324
|
-
}
|
|
325
|
-
])
|
|
326
|
-
|
|
327
|
-
const report = await getReport()
|
|
328
|
-
|
|
329
|
-
expect(report.rootUnreadyAPIs).toEqual([
|
|
330
|
-
{ key: { name: 'missing API' }, declaredBy: 'nobody', requiredBy: ['entryPoint 0'] },
|
|
331
|
-
{ key: { name: 'API B' }, declaredBy: { entryPointName: 'entryPoint 1' }, requiredBy: ['entryPoint 0'] }
|
|
332
|
-
])
|
|
333
|
-
})
|
|
334
|
-
|
|
335
|
-
it('should aggregate all entry points blocked on the same root API', async () => {
|
|
336
|
-
createAppHost([
|
|
337
|
-
{
|
|
338
|
-
name: 'entryPoint A',
|
|
339
|
-
getDependencyAPIs: () => [unreadAPI]
|
|
340
|
-
},
|
|
341
|
-
{
|
|
342
|
-
name: 'entryPoint B',
|
|
343
|
-
getDependencyAPIs: () => [unreadAPI]
|
|
344
|
-
}
|
|
345
|
-
])
|
|
346
|
-
|
|
347
|
-
const report = await getReport()
|
|
348
|
-
|
|
349
|
-
expect(report.rootUnreadyAPIs).toEqual([{ key: unreadAPI, declaredBy: 'nobody', requiredBy: ['entryPoint A', 'entryPoint B'] }])
|
|
350
|
-
})
|
|
351
|
-
|
|
352
|
-
it('should flag a probable dependency cycle when unready entry points have no root unready API', async () => {
|
|
353
|
-
createAppHost(
|
|
354
|
-
[
|
|
355
|
-
{
|
|
356
|
-
name: 'entryPoint A',
|
|
357
|
-
declareAPIs: () => [{ name: 'API X' }],
|
|
358
|
-
getDependencyAPIs: () => [{ name: 'API Y' }]
|
|
359
|
-
},
|
|
360
|
-
{
|
|
361
|
-
name: 'entryPoint B',
|
|
362
|
-
declareAPIs: () => [{ name: 'API Y' }],
|
|
363
|
-
getDependencyAPIs: () => [{ name: 'API X' }]
|
|
364
|
-
}
|
|
365
|
-
],
|
|
366
|
-
{ monitoring: {}, disableCheckCircularDependencies: true }
|
|
367
|
-
)
|
|
368
|
-
|
|
369
|
-
const report = await getReport()
|
|
370
|
-
|
|
371
|
-
expect(report.rootUnreadyAPIs).toEqual([])
|
|
372
|
-
expect(report.unreadyEntryPoints.map(entryPoint => entryPoint.name)).toEqual(['entryPoint A', 'entryPoint B'])
|
|
373
|
-
expect(report.probableDependencyCycle).toBe(true)
|
|
374
|
-
})
|
|
375
|
-
|
|
376
|
-
it('should not hang getRootUnreadyAPI on a dependency cycle', async () => {
|
|
377
|
-
createAppHost(
|
|
378
|
-
[
|
|
379
|
-
{
|
|
380
|
-
name: 'entryPoint A',
|
|
381
|
-
declareAPIs: () => [{ name: 'API X' }],
|
|
382
|
-
getDependencyAPIs: () => [{ name: 'API Y' }]
|
|
383
|
-
},
|
|
384
|
-
{
|
|
385
|
-
name: 'entryPoint B',
|
|
386
|
-
declareAPIs: () => [{ name: 'API Y' }],
|
|
387
|
-
getDependencyAPIs: () => [{ name: 'API X' }]
|
|
388
|
-
}
|
|
389
|
-
],
|
|
390
|
-
{ monitoring: {}, disableCheckCircularDependencies: true }
|
|
391
|
-
)
|
|
392
|
-
|
|
393
|
-
const unreadyAPIs = await getUnreadyAPIs()
|
|
394
|
-
|
|
395
|
-
expect(unreadyAPIs).toBeUndefined()
|
|
396
|
-
}, 3000)
|
|
397
|
-
})
|
|
398
248
|
})
|
package/test/testKit.spec.tsx
CHANGED
|
@@ -12,8 +12,7 @@ import {
|
|
|
12
12
|
asyncLoadMockPackage,
|
|
13
13
|
dependsOnMockPackageEntryPoint,
|
|
14
14
|
MockPublicAPI,
|
|
15
|
-
createAppHostAndWaitForLoading
|
|
16
|
-
AppHostLoadingTimeoutError
|
|
15
|
+
createAppHostAndWaitForLoading
|
|
17
16
|
} from '../testKit'
|
|
18
17
|
|
|
19
18
|
interface APIKeys {
|
|
@@ -148,10 +147,10 @@ describe('App Host TestKit', () => {
|
|
|
148
147
|
it('should throw if failed to load all packages', async () => {
|
|
149
148
|
const hostPromise = createAppHostAndWaitForLoading([dependsOnMockPackageEntryPoint], [])
|
|
150
149
|
jest.runAllTimers()
|
|
151
|
-
await expect(hostPromise).rejects.toThrow(new RegExp(
|
|
150
|
+
await expect(hostPromise).rejects.toThrow(new RegExp(MockPublicAPI.name))
|
|
152
151
|
})
|
|
153
152
|
|
|
154
|
-
it('should
|
|
153
|
+
it('should report all root unready APIs of independent unready entry points', async () => {
|
|
155
154
|
const hostPromise = createAppHostAndWaitForLoading(
|
|
156
155
|
[
|
|
157
156
|
{
|
|
@@ -168,24 +167,20 @@ describe('App Host TestKit', () => {
|
|
|
168
167
|
[]
|
|
169
168
|
)
|
|
170
169
|
jest.runAllTimers()
|
|
171
|
-
const error:
|
|
170
|
+
const error: Error = await hostPromise.then(
|
|
172
171
|
() => {
|
|
173
172
|
throw new Error('expected hostPromise to reject')
|
|
174
173
|
},
|
|
175
174
|
e => e
|
|
176
175
|
)
|
|
177
176
|
|
|
178
|
-
expect(error).toBeInstanceOf(AppHostLoadingTimeoutError)
|
|
179
|
-
expect(error.report.rootUnreadyAPIs.map(info => info.key.name)).toEqual(['missing A', 'missing B'])
|
|
180
177
|
expect(error.message).toContain('"missing A"')
|
|
181
178
|
expect(error.message).toContain('"missing B"')
|
|
182
|
-
expect(error.message).toContain('required by: entryPoint A')
|
|
183
|
-
expect(error.message).toContain('required by: entryPoint B')
|
|
184
179
|
})
|
|
185
180
|
|
|
186
181
|
it('should respect a custom loading timeout', async () => {
|
|
187
182
|
let settled = false
|
|
188
|
-
const hostPromise = createAppHostAndWaitForLoading([dependsOnMockPackageEntryPoint], [],
|
|
183
|
+
const hostPromise = createAppHostAndWaitForLoading([dependsOnMockPackageEntryPoint], [], 10000)
|
|
189
184
|
hostPromise.catch(() => (settled = true))
|
|
190
185
|
|
|
191
186
|
jest.advanceTimersByTime(9999)
|
|
@@ -194,15 +189,7 @@ describe('App Host TestKit', () => {
|
|
|
194
189
|
expect(settled).toBe(false)
|
|
195
190
|
|
|
196
191
|
jest.advanceTimersByTime(1)
|
|
197
|
-
await expect(hostPromise).rejects.
|
|
198
|
-
})
|
|
199
|
-
|
|
200
|
-
it('should not leave a pending timeout after successful loading', async () => {
|
|
201
|
-
const hostPromise = createAppHostAndWaitForLoading([dependsOnMockPackageEntryPoint, asyncLoadMockPackage], [])
|
|
202
|
-
jest.advanceTimersByTime(500)
|
|
203
|
-
const host = await hostPromise
|
|
204
|
-
expect(host.getAPI(MockPublicAPI)).toBeDefined()
|
|
205
|
-
expect(jest.getTimerCount()).toBe(0)
|
|
192
|
+
await expect(hostPromise).rejects.toThrow('timed out after 10000ms')
|
|
206
193
|
})
|
|
207
194
|
})
|
|
208
195
|
})
|