@canyonjs/report-component 0.0.3 → 0.0.5

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/index.css CHANGED
@@ -87,3 +87,84 @@
87
87
  margin-right: 5px;
88
88
  }
89
89
 
90
+ /* CoverageDetail 样式 */
91
+ .canyonjs-report-html .canyon-coverage-detail-container {
92
+ height: 100%;
93
+ position: relative;
94
+ }
95
+
96
+ .canyonjs-report-html .canyon-coverage-detail-editor {
97
+ width: 100%;
98
+ height: 100%;
99
+ }
100
+
101
+ /* ChangedCodeCoverageTable 折叠表格样式 */
102
+ .canyonjs-report-html .canyon-changed-code-coverage-table {
103
+ position: absolute;
104
+ top: 0;
105
+ left: 0;
106
+ right: 0;
107
+ z-index: 1000;
108
+ }
109
+
110
+ .canyonjs-report-html .canyon-changed-code-coverage-toggle {
111
+ position: absolute;
112
+ top: 0;
113
+ left: 0;
114
+ right: 0;
115
+ padding: 8px 16px;
116
+ background: #f5f5f5;
117
+ border: none;
118
+ border-bottom: 1px solid #e0e0e0;
119
+ color: #333333;
120
+ font-size: 13px;
121
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
122
+ cursor: pointer;
123
+ text-align: left;
124
+ display: flex;
125
+ align-items: center;
126
+ z-index: 1001;
127
+ transition: background 0.2s ease;
128
+ }
129
+
130
+ .canyonjs-report-html .canyon-changed-code-coverage-toggle:hover {
131
+ background: #e8e8e8;
132
+ }
133
+
134
+ .canyonjs-report-html .canyon-changed-code-coverage-icon {
135
+ margin-right: 8px;
136
+ }
137
+
138
+ .canyonjs-report-html .canyon-changed-code-coverage-arrow {
139
+ margin-left: 8px;
140
+ transition: transform 0.3s ease;
141
+ }
142
+
143
+ .canyonjs-report-html .canyon-changed-code-coverage-content {
144
+ position: absolute;
145
+ top: 33px;
146
+ left: 0;
147
+ right: 0;
148
+ max-height: 0;
149
+ overflow: hidden;
150
+ background: #ffffff;
151
+ border-bottom: 1px solid #e0e0e0;
152
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
153
+ z-index: 1000;
154
+ transition: max-height 0.3s ease;
155
+ }
156
+
157
+ .canyonjs-report-html .canyon-changed-code-coverage-table-wrapper {
158
+ padding: 16px;
159
+ background: #ffffff;
160
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
161
+ overflow: auto;
162
+ max-height: 300px;
163
+ }
164
+
165
+ .canyonjs-report-html .canyon-changed-code-coverage-table-title {
166
+ font-weight: bold;
167
+ font-size: 14px;
168
+ color: #007acc;
169
+ margin-bottom: 12px;
170
+ }
package/dist/index.js CHANGED
@@ -205,6 +205,142 @@ function coreFn(fileCoverage, fileDetail) {
205
205
  };
206
206
  }
207
207
 
208
+ //#endregion
209
+ //#region src/widgets/ChangedCodeCoverageTable.tsx
210
+ const ChangedCodeCoverageTable = ({ coverage, addLines }) => {
211
+ console.log("coverage", coverage);
212
+ console.log("addLines", addLines);
213
+ const [isOpen, setIsOpen] = useState(false);
214
+ const relatedStatements = useMemo(() => {
215
+ if (addLines.length === 0 || !coverage.s || !coverage.statementMap) return [];
216
+ const addedLinesSet = new Set(addLines);
217
+ const statements = [];
218
+ Object.entries(coverage.statementMap).forEach(([stId, meta]) => {
219
+ const startLine = meta.start.line;
220
+ const endLine = meta.end.line;
221
+ const startCol = meta.start.column;
222
+ const endCol = meta.end.column;
223
+ const relatedLines = [];
224
+ for (let line = startLine; line <= endLine; line++) if (addedLinesSet.has(line)) relatedLines.push(line);
225
+ if (relatedLines.length > 0) {
226
+ const count = coverage.s[stId] || 0;
227
+ const covered = count > 0;
228
+ const locationDisplay = endLine > startLine ? `${startLine}:${startCol + 1} - ${endLine}:${endCol + 1}` : `${startLine}:${startCol + 1}`;
229
+ const relatedLinesDisplay = relatedLines.join(", ");
230
+ statements.push({
231
+ key: stId,
232
+ Status: covered ? "✓ Covered" : "✗ Not Covered",
233
+ Location: locationDisplay,
234
+ "Changed Lines": relatedLinesDisplay,
235
+ "Hit Count": covered ? `${count}x` : "Not covered"
236
+ });
237
+ }
238
+ });
239
+ statements.sort((a, b) => {
240
+ return parseInt(a.Location.split(":")[0] || "0") - parseInt(b.Location.split(":")[0] || "0");
241
+ });
242
+ return statements;
243
+ }, [addLines, coverage]);
244
+ const coverageStats = useMemo(() => {
245
+ if (relatedStatements.length === 0) return {
246
+ coveredCount: 0,
247
+ totalCount: 0,
248
+ coveragePercent: 0
249
+ };
250
+ const coveredCount = relatedStatements.filter((s) => s.Status.includes("✓")).length;
251
+ const totalCount = relatedStatements.length;
252
+ return {
253
+ coveredCount,
254
+ totalCount,
255
+ coveragePercent: totalCount > 0 ? Math.round(coveredCount / totalCount * 100) : 0
256
+ };
257
+ }, [relatedStatements]);
258
+ if (relatedStatements.length === 0) return null;
259
+ return /* @__PURE__ */ jsxs("div", {
260
+ className: "canyon-changed-code-coverage-table",
261
+ children: [/* @__PURE__ */ jsxs("button", {
262
+ className: "canyon-changed-code-coverage-toggle",
263
+ onClick: () => setIsOpen(!isOpen),
264
+ type: "button",
265
+ children: [
266
+ /* @__PURE__ */ jsx("span", {
267
+ className: "canyon-changed-code-coverage-icon",
268
+ children: "📊"
269
+ }),
270
+ /* @__PURE__ */ jsxs("span", { children: [
271
+ "Changed Code Coverage: ",
272
+ coverageStats.coveragePercent,
273
+ "% (",
274
+ coverageStats.coveredCount,
275
+ "/",
276
+ coverageStats.totalCount,
277
+ ")"
278
+ ] }),
279
+ /* @__PURE__ */ jsx("span", {
280
+ className: "canyon-changed-code-coverage-arrow",
281
+ children: isOpen ? "▲" : "▼"
282
+ })
283
+ ]
284
+ }), /* @__PURE__ */ jsx("div", {
285
+ className: "canyon-changed-code-coverage-content",
286
+ style: { maxHeight: isOpen ? "350px" : "0" },
287
+ children: /* @__PURE__ */ jsxs("div", {
288
+ className: "canyon-changed-code-coverage-table-wrapper",
289
+ children: [/* @__PURE__ */ jsxs("div", {
290
+ className: "canyon-changed-code-coverage-table-title",
291
+ children: [
292
+ "Changed Code Statements (",
293
+ coverageStats.totalCount,
294
+ ") - Coverage:",
295
+ " ",
296
+ coverageStats.coveragePercent,
297
+ "% (",
298
+ coverageStats.coveredCount,
299
+ "/",
300
+ coverageStats.totalCount,
301
+ ")"
302
+ ]
303
+ }), /* @__PURE__ */ jsx(ConfigProvider, {
304
+ theme: { token: { borderRadius: 0 } },
305
+ children: /* @__PURE__ */ jsx(Table, {
306
+ dataSource: relatedStatements,
307
+ columns: [
308
+ {
309
+ title: "Status",
310
+ dataIndex: "Status",
311
+ key: "Status",
312
+ render: (text) => /* @__PURE__ */ jsx("span", {
313
+ style: { color: text.includes("✓") ? "#4caf50" : "#f44336" },
314
+ children: text
315
+ })
316
+ },
317
+ {
318
+ title: "Location",
319
+ dataIndex: "Location",
320
+ key: "Location"
321
+ },
322
+ {
323
+ title: "Changed Lines",
324
+ dataIndex: "Changed Lines",
325
+ key: "Changed Lines"
326
+ },
327
+ {
328
+ title: "Hit Count",
329
+ dataIndex: "Hit Count",
330
+ key: "Hit Count"
331
+ }
332
+ ],
333
+ pagination: false,
334
+ size: "small",
335
+ bordered: true
336
+ })
337
+ })]
338
+ })
339
+ })]
340
+ });
341
+ };
342
+ var ChangedCodeCoverageTable_default = ChangedCodeCoverageTable;
343
+
208
344
  //#endregion
209
345
  //#region src/widgets/lineNumbers.tsx
210
346
  function genBgColor(hit) {
@@ -264,6 +400,8 @@ function lineNumbers(lineNumber, linesState, _addLines) {
264
400
  const CoverageDetail = ({ source, coverage, diff }) => {
265
401
  const { lines } = coreFn(coverage, source);
266
402
  const addLines = diff.additions || [];
403
+ const ref = useRef(null);
404
+ const hasChangedLines = addLines.length > 0 && coverage["s"] && coverage["statementMap"];
267
405
  const linesState = (() => {
268
406
  return lines.map((line, index) => {
269
407
  return {
@@ -276,7 +414,6 @@ const CoverageDetail = ({ source, coverage, diff }) => {
276
414
  const lineNumbersMinChars = (() => {
277
415
  return Math.max(...linesState.map((line) => line.hit)).toString().length + 8;
278
416
  })();
279
- const ref = useRef(null);
280
417
  useEffect(() => {
281
418
  if (ref.current) {
282
419
  const dom = ref.current;
@@ -345,10 +482,27 @@ const CoverageDetail = ({ source, coverage, diff }) => {
345
482
  if (editor) editor?.createDecorationsCollection?.(decorations);
346
483
  }
347
484
  }
348
- }, [source]);
349
- return /* @__PURE__ */ jsx("div", {
350
- ref,
351
- style: { height: "100%" }
485
+ }, [source, coverage]);
486
+ return /* @__PURE__ */ jsxs("div", {
487
+ className: "canyon-coverage-detail-container",
488
+ style: {
489
+ height: "100%",
490
+ position: "relative"
491
+ },
492
+ children: [hasChangedLines ? /* @__PURE__ */ jsx(ChangedCodeCoverageTable_default, {
493
+ coverage,
494
+ addLines
495
+ }) : null, /* @__PURE__ */ jsx("div", {
496
+ ref,
497
+ className: "canyon-coverage-detail-editor",
498
+ style: {
499
+ height: hasChangedLines ? "calc(100% - 33px)" : "100%",
500
+ top: hasChangedLines ? "33px" : "0",
501
+ position: "absolute",
502
+ left: 0,
503
+ right: 0
504
+ }
505
+ })]
352
506
  });
353
507
  };
354
508
  var CoverageDetail_default = CoverageDetail;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@canyonjs/report-component",
3
3
  "type": "module",
4
- "version": "0.0.3",
4
+ "version": "0.0.5",
5
5
  "author": "Travis Zhang<https://github.com/travzhang>",
6
6
  "repository": {
7
7
  "type": "git",