`
* 的瓷贴卡,证明它不是"认表格"这条窄路,是通用的"host 的直接子元素就是行"。
*/
// @vitest-environment jsdom
import { describe, expect, it } from 'vitest';
import { collect } from '../src/ViewContainer.tsx';
/** 两颗候选料、每颗 3 个参数瓷贴(与嵌套形状那条用同一组事实数据,方便对照) */
const TILES_HOST =
'
';
function docOf(html: string): Document {
const doc = document.implementation.createHTMLDocument('');
doc.body.innerHTML = html;
return doc;
}
describe('collect():瓷贴(
)是 data-edit 宿主的直接子元素 —— 一瓷贴一记录,互不覆盖', () => {
it('6 个瓷贴收到 6 条记录(不是并成 2 条候选级记录)', () => {
const got = collect(docOf(TILES_HOST), 'parts.parameter');
expect(got).toHaveLength(6);
});
it('每条记录三格各自带对:主键 internal_pn + param_key + param_value,不互相覆盖', () => {
const got = collect(docOf(TILES_HOST), 'parts.parameter');
// 同一颗料的 3 条参数各自独立成行,3 个键值全部保留(与嵌套形状那条"只剩最后一瓷贴"相反)
const lm = got.filter((r) => r['internal_pn'] === 'LM2596S-5.0');
expect(lm).toHaveLength(3);
const byKey = new Map(lm.map((r) => [r['param_key'], r['param_value']]));
expect(byKey.get('input_voltage')).toBe('4.5~40');
expect(byKey.get('output_voltage')).toBe('5');
expect(byKey.get('enable_threshold')).toBe('2.5');
const xl = got.filter((r) => r['internal_pn'] === 'XL2596S-5.0');
expect(xl).toHaveLength(3);
expect(new Map(xl.map((r) => [r['param_key'], r['param_value']])).get('enable_threshold')).toBe('3.0');
});
/*
* 行容器换一个跟表格毫无关系的标签(`
`)结果不变 —— 证明 `rowOf` 认的是
* "host 的直接子元素",不是专挑某个标签名。
*
* 特意不拿 `` 来比:裸 `
`(不包在 `` 里)会撞上 HTML 解析算法的
* "foster parenting"(表格内容规则规定 `` 只能直接装 `| / | `,`` 这类
* 不合规内容会被解析器整体挪到 ` |
` 外面)——真拿裸 tr 包 input 试过,jsdom 吐出的是
* 9 条(3 个空 `
` + 6 个被挪出来的 `` 各自成行),这是 HTML 解析的固有行为,
* 与 `rowOf` 是否"认标签"无关,拿来当反例只会误导。已有的 `view-container-collect.test.ts`
* 用 `` 包着的 `` 早就证明过 tr 这条路是对的。
*/
it('行容器换成完全不相干的标签()结果不变 —— 证明 rowOf 认的是"host 的直接子元素",不是专挑某个标签名', () => {
const liHost =
'' +
'
' +
'' +
'' +
'';
const got = collect(docOf(liHost), 'parts.parameter');
expect(got).toHaveLength(3);
expect(new Set(got.map((r) => r['param_key']))).toEqual(new Set(['input_voltage', 'output_voltage', 'enable_threshold']));
});
it('变异验证:去掉一个瓷贴整行,记录数跟着从 6 变成 5 —— 证明「6 条」不是巧合,是按瓷贴数记', () => {
const oneLess = TILES_HOST.replace(
'',
'',
);
const got = collect(docOf(oneLess), 'parts.parameter');
expect(got).toHaveLength(5);
});
it('变异验证:摘掉一个瓷贴的主键 data-col(internal_pn)—— 只有那一条记录缺这一列,其余 5 条不受影响', () => {
const withoutOnePk = TILES_HOST.replace(
'',
'',
);
const got = collect(docOf(withoutOnePk), 'parts.parameter');
expect(got).toHaveLength(6);
const missingPk = got.filter((r) => !('internal_pn' in r));
expect(missingPk).toHaveLength(1);
expect(missingPk[0]?.['param_key']).toBe('enable_threshold');
expect(missingPk[0]?.['param_value']).toBe('2.5');
});
});