@opensip-cli/dashboard 0.1.10 → 0.1.12
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/README.md +4 -2
- package/dist/client-bundle.generated.d.ts.map +1 -1
- package/dist/client-bundle.generated.js +1 -1
- package/dist/client-bundle.generated.js.map +1 -1
- package/dist/code-paths/graph-view-model.js +0 -1
- package/dist/code-paths/graph-view-model.js.map +1 -1
- package/dist/css/theme.js +1 -1
- package/dist/generator.d.ts +2 -0
- package/dist/generator.d.ts.map +1 -1
- package/dist/generator.js +10 -4
- package/dist/generator.js.map +1 -1
- package/dist/report-cup-icon.d.ts +17 -0
- package/dist/report-cup-icon.d.ts.map +1 -0
- package/dist/report-cup-icon.js +34 -0
- package/dist/report-cup-icon.js.map +1 -0
- package/dist/tool-tabs-registrations.js +10 -0
- package/dist/tool-tabs-registrations.js.map +1 -1
- package/package.json +3 -3
- package/dist/__tests__/catalog-provenance.test.d.ts +0 -11
- package/dist/__tests__/catalog-provenance.test.d.ts.map +0 -1
- package/dist/__tests__/catalog-provenance.test.js +0 -112
- package/dist/__tests__/catalog-provenance.test.js.map +0 -1
- package/dist/__tests__/coupling-attribution.test.d.ts +0 -9
- package/dist/__tests__/coupling-attribution.test.d.ts.map +0 -1
- package/dist/__tests__/coupling-attribution.test.js +0 -95
- package/dist/__tests__/coupling-attribution.test.js.map +0 -1
- package/dist/__tests__/dashboard-bundle-weight.test.d.ts +0 -23
- package/dist/__tests__/dashboard-bundle-weight.test.d.ts.map +0 -1
- package/dist/__tests__/dashboard-bundle-weight.test.js +0 -80
- package/dist/__tests__/dashboard-bundle-weight.test.js.map +0 -1
- package/dist/__tests__/dashboard-cell-containment.test.d.ts +0 -2
- package/dist/__tests__/dashboard-cell-containment.test.d.ts.map +0 -1
- package/dist/__tests__/dashboard-cell-containment.test.js +0 -52
- package/dist/__tests__/dashboard-cell-containment.test.js.map +0 -1
- package/dist/__tests__/dashboard-cytoscape-vendor.test.d.ts +0 -10
- package/dist/__tests__/dashboard-cytoscape-vendor.test.d.ts.map +0 -1
- package/dist/__tests__/dashboard-cytoscape-vendor.test.js +0 -40
- package/dist/__tests__/dashboard-cytoscape-vendor.test.js.map +0 -1
- package/dist/__tests__/dashboard-editor-link.test.d.ts +0 -14
- package/dist/__tests__/dashboard-editor-link.test.d.ts.map +0 -1
- package/dist/__tests__/dashboard-editor-link.test.js +0 -87
- package/dist/__tests__/dashboard-editor-link.test.js.map +0 -1
- package/dist/__tests__/dashboard-el.test.d.ts +0 -18
- package/dist/__tests__/dashboard-el.test.d.ts.map +0 -1
- package/dist/__tests__/dashboard-el.test.js +0 -90
- package/dist/__tests__/dashboard-el.test.js.map +0 -1
- package/dist/__tests__/dashboard-filters.test.d.ts +0 -9
- package/dist/__tests__/dashboard-filters.test.d.ts.map +0 -1
- package/dist/__tests__/dashboard-filters.test.js +0 -87
- package/dist/__tests__/dashboard-filters.test.js.map +0 -1
- package/dist/__tests__/dashboard-function-card-singleton.test.d.ts +0 -9
- package/dist/__tests__/dashboard-function-card-singleton.test.d.ts.map +0 -1
- package/dist/__tests__/dashboard-function-card-singleton.test.js +0 -75
- package/dist/__tests__/dashboard-function-card-singleton.test.js.map +0 -1
- package/dist/__tests__/dashboard-function-card.test.d.ts +0 -10
- package/dist/__tests__/dashboard-function-card.test.d.ts.map +0 -1
- package/dist/__tests__/dashboard-function-card.test.js +0 -439
- package/dist/__tests__/dashboard-function-card.test.js.map +0 -1
- package/dist/__tests__/dashboard-function-row.test.d.ts +0 -11
- package/dist/__tests__/dashboard-function-row.test.d.ts.map +0 -1
- package/dist/__tests__/dashboard-function-row.test.js +0 -102
- package/dist/__tests__/dashboard-function-row.test.js.map +0 -1
- package/dist/__tests__/dashboard-generator-graph-catalog.test.d.ts +0 -9
- package/dist/__tests__/dashboard-generator-graph-catalog.test.d.ts.map +0 -1
- package/dist/__tests__/dashboard-generator-graph-catalog.test.js +0 -77
- package/dist/__tests__/dashboard-generator-graph-catalog.test.js.map +0 -1
- package/dist/__tests__/dashboard-graph-offline.integration.test.d.ts +0 -13
- package/dist/__tests__/dashboard-graph-offline.integration.test.d.ts.map +0 -1
- package/dist/__tests__/dashboard-graph-offline.integration.test.js +0 -57
- package/dist/__tests__/dashboard-graph-offline.integration.test.js.map +0 -1
- package/dist/__tests__/dashboard-graph-scc.test.d.ts +0 -17
- package/dist/__tests__/dashboard-graph-scc.test.d.ts.map +0 -1
- package/dist/__tests__/dashboard-graph-scc.test.js +0 -89
- package/dist/__tests__/dashboard-graph-scc.test.js.map +0 -1
- package/dist/__tests__/dashboard-graph-view-model.test.d.ts +0 -12
- package/dist/__tests__/dashboard-graph-view-model.test.d.ts.map +0 -1
- package/dist/__tests__/dashboard-graph-view-model.test.js +0 -331
- package/dist/__tests__/dashboard-graph-view-model.test.js.map +0 -1
- package/dist/__tests__/dashboard-help-drawer.test.d.ts +0 -9
- package/dist/__tests__/dashboard-help-drawer.test.d.ts.map +0 -1
- package/dist/__tests__/dashboard-help-drawer.test.js +0 -95
- package/dist/__tests__/dashboard-help-drawer.test.js.map +0 -1
- package/dist/__tests__/dashboard-html.test.d.ts +0 -2
- package/dist/__tests__/dashboard-html.test.d.ts.map +0 -1
- package/dist/__tests__/dashboard-html.test.js +0 -169
- package/dist/__tests__/dashboard-html.test.js.map +0 -1
- package/dist/__tests__/dashboard-indexes.test.d.ts +0 -11
- package/dist/__tests__/dashboard-indexes.test.d.ts.map +0 -1
- package/dist/__tests__/dashboard-indexes.test.js +0 -214
- package/dist/__tests__/dashboard-indexes.test.js.map +0 -1
- package/dist/__tests__/dashboard-pagination.test.d.ts +0 -15
- package/dist/__tests__/dashboard-pagination.test.d.ts.map +0 -1
- package/dist/__tests__/dashboard-pagination.test.js +0 -140
- package/dist/__tests__/dashboard-pagination.test.js.map +0 -1
- package/dist/__tests__/dashboard-path-utils.test.d.ts +0 -13
- package/dist/__tests__/dashboard-path-utils.test.d.ts.map +0 -1
- package/dist/__tests__/dashboard-path-utils.test.js +0 -62
- package/dist/__tests__/dashboard-path-utils.test.js.map +0 -1
- package/dist/__tests__/dashboard-search.test.d.ts +0 -10
- package/dist/__tests__/dashboard-search.test.d.ts.map +0 -1
- package/dist/__tests__/dashboard-search.test.js +0 -52
- package/dist/__tests__/dashboard-search.test.js.map +0 -1
- package/dist/__tests__/dashboard-sessions.test.d.ts +0 -14
- package/dist/__tests__/dashboard-sessions.test.d.ts.map +0 -1
- package/dist/__tests__/dashboard-sessions.test.js +0 -332
- package/dist/__tests__/dashboard-sessions.test.js.map +0 -1
- package/dist/__tests__/dashboard-trace.test.d.ts +0 -16
- package/dist/__tests__/dashboard-trace.test.d.ts.map +0 -1
- package/dist/__tests__/dashboard-trace.test.js +0 -170
- package/dist/__tests__/dashboard-trace.test.js.map +0 -1
- package/dist/__tests__/dashboard-validation.integration.test.d.ts +0 -14
- package/dist/__tests__/dashboard-validation.integration.test.d.ts.map +0 -1
- package/dist/__tests__/dashboard-validation.integration.test.js +0 -221
- package/dist/__tests__/dashboard-validation.integration.test.js.map +0 -1
- package/dist/__tests__/dashboard-view-conformance.test.d.ts +0 -12
- package/dist/__tests__/dashboard-view-conformance.test.d.ts.map +0 -1
- package/dist/__tests__/dashboard-view-conformance.test.js +0 -52
- package/dist/__tests__/dashboard-view-conformance.test.js.map +0 -1
- package/dist/__tests__/dashboard-view-coupling.test.d.ts +0 -7
- package/dist/__tests__/dashboard-view-coupling.test.d.ts.map +0 -1
- package/dist/__tests__/dashboard-view-coupling.test.js +0 -360
- package/dist/__tests__/dashboard-view-coupling.test.js.map +0 -1
- package/dist/__tests__/dashboard-view-distribution.test.d.ts +0 -10
- package/dist/__tests__/dashboard-view-distribution.test.d.ts.map +0 -1
- package/dist/__tests__/dashboard-view-distribution.test.js +0 -249
- package/dist/__tests__/dashboard-view-distribution.test.js.map +0 -1
- package/dist/__tests__/dashboard-view-graph.test.d.ts +0 -13
- package/dist/__tests__/dashboard-view-graph.test.d.ts.map +0 -1
- package/dist/__tests__/dashboard-view-graph.test.js +0 -299
- package/dist/__tests__/dashboard-view-graph.test.js.map +0 -1
- package/dist/__tests__/dashboard-view-template.test.d.ts +0 -20
- package/dist/__tests__/dashboard-view-template.test.d.ts.map +0 -1
- package/dist/__tests__/dashboard-view-template.test.js +0 -206
- package/dist/__tests__/dashboard-view-template.test.js.map +0 -1
- package/dist/__tests__/dashboard.test.d.ts +0 -2
- package/dist/__tests__/dashboard.test.d.ts.map +0 -1
- package/dist/__tests__/dashboard.test.js +0 -129
- package/dist/__tests__/dashboard.test.js.map +0 -1
- package/dist/__tests__/graph-tab.test.d.ts +0 -10
- package/dist/__tests__/graph-tab.test.d.ts.map +0 -1
- package/dist/__tests__/graph-tab.test.js +0 -78
- package/dist/__tests__/graph-tab.test.js.map +0 -1
- package/dist/client/el.d.ts +0 -17
- package/dist/client/el.d.ts.map +0 -1
- package/dist/client/el.js +0 -36
- package/dist/client/el.js.map +0 -1
- package/dist/code-paths/__tests__/views-registry.test.d.ts +0 -18
- package/dist/code-paths/__tests__/views-registry.test.d.ts.map +0 -1
- package/dist/code-paths/__tests__/views-registry.test.js +0 -41
- package/dist/code-paths/__tests__/views-registry.test.js.map +0 -1
|
@@ -1,102 +0,0 @@
|
|
|
1
|
-
/// <reference lib="dom" />
|
|
2
|
-
/**
|
|
3
|
-
* @vitest-environment jsdom
|
|
4
|
-
*
|
|
5
|
-
* `renderFunctionRows` shared helper — §11.2 / §11.4.
|
|
6
|
-
*
|
|
7
|
-
* Three column configurations corresponding to the Hot/Big/Wide views:
|
|
8
|
-
* verifies the helper produces the right header cells and the right
|
|
9
|
-
* per-row cell values.
|
|
10
|
-
*/
|
|
11
|
-
import { describe, expect, it, beforeEach } from 'vitest';
|
|
12
|
-
import { DASHBOARD_CLIENT_BUNDLE } from '../client-bundle.generated.js';
|
|
13
|
-
function loadRenderFn() {
|
|
14
|
-
// `renderFunctionRows` (with `el`, the paginators and `makeSortable`) now all
|
|
15
|
-
// live in the typed client bundle (L4) and are exposed as page globals;
|
|
16
|
-
// `var sessions = []` satisfies checks.ts's load-time `computeCheckStats()` read.
|
|
17
|
-
// eslint-disable-next-line @typescript-eslint/no-implied-eval, sonarjs/code-eval -- Trusted source: our own bundled dashboard JS.
|
|
18
|
-
return new Function('var sessions = [];\n' + DASHBOARD_CLIENT_BUNDLE + '\nreturn renderFunctionRows;')();
|
|
19
|
-
}
|
|
20
|
-
beforeEach(() => {
|
|
21
|
-
document.body.innerHTML = '';
|
|
22
|
-
});
|
|
23
|
-
describe('renderFunctionRows', () => {
|
|
24
|
-
it('Hot view column shape: Function / Callers / Package / File', () => {
|
|
25
|
-
const f = loadRenderFn();
|
|
26
|
-
const c = document.createElement('div');
|
|
27
|
-
f(c, {
|
|
28
|
-
occurrences: [
|
|
29
|
-
{ simpleName: 'logger', __callers: 12, filePath: 'packages/core/src/lib/logger.ts:42' },
|
|
30
|
-
],
|
|
31
|
-
columns: [
|
|
32
|
-
{ label: 'Function', value: (o) => o.simpleName },
|
|
33
|
-
{ label: 'Callers', value: (o) => o.__callers },
|
|
34
|
-
{ label: 'Package', value: () => 'core' },
|
|
35
|
-
{ label: 'File', value: (o) => o.filePath },
|
|
36
|
-
],
|
|
37
|
-
});
|
|
38
|
-
// eslint-disable-next-line unicorn/prefer-spread -- TS NodeListOf iteration via spread requires lib.dom.iterable; Array.from is the portable form for the test target.
|
|
39
|
-
const ths = Array.from(c.querySelectorAll('th'));
|
|
40
|
-
expect(ths.map((t) => t.textContent)).toEqual(['Function', 'Callers', 'Package', 'File']);
|
|
41
|
-
// eslint-disable-next-line unicorn/prefer-spread -- See above.
|
|
42
|
-
const tds = Array.from(c.querySelectorAll('tbody td'));
|
|
43
|
-
expect(tds.map((t) => t.textContent)).toEqual([
|
|
44
|
-
'logger',
|
|
45
|
-
'12',
|
|
46
|
-
'core',
|
|
47
|
-
'packages/core/src/lib/logger.ts:42',
|
|
48
|
-
]);
|
|
49
|
-
});
|
|
50
|
-
it('Big view column shape: Function / Lines / Kind / Package / File', () => {
|
|
51
|
-
const f = loadRenderFn();
|
|
52
|
-
const c = document.createElement('div');
|
|
53
|
-
f(c, {
|
|
54
|
-
occurrences: [
|
|
55
|
-
{
|
|
56
|
-
simpleName: 'foo',
|
|
57
|
-
__size: 42,
|
|
58
|
-
kind: 'function-declaration',
|
|
59
|
-
filePath: 'packages/x/src/x.ts:1',
|
|
60
|
-
},
|
|
61
|
-
],
|
|
62
|
-
columns: [
|
|
63
|
-
{ label: 'Function', value: (o) => o.simpleName },
|
|
64
|
-
{ label: 'Lines', value: (o) => o.__size },
|
|
65
|
-
{ label: 'Kind', value: (o) => o.kind },
|
|
66
|
-
{ label: 'Package', value: () => 'x' },
|
|
67
|
-
{ label: 'File', value: (o) => o.filePath },
|
|
68
|
-
],
|
|
69
|
-
});
|
|
70
|
-
expect(c.querySelectorAll('thead th').length).toBe(5);
|
|
71
|
-
});
|
|
72
|
-
it('Wide view shape includes a Signature column with the parameter thumb', () => {
|
|
73
|
-
const f = loadRenderFn();
|
|
74
|
-
const c = document.createElement('div');
|
|
75
|
-
f(c, {
|
|
76
|
-
occurrences: [
|
|
77
|
-
{
|
|
78
|
-
simpleName: 'connect',
|
|
79
|
-
__arity: 5,
|
|
80
|
-
__thumb: '(a, b, c, d, e)',
|
|
81
|
-
filePath: 'packages/x/x.ts:1',
|
|
82
|
-
},
|
|
83
|
-
],
|
|
84
|
-
columns: [
|
|
85
|
-
{ label: 'Function', value: (o) => o.simpleName },
|
|
86
|
-
{ label: 'Params', value: (o) => o.__arity },
|
|
87
|
-
{ label: 'Signature', value: (o) => o.__thumb },
|
|
88
|
-
{ label: 'Package', value: () => 'x' },
|
|
89
|
-
{ label: 'File', value: (o) => o.filePath },
|
|
90
|
-
],
|
|
91
|
-
});
|
|
92
|
-
const sigCell = c.querySelectorAll('tbody td')[2];
|
|
93
|
-
expect(sigCell.textContent).toBe('(a, b, c, d, e)');
|
|
94
|
-
});
|
|
95
|
-
it('renders the empty state for zero rows', () => {
|
|
96
|
-
const f = loadRenderFn();
|
|
97
|
-
const c = document.createElement('div');
|
|
98
|
-
f(c, { occurrences: [], columns: [{ label: 'X', value: () => 'y' }] });
|
|
99
|
-
expect(c.querySelector('.empty')).not.toBeNull();
|
|
100
|
-
});
|
|
101
|
-
});
|
|
102
|
-
//# sourceMappingURL=dashboard-function-row.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"dashboard-function-row.test.js","sourceRoot":"","sources":["../../src/__tests__/dashboard-function-row.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Generator-level wiring tests for the v0.3 graph-catalog inline blob
|
|
3
|
-
* and the editor-protocol JS constant.
|
|
4
|
-
*
|
|
5
|
-
* Covers Phase P0 (catalog block emission, null vs non-null) and the
|
|
6
|
-
* Phase P9 hook (editor protocol constant).
|
|
7
|
-
*/
|
|
8
|
-
export {};
|
|
9
|
-
//# sourceMappingURL=dashboard-generator-graph-catalog.test.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"dashboard-generator-graph-catalog.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/dashboard-generator-graph-catalog.test.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG"}
|
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Generator-level wiring tests for the v0.3 graph-catalog inline blob
|
|
3
|
-
* and the editor-protocol JS constant.
|
|
4
|
-
*
|
|
5
|
-
* Covers Phase P0 (catalog block emission, null vs non-null) and the
|
|
6
|
-
* Phase P9 hook (editor protocol constant).
|
|
7
|
-
*/
|
|
8
|
-
import { describe, expect, it } from 'vitest';
|
|
9
|
-
import { generateDashboardHtml } from '../generator.js';
|
|
10
|
-
const minimalCatalog = {
|
|
11
|
-
version: '2.0',
|
|
12
|
-
tool: 'graph',
|
|
13
|
-
language: 'typescript',
|
|
14
|
-
builtAt: '2026-05-17T00:00:00Z',
|
|
15
|
-
functions: {
|
|
16
|
-
foo: [
|
|
17
|
-
{
|
|
18
|
-
bodyHash: 'h1',
|
|
19
|
-
simpleName: 'foo',
|
|
20
|
-
qualifiedName: 'pkg.foo',
|
|
21
|
-
filePath: 'packages/x/src/foo.ts',
|
|
22
|
-
line: 1,
|
|
23
|
-
column: 0,
|
|
24
|
-
endLine: 5,
|
|
25
|
-
kind: 'function-declaration',
|
|
26
|
-
params: [],
|
|
27
|
-
returnType: null,
|
|
28
|
-
enclosingClass: null,
|
|
29
|
-
decorators: [],
|
|
30
|
-
visibility: 'exported',
|
|
31
|
-
inTestFile: false,
|
|
32
|
-
definedInGenerated: false,
|
|
33
|
-
calls: [],
|
|
34
|
-
},
|
|
35
|
-
],
|
|
36
|
-
},
|
|
37
|
-
};
|
|
38
|
-
describe('generateDashboardHtml — graph catalog wiring', () => {
|
|
39
|
-
it('emits no id="graph-catalog" block when graphCatalog is null', () => {
|
|
40
|
-
const html = generateDashboardHtml({ sessions: [], graphCatalog: null });
|
|
41
|
-
expect(html).not.toContain('id="graph-catalog"');
|
|
42
|
-
});
|
|
43
|
-
it('emits the graph-catalog blob and is parseable JSON when supplied', () => {
|
|
44
|
-
const html = generateDashboardHtml({ sessions: [], graphCatalog: minimalCatalog });
|
|
45
|
-
expect(html).toContain('id="graph-catalog"');
|
|
46
|
-
// Pull out the blob and re-parse it.
|
|
47
|
-
const m = /<script type="application\/json" id="graph-catalog">([\s\S]*?)<\/script>/.exec(html);
|
|
48
|
-
expect(m).not.toBeNull();
|
|
49
|
-
const blob = m[1];
|
|
50
|
-
// Reverse the < / > escape that escapeForScriptContext applies.
|
|
51
|
-
const unescaped = blob.replaceAll(String.raw `<`, '<').replaceAll(String.raw `>`, '>');
|
|
52
|
-
const parsed = JSON.parse(unescaped);
|
|
53
|
-
expect(parsed.version).toBe('2.0');
|
|
54
|
-
expect(Object.keys(parsed.functions)).toContain('foo');
|
|
55
|
-
});
|
|
56
|
-
it('embeds EDITOR_PROTOCOL = null when no editorProtocol is supplied', () => {
|
|
57
|
-
const html = generateDashboardHtml({ sessions: [], graphCatalog: null });
|
|
58
|
-
expect(html).toContain('const EDITOR_PROTOCOL = null;');
|
|
59
|
-
});
|
|
60
|
-
it('embeds EDITOR_PROTOCOL as a JS string constant when supplied', () => {
|
|
61
|
-
const html = generateDashboardHtml({
|
|
62
|
-
sessions: [],
|
|
63
|
-
graphCatalog: minimalCatalog,
|
|
64
|
-
editorProtocol: 'vscode',
|
|
65
|
-
});
|
|
66
|
-
expect(html).toContain('const EDITOR_PROTOCOL = "vscode";');
|
|
67
|
-
});
|
|
68
|
-
it('embeds the restructured view ids via the views[] registry', () => {
|
|
69
|
-
const html = generateDashboardHtml({ sessions: [], graphCatalog: minimalCatalog });
|
|
70
|
-
// The views register from the typed client bundle (L4); esbuild emits
|
|
71
|
-
// double-quoted object values, so the marker is the bundled form.
|
|
72
|
-
for (const id of ['graph', 'coupling', 'distribution']) {
|
|
73
|
-
expect(html).toContain(`id: "${id}"`);
|
|
74
|
-
}
|
|
75
|
-
});
|
|
76
|
-
});
|
|
77
|
-
//# sourceMappingURL=dashboard-generator-graph-catalog.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"dashboard-generator-graph-catalog.test.js","sourceRoot":"","sources":["../../src/__tests__/dashboard-generator-graph-catalog.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Offline-render guarantee for the Graph view.
|
|
3
|
-
*
|
|
4
|
-
* Playwright is not part of this package's toolchain, so rather than boot a
|
|
5
|
-
* real browser this test asserts the offline property at the artifact
|
|
6
|
-
* level: a generated report inlines the Cytoscape renderer and the
|
|
7
|
-
* projected view-model with ZERO external `<script src>` references, so it
|
|
8
|
-
* renders the Graph view with the network disabled ("open an archived
|
|
9
|
-
* report on a plane"). The only permitted external reference is the Google
|
|
10
|
-
* Fonts stylesheet `<link>` the report already carried before this work.
|
|
11
|
-
*/
|
|
12
|
-
export {};
|
|
13
|
-
//# sourceMappingURL=dashboard-graph-offline.integration.test.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"dashboard-graph-offline.integration.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/dashboard-graph-offline.integration.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG"}
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Offline-render guarantee for the Graph view.
|
|
3
|
-
*
|
|
4
|
-
* Playwright is not part of this package's toolchain, so rather than boot a
|
|
5
|
-
* real browser this test asserts the offline property at the artifact
|
|
6
|
-
* level: a generated report inlines the Cytoscape renderer and the
|
|
7
|
-
* projected view-model with ZERO external `<script src>` references, so it
|
|
8
|
-
* renders the Graph view with the network disabled ("open an archived
|
|
9
|
-
* report on a plane"). The only permitted external reference is the Google
|
|
10
|
-
* Fonts stylesheet `<link>` the report already carried before this work.
|
|
11
|
-
*/
|
|
12
|
-
import { readFileSync } from 'node:fs';
|
|
13
|
-
import { dirname, join } from 'node:path';
|
|
14
|
-
import { fileURLToPath } from 'node:url';
|
|
15
|
-
import { describe, expect, it } from 'vitest';
|
|
16
|
-
import { generateDashboardHtml } from '../generator.js';
|
|
17
|
-
const HERE = dirname(fileURLToPath(import.meta.url));
|
|
18
|
-
function loadFixture() {
|
|
19
|
-
const candidates = [
|
|
20
|
-
join(HERE, 'fixtures', 'catalog-small.json'),
|
|
21
|
-
join(HERE, '..', '..', 'src', '__tests__', 'fixtures', 'catalog-small.json'),
|
|
22
|
-
];
|
|
23
|
-
for (const p of candidates) {
|
|
24
|
-
try {
|
|
25
|
-
return JSON.parse(readFileSync(p, 'utf8'));
|
|
26
|
-
}
|
|
27
|
-
catch {
|
|
28
|
-
// next
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
throw new Error('catalog-small.json fixture not found');
|
|
32
|
-
}
|
|
33
|
-
describe('Graph view — offline render guarantee', () => {
|
|
34
|
-
const html = generateDashboardHtml({ sessions: [], graphCatalog: loadFixture() });
|
|
35
|
-
it('inlines the Cytoscape renderer (no CDN fetch)', () => {
|
|
36
|
-
expect(html).toContain('cytoscape');
|
|
37
|
-
expect(html).toContain('cytoscapeDagre');
|
|
38
|
-
});
|
|
39
|
-
it('embeds the projected graph-view-model blob', () => {
|
|
40
|
-
expect(html).toContain('id="graph-view-model"');
|
|
41
|
-
});
|
|
42
|
-
it('registers the Graph view', () => {
|
|
43
|
-
// The view registers from the typed client bundle (L4) — esbuild emits
|
|
44
|
-
// double-quoted object keys/values, so the marker is the bundled form.
|
|
45
|
-
expect(html).toContain('id: "graph"');
|
|
46
|
-
expect(html).toContain('code-paths-graph-canvas');
|
|
47
|
-
});
|
|
48
|
-
it('has no external <script src> references (renders fully offline)', () => {
|
|
49
|
-
const scriptSrc = /<script[^>]*\ssrc=["'][^"']+["']/gi;
|
|
50
|
-
const matches = html.match(scriptSrc) ?? [];
|
|
51
|
-
expect(matches).toHaveLength(0);
|
|
52
|
-
});
|
|
53
|
-
it('has no cytoscape CDN URL', () => {
|
|
54
|
-
expect(/https?:\/\/[^"']*cytoscape/i.test(html)).toBe(false);
|
|
55
|
-
});
|
|
56
|
-
});
|
|
57
|
-
//# sourceMappingURL=dashboard-graph-offline.integration.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"dashboard-graph-offline.integration.test.js","sourceRoot":"","sources":["../../src/__tests__/dashboard-graph-offline.integration.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAE9C,OAAO,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAIxD,MAAM,IAAI,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAErD,SAAS,WAAW;IAClB,MAAM,UAAU,GAAG;QACjB,IAAI,CAAC,IAAI,EAAE,UAAU,EAAE,oBAAoB,CAAC;QAC5C,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,oBAAoB,CAAC;KAC7E,CAAC;IACF,KAAK,MAAM,CAAC,IAAI,UAAU,EAAE,CAAC;QAC3B,IAAI,CAAC;YACH,OAAO,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,EAAE,MAAM,CAAC,CAAiB,CAAC;QAC7D,CAAC;QAAC,MAAM,CAAC;YACP,OAAO;QACT,CAAC;IACH,CAAC;IACD,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;AAC1D,CAAC;AAED,QAAQ,CAAC,uCAAuC,EAAE,GAAG,EAAE;IACrD,MAAM,IAAI,GAAG,qBAAqB,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,YAAY,EAAE,WAAW,EAAE,EAAE,CAAC,CAAC;IAElF,EAAE,CAAC,+CAA+C,EAAE,GAAG,EAAE;QACvD,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;QACpC,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC;IAC3C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4CAA4C,EAAE,GAAG,EAAE;QACpD,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,uBAAuB,CAAC,CAAC;IAClD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0BAA0B,EAAE,GAAG,EAAE;QAClC,uEAAuE;QACvE,uEAAuE;QACvE,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC;QACtC,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,yBAAyB,CAAC,CAAC;IACpD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iEAAiE,EAAE,GAAG,EAAE;QACzE,MAAM,SAAS,GAAG,oCAAoC,CAAC;QACvD,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC;QAC5C,MAAM,CAAC,OAAO,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;IAClC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0BAA0B,EAAE,GAAG,EAAE;QAClC,MAAM,CAAC,6BAA6B,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC/D,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Tarjan SCC primitives — `buildAdjacency` and `tarjanSccIds`.
|
|
3
|
-
*
|
|
4
|
-
* `graph-view-model.test.ts` exercises the SCC pass end-to-end through the
|
|
5
|
-
* projector, but only along the "happy" structural paths (clean two-package
|
|
6
|
-
* cycles, self-loops). These tests drive the lower-level primitives directly
|
|
7
|
-
* to lock the defensive/edge branches the projector never produces:
|
|
8
|
-
*
|
|
9
|
-
* - `buildAdjacency`: an edge whose `source` is not a known node (dropped),
|
|
10
|
-
* and a duplicate edge (deduped — `includes` guard).
|
|
11
|
-
* - `tarjanSccIds`: a node id with no adjacency entry (the `?? []` fallback),
|
|
12
|
-
* a cross-edge into an already-finished node NOT on the stack (the
|
|
13
|
-
* `onStack` false branch), a self-loop singleton (cyclic), and a trivial
|
|
14
|
-
* singleton (omitted → null).
|
|
15
|
-
*/
|
|
16
|
-
export {};
|
|
17
|
-
//# sourceMappingURL=dashboard-graph-scc.test.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"dashboard-graph-scc.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/dashboard-graph-scc.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG"}
|
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Tarjan SCC primitives — `buildAdjacency` and `tarjanSccIds`.
|
|
3
|
-
*
|
|
4
|
-
* `graph-view-model.test.ts` exercises the SCC pass end-to-end through the
|
|
5
|
-
* projector, but only along the "happy" structural paths (clean two-package
|
|
6
|
-
* cycles, self-loops). These tests drive the lower-level primitives directly
|
|
7
|
-
* to lock the defensive/edge branches the projector never produces:
|
|
8
|
-
*
|
|
9
|
-
* - `buildAdjacency`: an edge whose `source` is not a known node (dropped),
|
|
10
|
-
* and a duplicate edge (deduped — `includes` guard).
|
|
11
|
-
* - `tarjanSccIds`: a node id with no adjacency entry (the `?? []` fallback),
|
|
12
|
-
* a cross-edge into an already-finished node NOT on the stack (the
|
|
13
|
-
* `onStack` false branch), a self-loop singleton (cyclic), and a trivial
|
|
14
|
-
* singleton (omitted → null).
|
|
15
|
-
*/
|
|
16
|
-
import { describe, expect, it } from 'vitest';
|
|
17
|
-
import { buildAdjacency, tarjanSccIds } from '../code-paths/graph-scc.js';
|
|
18
|
-
describe('buildAdjacency', () => {
|
|
19
|
-
it('builds source → unique target lists for known nodes', () => {
|
|
20
|
-
const adj = buildAdjacency([{ id: 'a' }, { id: 'b' }, { id: 'c' }], [
|
|
21
|
-
{ source: 'a', target: 'b' },
|
|
22
|
-
{ source: 'a', target: 'c' },
|
|
23
|
-
]);
|
|
24
|
-
expect(adj.get('a')).toEqual(['b', 'c']);
|
|
25
|
-
expect(adj.get('b')).toEqual([]);
|
|
26
|
-
expect(adj.get('c')).toEqual([]);
|
|
27
|
-
});
|
|
28
|
-
it('drops an edge whose source is not a registered node (no entry to push into)', () => {
|
|
29
|
-
// `ghost` was never declared as a node → adjacency.get returns undefined →
|
|
30
|
-
// the `out &&` guard short-circuits and the edge is silently dropped.
|
|
31
|
-
const adj = buildAdjacency([{ id: 'a' }], [{ source: 'ghost', target: 'a' }]);
|
|
32
|
-
expect(adj.has('ghost')).toBe(false);
|
|
33
|
-
expect(adj.get('a')).toEqual([]);
|
|
34
|
-
// No stray key was created for the unknown source.
|
|
35
|
-
expect([...adj.keys()]).toEqual(['a']);
|
|
36
|
-
});
|
|
37
|
-
it('dedupes a repeated edge (includes guard) so adjacency stays unique', () => {
|
|
38
|
-
const adj = buildAdjacency([{ id: 'a' }, { id: 'b' }], [
|
|
39
|
-
{ source: 'a', target: 'b' },
|
|
40
|
-
{ source: 'a', target: 'b' },
|
|
41
|
-
]);
|
|
42
|
-
expect(adj.get('a')).toEqual(['b']);
|
|
43
|
-
});
|
|
44
|
-
});
|
|
45
|
-
describe('tarjanSccIds', () => {
|
|
46
|
-
it('returns an empty map when there are no cycles (all trivial singletons omitted)', () => {
|
|
47
|
-
const nodes = ['a', 'b'];
|
|
48
|
-
const adj = buildAdjacency([{ id: 'a' }, { id: 'b' }], [{ source: 'a', target: 'b' }]);
|
|
49
|
-
const scc = tarjanSccIds(nodes, adj);
|
|
50
|
-
expect(scc.size).toBe(0);
|
|
51
|
-
});
|
|
52
|
-
it('tolerates a node id with no adjacency entry (the `?? []` fallback)', () => {
|
|
53
|
-
// 'lonely' is in the node list but the adjacency map has no key for it.
|
|
54
|
-
const adj = new Map([['a', []]]);
|
|
55
|
-
const scc = tarjanSccIds(['lonely', 'a'], adj);
|
|
56
|
-
// No cycle → empty, and crucially it does not throw on the missing entry.
|
|
57
|
-
expect(scc.size).toBe(0);
|
|
58
|
-
});
|
|
59
|
-
it('flags a two-node cycle with a shared, deterministic sccId', () => {
|
|
60
|
-
const adj = buildAdjacency([{ id: 'a' }, { id: 'b' }], [
|
|
61
|
-
{ source: 'a', target: 'b' },
|
|
62
|
-
{ source: 'b', target: 'a' },
|
|
63
|
-
]);
|
|
64
|
-
const scc = tarjanSccIds(['a', 'b'], adj);
|
|
65
|
-
expect(scc.get('a')).toBe('scc:a'); // smallest member id
|
|
66
|
-
expect(scc.get('a')).toBe(scc.get('b'));
|
|
67
|
-
});
|
|
68
|
-
it('flags a self-loop singleton as cyclic but omits a trivial singleton', () => {
|
|
69
|
-
const adj = buildAdjacency([{ id: 'self' }, { id: 'plain' }], [{ source: 'self', target: 'self' }]);
|
|
70
|
-
const scc = tarjanSccIds(['self', 'plain'], adj);
|
|
71
|
-
expect(scc.get('self')).toBe('scc:self');
|
|
72
|
-
expect(scc.has('plain')).toBe(false);
|
|
73
|
-
});
|
|
74
|
-
it('handles a cross-edge into an already-finished node not on the stack (onStack false branch)', () => {
|
|
75
|
-
// Diamond: a→b, a→c, b→d, c→d. When `a` scans `c` after `b`'s subtree
|
|
76
|
-
// (including d) has fully closed, d is visited but NO LONGER on the stack
|
|
77
|
-
// — exercising the `onStack.has(w)` false branch in scanSuccessors. No
|
|
78
|
-
// node is in a cycle, so the result is empty but must not misclassify.
|
|
79
|
-
const adj = buildAdjacency([{ id: 'a' }, { id: 'b' }, { id: 'c' }, { id: 'd' }], [
|
|
80
|
-
{ source: 'a', target: 'b' },
|
|
81
|
-
{ source: 'a', target: 'c' },
|
|
82
|
-
{ source: 'b', target: 'd' },
|
|
83
|
-
{ source: 'c', target: 'd' },
|
|
84
|
-
]);
|
|
85
|
-
const scc = tarjanSccIds(['a', 'b', 'c', 'd'], adj);
|
|
86
|
-
expect(scc.size).toBe(0);
|
|
87
|
-
});
|
|
88
|
-
});
|
|
89
|
-
//# sourceMappingURL=dashboard-graph-scc.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"dashboard-graph-scc.test.js","sourceRoot":"","sources":["../../src/__tests__/dashboard-graph-scc.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* View-model projection — `projectCatalogToGraphViewModel`.
|
|
3
|
-
*
|
|
4
|
-
* The projector aggregates the function call graph up to PACKAGE granularity
|
|
5
|
-
* (item 10): one node per package, one edge per directed package→package
|
|
6
|
-
* coupling with a call-count weight. These tests lock the schema, the
|
|
7
|
-
* package-attribution (mirroring `pkgOf`), the weight accounting, the
|
|
8
|
-
* totalCoupling sizing input, the external-target drop, the cross-package SCC
|
|
9
|
-
* pass, and the byte budget.
|
|
10
|
-
*/
|
|
11
|
-
export {};
|
|
12
|
-
//# sourceMappingURL=dashboard-graph-view-model.test.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"dashboard-graph-view-model.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/dashboard-graph-view-model.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG"}
|