Files
oak-editor/crates/oakplugin/tests/push_button_test.rs
T
Mike-Solar b4ceaa9cab feat(oakplugin): GL render bridge, color picker, push-button action, worker progress, Interact host
- gl_bridge: macOS CGL offscreen context (process-wide singleton,
  serialized GlGuard), real GL output textures/FBOs, glReadPixels
  readback with vertical flip and format conversion; use_opengl now
  really engages for OpenGLRenderSupported plugins (verified with real
  GL rendering: C smoke 11/11, unit tests, GL e2e).
- OfxColor: color params get a swatch button plus a real picker popup
  (RGBA sliders, live preview, hex input, undoable commit) replacing
  the four spinboxes.
- Push buttons route kOfxActionInstanceChanged (UserEdited) per the
  OFX contract; test plugin asserts the callback.
- Worker-side plugin progress flows to the main-process progress
  dialog over the NDJSON control channel, with cancel propagation.
- OFX Interact host: NewInteract/Describe lifecycle, Draw/Pen/Key/Idle
  action surface with proper in-args, DrawSuite v1 host implementation
  sharing the gl_bridge context; interact test plugin verifies the
  event stream and real GL drawing.
2026-08-19 22:14:54 +08:00

80 lines
3.3 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// 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 <http://www.gnu.org/licenses/>.
//! push button → `kOfxActionInstanceChanged` 路由(端到端)。
//!
//! 链路:`scan_path`(最小测试插件,cbits/oak_test_plugin.cdescribe
//! 里定义了 push button 参数 "button"instanceChanged 时按
//! `OAK_TEST_PLUGIN_INSTANCECHANGED_MARKER` 指向的文件追加一行)→
//! `create_instance` → `push_button_clicked`(置值 + 路由
//! UserEdited instanceChanged)→ 插件记录回调次数。
//!
//! 测试插件未构建时 skip(common 约定)。宿主单例经 `common::with_host`
//! 串行化。
mod common;
use oakplugin::host::Host;
const PLUGIN_ID: &str = "org.oak.test-plugin";
#[test]
fn push_button_press_routes_instance_changed() {
common::with_host(|| {
let Some(dir) = common::test_plugin_scan_dir() else {
common::skip("最小测试插件未构建");
return;
};
if Host::global().cache.scan_path(&dir).is_err() {
common::skip("测试插件扫描失败");
return;
}
let inst = Host::global()
.create_instance(PLUGIN_ID, None)
.expect("实例");
let id = oakplugin::node_factory::register_instance(inst.clone());
// The C plugin appends one line per instanceChanged("button") to the
// marker file; the assertion reads it back.
let marker = std::env::temp_dir().join(format!("oak-push-{}.log", std::process::id()));
let _ = std::fs::remove_file(&marker);
std::env::set_var("OAK_TEST_PLUGIN_INSTANCECHANGED_MARKER", &marker);
// The button param exists and is a push button.
let p = inst.value.params.find("button").expect("button 参数");
assert_eq!(p.def.ofx_type, oakplugin::param::TYPE_PUSHBUTTON);
// First press: set + routed to the plugin.
assert!(oakplugin::node_factory::push_button_clicked(id, "button"));
// Unknown / non-button params are rejected without touching the entry.
assert!(!oakplugin::node_factory::push_button_clicked(id, "gain"));
assert!(!oakplugin::node_factory::push_button_clicked(id, "nope"));
assert!(!oakplugin::node_factory::push_button_clicked(u64::MAX, "button"));
// Second press on the real button: routed again.
assert!(oakplugin::node_factory::push_button_clicked(id, "button"));
// Exactly the two real presses reached the plugin's instanceChanged.
let log = std::fs::read_to_string(&marker).expect("marker 文件应存在");
assert_eq!(log.lines().count(), 2, "marker log:\n{log}");
assert!(log.contains("instanceChanged"), "marker log:\n{log}");
std::env::remove_var("OAK_TEST_PLUGIN_INSTANCECHANGED_MARKER");
let _ = std::fs::remove_file(&marker);
oakplugin::node_factory::unregister_instance(id);
Host::global().shutdown();
});
}