use embers_server::{BufferAttachment, Node, ServerState};
#[test]
fn moving_buffer_between_leaves_replaces_target_and_closes_source_view() {
let mut state = ServerState::new();
let session_id = state.create_session("main");
let first_buffer = state.create_buffer("one", vec!["/bin/sh".to_owned()], None);
state
.add_root_tab_from_buffer(session_id, "one", first_buffer)
.expect("add root tab");
let first_leaf = state
.session(session_id)
.expect("session exists")
.focused_leaf
.expect("root tab focuses first leaf");
let second_buffer = state.create_buffer("two", vec!["/bin/sh".to_owned()], None);
state
.split_leaf_with_new_buffer(
first_leaf,
embers_core::SplitDirection::Horizontal,
second_buffer,
)
.expect("split root leaf");
let second_leaf = state
.session(session_id)
.expect("session exists")
.focused_leaf
.expect("split focuses new leaf");
state
.move_buffer_to_leaf(first_buffer, second_leaf)
.expect("move buffer into target leaf");
assert_eq!(
state.session(session_id).expect("session exists").root_node,
second_leaf
);
assert_eq!(state.node_parent(second_leaf).expect("target parent"), None);
match state.node(second_leaf).expect("target leaf exists") {
Node::BufferView(view) => assert_eq!(view.buffer_id, first_buffer),
other => panic!("expected target buffer view, got {other:?}"),
}
assert!(matches!(
&state.buffer(first_buffer).expect("buffer exists").attachment,
BufferAttachment::Attached(node_id) if *node_id == second_leaf
));
assert!(matches!(
&state
.buffer(second_buffer)
.expect("buffer exists")
.attachment,
BufferAttachment::Detached
));
assert_eq!(
state
.session(session_id)
.expect("session exists")
.focused_leaf,
Some(second_leaf)
);
state.validate().expect("move keeps state valid");
}
#[test]
fn detached_buffer_can_reattach_to_existing_leaf() {
let mut state = ServerState::new();
let session_id = state.create_session("main");
let first_buffer = state.create_buffer("one", vec!["/bin/sh".to_owned()], None);
state
.add_root_tab_from_buffer(session_id, "one", first_buffer)
.expect("add root tab");
let first_leaf = state
.session(session_id)
.expect("session exists")
.focused_leaf
.expect("root tab focuses first leaf");
state.close_node(first_leaf).expect("close source view");
let second_buffer = state.create_buffer("two", vec!["/bin/sh".to_owned()], None);
state
.add_root_tab_from_buffer(session_id, "two", second_buffer)
.expect("add replacement root tab");
let second_leaf = state
.session(session_id)
.expect("session exists")
.focused_leaf
.expect("replacement root tab focuses second leaf");
state
.move_buffer_to_leaf(first_buffer, second_leaf)
.expect("reattach detached buffer");
match state.node(second_leaf).expect("target leaf exists") {
Node::BufferView(view) => assert_eq!(view.buffer_id, first_buffer),
other => panic!("expected target buffer view, got {other:?}"),
}
assert!(matches!(
&state.buffer(first_buffer).expect("buffer exists").attachment,
BufferAttachment::Attached(node_id) if *node_id == second_leaf
));
assert!(matches!(
&state
.buffer(second_buffer)
.expect("buffer exists")
.attachment,
BufferAttachment::Detached
));
state.validate().expect("reattach keeps state valid");
}
#[test]
fn attached_buffers_must_detach_before_cross_session_move() {
let mut state = ServerState::new();
let source_session = state.create_session("source");
let target_session = state.create_session("target");
let source_buffer = state.create_buffer("one", vec!["/bin/sh".to_owned()], None);
state
.add_root_tab_from_buffer(source_session, "one", source_buffer)
.expect("add source tab");
let source_leaf = state
.session(source_session)
.expect("source session exists")
.focused_leaf
.expect("source tab focuses source leaf");
let target_buffer = state.create_buffer("two", vec!["/bin/sh".to_owned()], None);
state
.add_root_tab_from_buffer(target_session, "two", target_buffer)
.expect("add target tab");
let target_leaf = state
.session(target_session)
.expect("target session exists")
.focused_leaf
.expect("target tab focuses target leaf");
let error = state
.move_buffer_to_leaf(source_buffer, target_leaf)
.expect_err("attached cross-session move should be rejected");
assert!(
error
.to_string()
.contains("detached before moving across sessions")
);
state.close_node(source_leaf).expect("detach source view");
state
.move_buffer_to_leaf(source_buffer, target_leaf)
.expect("detached buffer can move across sessions");
match state.node(target_leaf).expect("target leaf exists") {
Node::BufferView(view) => assert_eq!(view.buffer_id, source_buffer),
other => panic!("expected target buffer view, got {other:?}"),
}
state
.validate()
.expect("cross-session reattach keeps state valid");
}