base.js
2.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
/**
* Vitest 预设的「默认值」与共享工具 —— 共享 coverage 门槛 / include / reporter + 深合并。
*
* `index.js` 持有 node/vue 两个工厂,本文件持有跨工厂共享的默认数据与无副作用 `deepMerge`。
* coverage 门槛是「单一来源」:全仓收紧门槛改这一处,所有消费包下次跑即生效(§2 验收 5)。
* 预设为纯配置:不读 env、不建连接。
*/
/**
* @param {unknown} v
* @returns {boolean}
*/
function isPlainObject(v) {
if (v === null || typeof v !== 'object' || Array.isArray(v)) return false
const proto = Object.getPrototypeOf(v)
return proto === Object.prototype || proto === null
}
/**
* 递归深合并(嵌套对象逐层合并、数组与标量整体替换)。
* 保证 app 传 `test.coverage.thresholds` 只覆盖门槛字段,不抹掉其余默认。
* @template T
* @param {T} base
* @param {Record<string, unknown>} override
* @returns {T}
*/
export function deepMerge(base, override) {
if (!isPlainObject(override)) return /** @type {T} */ (override ?? base)
const out = isPlainObject(base) ? { ...base } : {}
for (const key of Object.keys(override)) {
const o = override[key]
const b = /** @type {Record<string, unknown>} */ (out)[key]
if (isPlainObject(b) && isPlainObject(o)) {
/** @type {Record<string, unknown>} */ (out)[key] = deepMerge(b, o)
} else {
/** @type {Record<string, unknown>} */ (out)[key] = o
}
}
return /** @type {T} */ (out)
}
/** 全仓统一的覆盖率门槛(单一来源)。改这里 = 全仓消费包门槛同步变化。 */
export const COVERAGE_THRESHOLDS = Object.freeze({
lines: 80,
functions: 80,
branches: 75,
statements: 80,
})
/** 全仓统一的 test 匹配 / 排除 / reporter / coverage 约定。 */
export function buildSharedTestConfig() {
return {
globals: true,
include: ['test/**/*.test.js', 'src/**/*.test.js'],
exclude: ['**/node_modules/**', '**/dist/**', '**/coverage/**'],
reporters: ['default'],
coverage: {
provider: 'v8',
reporter: ['text', 'lcov'],
include: ['src/**/*.js'],
exclude: ['**/*.test.js', '**/test/**'],
thresholds: { ...COVERAGE_THRESHOLDS },
},
}
}