Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
147 lines
6.3 KiB
Rust
147 lines
6.3 KiB
Rust
//! Password prompts, zoomed pairs, jumps across (C11.1).
|
|
|
|
use ely_office::{Dialog, Dialogs as _, Tabs as _};
|
|
use gpui::{Entity, Modifiers, ScrollDelta, ScrollWheelEvent, TestAppContext, VisualTestContext, point, px};
|
|
|
|
use super::{file, frames, settle, shown, windowed};
|
|
use crate::layout::{Mode, Zoom};
|
|
use crate::view::PdfView;
|
|
use crate::viewer::Viewer;
|
|
|
|
/// The file the open prompt asks for.
|
|
fn asking(app: &gpui::App, viewer: &Entity<Viewer>) -> Option<std::path::PathBuf> {
|
|
match &viewer.read(app).core.dialog {
|
|
Some(Dialog::Password { path, .. }) => Some(path.clone()),
|
|
_ => None,
|
|
}
|
|
}
|
|
|
|
/// Two files asked for at once, as locked loads do.
|
|
fn asked<'a>(cx: &'a mut TestAppContext, dir: &std::path::Path) -> (Entity<Viewer>, &'a mut VisualTestContext, [std::path::PathBuf; 2]) {
|
|
let (viewer, cx) = windowed(cx, dir, &[], true);
|
|
let paths = [file(dir, "a.pdf", &[(612.0, 792.0, &["a"])]), file(dir, "b.pdf", &[(612.0, 792.0, &["b"])])];
|
|
cx.update(|window, app| viewer.update(app, |viewer, cx| {
|
|
for path in &paths {
|
|
viewer.ask_password(path.clone(), false, false, window, cx);
|
|
}
|
|
}));
|
|
frames(cx);
|
|
(viewer, cx, paths)
|
|
}
|
|
|
|
#[test]
|
|
fn a_typed_password_opens_the_file() {
|
|
let dir = tempfile::tempdir().expect("a temp dir");
|
|
let mut cx = TestAppContext::single();
|
|
let (viewer, cx, paths) = asked(&mut cx, dir.path());
|
|
// An open file takes any password.
|
|
cx.simulate_input("secret");
|
|
cx.simulate_keystrokes("enter");
|
|
settle(cx, |app| viewer.read(app).core.tabs.len() == 1);
|
|
assert_eq!(cx.update(|_, app| asking(app, &viewer)), Some(paths[1].clone()), "the next asks");
|
|
}
|
|
|
|
#[test]
|
|
fn escape_gives_up_each_queued_file_in_turn() {
|
|
let dir = tempfile::tempdir().expect("a temp dir");
|
|
let mut cx = TestAppContext::single();
|
|
let (viewer, cx, paths) = asked(&mut cx, dir.path());
|
|
assert_eq!(cx.update(|_, app| asking(app, &viewer)), Some(paths[0].clone()));
|
|
cx.simulate_keystrokes("escape");
|
|
settle(cx, |app| asking(app, &viewer) == Some(paths[1].clone()));
|
|
frames(cx);
|
|
cx.simulate_keystrokes("escape");
|
|
settle(cx, |app| viewer.read(app).core.dialog.is_none());
|
|
assert!(cx.update(|_, app| viewer.read(app).active_tab().is_none()));
|
|
}
|
|
|
|
/// Two zoomed Letter pages side by side.
|
|
fn zoomed_pair<'a>(cx: &'a mut TestAppContext, dir: &std::path::Path) -> (Entity<PdfView>, &'a mut VisualTestContext) {
|
|
let pages: &[(f32, f32, &[&str])] = &[(612.0, 792.0, &["one"]), (612.0, 792.0, &["two"])];
|
|
let (viewer, cx) = windowed(cx, dir, &[file(dir, "pair.pdf", pages)], true);
|
|
let view = shown(cx, &viewer);
|
|
settle(cx, |app| view.read(app).room.size.width > px(100.0));
|
|
cx.update(|_, app| view.update(app, |view, cx| {
|
|
(view.mode, view.zoom) = (Mode::Two, Zoom::Scale(4.0));
|
|
cx.notify();
|
|
}));
|
|
frames(cx);
|
|
(view, cx)
|
|
}
|
|
|
|
#[test]
|
|
fn two_pages_keep_the_right_hand_page() {
|
|
let dir = tempfile::tempdir().expect("a temp dir");
|
|
let mut cx = TestAppContext::single();
|
|
let pages: &[(f32, f32, &[&str])] = &[(612.0, 792.0, &["one"]), (612.0, 792.0, &["two"]), (612.0, 792.0, &["three"])];
|
|
let (viewer, cx) = windowed(&mut cx, dir.path(), &[file(dir.path(), "three.pdf", pages)], true);
|
|
let view = shown(cx, &viewer);
|
|
settle(cx, |app| view.read(app).room.size.width > px(100.0));
|
|
cx.update(|_, app| view.update(app, |view, cx| {
|
|
view.mode = Mode::Two;
|
|
view.show(1, 0.0, cx);
|
|
}));
|
|
frames(cx);
|
|
assert_eq!(cx.update(|_, app| view.read(app).current), 1);
|
|
}
|
|
|
|
#[test]
|
|
fn scrolling_across_to_the_right_page_makes_it_current() {
|
|
let dir = tempfile::tempdir().expect("a temp dir");
|
|
let mut cx = TestAppContext::single();
|
|
let (view, cx) = zoomed_pair(&mut cx, dir.path());
|
|
cx.update(|_, app| view.update(app, |view, cx| {
|
|
let right = view.laid_out().placed[1].x;
|
|
let y = view.scroll.offset().y;
|
|
view.scroll.set_offset(point(px(-right), y));
|
|
cx.notify();
|
|
}));
|
|
frames(cx);
|
|
assert_eq!(cx.update(|_, app| view.read(app).current), 1);
|
|
}
|
|
|
|
#[test]
|
|
fn a_jump_to_the_right_page_brings_it_across() {
|
|
let dir = tempfile::tempdir().expect("a temp dir");
|
|
let mut cx = TestAppContext::single();
|
|
let (view, cx) = zoomed_pair(&mut cx, dir.path());
|
|
cx.update(|_, app| view.update(app, |view, cx| view.show(1, 0.0, cx)));
|
|
frames(cx);
|
|
let (x, left, wide) = cx.update(|_, app| {
|
|
let view = view.read(app);
|
|
(view.laid_out().placed[1].x, -f32::from(view.scroll.offset().x), f32::from(view.room.size.width))
|
|
});
|
|
assert!(x >= left && x < left + wide, "page at {x}, view {left}..{}", left + wide);
|
|
}
|
|
|
|
#[test]
|
|
fn ctrl_and_a_wheel_notch_step_the_zoom_once() {
|
|
let dir = tempfile::tempdir().expect("a temp dir");
|
|
let mut cx = TestAppContext::single();
|
|
let pages: &[(f32, f32, &[&str])] = &[(612.0, 792.0, &["one"]), (612.0, 792.0, &["two"]), (612.0, 792.0, &["three"])];
|
|
let (viewer, cx) = windowed(&mut cx, dir.path(), &[file(dir.path(), "three.pdf", pages)], true);
|
|
let view = shown(cx, &viewer);
|
|
settle(cx, |app| view.read(app).room.size.width > px(100.0));
|
|
cx.update(|_, app| view.update(app, |view, cx| view.change(|view, _| view.zoom = Zoom::Scale(1.0), cx)));
|
|
frames(cx);
|
|
let at = cx.update(|_, app| view.read(app).room.center());
|
|
let wheel = |modifiers, y| ScrollWheelEvent { position: at, delta: ScrollDelta::Lines(point(0.0, y)), modifiers, ..Default::default() };
|
|
let other = match cfg!(target_os = "macos") {
|
|
true => Modifiers { control: true, ..Default::default() },
|
|
false => Modifiers { platform: true, ..Default::default() },
|
|
};
|
|
let read = |cx: &mut VisualTestContext| cx.update(|_, app| (view.read(app).zoom, view.read(app).scroll.offset().y));
|
|
cx.simulate_event(wheel(other, -3.0));
|
|
frames(cx);
|
|
let (zoom, scrolled) = read(cx);
|
|
assert_eq!(zoom, Zoom::Scale(1.0), "only Ctrl, or Cmd on macOS");
|
|
assert!(scrolled < px(0.0), "a plain wheel scrolls");
|
|
cx.simulate_event(wheel(Modifiers::secondary_key(), 3.0));
|
|
frames(cx);
|
|
assert_eq!(read(cx).0, Zoom::Scale(crate::keys::stepped(1.0, true)), "a notch is one step");
|
|
cx.simulate_event(wheel(Modifiers::secondary_key(), -3.0));
|
|
cx.simulate_event(wheel(Modifiers::secondary_key(), -3.0));
|
|
frames(cx);
|
|
assert_eq!(read(cx).0, Zoom::Scale(crate::keys::stepped(1.0, false)));
|
|
}
|