Skip to content

[finding][drivers] 两个驱动包的测试脚手架用 (driver as any).knex 触达一个 protected 成员 —— 为读一个成员抹掉整个 driver 的类型(实测 52 文件 / 107 行) #6521

Description

@os-zhuang

#6320(PR #6517)的实施中带出。观察类,不是今天会炸的缺陷:无用户可触达面,pnpm test 全绿,任何门禁都不报。按 PD #10 另立单记录,不在 #6320 的 PR 里顺手扫。

事实(实测于 origin/main

SqlDriver.knex 声明为 protectedpackages/drivers/driver-sql/src/sql-driver.ts:1876),所以类外的测试 fixture 确实需要一次强制转换才能拿到 knex 实例做建表/插数据。当前全仓统一用的写法是:

let knexInstance: any;
knexInstance = (driver as any).knex;

git grep -c "as any).knex" origin/main -- packages/drivers/ 逐包汇总(计的是命中行数,非命中次数):

文件数 命中行数
driver-sql 37 74
driver-sqlite-wasm 14 32
driver-turso 1 1
合计 52 107

其中 packages/drivers/driver-sqlite-wasm/src/sqlite-wasm-driver.ts非测试代码里的一处,其余在测试里。

为什么记下来

  1. as any 在这里是过量的。要读的成员只有一个(knex),但 as any 把整个 driver 的类型一起抹掉 —— 同一个 knexInstance 变量随后也被声明成 any,于是它上面的 schema.createTable / .insert / .destroy 全部不受检查,createTable 的回调参数也只能写成 (t: any)。一次转换的代价被放大到整条 fixture 链。

  2. 它落在所有既有门禁的盲区里,这一点是实测的、不是推断的:

  3. 现成的替代写法就在仓里fix(drivers): 聚合函数拒收带上 ADR-0112 信封,并把两类条件分开措辞 (#5907) #6204 体例):点名要读的那一个成员,而不是抹掉整个对象。

    import type { Knex } from 'knex';
    let knexInstance: Knex;
    knexInstance = (driver as unknown as { knex: Knex }).knex;

    PR refactor(driver-sql)!: distinct 的第三参收成裸 FilterCondition (#6320) #6517 已在它自己新增的两个测试文件上用了这个写法并验证通过(两包 typecheck 绿、967 + 257 测试通过、eslint 绿),knex 在两个包里都是直接依赖,所以 import type { Knex } 处处可用。⛔ 它没有顺手扫兄弟文件 —— 超出 drivers: distinct 的第三参在 memory 与 sql 上语义不同 —— 把 sql 那面的写法交给 memory,静默返回未过滤全集(运行期实测) #6320 的范围。

不代裁的处置线索

  • 这是测试脚手架的类型卫生,不是契约缺陷,严重度应由分诊定,不由本单预设;
  • 若要扫,扫的是一个机械替换(52 文件),但值不值得扫是个判断题:它买到的是 fixture 链上的类型检查,付出的是一次大面积改动与其后的合并冲突面;
  • 另一个方向是根本不扫,而是给 SqlDriver 一个测试用的具名读取口,让 fixture 不再需要任何转换 —— 但那是往驱动上加面,需要真实业务/测试拉力才划算,⛔ 本单不预判;
  • 第三条:sqlite-wasm-driver.ts 里那一处非测试出现值得单独看一眼,与测试里的那批不是同一回事。

关联:#6320 / PR #6517(出处)、#4918(有意排除测试代码的那条护栏,已 closed)、#6204as unknown as 具名类型 的体例)。

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions