@51jbs/incremental-coverage-plugin 1.0.1

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Chuanjing Li
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,59 @@
1
+ # 增量覆盖率插件 (Incremental Coverage Plugin)
2
+
3
+ > 🎯 **核心目标**: 精准追踪代码变更后的覆盖率情况,为研发自测提供量化数据支撑。
4
+
5
+ 本插件基于 `babel-plugin-istanbul` 和 `istanbul-diff`,通过集成 Git 差异分析,自动计算自测过程中的增量覆盖率。
6
+
7
+ ## ✨ 核心价值
8
+
9
+ - **🚀 聚焦变更**: 告别冗长的全量覆盖率报告,核心关注你改动的那几行代码。
10
+ - **🛡 质量契约**: 设置增量覆盖率阈值,作为代码合并与上线的硬性质量指标。
11
+ - **🔗 一站式集成**: 深度集成 Git,自动解析 Diff 提取新增行号,无需手动干预。
12
+ - **🔋 生产就绪**: 具备防抖上报、故障重试及报告自动清理机制,保障构建链路稳定。
13
+
14
+ ## 🏗️ 核心模块
15
+
16
+ | 模块 | 职责 |
17
+ |------|------|
18
+ | **CoverageCollector** | 负责浏览器端数据的收集与内存合并 |
19
+ | **CoverageDiffer** | 使用 istanbul-diff 计算基准与当前的差异 |
20
+ | **GitService** | 自动提取 Git Diff 变更行号 |
21
+ | **CoverageReporter** | 生成可视化 HTML 报告与 JSON 结构化数据 |
22
+
23
+ ## 📦 安装
24
+
25
+ ### 前置要求
26
+
27
+ - Node.js >= 16.0.0
28
+ - Git 仓库(必需)
29
+ - **Webpack 4 或 5**(完全支持)
30
+ - **webpack-dev-server 3.x 或 4.x**(自动适配)
31
+
32
+ ### 快速安装
33
+
34
+ ```bash
35
+ npm install @51jbs/incremental-coverage-plugin --save-dev
36
+ ```
37
+
38
+ ### 验证安装
39
+
40
+ ```bash
41
+ npm ls @51jbs/incremental-coverage-plugin
42
+ ```
43
+
44
+ > 💡 **提示**:插件已内置所有必要依赖(包括 `@babel/core`、`istanbul-lib-*`),无需额外安装。
45
+
46
+ ## 📚 快速导航
47
+
48
+ - [**安装指南**](./docs/installation.md): 详细的安装步骤和前置要求检查。
49
+ - [**快速开始**](./docs/quick-start.md): 15 分钟完成 Webpack 项目接入。
50
+ - [**功能特性**](./docs/features.md): 深入了解增量计算与生产级保护机制。
51
+ - [**故障排查**](./docs/troubleshooting.md): 常见问题诊断和解决方案。
52
+ - [**技术架构**](./docs/architecture.md): 查看整体设计方案与时序图。
53
+ - [**API 参考**](./docs/api.md): 查看详细的配置项说明。
54
+
55
+ ---
56
+
57
+ ## 📄 许可证
58
+
59
+ 本项目采用 [MIT](https://github.com/chuanjing729-glitch/fe-workspace/blob/main/packages/incremental-coverage-plugin/LICENSE) 许可证发布。
@@ -0,0 +1,314 @@
1
+ import * as unplugin from 'unplugin';
2
+ import { I as IncrementalCoverageOptions, C as CoverageMap, a as IncrementalCoverageResult, G as GitDiffResult } from './types-PPxtKDSr.mjs';
3
+
4
+ /**
5
+ * Incremental Coverage Plugin
6
+ *
7
+ * 轻量级增量覆盖率插件,基于以下技术:
8
+ * - babel-plugin-istanbul: 代码插桩
9
+ * - istanbul-diff: 增量覆盖率计算
10
+ * - unplugin: 多构建工具支持
11
+ *
12
+ * @example
13
+ * // Webpack
14
+ * new WebpackIncrementalCoveragePlugin({ include: ['src/**'] })
15
+ *
16
+ * // Vite
17
+ * ViteIncrementalCoveragePlugin({ include: ['src/**'] })
18
+ */
19
+ declare const IncrementalCoveragePlugin: unplugin.UnpluginInstance<IncrementalCoverageOptions | undefined, boolean>;
20
+
21
+ /**
22
+ * 覆盖率收集器
23
+ *
24
+ * 负责接收和合并来自浏览器的覆盖率数据
25
+ * 维护全局的覆盖率状态,支持多次上报的数据累加
26
+ *
27
+ * @module collector
28
+ */
29
+
30
+ /**
31
+ * Coverage Collector - 覆盖率收集器
32
+ *
33
+ * 核心职责:
34
+ * 1. 接收浏览器上报的覆盖率数据
35
+ * 2. 合并多次上报的数据(累加执行次数)
36
+ * 3. 维护全局覆盖率状态
37
+ *
38
+ * @example
39
+ * const collector = new CoverageCollector();
40
+ * const merged = collector.merge(newCoverageData);
41
+ */
42
+ declare class CoverageCollector {
43
+ /**
44
+ * 全局覆盖率映射表
45
+ *
46
+ * 键是文件路径,值是该文件的覆盖率数据
47
+ * 这个对象会随着数据上报不断更新
48
+ */
49
+ private coverageMap;
50
+ /**
51
+ * 合并新的覆盖率数据
52
+ *
53
+ * 算法说明:
54
+ * 1. 遍历新数据中的每个文件
55
+ * 2. 如果是首次出现的文件,直接存储
56
+ * 3. 如果文件已存在,合并执行次数(累加)
57
+ *
58
+ * 为什么要累加?
59
+ * - 用户可能多次执行同一段代码
60
+ * - 需要记录总的执行次数,而不是覆盖
61
+ *
62
+ * @param newCoverage - 新上报的覆盖率数据
63
+ * @returns 合并后的完整覆盖率数据
64
+ *
65
+ * @example
66
+ * // 第一次上报
67
+ * collector.merge({ 'src/utils.ts': { s: { '0': 1 } } });
68
+ * // 第二次上报(同一文件)
69
+ * collector.merge({ 'src/utils.ts': { s: { '0': 2 } } });
70
+ * // 结果:s['0'] = 3(累加)
71
+ */
72
+ merge(newCoverage: CoverageMap): CoverageMap;
73
+ /**
74
+ * 获取当前的覆盖率数据
75
+ *
76
+ * @returns 当前的完整覆盖率映射表
77
+ */
78
+ getCoverage(): CoverageMap;
79
+ /**
80
+ * 重置覆盖率数据
81
+ *
82
+ * 清空所有已收集的数据,重新开始
83
+ * 通常在需要重新计算覆盖率时使用
84
+ */
85
+ reset(): void;
86
+ /**
87
+ * 合并两个覆盖率数据对象
88
+ *
89
+ * 合并策略:
90
+ * 1. 语句覆盖(s):执行次数累加
91
+ * 2. 函数覆盖(f):执行次数累加
92
+ * 3. 分支覆盖(b):数组元素逐个累加
93
+ *
94
+ * 注意:
95
+ * - statementMap、fnMap、branchMap 不需要合并(它们是静态的位置信息)
96
+ * - 只有执行次数(s、f、b)需要累加
97
+ *
98
+ * @param existing - 已存在的覆盖率数据
99
+ * @param newData - 新的覆盖率数据
100
+ * @returns 合并后的覆盖率数据
101
+ *
102
+ * @private
103
+ */
104
+ private mergeCoverageData;
105
+ }
106
+
107
+ /**
108
+ * 覆盖率差异计算器
109
+ *
110
+ * 负责计算增量覆盖率,这是插件的核心模块
111
+ *
112
+ * 工作流程:
113
+ * 1. 加载 baseline 覆盖率(参考基准)
114
+ * 2. 使用 istanbul-diff 计算差异
115
+ * 3. 结合 Git diff 获取变更的文件和行号
116
+ * 4. 计算每个变更文件的覆盖率
117
+ * 5. 汇总整体覆盖率
118
+ * 6. 保存新的 baseline(可选)
119
+ *
120
+ * @module differ
121
+ */
122
+
123
+ /**
124
+ * Coverage Differ - 覆盖率差异计算器
125
+ *
126
+ * 核心职责:
127
+ * 1. 管理 baseline 覆盖率(加载/保存)
128
+ * 2. 使用 istanbul-diff 计算覆盖率差异
129
+ * 3. 结合 Git diff 确定需要检查的代码行
130
+ * 4. 计算增量覆盖率百分比
131
+ *
132
+ * @example
133
+ * const differ = new CoverageDiffer(options);
134
+ * const result = await differ.calculate(currentCoverage);
135
+ */
136
+ declare class CoverageDiffer {
137
+ private options;
138
+ constructor(options: IncrementalCoverageOptions);
139
+ /**
140
+ * 计算增量覆盖率
141
+ *
142
+ * 这是最核心的方法,完整的计算流程:
143
+ *
144
+ * 1. 加载 baseline(如果存在)
145
+ * 2. 使用 istanbul-diff 计算差异
146
+ * 3. 获取 Git 变更的文件和行号
147
+ * 4. 对每个变更文件:
148
+ * a. 获取该文件的覆盖率数据
149
+ * b. 找出变更的行号
150
+ * c. 检查这些行是否被覆盖
151
+ * d. 计算覆盖率百分比
152
+ * 5. 汇总所有文件的覆盖率
153
+ * 6. 保存新的 baseline(如果需要)
154
+ *
155
+ * @param currentCoverage - 当前的覆盖率数据
156
+ * @returns 增量覆盖率计算结果
157
+ *
158
+ * @example
159
+ * const result = await differ.calculate(coverageMap);
160
+ * console.log(`Overall coverage: ${result.overall.coverageRate}%`);
161
+ */
162
+ calculate(currentCoverage: CoverageMap): Promise<IncrementalCoverageResult>;
163
+ /**
164
+ * 从文件加载 baseline 覆盖率
165
+ *
166
+ * Baseline 是参考基准,用于对比当前覆盖率的变化
167
+ * 通常在首次运行时创建,之后保持不变(除非手动更新)
168
+ *
169
+ * @returns baseline 覆盖率数据,如果文件不存在则返回 null
170
+ * @private
171
+ */
172
+ private loadBaseline;
173
+ /**
174
+ * 保存 baseline 覆盖率到文件
175
+ *
176
+ * 将当前的覆盖率数据保存为 baseline,供后续对比使用
177
+ *
178
+ * 注意:
179
+ * - 会自动创建目录(如果不存在)
180
+ * - 使用 JSON 格式,便于查看和调试
181
+ * - 格式化输出(2 空格缩进)
182
+ *
183
+ * @param coverage - 要保存的覆盖率数据
184
+ * @private
185
+ */
186
+ private saveBaseline;
187
+ /**
188
+ * 获取未覆盖的行号列表
189
+ *
190
+ * 算法说明:
191
+ * 1. 遍历每一个变更的行号
192
+ * 2. 检查是否有语句(statement)覆盖这一行
193
+ * 3. 如果有语句覆盖且执行次数 > 0,则该行被覆盖
194
+ * 4. 否则,该行未被覆盖
195
+ *
196
+ * 为什么检查 statementMap?
197
+ * - Istanbul 的覆盖率是基于语句(statement)的
198
+ * - statementMap 记录了每个语句的位置(起始行、结束行)
199
+ * - 通过检查语句的位置,可以知道某一行是否被覆盖
200
+ *
201
+ * 为什么检查执行次数?
202
+ * - coverage.s[stmtId] 记录了语句的执行次数
203
+ * - 如果执行次数 > 0,说明这个语句被执行过
204
+ * - 如果执行次数 = 0,说明这个语句没有被执行
205
+ *
206
+ * @param coverage - 文件的覆盖率数据
207
+ * @param changedLines - 变更的行号列表
208
+ * @returns 未覆盖的行号列表
209
+ *
210
+ * @example
211
+ * const uncovered = this.getUncoveredLines(coverage, [10, 11, 12]);
212
+ * // 返回: [11] (假设第 11 行没有被覆盖)
213
+ *
214
+ * @private
215
+ */
216
+ private getUncoveredLines;
217
+ /**
218
+ * 判断是否为有效的源码文件
219
+ * 用于过滤 node_modules, lockfiles 和非源码文件
220
+ * @private
221
+ */
222
+ private isValidSourceFile;
223
+ }
224
+
225
+ /**
226
+ * 覆盖率报告生成器
227
+ *
228
+ * 负责生成各种格式的覆盖率报告
229
+ *
230
+ * 核心功能:
231
+ * 1. 生成 HTML 格式的可视化报告
232
+ * 2. 生成 JSON 格式的数据报告
233
+ * 3. 维护报告文件(最新报告、历史报告及自动清理)
234
+ *
235
+ * @module reporter
236
+ */
237
+
238
+ /**
239
+ * Coverage Reporter - 覆盖率报告生成器
240
+ */
241
+ declare class CoverageReporter {
242
+ private options;
243
+ private outputDir;
244
+ constructor(options: IncrementalCoverageOptions);
245
+ /**
246
+ * 生成增量覆盖率报告
247
+ *
248
+ * @param result 增量计算结果
249
+ * @returns 报告保存的路径
250
+ */
251
+ generate(result: IncrementalCoverageResult): Promise<string>;
252
+ /**
253
+ * 渲染 HTML 模板
254
+ *
255
+ * @param result 计算结果
256
+ * @private
257
+ */
258
+ private renderHtml;
259
+ /**
260
+ * 清理超出保留数量的历史报告
261
+ * @private
262
+ */
263
+ private cleanupOldReports;
264
+ }
265
+
266
+ /**
267
+ * Git 服务模块
268
+ *
269
+ * 负责与 Git 交互,获取代码变更信息
270
+ *
271
+ * 核心功能:
272
+ * 1. 获取变更的文件列表
273
+ * 2. 解析 Git diff 输出
274
+ * 3. 提取新增和删除的行号
275
+ *
276
+ * @module git
277
+ */
278
+
279
+ /**
280
+ * 获取 Git diff 信息
281
+ *
282
+ * 对比当前分支(HEAD)与指定基准分支的差异
283
+ * 返回变更的文件列表和具体的行号信息
284
+ *
285
+ * 工作流程:
286
+ * 1. 使用 git.diffSummary() 获取变更文件列表
287
+ * 2. 对每个文件使用 git.diff() 获取详细差异
288
+ * 3. 解析 diff 输出,提取行号
289
+ *
290
+ * @param base - 对比的基准分支(例如:'main', 'develop')
291
+ * @returns Git diff 结果,包含文件列表和行号信息
292
+ *
293
+ * @example
294
+ * const diff = await getGitDiff('main');
295
+ * console.log('Changed files:', diff.files);
296
+ * console.log('Added lines in file.ts:', diff.additions['file.ts']);
297
+ */
298
+ declare function getGitDiff(base?: string): Promise<GitDiffResult>;
299
+ /**
300
+ * 获取变更的文件列表
301
+ *
302
+ * 这是 getGitDiff 的简化版本,只返回文件列表
303
+ * 适用于只需要知道哪些文件变更了,不需要具体行号的场景
304
+ *
305
+ * @param base - 对比的基准分支
306
+ * @returns 变更的文件路径列表
307
+ *
308
+ * @example
309
+ * const files = await getChangedFiles('main');
310
+ * console.log('Changed files:', files);
311
+ */
312
+ declare function getChangedFiles(base?: string): Promise<string[]>;
313
+
314
+ export { CoverageCollector, CoverageDiffer, CoverageReporter, IncrementalCoverageOptions, IncrementalCoveragePlugin, getChangedFiles, getGitDiff };
@@ -0,0 +1,314 @@
1
+ import * as unplugin from 'unplugin';
2
+ import { I as IncrementalCoverageOptions, C as CoverageMap, a as IncrementalCoverageResult, G as GitDiffResult } from './types-PPxtKDSr.js';
3
+
4
+ /**
5
+ * Incremental Coverage Plugin
6
+ *
7
+ * 轻量级增量覆盖率插件,基于以下技术:
8
+ * - babel-plugin-istanbul: 代码插桩
9
+ * - istanbul-diff: 增量覆盖率计算
10
+ * - unplugin: 多构建工具支持
11
+ *
12
+ * @example
13
+ * // Webpack
14
+ * new WebpackIncrementalCoveragePlugin({ include: ['src/**'] })
15
+ *
16
+ * // Vite
17
+ * ViteIncrementalCoveragePlugin({ include: ['src/**'] })
18
+ */
19
+ declare const IncrementalCoveragePlugin: unplugin.UnpluginInstance<IncrementalCoverageOptions | undefined, boolean>;
20
+
21
+ /**
22
+ * 覆盖率收集器
23
+ *
24
+ * 负责接收和合并来自浏览器的覆盖率数据
25
+ * 维护全局的覆盖率状态,支持多次上报的数据累加
26
+ *
27
+ * @module collector
28
+ */
29
+
30
+ /**
31
+ * Coverage Collector - 覆盖率收集器
32
+ *
33
+ * 核心职责:
34
+ * 1. 接收浏览器上报的覆盖率数据
35
+ * 2. 合并多次上报的数据(累加执行次数)
36
+ * 3. 维护全局覆盖率状态
37
+ *
38
+ * @example
39
+ * const collector = new CoverageCollector();
40
+ * const merged = collector.merge(newCoverageData);
41
+ */
42
+ declare class CoverageCollector {
43
+ /**
44
+ * 全局覆盖率映射表
45
+ *
46
+ * 键是文件路径,值是该文件的覆盖率数据
47
+ * 这个对象会随着数据上报不断更新
48
+ */
49
+ private coverageMap;
50
+ /**
51
+ * 合并新的覆盖率数据
52
+ *
53
+ * 算法说明:
54
+ * 1. 遍历新数据中的每个文件
55
+ * 2. 如果是首次出现的文件,直接存储
56
+ * 3. 如果文件已存在,合并执行次数(累加)
57
+ *
58
+ * 为什么要累加?
59
+ * - 用户可能多次执行同一段代码
60
+ * - 需要记录总的执行次数,而不是覆盖
61
+ *
62
+ * @param newCoverage - 新上报的覆盖率数据
63
+ * @returns 合并后的完整覆盖率数据
64
+ *
65
+ * @example
66
+ * // 第一次上报
67
+ * collector.merge({ 'src/utils.ts': { s: { '0': 1 } } });
68
+ * // 第二次上报(同一文件)
69
+ * collector.merge({ 'src/utils.ts': { s: { '0': 2 } } });
70
+ * // 结果:s['0'] = 3(累加)
71
+ */
72
+ merge(newCoverage: CoverageMap): CoverageMap;
73
+ /**
74
+ * 获取当前的覆盖率数据
75
+ *
76
+ * @returns 当前的完整覆盖率映射表
77
+ */
78
+ getCoverage(): CoverageMap;
79
+ /**
80
+ * 重置覆盖率数据
81
+ *
82
+ * 清空所有已收集的数据,重新开始
83
+ * 通常在需要重新计算覆盖率时使用
84
+ */
85
+ reset(): void;
86
+ /**
87
+ * 合并两个覆盖率数据对象
88
+ *
89
+ * 合并策略:
90
+ * 1. 语句覆盖(s):执行次数累加
91
+ * 2. 函数覆盖(f):执行次数累加
92
+ * 3. 分支覆盖(b):数组元素逐个累加
93
+ *
94
+ * 注意:
95
+ * - statementMap、fnMap、branchMap 不需要合并(它们是静态的位置信息)
96
+ * - 只有执行次数(s、f、b)需要累加
97
+ *
98
+ * @param existing - 已存在的覆盖率数据
99
+ * @param newData - 新的覆盖率数据
100
+ * @returns 合并后的覆盖率数据
101
+ *
102
+ * @private
103
+ */
104
+ private mergeCoverageData;
105
+ }
106
+
107
+ /**
108
+ * 覆盖率差异计算器
109
+ *
110
+ * 负责计算增量覆盖率,这是插件的核心模块
111
+ *
112
+ * 工作流程:
113
+ * 1. 加载 baseline 覆盖率(参考基准)
114
+ * 2. 使用 istanbul-diff 计算差异
115
+ * 3. 结合 Git diff 获取变更的文件和行号
116
+ * 4. 计算每个变更文件的覆盖率
117
+ * 5. 汇总整体覆盖率
118
+ * 6. 保存新的 baseline(可选)
119
+ *
120
+ * @module differ
121
+ */
122
+
123
+ /**
124
+ * Coverage Differ - 覆盖率差异计算器
125
+ *
126
+ * 核心职责:
127
+ * 1. 管理 baseline 覆盖率(加载/保存)
128
+ * 2. 使用 istanbul-diff 计算覆盖率差异
129
+ * 3. 结合 Git diff 确定需要检查的代码行
130
+ * 4. 计算增量覆盖率百分比
131
+ *
132
+ * @example
133
+ * const differ = new CoverageDiffer(options);
134
+ * const result = await differ.calculate(currentCoverage);
135
+ */
136
+ declare class CoverageDiffer {
137
+ private options;
138
+ constructor(options: IncrementalCoverageOptions);
139
+ /**
140
+ * 计算增量覆盖率
141
+ *
142
+ * 这是最核心的方法,完整的计算流程:
143
+ *
144
+ * 1. 加载 baseline(如果存在)
145
+ * 2. 使用 istanbul-diff 计算差异
146
+ * 3. 获取 Git 变更的文件和行号
147
+ * 4. 对每个变更文件:
148
+ * a. 获取该文件的覆盖率数据
149
+ * b. 找出变更的行号
150
+ * c. 检查这些行是否被覆盖
151
+ * d. 计算覆盖率百分比
152
+ * 5. 汇总所有文件的覆盖率
153
+ * 6. 保存新的 baseline(如果需要)
154
+ *
155
+ * @param currentCoverage - 当前的覆盖率数据
156
+ * @returns 增量覆盖率计算结果
157
+ *
158
+ * @example
159
+ * const result = await differ.calculate(coverageMap);
160
+ * console.log(`Overall coverage: ${result.overall.coverageRate}%`);
161
+ */
162
+ calculate(currentCoverage: CoverageMap): Promise<IncrementalCoverageResult>;
163
+ /**
164
+ * 从文件加载 baseline 覆盖率
165
+ *
166
+ * Baseline 是参考基准,用于对比当前覆盖率的变化
167
+ * 通常在首次运行时创建,之后保持不变(除非手动更新)
168
+ *
169
+ * @returns baseline 覆盖率数据,如果文件不存在则返回 null
170
+ * @private
171
+ */
172
+ private loadBaseline;
173
+ /**
174
+ * 保存 baseline 覆盖率到文件
175
+ *
176
+ * 将当前的覆盖率数据保存为 baseline,供后续对比使用
177
+ *
178
+ * 注意:
179
+ * - 会自动创建目录(如果不存在)
180
+ * - 使用 JSON 格式,便于查看和调试
181
+ * - 格式化输出(2 空格缩进)
182
+ *
183
+ * @param coverage - 要保存的覆盖率数据
184
+ * @private
185
+ */
186
+ private saveBaseline;
187
+ /**
188
+ * 获取未覆盖的行号列表
189
+ *
190
+ * 算法说明:
191
+ * 1. 遍历每一个变更的行号
192
+ * 2. 检查是否有语句(statement)覆盖这一行
193
+ * 3. 如果有语句覆盖且执行次数 > 0,则该行被覆盖
194
+ * 4. 否则,该行未被覆盖
195
+ *
196
+ * 为什么检查 statementMap?
197
+ * - Istanbul 的覆盖率是基于语句(statement)的
198
+ * - statementMap 记录了每个语句的位置(起始行、结束行)
199
+ * - 通过检查语句的位置,可以知道某一行是否被覆盖
200
+ *
201
+ * 为什么检查执行次数?
202
+ * - coverage.s[stmtId] 记录了语句的执行次数
203
+ * - 如果执行次数 > 0,说明这个语句被执行过
204
+ * - 如果执行次数 = 0,说明这个语句没有被执行
205
+ *
206
+ * @param coverage - 文件的覆盖率数据
207
+ * @param changedLines - 变更的行号列表
208
+ * @returns 未覆盖的行号列表
209
+ *
210
+ * @example
211
+ * const uncovered = this.getUncoveredLines(coverage, [10, 11, 12]);
212
+ * // 返回: [11] (假设第 11 行没有被覆盖)
213
+ *
214
+ * @private
215
+ */
216
+ private getUncoveredLines;
217
+ /**
218
+ * 判断是否为有效的源码文件
219
+ * 用于过滤 node_modules, lockfiles 和非源码文件
220
+ * @private
221
+ */
222
+ private isValidSourceFile;
223
+ }
224
+
225
+ /**
226
+ * 覆盖率报告生成器
227
+ *
228
+ * 负责生成各种格式的覆盖率报告
229
+ *
230
+ * 核心功能:
231
+ * 1. 生成 HTML 格式的可视化报告
232
+ * 2. 生成 JSON 格式的数据报告
233
+ * 3. 维护报告文件(最新报告、历史报告及自动清理)
234
+ *
235
+ * @module reporter
236
+ */
237
+
238
+ /**
239
+ * Coverage Reporter - 覆盖率报告生成器
240
+ */
241
+ declare class CoverageReporter {
242
+ private options;
243
+ private outputDir;
244
+ constructor(options: IncrementalCoverageOptions);
245
+ /**
246
+ * 生成增量覆盖率报告
247
+ *
248
+ * @param result 增量计算结果
249
+ * @returns 报告保存的路径
250
+ */
251
+ generate(result: IncrementalCoverageResult): Promise<string>;
252
+ /**
253
+ * 渲染 HTML 模板
254
+ *
255
+ * @param result 计算结果
256
+ * @private
257
+ */
258
+ private renderHtml;
259
+ /**
260
+ * 清理超出保留数量的历史报告
261
+ * @private
262
+ */
263
+ private cleanupOldReports;
264
+ }
265
+
266
+ /**
267
+ * Git 服务模块
268
+ *
269
+ * 负责与 Git 交互,获取代码变更信息
270
+ *
271
+ * 核心功能:
272
+ * 1. 获取变更的文件列表
273
+ * 2. 解析 Git diff 输出
274
+ * 3. 提取新增和删除的行号
275
+ *
276
+ * @module git
277
+ */
278
+
279
+ /**
280
+ * 获取 Git diff 信息
281
+ *
282
+ * 对比当前分支(HEAD)与指定基准分支的差异
283
+ * 返回变更的文件列表和具体的行号信息
284
+ *
285
+ * 工作流程:
286
+ * 1. 使用 git.diffSummary() 获取变更文件列表
287
+ * 2. 对每个文件使用 git.diff() 获取详细差异
288
+ * 3. 解析 diff 输出,提取行号
289
+ *
290
+ * @param base - 对比的基准分支(例如:'main', 'develop')
291
+ * @returns Git diff 结果,包含文件列表和行号信息
292
+ *
293
+ * @example
294
+ * const diff = await getGitDiff('main');
295
+ * console.log('Changed files:', diff.files);
296
+ * console.log('Added lines in file.ts:', diff.additions['file.ts']);
297
+ */
298
+ declare function getGitDiff(base?: string): Promise<GitDiffResult>;
299
+ /**
300
+ * 获取变更的文件列表
301
+ *
302
+ * 这是 getGitDiff 的简化版本,只返回文件列表
303
+ * 适用于只需要知道哪些文件变更了,不需要具体行号的场景
304
+ *
305
+ * @param base - 对比的基准分支
306
+ * @returns 变更的文件路径列表
307
+ *
308
+ * @example
309
+ * const files = await getChangedFiles('main');
310
+ * console.log('Changed files:', files);
311
+ */
312
+ declare function getChangedFiles(base?: string): Promise<string[]>;
313
+
314
+ export { CoverageCollector, CoverageDiffer, CoverageReporter, IncrementalCoverageOptions, IncrementalCoveragePlugin, getChangedFiles, getGitDiff };