3.8 KiB
FAIL
crates/ely-files/src/session.rs:192 — reload() 把修订号重置为 0,保存票据仅携带修订号,旧任务因此能够匹配重新加载后的新编辑,违反 FILE-03。隔离测试复现:编辑到 revision=1,取得保存票据并写盘;保存完成回调到达前调用 reload(),再编辑一次;随后 finish_save(old_ticket, path) 返回成功,状态实际为 Saved,revision 和 saved_revision 都是 1,此时重新加载后的编辑尚未写盘。修复方向:保证重新加载前后的修订身份唯一,使重新加载失效旧保存票据,并补充这个回调顺序的回归测试。
crates/ely-files/src/session.rs:194 — reload() 无条件设为 Saved,使只读视图获得保存权限,违反 §6.1 的只读副本约束。隔离测试中,Session::read_only(path) 经外部更新后调用 reload(),随后 state() 返回 Saved,begin_save() 返回成功;与原可写会话同时存在的视图因此可以写入同一文件。修复方向:重新加载保留访问模式,所有状态转换持续维护只读约束,并覆盖只读视图重新加载后保存被拒绝的测试。
crates/ely-files/src/session.rs:165 — 保存完成无条件覆盖较新的外部修改状态,同时把完成时读取到的磁盘指纹记成已保存指纹,违反 FILE-02。隔离测试复现:取得票据并写入本次保存内容,另一程序随后改写文件,调用 external_modified(),最后收到本次保存的完成回调并调用 finish_save();实际状态变成 Saved,记录的指纹属于外部内容,会话内容仍属于本次保存修订。修复方向:保存完成只确认对应任务写入的版本,保留其后发生的外部修改通知及冲突状态,并增加乱序完成回调测试。
crates/ely-files/src/session.rs:398 — 去重仅比较规范化路径,硬链接会产生两个可写会话,违反 §6.1 的同文件聚焦要求。隔离测试通过 std::fs::hard_link(doc, alias) 创建同一文件的两个名字,依次执行 open(doc, false) 和 open(alias, false),实际返回 Fresh(0)、Fresh(1),第二次应聚焦已有会话。修复方向:结合文件系统文件身份识别硬链接别名,保留路径用于显示,并加入真实硬链接去重测试。
crates/ely-files/src/session.rs:392 — canonicalize() 的所有错误被 unwrap_or_else 吞掉并静默改用原路径,违反错误暴露规则,也会改变已打开文件的去重键。隔离测试先通过符号链接打开文件,删除其目标后再次以同一符号链接调用 open(),实际返回 Fresh(1);底层 canonicalize() 已明确失败。对原本缺失的路径,open() 同样直接登记为新会话。修复方向:向调用方传播路径解析错误,失败时保持会话登记不变;为 open() 和 is_open() 补充解析失败测试。
crates/ely-files/src/session.rs:92 — FILE-02 要求的 Loading 状态不可达。load() 只读取元数据便构造 Saved,全部构造及转换方法均未设置 Loading,state 又是私有字段;当文档内核仍在异步加载大文件时,调用方无法用此会话表示加载中。源码检索确认 SaveState::Loading 唯一用处是显示字符串分支。修复方向:提供实际的加载开始、成功及失败转换,并测试加载完成前的状态及允许操作。
crates/ely-files/src/session.rs:202 — SaveError 是闲置的公开错误类型,违反无 dead code 规则。全项目检索仅找到定义和再导出;实际只读保存失败由 begin_save() 返回 Err(SaveState::ReadOnly),既有只读测试也只验证该返回值,SaveError::ReadOnly 从未构造或消费。修复方向:删除闲置类型及导出,或让现有保存错误路径实际使用该类型,并同步测试。