// Oak Video Editor - Non-Linear Video Editor
// Copyright (C) 2026 Oak Team
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
//! handle.rs 的契约测试:`RefBox` 容器。
//!
//! 单库化(M14 R5)后 crate 内部不再传 CHandle——原 CHandle 装拆
//! (`make_owned`/`make_borrowed`/`get`)、panic 兜底(`guard`/
//! `guard_handle`/`guard_void`)与身份注册表(`Registry`)均已删除。
//! [`oakplugin::handle::RefBox`] 仅作为 `Host::create_instance` 的
//! 边界返回类型保留(`Arc>`,oakengine test_support
//! 消费);此处验证其基本契约。每个测试只验一条规则,命名即规约。
mod common;
use std::sync::atomic::{AtomicU32, AtomicUsize, Ordering};
use std::sync::Arc;
use oakplugin::handle::RefBox;
/// 析构标志:以"被析构次数"断言对象的销毁时机(Arc 生命周期语义的
/// 行为探针)。
struct DropFlag(Arc);
impl Drop for DropFlag {
fn drop(&mut self) {
self.0.fetch_add(1, Ordering::Relaxed);
}
}
/// 值可经 `.value` 字段取回(create_instance 返回后调用方的访问方式)。
#[test]
fn refbox_exposes_value_by_field() {
let boxed = RefBox {
refs: AtomicU32::new(1),
value: 7u32,
};
assert_eq!(boxed.value, 7);
}
/// 生命周期完全由外层 Arc 管理:`refs` 只以固定值 1 构造(无 thunk
/// 增减),Arc 归零时内含对象恰好析构一次;弱引用在 Arc 存活期间
/// 有效、归零后失效(host 的活跃实例表即 Weak 列表)。
#[test]
fn refbox_value_drops_exactly_once_when_arc_reaches_zero() {
let drops = Arc::new(AtomicUsize::new(0));
let boxed = Arc::new(RefBox {
refs: AtomicU32::new(1),
value: DropFlag(drops.clone()),
});
let weak = Arc::downgrade(&boxed);
assert!(weak.upgrade().is_some());
assert_eq!(drops.load(Ordering::Relaxed), 0);
drop(boxed);
assert_eq!(drops.load(Ordering::Relaxed), 1);
assert!(weak.upgrade().is_none());
}