@opensip-cli/dashboard 0.1.11 → 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.
Files changed (148) hide show
  1. package/README.md +2 -2
  2. package/dist/client-bundle.generated.d.ts.map +1 -1
  3. package/dist/client-bundle.generated.js +1 -1
  4. package/dist/client-bundle.generated.js.map +1 -1
  5. package/dist/generator.d.ts.map +1 -1
  6. package/dist/generator.js +4 -3
  7. package/dist/generator.js.map +1 -1
  8. package/dist/report-cup-icon.d.ts +17 -0
  9. package/dist/report-cup-icon.d.ts.map +1 -0
  10. package/dist/report-cup-icon.js +34 -0
  11. package/dist/report-cup-icon.js.map +1 -0
  12. package/package.json +3 -3
  13. package/dist/__tests__/catalog-provenance.test.d.ts +0 -11
  14. package/dist/__tests__/catalog-provenance.test.d.ts.map +0 -1
  15. package/dist/__tests__/catalog-provenance.test.js +0 -112
  16. package/dist/__tests__/catalog-provenance.test.js.map +0 -1
  17. package/dist/__tests__/coupling-attribution.test.d.ts +0 -9
  18. package/dist/__tests__/coupling-attribution.test.d.ts.map +0 -1
  19. package/dist/__tests__/coupling-attribution.test.js +0 -95
  20. package/dist/__tests__/coupling-attribution.test.js.map +0 -1
  21. package/dist/__tests__/dashboard-bundle-weight.test.d.ts +0 -23
  22. package/dist/__tests__/dashboard-bundle-weight.test.d.ts.map +0 -1
  23. package/dist/__tests__/dashboard-bundle-weight.test.js +0 -80
  24. package/dist/__tests__/dashboard-bundle-weight.test.js.map +0 -1
  25. package/dist/__tests__/dashboard-cell-containment.test.d.ts +0 -2
  26. package/dist/__tests__/dashboard-cell-containment.test.d.ts.map +0 -1
  27. package/dist/__tests__/dashboard-cell-containment.test.js +0 -52
  28. package/dist/__tests__/dashboard-cell-containment.test.js.map +0 -1
  29. package/dist/__tests__/dashboard-cytoscape-vendor.test.d.ts +0 -10
  30. package/dist/__tests__/dashboard-cytoscape-vendor.test.d.ts.map +0 -1
  31. package/dist/__tests__/dashboard-cytoscape-vendor.test.js +0 -40
  32. package/dist/__tests__/dashboard-cytoscape-vendor.test.js.map +0 -1
  33. package/dist/__tests__/dashboard-editor-link.test.d.ts +0 -14
  34. package/dist/__tests__/dashboard-editor-link.test.d.ts.map +0 -1
  35. package/dist/__tests__/dashboard-editor-link.test.js +0 -87
  36. package/dist/__tests__/dashboard-editor-link.test.js.map +0 -1
  37. package/dist/__tests__/dashboard-el.test.d.ts +0 -18
  38. package/dist/__tests__/dashboard-el.test.d.ts.map +0 -1
  39. package/dist/__tests__/dashboard-el.test.js +0 -90
  40. package/dist/__tests__/dashboard-el.test.js.map +0 -1
  41. package/dist/__tests__/dashboard-filters.test.d.ts +0 -9
  42. package/dist/__tests__/dashboard-filters.test.d.ts.map +0 -1
  43. package/dist/__tests__/dashboard-filters.test.js +0 -87
  44. package/dist/__tests__/dashboard-filters.test.js.map +0 -1
  45. package/dist/__tests__/dashboard-function-card-singleton.test.d.ts +0 -9
  46. package/dist/__tests__/dashboard-function-card-singleton.test.d.ts.map +0 -1
  47. package/dist/__tests__/dashboard-function-card-singleton.test.js +0 -75
  48. package/dist/__tests__/dashboard-function-card-singleton.test.js.map +0 -1
  49. package/dist/__tests__/dashboard-function-card.test.d.ts +0 -10
  50. package/dist/__tests__/dashboard-function-card.test.d.ts.map +0 -1
  51. package/dist/__tests__/dashboard-function-card.test.js +0 -439
  52. package/dist/__tests__/dashboard-function-card.test.js.map +0 -1
  53. package/dist/__tests__/dashboard-function-row.test.d.ts +0 -11
  54. package/dist/__tests__/dashboard-function-row.test.d.ts.map +0 -1
  55. package/dist/__tests__/dashboard-function-row.test.js +0 -102
  56. package/dist/__tests__/dashboard-function-row.test.js.map +0 -1
  57. package/dist/__tests__/dashboard-generator-graph-catalog.test.d.ts +0 -9
  58. package/dist/__tests__/dashboard-generator-graph-catalog.test.d.ts.map +0 -1
  59. package/dist/__tests__/dashboard-generator-graph-catalog.test.js +0 -77
  60. package/dist/__tests__/dashboard-generator-graph-catalog.test.js.map +0 -1
  61. package/dist/__tests__/dashboard-graph-offline.integration.test.d.ts +0 -13
  62. package/dist/__tests__/dashboard-graph-offline.integration.test.d.ts.map +0 -1
  63. package/dist/__tests__/dashboard-graph-offline.integration.test.js +0 -57
  64. package/dist/__tests__/dashboard-graph-offline.integration.test.js.map +0 -1
  65. package/dist/__tests__/dashboard-graph-scc.test.d.ts +0 -17
  66. package/dist/__tests__/dashboard-graph-scc.test.d.ts.map +0 -1
  67. package/dist/__tests__/dashboard-graph-scc.test.js +0 -89
  68. package/dist/__tests__/dashboard-graph-scc.test.js.map +0 -1
  69. package/dist/__tests__/dashboard-graph-view-model.test.d.ts +0 -12
  70. package/dist/__tests__/dashboard-graph-view-model.test.d.ts.map +0 -1
  71. package/dist/__tests__/dashboard-graph-view-model.test.js +0 -331
  72. package/dist/__tests__/dashboard-graph-view-model.test.js.map +0 -1
  73. package/dist/__tests__/dashboard-help-drawer.test.d.ts +0 -9
  74. package/dist/__tests__/dashboard-help-drawer.test.d.ts.map +0 -1
  75. package/dist/__tests__/dashboard-help-drawer.test.js +0 -95
  76. package/dist/__tests__/dashboard-help-drawer.test.js.map +0 -1
  77. package/dist/__tests__/dashboard-html.test.d.ts +0 -2
  78. package/dist/__tests__/dashboard-html.test.d.ts.map +0 -1
  79. package/dist/__tests__/dashboard-html.test.js +0 -169
  80. package/dist/__tests__/dashboard-html.test.js.map +0 -1
  81. package/dist/__tests__/dashboard-indexes.test.d.ts +0 -11
  82. package/dist/__tests__/dashboard-indexes.test.d.ts.map +0 -1
  83. package/dist/__tests__/dashboard-indexes.test.js +0 -214
  84. package/dist/__tests__/dashboard-indexes.test.js.map +0 -1
  85. package/dist/__tests__/dashboard-pagination.test.d.ts +0 -15
  86. package/dist/__tests__/dashboard-pagination.test.d.ts.map +0 -1
  87. package/dist/__tests__/dashboard-pagination.test.js +0 -140
  88. package/dist/__tests__/dashboard-pagination.test.js.map +0 -1
  89. package/dist/__tests__/dashboard-path-utils.test.d.ts +0 -13
  90. package/dist/__tests__/dashboard-path-utils.test.d.ts.map +0 -1
  91. package/dist/__tests__/dashboard-path-utils.test.js +0 -62
  92. package/dist/__tests__/dashboard-path-utils.test.js.map +0 -1
  93. package/dist/__tests__/dashboard-search.test.d.ts +0 -10
  94. package/dist/__tests__/dashboard-search.test.d.ts.map +0 -1
  95. package/dist/__tests__/dashboard-search.test.js +0 -52
  96. package/dist/__tests__/dashboard-search.test.js.map +0 -1
  97. package/dist/__tests__/dashboard-sessions.test.d.ts +0 -14
  98. package/dist/__tests__/dashboard-sessions.test.d.ts.map +0 -1
  99. package/dist/__tests__/dashboard-sessions.test.js +0 -400
  100. package/dist/__tests__/dashboard-sessions.test.js.map +0 -1
  101. package/dist/__tests__/dashboard-trace.test.d.ts +0 -16
  102. package/dist/__tests__/dashboard-trace.test.d.ts.map +0 -1
  103. package/dist/__tests__/dashboard-trace.test.js +0 -170
  104. package/dist/__tests__/dashboard-trace.test.js.map +0 -1
  105. package/dist/__tests__/dashboard-validation.integration.test.d.ts +0 -14
  106. package/dist/__tests__/dashboard-validation.integration.test.d.ts.map +0 -1
  107. package/dist/__tests__/dashboard-validation.integration.test.js +0 -221
  108. package/dist/__tests__/dashboard-validation.integration.test.js.map +0 -1
  109. package/dist/__tests__/dashboard-view-conformance.test.d.ts +0 -12
  110. package/dist/__tests__/dashboard-view-conformance.test.d.ts.map +0 -1
  111. package/dist/__tests__/dashboard-view-conformance.test.js +0 -52
  112. package/dist/__tests__/dashboard-view-conformance.test.js.map +0 -1
  113. package/dist/__tests__/dashboard-view-coupling.test.d.ts +0 -7
  114. package/dist/__tests__/dashboard-view-coupling.test.d.ts.map +0 -1
  115. package/dist/__tests__/dashboard-view-coupling.test.js +0 -360
  116. package/dist/__tests__/dashboard-view-coupling.test.js.map +0 -1
  117. package/dist/__tests__/dashboard-view-distribution.test.d.ts +0 -10
  118. package/dist/__tests__/dashboard-view-distribution.test.d.ts.map +0 -1
  119. package/dist/__tests__/dashboard-view-distribution.test.js +0 -249
  120. package/dist/__tests__/dashboard-view-distribution.test.js.map +0 -1
  121. package/dist/__tests__/dashboard-view-graph.test.d.ts +0 -13
  122. package/dist/__tests__/dashboard-view-graph.test.d.ts.map +0 -1
  123. package/dist/__tests__/dashboard-view-graph.test.js +0 -299
  124. package/dist/__tests__/dashboard-view-graph.test.js.map +0 -1
  125. package/dist/__tests__/dashboard-view-template.test.d.ts +0 -20
  126. package/dist/__tests__/dashboard-view-template.test.d.ts.map +0 -1
  127. package/dist/__tests__/dashboard-view-template.test.js +0 -206
  128. package/dist/__tests__/dashboard-view-template.test.js.map +0 -1
  129. package/dist/__tests__/dashboard.test.d.ts +0 -2
  130. package/dist/__tests__/dashboard.test.d.ts.map +0 -1
  131. package/dist/__tests__/dashboard.test.js +0 -129
  132. package/dist/__tests__/dashboard.test.js.map +0 -1
  133. package/dist/__tests__/graph-tab.test.d.ts +0 -10
  134. package/dist/__tests__/graph-tab.test.d.ts.map +0 -1
  135. package/dist/__tests__/graph-tab.test.js +0 -78
  136. package/dist/__tests__/graph-tab.test.js.map +0 -1
  137. package/dist/__tests__/yagni-tab.test.d.ts +0 -13
  138. package/dist/__tests__/yagni-tab.test.d.ts.map +0 -1
  139. package/dist/__tests__/yagni-tab.test.js +0 -85
  140. package/dist/__tests__/yagni-tab.test.js.map +0 -1
  141. package/dist/client/el.d.ts +0 -17
  142. package/dist/client/el.d.ts.map +0 -1
  143. package/dist/client/el.js +0 -36
  144. package/dist/client/el.js.map +0 -1
  145. package/dist/code-paths/__tests__/views-registry.test.d.ts +0 -18
  146. package/dist/code-paths/__tests__/views-registry.test.d.ts.map +0 -1
  147. package/dist/code-paths/__tests__/views-registry.test.js +0 -41
  148. package/dist/code-paths/__tests__/views-registry.test.js.map +0 -1
@@ -1,360 +0,0 @@
1
- /// <reference lib="dom" />
2
- /**
3
- * @vitest-environment jsdom
4
- *
5
- * View 4 (Package coupling) — N×N matrix + drilldown.
6
- */
7
- import { describe, expect, it, beforeEach, vi } from 'vitest';
8
- import { DASHBOARD_CLIENT_BUNDLE } from '../client-bundle.generated.js';
9
- function loadEnv(catalog) {
10
- // The coupling view (and the whole Code Paths panel + prelude) now lives in
11
- // the typed client bundle (L4): loading the bundle registers the view into the
12
- // bundle's `views` global at IIFE eval. Declare the page globals the bundle
13
- // reads (sessions, EDITOR_PROTOCOL, graphCatalog, graphIndexes); seed
14
- // graphCatalog/graphIndexes after the bundle has defined `buildIndexes`.
15
- const head = `
16
- var sessions = [];
17
- var EDITOR_PROTOCOL = null;
18
- var graphCatalog = null;
19
- var graphIndexes = null;
20
- `;
21
- const tail = `
22
- graphCatalog = ${JSON.stringify(catalog)};
23
- graphIndexes = buildIndexes(graphCatalog);
24
- return { views, graphCatalog, graphIndexes, filterState };
25
- `;
26
- // eslint-disable-next-line @typescript-eslint/no-implied-eval, sonarjs/code-eval -- Trusted source: our own bundled dashboard JS.
27
- const factory = new Function(head + DASHBOARD_CLIENT_BUNDLE + tail);
28
- return factory();
29
- }
30
- function makeOcc(over) {
31
- return {
32
- qualifiedName: over.simpleName,
33
- line: 1,
34
- column: 0,
35
- endLine: 5,
36
- kind: 'function-declaration',
37
- params: [],
38
- returnType: null,
39
- enclosingClass: null,
40
- decorators: [],
41
- visibility: 'exported',
42
- inTestFile: false,
43
- definedInGenerated: false,
44
- calls: [],
45
- ...over,
46
- };
47
- }
48
- beforeEach(() => {
49
- document.body.innerHTML = '';
50
- });
51
- describe('View 4 — Coupling matrix', () => {
52
- it('renders an N×N matrix with the right cell counts for two packages', () => {
53
- const catalog = {
54
- version: '2.0',
55
- tool: 'graph',
56
- language: 'typescript',
57
- builtAt: 'now',
58
- functions: {
59
- a: [
60
- makeOcc({
61
- bodyHash: 'a',
62
- simpleName: 'a',
63
- filePath: 'packages/cli/src/a.ts',
64
- calls: [
65
- {
66
- to: ['x', 'y'],
67
- line: 1,
68
- column: 0,
69
- resolution: 'static',
70
- confidence: 'high',
71
- text: '...',
72
- },
73
- ],
74
- }),
75
- ],
76
- b: [
77
- makeOcc({
78
- bodyHash: 'b',
79
- simpleName: 'b',
80
- filePath: 'packages/cli/src/b.ts',
81
- calls: [
82
- {
83
- to: ['x'],
84
- line: 1,
85
- column: 0,
86
- resolution: 'static',
87
- confidence: 'high',
88
- text: '...',
89
- },
90
- ],
91
- }),
92
- ],
93
- x: [makeOcc({ bodyHash: 'x', simpleName: 'x', filePath: 'packages/contracts/src/x.ts' })],
94
- y: [makeOcc({ bodyHash: 'y', simpleName: 'y', filePath: 'packages/contracts/src/y.ts' })],
95
- },
96
- // Engine-emitted edge feature: cli→contracts has 3 call sites (a→x, a→y, b→x).
97
- features: { edge: [{ callerPackage: 'cli', calleePackage: 'contracts', count: 3 }] },
98
- };
99
- const env = loadEnv(catalog);
100
- const c = document.createElement('div');
101
- env.views
102
- .find((v) => v.id === 'coupling')
103
- .render(c, env.graphCatalog, env.graphIndexes, env.filterState);
104
- const cliRow = c.querySelector('td.coupling-cell[data-caller="cli"][data-callee="contracts"]');
105
- expect(cliRow).not.toBeNull();
106
- expect(cliRow.textContent).toBe('3'); // a→x, a→y, b→x
107
- });
108
- it('wraps the table in a bounded scroll container so a large matrix stays on the page', () => {
109
- const catalog = {
110
- version: '2.0',
111
- tool: 'graph',
112
- language: 'typescript',
113
- builtAt: 'now',
114
- functions: {
115
- a: [
116
- makeOcc({
117
- bodyHash: 'a',
118
- simpleName: 'a',
119
- filePath: 'packages/cli/src/a.ts',
120
- calls: [
121
- {
122
- to: ['x'],
123
- line: 1,
124
- column: 0,
125
- resolution: 'static',
126
- confidence: 'high',
127
- text: 'x()',
128
- },
129
- ],
130
- }),
131
- ],
132
- x: [makeOcc({ bodyHash: 'x', simpleName: 'x', filePath: 'packages/contracts/src/x.ts' })],
133
- },
134
- features: { edge: [{ callerPackage: 'cli', calleePackage: 'contracts', count: 1 }] },
135
- };
136
- const env = loadEnv(catalog);
137
- const c = document.createElement('div');
138
- env.views
139
- .find((v) => v.id === 'coupling')
140
- .render(c, env.graphCatalog, env.graphIndexes, env.filterState);
141
- const scroll = c.querySelector('.coupling-scroll');
142
- expect(scroll).not.toBeNull();
143
- // The table must live *inside* the scroll container — that's what gives it
144
- // both scrollbars instead of overflowing the page.
145
- expect(scroll.querySelector('table.coupling-table')).not.toBeNull();
146
- });
147
- it('opens a drilldown card listing the call sites when a cell is clicked', () => {
148
- const catalog = {
149
- version: '2.0',
150
- tool: 'graph',
151
- language: 'typescript',
152
- builtAt: 'now',
153
- functions: {
154
- caller: [
155
- makeOcc({
156
- bodyHash: 'c1',
157
- simpleName: 'caller',
158
- filePath: 'packages/cli/src/c.ts',
159
- calls: [
160
- {
161
- to: ['t1'],
162
- line: 7,
163
- column: 0,
164
- resolution: 'static',
165
- confidence: 'high',
166
- text: 'target()',
167
- },
168
- ],
169
- }),
170
- ],
171
- target: [
172
- makeOcc({
173
- bodyHash: 't1',
174
- simpleName: 'target',
175
- filePath: 'packages/contracts/src/t.ts',
176
- }),
177
- ],
178
- },
179
- features: { edge: [{ callerPackage: 'cli', calleePackage: 'contracts', count: 1 }] },
180
- };
181
- const env = loadEnv(catalog);
182
- const c = document.createElement('div');
183
- env.views
184
- .find((v) => v.id === 'coupling')
185
- .render(c, env.graphCatalog, env.graphIndexes, env.filterState);
186
- const cell = c.querySelector('td.coupling-cell[data-caller="cli"][data-callee="contracts"]');
187
- cell.dispatchEvent(new MouseEvent('click', { bubbles: true }));
188
- const overlay = document.querySelector('.function-card-overlay');
189
- expect(overlay).not.toBeNull();
190
- expect(overlay.textContent).toContain('cli → contracts');
191
- expect(overlay.textContent).toContain('caller');
192
- expect(overlay.textContent).toContain('target');
193
- });
194
- it('emits an empty cell shape when there are no calls in this direction', () => {
195
- const catalog = {
196
- version: '2.0',
197
- tool: 'graph',
198
- language: 'typescript',
199
- builtAt: 'now',
200
- functions: {
201
- a: [
202
- makeOcc({
203
- bodyHash: 'a',
204
- simpleName: 'a',
205
- filePath: 'packages/cli/src/a.ts',
206
- calls: [
207
- {
208
- to: ['b'],
209
- line: 1,
210
- column: 0,
211
- resolution: 'static',
212
- confidence: 'high',
213
- text: 'b()',
214
- },
215
- ],
216
- }),
217
- ],
218
- b: [makeOcc({ bodyHash: 'b', simpleName: 'b', filePath: 'packages/cli/src/b.ts' })],
219
- },
220
- // Only the cli→cli diagonal edge ⇒ a 1×1 matrix.
221
- features: { edge: [{ callerPackage: 'cli', calleePackage: 'cli', count: 1 }] },
222
- };
223
- const env = loadEnv(catalog);
224
- const c = document.createElement('div');
225
- env.views
226
- .find((v) => v.id === 'coupling')
227
- .render(c, env.graphCatalog, env.graphIndexes, env.filterState);
228
- // cli→contracts has no calls; the diagonal (cli→cli) does. There is no
229
- // 'contracts' caller, so the matrix is 1×1.
230
- const cells = c.querySelectorAll('td.coupling-cell');
231
- expect(cells.length).toBe(1);
232
- expect(cells[0].textContent).toBe('1');
233
- });
234
- it('renders an Export CSV button in the coupling toolbar', () => {
235
- const catalog = {
236
- version: '2.0',
237
- tool: 'graph',
238
- language: 'typescript',
239
- builtAt: 'now',
240
- functions: {
241
- a: [
242
- makeOcc({
243
- bodyHash: 'a',
244
- simpleName: 'a',
245
- filePath: 'packages/cli/src/a.ts',
246
- calls: [
247
- {
248
- to: ['x'],
249
- line: 1,
250
- column: 0,
251
- resolution: 'static',
252
- confidence: 'high',
253
- text: 'x()',
254
- },
255
- ],
256
- }),
257
- ],
258
- x: [makeOcc({ bodyHash: 'x', simpleName: 'x', filePath: 'packages/contracts/src/x.ts' })],
259
- },
260
- features: { edge: [{ callerPackage: 'cli', calleePackage: 'contracts', count: 3 }] },
261
- };
262
- const env = loadEnv(catalog);
263
- const c = document.createElement('div');
264
- env.views
265
- .find((v) => v.id === 'coupling')
266
- .render(c, env.graphCatalog, env.graphIndexes, env.filterState);
267
- const btn = c.querySelector('.coupling-export-btn');
268
- expect(btn).not.toBeNull();
269
- expect(btn.textContent).toBe('Export CSV');
270
- });
271
- it('downloads the coupling matrix as a wide, properly-escaped CSV mirroring the table', () => {
272
- const catalog = {
273
- version: '2.0',
274
- tool: 'graph',
275
- language: 'typescript',
276
- builtAt: 'now',
277
- functions: {
278
- a: [makeOcc({ bodyHash: 'a', simpleName: 'a', filePath: 'packages/cli/src/a.ts' })],
279
- x: [makeOcc({ bodyHash: 'x', simpleName: 'x', filePath: 'packages/contracts/src/x.ts' })],
280
- },
281
- features: {
282
- edge: [
283
- { callerPackage: 'cli', calleePackage: 'contracts', count: 3 },
284
- { callerPackage: 'cli', calleePackage: 'cli', count: 2 },
285
- // A package name with a comma forces RFC-4180 quoting.
286
- { callerPackage: 'odd,pkg', calleePackage: 'cli', count: 1 },
287
- // A scoped package starts with '@' — a CSV/formula-injection trigger
288
- // that must be neutralized with a leading apostrophe.
289
- { callerPackage: '@scope/pkg', calleePackage: 'cli', count: 4 },
290
- ],
291
- },
292
- };
293
- const env = loadEnv(catalog);
294
- const c = document.createElement('div');
295
- env.views
296
- .find((v) => v.id === 'coupling')
297
- .render(c, env.graphCatalog, env.graphIndexes, env.filterState);
298
- // Capture the Blob the download path hands to URL.createObjectURL.
299
- const createSpy = vi.spyOn(URL, 'createObjectURL').mockReturnValue('blob:mock');
300
- const revokeSpy = vi.spyOn(URL, 'revokeObjectURL').mockImplementation(() => undefined);
301
- const btn = c.querySelector('.coupling-export-btn');
302
- btn.dispatchEvent(new MouseEvent('click', { bubbles: true }));
303
- expect(createSpy).toHaveBeenCalledTimes(1);
304
- const blob = createSpy.mock.calls[0][0];
305
- createSpy.mockRestore();
306
- revokeSpy.mockRestore();
307
- return blob.text().then((text) => {
308
- const lines = text.split('\n');
309
- // Wide matrix: a corner cell + one column per callee package, sorted.
310
- // Package set + sort match the table: ['@scope/pkg','cli','contracts','odd,pkg'].
311
- expect(lines[0].startsWith('caller')).toBe(true);
312
- // The '@'-scoped header is apostrophe-guarded; the comma-bearing one quoted.
313
- expect(lines[0]).toContain('\'@scope/pkg,cli,contracts,"odd,pkg"');
314
- // One row per caller (every package), cells are the directed counts (0 = none).
315
- expect(lines).toContain("'@scope/pkg,0,4,0,0");
316
- expect(lines).toContain('cli,0,2,3,0');
317
- expect(lines).toContain('contracts,0,0,0,0');
318
- expect(lines).toContain('"odd,pkg",0,1,0,0');
319
- // 1 header + 4 caller rows (full N×N, no truncation).
320
- expect(lines.length).toBe(5);
321
- });
322
- });
323
- it('shows the no-data empty state when the catalog carries no edge feature', () => {
324
- const catalog = {
325
- version: '2.0',
326
- tool: 'graph',
327
- language: 'typescript',
328
- builtAt: 'now',
329
- functions: {
330
- a: [
331
- makeOcc({
332
- bodyHash: 'a',
333
- simpleName: 'a',
334
- filePath: 'packages/cli/src/a.ts',
335
- calls: [
336
- {
337
- to: ['x'],
338
- line: 1,
339
- column: 0,
340
- resolution: 'static',
341
- confidence: 'high',
342
- text: 'x()',
343
- },
344
- ],
345
- }),
346
- ],
347
- x: [makeOcc({ bodyHash: 'x', simpleName: 'x', filePath: 'packages/contracts/src/x.ts' })],
348
- },
349
- // No features blob (a non-dashboard run) ⇒ no client recompute, no-data state.
350
- };
351
- const env = loadEnv(catalog);
352
- const c = document.createElement('div');
353
- env.views
354
- .find((v) => v.id === 'coupling')
355
- .render(c, env.graphCatalog, env.graphIndexes, env.filterState);
356
- expect(c.querySelector('.empty')).not.toBeNull();
357
- expect(c.querySelector('td.coupling-cell')).toBeNull();
358
- });
359
- });
360
- //# sourceMappingURL=dashboard-view-coupling.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"dashboard-view-coupling.test.js","sourceRoot":"","sources":["../../src/__tests__/dashboard-view-coupling.test.ts"],"names":[],"mappings":"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"}
@@ -1,10 +0,0 @@
1
- /**
2
- * @vitest-environment jsdom
3
- *
4
- * Functions (distribution) view — the ranked-distribution affordance that
5
- * also hosts the in-table name filter folded in from the former standalone
6
- * Search subtab. Verifies the search input renders above the table and
7
- * re-filters the rows in place by function simple-name.
8
- */
9
- export {};
10
- //# sourceMappingURL=dashboard-view-distribution.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"dashboard-view-distribution.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/dashboard-view-distribution.test.ts"],"names":[],"mappings":"AACA;;;;;;;GAOG"}
@@ -1,249 +0,0 @@
1
- /// <reference lib="dom" />
2
- /**
3
- * @vitest-environment jsdom
4
- *
5
- * Functions (distribution) view — the ranked-distribution affordance that
6
- * also hosts the in-table name filter folded in from the former standalone
7
- * Search subtab. Verifies the search input renders above the table and
8
- * re-filters the rows in place by function simple-name.
9
- */
10
- import { describe, expect, it, beforeEach } from 'vitest';
11
- import { DASHBOARD_CLIENT_BUNDLE } from '../client-bundle.generated.js';
12
- function loadEnv(catalog) {
13
- // The distribution view (and the whole Code Paths panel + prelude) now lives
14
- // in the typed client bundle (L4): loading the bundle registers the view into
15
- // the bundle's `views` global at IIFE eval. Declare the page globals the
16
- // bundle reads (sessions, EDITOR_PROTOCOL, graphCatalog, graphIndexes); seed
17
- // graphCatalog/graphIndexes after the bundle has defined `buildIndexes`.
18
- const head = `
19
- var sessions = [];
20
- var EDITOR_PROTOCOL = null;
21
- var graphCatalog = null;
22
- var graphIndexes = null;
23
- `;
24
- const tail = `
25
- graphCatalog = ${JSON.stringify(catalog)};
26
- graphIndexes = buildIndexes(graphCatalog);
27
- return { views, graphCatalog, graphIndexes, filterState };
28
- `;
29
- // eslint-disable-next-line @typescript-eslint/no-implied-eval, sonarjs/code-eval -- Trusted source: our own bundled dashboard JS.
30
- const factory = new Function(head + DASHBOARD_CLIENT_BUNDLE + tail);
31
- return factory();
32
- }
33
- function makeOcc(over) {
34
- return {
35
- qualifiedName: over.simpleName,
36
- line: 1,
37
- column: 0,
38
- endLine: 5,
39
- kind: 'function-declaration',
40
- params: [],
41
- returnType: null,
42
- enclosingClass: null,
43
- decorators: [],
44
- visibility: 'exported',
45
- inTestFile: false,
46
- definedInGenerated: false,
47
- calls: [],
48
- ...over,
49
- };
50
- }
51
- const catalog = {
52
- version: '2.0',
53
- tool: 'graph',
54
- language: 'typescript',
55
- builtAt: 'now',
56
- functions: {
57
- a: [makeOcc({ bodyHash: 'a', simpleName: 'validateInput', filePath: 'packages/cli/src/a.ts' })],
58
- b: [makeOcc({ bodyHash: 'b', simpleName: 'renderTable', filePath: 'packages/cli/src/b.ts' })],
59
- c: [makeOcc({ bodyHash: 'c', simpleName: 'parseConfig', filePath: 'packages/cli/src/c.ts' })],
60
- },
61
- };
62
- function renderDistribution() {
63
- const env = loadEnv(catalog);
64
- const view = document.createElement('div');
65
- env.views
66
- .find((v) => v.id === 'distribution')
67
- .render(view, env.graphCatalog, env.graphIndexes, env.filterState);
68
- return { view };
69
- }
70
- beforeEach(() => {
71
- document.body.innerHTML = '';
72
- });
73
- describe('Functions (distribution) view', () => {
74
- it('renders a name-filter search input above the table', () => {
75
- const { view } = renderDistribution();
76
- const input = view.querySelector('#code-paths-search-distribution');
77
- expect(input).not.toBeNull();
78
- // The input must precede the rendered table in document order.
79
- const firstRow = view.querySelector('[data-body-hash]');
80
- expect(firstRow).not.toBeNull();
81
- expect(input.compareDocumentPosition(firstRow) & Node.DOCUMENT_POSITION_FOLLOWING).toBeTruthy();
82
- });
83
- it('shows every function before any filtering', () => {
84
- const { view } = renderDistribution();
85
- expect(view.querySelectorAll('[data-body-hash]').length).toBe(3);
86
- });
87
- it('re-filters rows in place by simple-name substring', () => {
88
- const { view } = renderDistribution();
89
- const input = view.querySelector('#code-paths-search-distribution');
90
- input.value = 'parse';
91
- input.dispatchEvent(new Event('input', { bubbles: true }));
92
- const rows = view.querySelectorAll('[data-body-hash]');
93
- expect(rows.length).toBe(1);
94
- expect(view.textContent).toContain('parseConfig');
95
- expect(view.textContent).not.toContain('validateInput');
96
- });
97
- it('collapses to the empty state when nothing matches, and restores on clear', () => {
98
- const { view } = renderDistribution();
99
- const input = view.querySelector('#code-paths-search-distribution');
100
- input.value = 'zzz-no-such-name';
101
- input.dispatchEvent(new Event('input', { bubbles: true }));
102
- expect(view.querySelectorAll('[data-body-hash]').length).toBe(0);
103
- expect(view.querySelector('.empty')).not.toBeNull();
104
- input.value = '';
105
- input.dispatchEvent(new Event('input', { bubbles: true }));
106
- expect(view.querySelectorAll('[data-body-hash]').length).toBe(3);
107
- });
108
- it('renders the "Functions (N)" heading with ⓘ ABOVE the controls (like Coupling/Visualization)', () => {
109
- const { view } = renderDistribution();
110
- const heading = view.querySelector('h3');
111
- const info = view.querySelector('.section-info');
112
- const controls = view.querySelector('.code-paths-ranked-controls');
113
- expect(heading).not.toBeNull();
114
- expect(heading.textContent).toContain('Functions (3)'); // 3 functions in the sample
115
- expect(info).not.toBeNull();
116
- expect(controls).not.toBeNull();
117
- // The heading must precede the controls row in document order.
118
- expect(heading.compareDocumentPosition(controls) & Node.DOCUMENT_POSITION_FOLLOWING).toBeTruthy();
119
- });
120
- it('updates the heading count as the filter narrows the rows', () => {
121
- const { view } = renderDistribution();
122
- const input = view.querySelector('#code-paths-search-distribution');
123
- input.value = 'parse';
124
- input.dispatchEvent(new Event('input', { bubbles: true }));
125
- expect(view.querySelector('h3').textContent).toContain('Functions (1)');
126
- });
127
- it('renders Kind and Package single-select dropdowns before the search box', () => {
128
- const { view } = renderDistribution();
129
- const kind = view.querySelector('select[data-control="fn-kind"]');
130
- const pkg = view.querySelector('select[data-control="fn-package"]');
131
- const search = view.querySelector('#code-paths-search-distribution');
132
- expect(kind).not.toBeNull();
133
- expect(pkg).not.toBeNull();
134
- // Defaults select "all".
135
- expect(kind.value).toBe('');
136
- expect(pkg.value).toBe('');
137
- expect(kind.options[0].textContent).toBe('All kinds');
138
- expect(pkg.options[0].textContent).toBe('All packages');
139
- // Order in the controls row: Kind, Package, then the search box.
140
- expect(kind.compareDocumentPosition(pkg) & Node.DOCUMENT_POSITION_FOLLOWING).toBeTruthy();
141
- expect(pkg.compareDocumentPosition(search) & Node.DOCUMENT_POSITION_FOLLOWING).toBeTruthy();
142
- });
143
- it('filters the table by the selected Package', () => {
144
- const env = loadEnv({
145
- version: '2.0',
146
- tool: 'graph',
147
- language: 'typescript',
148
- builtAt: 'now',
149
- functions: {
150
- a: [
151
- makeOcc({
152
- bodyHash: 'a',
153
- simpleName: 'validateInput',
154
- filePath: 'packages/cli/src/a.ts',
155
- }),
156
- ],
157
- z: [
158
- makeOcc({
159
- bodyHash: 'z',
160
- simpleName: 'ztarget',
161
- filePath: 'packages/contracts/src/z.ts',
162
- }),
163
- ],
164
- },
165
- });
166
- const view = document.createElement('div');
167
- env.views
168
- .find((v) => v.id === 'distribution')
169
- .render(view, env.graphCatalog, env.graphIndexes, env.filterState);
170
- expect(view.querySelectorAll('[data-body-hash]').length).toBe(2);
171
- const pkg = view.querySelector('select[data-control="fn-package"]');
172
- pkg.value = 'contracts';
173
- pkg.dispatchEvent(new Event('change', { bubbles: true }));
174
- const rows = view.querySelectorAll('[data-body-hash]');
175
- expect(rows.length).toBe(1);
176
- expect(view.textContent).toContain('ztarget');
177
- expect(view.textContent).not.toContain('validateInput');
178
- });
179
- it('no longer renders a "Test-only" column', () => {
180
- const { view } = renderDistribution();
181
- const headers = [...view.querySelectorAll('th')].map((th) => th.textContent);
182
- expect(headers).not.toContain('Test-only');
183
- });
184
- it('the "Test-only" toggle narrows the table to test-only functions', () => {
185
- const edge = {
186
- line: 1,
187
- column: 0,
188
- resolution: 'static',
189
- confidence: 'high',
190
- text: 'x()',
191
- };
192
- const env = loadEnv({
193
- version: '2.0',
194
- tool: 'graph',
195
- language: 'typescript',
196
- builtAt: 'now',
197
- functions: {
198
- // Production fn reached ONLY from a test file → test-only.
199
- prod: [
200
- makeOcc({ bodyHash: 'prod', simpleName: 'prodFn', filePath: 'packages/cli/src/prod.ts' }),
201
- ],
202
- // Production fn reached from production code → not test-only.
203
- normal: [
204
- makeOcc({
205
- bodyHash: 'normal',
206
- simpleName: 'normalFn',
207
- filePath: 'packages/cli/src/normal.ts',
208
- }),
209
- ],
210
- normalCaller: [
211
- makeOcc({
212
- bodyHash: 'normalCaller',
213
- simpleName: 'callerFn',
214
- filePath: 'packages/cli/src/nc.ts',
215
- calls: [{ to: ['normal'], ...edge }],
216
- }),
217
- ],
218
- // A test-file fn that calls prod (excluded from the table by production-only default).
219
- testFn: [
220
- makeOcc({
221
- bodyHash: 'testFn',
222
- simpleName: 'testFn',
223
- filePath: 'packages/cli/src/__tests__/t.test.ts',
224
- inTestFile: true,
225
- calls: [{ to: ['prod'], ...edge }],
226
- }),
227
- ],
228
- },
229
- });
230
- const view = document.createElement('div');
231
- env.views
232
- .find((v) => v.id === 'distribution')
233
- .render(view, env.graphCatalog, env.graphIndexes, env.filterState);
234
- // Production-only by default (testFn lives in a test file) → 3 rows.
235
- expect(view.querySelectorAll('[data-body-hash]').length).toBe(3);
236
- const toggle = view.querySelector('input[data-control="fn-toggle"]');
237
- expect(toggle).not.toBeNull();
238
- // The toggle renders after the search box.
239
- const search = view.querySelector('#code-paths-search-distribution');
240
- expect(search.compareDocumentPosition(toggle) & Node.DOCUMENT_POSITION_FOLLOWING).toBeTruthy();
241
- toggle.checked = true;
242
- toggle.dispatchEvent(new Event('change', { bubbles: true }));
243
- // Only the test-only production function remains.
244
- expect(view.querySelectorAll('[data-body-hash]').length).toBe(1);
245
- expect(view.textContent).toContain('prodFn');
246
- expect(view.textContent).not.toContain('normalFn');
247
- });
248
- });
249
- //# sourceMappingURL=dashboard-view-distribution.test.js.map