Files
mindfulness/spec_kit/Text Wrap/modules/width-measurement/tasks.md
2026-02-10 11:39:33 +08:00

6.2 KiB
Raw Blame History

width-measurement任务清单

对应计划:spec_kit/Text Wrap/modules/width-measurement/plan.md

状态含义:[ ] 未完成,[x] 已完成。
执行完本清单后,需要在 spec_kit/overview.mdText Wrap 条目下补充“已完成编码/任务执行完毕”的标记(见最后一节)。


0. 任务标记规则

  • 用勾选框标记执行状态:
    • [ ] 未完成
    • [x] 已完成
  • 每个任务必须可独立验收(有明确产出与检查方式)。
  • 所有代码注释必须为简体中文,并把“缓存 key / 降级语义 / 报错口径”写死,避免后续模块漂移。

1. 前置检查(依赖与约束确认)

  • 1.1 确认 availableWidth 由设备侧传入(本模块不内置 widgetProfiles

    • 验收:在本模块实现中不引入任何固定宽度常量表;仅消费上层传入的宽度与 profile。
  • 1.2 确认 APP 测量方案采用成熟库(默认 react-native-text-size

    • 验收client/package.json 中存在该依赖(或团队等价成熟方案),并且测量封装函数仅依赖该库/注入点。

2. 依赖与目录骨架(客户端侧实现)

  • 2.1 新建目录 client/src/features/textWrap/measure/

    • 产出(建议文件):
      • types.tsFontSpec/ContextProfile/MeasureResult
      • errors.ts(缺字段报错)
      • fontSpecKey.ts
      • cache.ts(两级缓存 + 上限)
      • measureWidthImpl.ts(对接成熟测量库)
      • measureWidthCached.ts
      • measureSliceWidthCached.ts
      • __tests__/widthMeasurement.test.ts
      • index.ts(统一导出)
    • 验收目录存在TS 可正常 import不报路径错误
  • 2.2 新增依赖 react-native-text-size(如项目未安装)

    • 命令(示例):
      • cd client && npm install react-native-text-size
    • 验收
      • 安装成功
      • npm test 不受影响(后续任务再补充本模块测试)

3. fontSpec 强校验(缺失直接报错)

  • 3.1 定义 FontSpec 类型(必须字段:fontSize/fontFamily/fontWeight

    • 验收:类型层面可表达“必填字段”,并在运行时也做校验。
  • 3.2 实现运行时校验与错误(简体中文)

    • 要求
      • 缺失任一字段直接抛错
      • 错误信息包含:缺失字段名 + 建议调用方补齐的位置(例如 wrapText({ fontSpec: ... })
      • 禁止隐式默认值
    • 验收:单测断言会抛错且错误信息包含缺失字段名。

4. fontSpecKey 与 contextProfile确定性 key 体系)

  • 4.1 实现 buildFontSpecKey(fontSpec)

    • 规则fontFamily|fontWeight|fontSize(顺序固定)
    • 验收同输入同输出fontSize 非有限数时报错。
  • 4.2 定义 contextProfile 拼接规则并实现 helper

    • 要求
      • APPAPP|<platform>|<scale?>(字段顺序固定)
      • WIDGETWIDGET|<widgetSize?>(无 widgetSize 时为 WIDGET
    • 验收:输出字符串稳定;不同 profile 必须产生不同缓存 key。

5. 两级缓存(有上限 + 确定性)

  • 5.1 实现缓存容器(模块级常驻)

    • 要求
      • 字符串测量缓存textKey
      • 切片测量缓存sliceKey
      • 容量上限策略LRU 优先;若不引入依赖,先 Map + 超限清空(并预留打点钩子)
    • 验收:单测可验证缓存命中会减少底层测量调用次数。
  • 5.2 定义 key 生成规则并实现

    • 规则
      • textKey = <contextProfile>|<fontSpecKey>|<text>
      • sliceKey = <contextProfile>|<fontSpecKey>|<start>|<end>
    • 验收key 生成不依赖对象遍历顺序;同输入同 key。

6. 测量实现与降级approx mode

  • 6.1 实现 measureWidthImpl(text, fontSpec)APP

    • 要求
      • 依赖成熟库测量宽度
      • 返回值必须校验:有限且非负
    • 验收:在单测中用 mock 替代真实库,验证封装逻辑与校验逻辑即可(不做像素级断言)。
  • 6.2 实现 measureWidthCached(...)

    • 行为
      • 正常测量:返回 { width:number, meta:{ isApprox:false } }
      • 进入 approx返回 { width:null, meta:{ isApprox:true, reason } }
    • approx 触发条件(任一满足):
      • 未提供测量能力 / context=WIDGET 且上层不启用测量 -> WIDTH_UNKNOWN
      • 抛错/NaN/Infinity/负数 -> MEASURE_FAILED
    • 验收:单测覆盖两类 reason。
  • 6.3 实现 measureSliceWidthCached(...)(切片测量)

    • 要求
      • 通过 joinTokens(start,end) 生成切片文本
      • 使用切片缓存避免 DP 反复测量
    • 验收:单测验证同 sliceKey 不重复调用底层测量。

7. 单元测试Vitest

  • 7.1 新建 __tests__/widthMeasurement.test.ts 并覆盖以下用例
    • fontSpec 报错:缺字段必抛错(错误信息含字段名)
    • 缓存命中:同 key 不重复调用底层测量 mock
    • 缓存隔离:不同 contextProfile/fontSpecKey 不互相污染
    • 降级
      • 缺测量能力 -> width=null + WIDTH_UNKNOWN
      • 测量抛错/NaN -> width=null + MEASURE_FAILED
    • 验收npm test 稳定通过。

8. 最终自检清单(合入前)

  • 8.1 npm test 通过(包含本模块新增用例)

    • 验收:不影响现有测试文件。
  • 8.2 npx tsc --noEmit 通过(或项目既有 TS 检查命令通过)

    • 验收:无类型错误。
  • 8.3 注释与口径自检(简体中文)

    • 检查点
      • fontSpec 缺字段“必须报错”
      • key 生成规则与 contextProfile 口径
      • approx mode 的 reason 语义WIDTH_UNKNOWN / MEASURE_FAILED
    • 验收:后续模块开发者只看代码也不会产生歧义。

9. 文档回写(任务清单执行完毕后必须做)

  • 9.1 在 spec_kit/overview.mdText Wrap 条目下补充执行状态
    • 建议写法
      • 增加一行:- **已完成编码(阶段性)**width-measurement宽度测量与降级
    • 验收overview 能反映该子模块已完成,便于全局追踪。