feat: ReadingEvent V2 delta semantics verification (DOC-FULL-003)

- 新增 test_delta_semantics_per_event_type: 验证所有 5 种事件类型的
  activeSecondsDelta 均为增量语义(非累计值)
- ReadingEventV2 + ReadingEventTypeV2 已有完整实现(610行/22测试)
- No readingTargetType/userId/knowledgeBaseId(编译时保证)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
wangdl 2026-06-11 21:05:17 +08:00
parent 7d678b4bb3
commit e64f96d43c

View File

@ -607,4 +607,35 @@ mod tests {
}
teardown_session(&sid);
}
#[test]
fn test_delta_semantics_per_event_type() {
let _guard = lock_test();
let sid = setup_session("mat_delta");
// material_opened: delta must be 0
let e1 = push_material_opened_v2(&sid, "mat_delta", 1000).unwrap();
assert_eq!(e1.active_seconds_delta, 0);
// position_changed: delta must be 0
let e2 = push_position_changed_v2(&sid, "mat_delta", ReadingPosition::Unknown, 2000).unwrap();
assert_eq!(e2.active_seconds_delta, 0);
// marked_as_read: delta must be 0
let e3 = push_marked_as_read_v2(&sid, "mat_delta", 3000).unwrap();
assert_eq!(e3.active_seconds_delta, 0);
// heartbeat: delta is the caller-provided active_seconds_delta (non-zero)
let e4 = push_heartbeat_v2(&sid, "mat_delta", 15, None, 4000).unwrap();
assert_eq!(e4.active_seconds_delta, 15);
// material_closed: delta is the residual active time at close
let e5 = push_material_closed_v2(&sid, "mat_delta", 5, 5000).unwrap();
assert_eq!(e5.active_seconds_delta, 5);
// Verify all deltas are NOT accumulated — they are per-event increments
assert_eq!(e1.active_seconds_delta + e2.active_seconds_delta + e3.active_seconds_delta + e4.active_seconds_delta + e5.active_seconds_delta, 20);
teardown_session(&sid);
}
}