Files
gpui-native-kit/crates/core/tests/clipboard.rs
T

139 lines
4.2 KiB
Rust

use std::{cell::RefCell, rc::Rc};
use gpui::{
AnyWindowHandle, AppContext as _, Context, IntoElement, Modifiers, ParentElement as _, Render,
Styled as _, TestAppContext, VisualTestContext, Window, div,
};
use gpui_native_core::clipboard::{COPIED_DURATION, ClipboardButton};
use gpui_native_theme::Theme;
const VALUE: &str = "https://example.com/repo.git";
struct Harness {
copies: Rc<RefCell<usize>>,
disabled: bool,
}
impl Render for Harness {
fn render(&mut self, _window: &mut Window, _cx: &mut Context<Self>) -> impl IntoElement {
let copies = self.copies.clone();
div().size_full().flex().flex_col().child(
ClipboardButton::new("test-clipboard", VALUE)
.disabled(self.disabled)
.on_copied(move |_| *copies.borrow_mut() += 1),
)
}
}
/// A maximized window whose button stretches across the top control row, so
/// `point(px(60.), px(14.))` always lands on it.
fn clipboard_window(
disabled: bool,
) -> (
TestAppContext,
VisualTestContext,
AnyWindowHandle,
Rc<RefCell<usize>>,
) {
let mut cx = TestAppContext::single();
cx.update(Theme::init);
let copies = Rc::new(RefCell::new(0));
let harness_copies = copies.clone();
let window = cx.add_window(move |_, _| Harness {
copies: harness_copies,
disabled,
});
let window = window.into();
cx.update_window(window, |_, window, cx| {
window.draw(cx).clear(cx);
})
.unwrap();
let visual = VisualTestContext::from_window(window, &cx);
(cx, visual, window, copies)
}
fn draw(visual: &mut VisualTestContext, window: AnyWindowHandle) {
visual
.update_window(window, |_, window, cx| {
window.draw(cx).clear(cx);
})
.unwrap();
}
fn clipboard_text(visual: &mut VisualTestContext) -> String {
visual.update(|_window, cx| {
cx.read_from_clipboard()
.and_then(|item| item.text())
.unwrap_or_default()
})
}
fn click(visual: &mut VisualTestContext) {
let selector = if visual.debug_bounds("clipboard").is_some() {
"clipboard"
} else {
"clipboard-copied"
};
let bounds = visual
.debug_bounds(selector)
.expect("clipboard button should be rendered");
visual.simulate_click(bounds.center(), Modifiers::default());
}
#[test]
fn click_copies_the_value_and_fires_on_copied() {
let (_cx, mut visual, _window, copies) = clipboard_window(false);
click(&mut visual);
assert_eq!(clipboard_text(&mut visual), VALUE);
assert_eq!(*copies.borrow(), 1);
}
#[test]
fn disabled_button_does_not_copy() {
let (_cx, mut visual, _window, copies) = clipboard_window(true);
click(&mut visual);
assert_eq!(clipboard_text(&mut visual), "");
assert_eq!(*copies.borrow(), 0);
}
#[test]
fn copied_confirmation_shows_then_reverts() {
let (cx, mut visual, window, _copies) = clipboard_window(false);
click(&mut visual);
draw(&mut visual, window);
assert!(
visual.debug_bounds("clipboard-copied").is_some(),
"the check mark state should render right after the click"
);
assert!(visual.debug_bounds("clipboard").is_none());
cx.executor().advance_clock(COPIED_DURATION);
visual.run_until_parked();
draw(&mut visual, window);
assert!(
visual.debug_bounds("clipboard").is_some(),
"the copy icon should return once the confirmation window passes"
);
assert!(visual.debug_bounds("clipboard-copied").is_none());
}
#[test]
fn a_second_click_within_the_window_keeps_the_confirmation_up() {
let (cx, mut visual, window, _copies) = clipboard_window(false);
click(&mut visual);
cx.executor().advance_clock(COPIED_DURATION / 2);
click(&mut visual);
cx.executor().advance_clock(COPIED_DURATION / 2);
visual.run_until_parked();
draw(&mut visual, window);
assert!(
visual.debug_bounds("clipboard-copied").is_some(),
"the first click's stale revert must not clear the second click's confirmation"
);
cx.executor().advance_clock(COPIED_DURATION);
visual.run_until_parked();
draw(&mut visual, window);
assert!(visual.debug_bounds("clipboard").is_some());
}