This commit is contained in:
2026-10-31 01:50:35 +03:00
parent 19e05e7ed0
commit afd7600150
8 changed files with 740 additions and 8 deletions
+137
View File
@@ -17,6 +17,7 @@ use crate::editor::{FocusAfterSync, Language, Workspace};
use crate::keymap::{KeyBinding, KeyContext, KeyHandler, KeyMap, Modifiers as KeyModifiers};
use crate::panel::PanelBlock;
use crate::script::ScriptEngine;
use crate::toolbar::ToolbarKind;
use crate::tree::TreeNode;
fn install_api(workspace: Rc<RefCell<Workspace>>) -> (AppApi, Rc<RefCell<KeyMap>>) {
@@ -364,6 +365,97 @@ fn lua_script_can_control_panels() {
let _ = std::fs::remove_dir_all(&dir);
}
#[test]
fn lua_script_configures_toolbar_and_hides_items_by_id() {
let workspace = Rc::new(RefCell::new(Workspace::default()));
let (api, _keymap) = install_api(workspace);
let toolbar = api.toolbar_handle();
let dir = temp_script_dir("toolbar");
let script = dir.join("toolbar.lua");
std::fs::write(
&script,
r##"
app.toolbar:add_label("Готово", nil, "#808080", "status", "left")
app.toolbar:add_button("Запустить", "play", nil, "run", "right", function() end)
app.toolbar:add_label("UTF-8", nil, nil, "encoding", "right")
assert(app.toolbar:hide("run") == true)
assert(app.toolbar:show("run") == true)
assert(app.toolbar:hide("missing") == false)
assert(app.toolbar:show("missing") == false)
-- Неизвестная сторона и иконка — ошибка, а не молчаливый пропуск.
assert(not pcall(function()
app.toolbar:add_label("x", nil, nil, "bad", "middle")
end))
assert(not pcall(function()
app.toolbar:add_label("x", "not-an-icon", nil, "bad-icon", "left")
end))
assert(not pcall(function()
app.toolbar:add_label("x", nil, "not-a-color", "bad-color", "left")
end))
"##,
)
.expect("toolbar.lua");
let engine = ScriptEngine::new(api).expect("движок Lua");
engine
.run_file(&script)
.expect("верхняя панель должна настраиваться из Lua");
let toolbar = toolbar.borrow();
assert_eq!(toolbar.left().len(), 1);
assert_eq!(toolbar.left()[0].id, "status");
assert_eq!(toolbar.left()[0].text, "Готово");
assert!(toolbar.left()[0].background.is_some());
assert!(toolbar.left()[0].visible);
// Первый добавленный элемент правой области рисуется у правого края.
assert_eq!(toolbar.right().len(), 2);
assert_eq!(toolbar.right()[0].id, "run");
assert!(matches!(
toolbar.right()[0].kind,
ToolbarKind::Button { .. }
));
assert!(toolbar.right()[0].visible);
assert_eq!(toolbar.right()[1].id, "encoding");
assert!(matches!(toolbar.right()[1].kind, ToolbarKind::Label));
let _ = std::fs::remove_dir_all(&dir);
}
#[test]
fn toolbar_replaces_items_with_the_same_id() {
let workspace = Rc::new(RefCell::new(Workspace::default()));
let (api, _keymap) = install_api(workspace);
let toolbar_api = api.toolbar();
let toolbar = api.toolbar_handle();
toolbar_api
.add_label("Старый".into(), None, None, "item".into(), "left".into())
.expect("лейбл");
toolbar_api
.add_label(
"Новый".into(),
None,
Some("#112233".into()),
"item".into(),
"right".into(),
)
.expect("замена");
let toolbar = toolbar.borrow();
assert!(toolbar.left().is_empty());
assert_eq!(toolbar.right().len(), 1);
assert_eq!(toolbar.right()[0].text, "Новый");
drop(toolbar);
toolbar_api.clear();
assert!(!toolbar_api.hide("item".to_string()));
assert!(api.toolbar_handle().borrow().right().is_empty());
}
#[test]
fn lua_tree_block_appends_sorts_and_removes_nodes() {
let workspace = Rc::new(RefCell::new(Workspace::default()));
@@ -1128,6 +1220,51 @@ fn opened_panels_render_without_panicking(cx: &mut TestAppContext) {
assert!(api.bottom_panel_handle().borrow().is_open());
}
#[gpui_kit::test]
fn toolbar_items_render_from_api(cx: &mut TestAppContext) {
cx.update(gpui_kit::init);
let (app, visual) = cx.add_window_view(MyApp::new);
// Функция создаётся в отдельном Lua-состоянии: для проверки отрисовки
// достаточно, чтобы обработчик существовал.
let lua = mlua::Lua::new();
let callback = lua
.load("return function() end")
.eval::<mlua::Function>()
.unwrap();
let toolbar = AppApi::global().toolbar();
toolbar
.add_label(
"Слева".into(),
Some("file".into()),
Some("#808080".into()),
"label".into(),
"left".into(),
)
.expect("лейбл");
toolbar
.add_button(
"Кнопка".into(),
Some("play".into()),
None,
"button".into(),
"right".into(),
callback,
)
.expect("кнопка");
visual.update(|_window, cx| {
app.update(cx, |_, cx| cx.notify());
});
visual.run_until_parked();
let toolbar = AppApi::global().toolbar_handle();
assert_eq!(toolbar.borrow().left().len(), 1);
assert_eq!(toolbar.borrow().right().len(), 1);
}
#[gpui_kit::test]
fn tree_block_renders_with_nested_nodes(cx: &mut TestAppContext) {
cx.update(gpui_kit::init);