1
0
Fork 0
forked from wry/wry

it: test suspended state

This commit is contained in:
Julian Orth 2024-04-02 14:30:24 +02:00
parent 3f4386609e
commit 91022cd1c8
12 changed files with 119 additions and 33 deletions

View file

@ -64,7 +64,7 @@ const STATE_TILED_LEFT: u32 = 5;
const STATE_TILED_RIGHT: u32 = 6;
const STATE_TILED_TOP: u32 = 7;
const STATE_TILED_BOTTOM: u32 = 8;
const STATE_SUSPENDED: u32 = 9;
pub const STATE_SUSPENDED: u32 = 9;
#[allow(dead_code)]
const CAP_WINDOW_MENU: u32 = 1;

View file

@ -42,6 +42,10 @@ mod tests;
const SINGLE_THREAD: bool = false;
pub fn run_tests() {
run_tests_(tests::tests());
}
fn run_tests_(tests: Vec<&'static dyn TestCase>) {
leaks::init();
test_logger::install();
test_logger::set_level(Level::Trace);
@ -54,13 +58,13 @@ pub fn run_tests() {
failed: Default::default(),
});
if SINGLE_THREAD {
for test in tests::tests() {
for test in tests {
with_test_config(|cfg| {
run_test(&it_run, test, cfg);
})
}
} else {
let queue = Arc::new(Mutex::new(VecDeque::from_iter(tests::tests())));
let queue = Arc::new(Mutex::new(VecDeque::from_iter(tests)));
let mut threads = vec![];
let num_cpus = match num_cpus() {
Ok(n) => n,
@ -139,7 +143,7 @@ fn run_test(it_run: &ItRun, test: &'static dyn TestCase, cfg: Rc<TestConfig>) {
Box::new(async move {
let future: Pin<_> = test.run(testrun.clone()).into();
let future = state.eng.spawn2(Phase::Present, future);
let timeout = state.wheel.timeout(5000);
let timeout = state.wheel.timeout(500000);
match future::select(future, timeout).await {
Either::Left((Ok(..), _)) => {}
Either::Left((Err(e), _)) => {

View file

@ -81,6 +81,7 @@ impl TestClient {
}
pub async fn sync(&self) {
self.run.state.eng.yield_now().await;
self.run.sync().await;
self.tran.sync().await;
}

View file

@ -193,7 +193,7 @@ impl TestRegistry {
tran: self.tran.clone(),
destroyed: Cell::new(false),
});
self.bind(&jc, singletons.xdg_wm_base, 3)?;
self.bind(&jc, singletons.xdg_wm_base, 6)?;
self.xdg.set(Some(jc.clone()));
Ok(jc)
}

View file

@ -2,8 +2,11 @@ use {
crate::{
ifs::wl_surface::xdg_surface::XdgSurface,
it::{
test_error::TestError, test_ifs::test_xdg_toplevel::TestXdgToplevel,
test_object::TestObject, test_transport::TestTransport, testrun::ParseFull,
test_error::TestError,
test_ifs::test_xdg_toplevel::{TestXdgToplevel, TestXdgToplevelCore},
test_object::TestObject,
test_transport::TestTransport,
testrun::ParseFull,
},
utils::buffd::MsgParser,
wire::{xdg_surface::*, XdgSurfaceId},
@ -33,20 +36,20 @@ impl TestXdgSurface {
self_id: self.id,
id,
})?;
self.tran.sync().await;
let client = self.tran.get_client()?;
let server = client.lookup(id)?;
let tl = Rc::new(TestXdgToplevel {
let core = Rc::new(TestXdgToplevelCore {
id,
tran: self.tran.clone(),
destroyed: Cell::new(false),
server,
width: Cell::new(0),
height: Cell::new(0),
states: Default::default(),
close_requested: Cell::new(false),
});
self.tran.add_obj(tl.clone())?;
self.tran.add_obj(core.clone())?;
self.tran.sync().await;
let client = self.tran.get_client()?;
let server = client.lookup(id)?;
let tl = Rc::new(TestXdgToplevel { core, server });
Ok(tl)
}

View file

@ -18,11 +18,10 @@ use {
},
};
pub struct TestXdgToplevel {
pub struct TestXdgToplevelCore {
pub id: XdgToplevelId,
pub tran: Rc<TestTransport>,
pub destroyed: Cell<bool>,
pub server: Rc<XdgToplevel>,
pub width: Cell<i32>,
pub height: Cell<i32>,
@ -31,14 +30,12 @@ pub struct TestXdgToplevel {
pub close_requested: Cell<bool>,
}
impl TestXdgToplevel {
pub fn destroy(&self) -> Result<(), TestError> {
if !self.destroyed.replace(true) {
self.tran.send(Destroy { self_id: self.id })?;
}
Ok(())
}
pub struct TestXdgToplevel {
pub core: Rc<TestXdgToplevelCore>,
pub server: Rc<XdgToplevel>,
}
impl TestXdgToplevel {
pub fn container_parent(&self) -> TestResult<Rc<ContainerNode>> {
let parent = match self.server.tl_data().parent.get() {
Some(p) => p,
@ -49,6 +46,15 @@ impl TestXdgToplevel {
_ => bail!("toplevel parent is not a container"),
}
}
}
impl TestXdgToplevelCore {
pub fn destroy(&self) -> Result<(), TestError> {
if !self.destroyed.replace(true) {
self.tran.send(Destroy { self_id: self.id })?;
}
Ok(())
}
fn handle_configure(&self, parser: MsgParser<'_, '_>) -> Result<(), TestError> {
let ev = Configure::parse_full(parser)?;
@ -68,20 +74,26 @@ impl TestXdgToplevel {
let _ev = ConfigureBounds::parse_full(parser)?;
Ok(())
}
fn handle_wm_capabilities(&self, parser: MsgParser<'_, '_>) -> Result<(), TestError> {
let _ev = WmCapabilities::parse_full(parser)?;
Ok(())
}
}
impl Drop for TestXdgToplevel {
impl Drop for TestXdgToplevelCore {
fn drop(&mut self) {
let _ = self.destroy();
}
}
test_object! {
TestXdgToplevel, XdgToplevel;
TestXdgToplevelCore, XdgToplevel;
CONFIGURE => handle_configure,
CLOSE => handle_close,
CONFIGURE_BOUNDS => handle_configure_bounds,
WM_CAPABILITIES => handle_wm_capabilities,
}
impl TestObject for TestXdgToplevel {}
impl TestObject for TestXdgToplevelCore {}

View file

@ -1,13 +1,20 @@
use {
crate::{
it::test_error::TestResult,
tree::{OutputNode, WorkspaceNode},
it::{
test_error::TestResult,
test_utils::{
test_container_node_ext::TestContainerExt,
test_workspace_node_ext::TestWorkspaceNodeExt,
},
},
tree::{OutputNode, ToplevelNode, WorkspaceNode},
},
std::rc::Rc,
};
pub trait TestOutputNodeExt {
fn workspace(&self) -> TestResult<Rc<WorkspaceNode>>;
fn first_toplevel(&self) -> TestResult<Rc<dyn ToplevelNode>>;
}
impl TestOutputNodeExt for OutputNode {
@ -17,4 +24,8 @@ impl TestOutputNodeExt for OutputNode {
Some(w) => Ok(w),
}
}
fn first_toplevel(&self) -> TestResult<Rc<dyn ToplevelNode>> {
self.workspace()?.container()?.first_toplevel()
}
}

View file

@ -28,7 +28,7 @@ impl TestWindow {
self.surface.attach(buffer.id)?;
self.viewport.set_source(0, 0, 1, 1)?;
self.viewport
.set_destination(self.tl.width.get(), self.tl.height.get())?;
.set_destination(self.tl.core.width.get(), self.tl.core.height.get())?;
self.xdg.ack_configure(self.xdg.last_serial.get())?;
self.surface.commit()?;
self.surface.tran.sync().await;

View file

@ -23,6 +23,11 @@ macro_rules! testcase {
Box::new(test(testrun))
}
}
#[test]
fn single() {
crate::it::run_tests_(vec![&Test])
}
};
}
@ -47,6 +52,7 @@ mod t0018_click_to_active_ws;
mod t0019_natural_scrolling;
mod t0020_surface_offset;
mod t0021_preferred_buffer_scale;
mod t0022_toplevel_suspended;
pub trait TestCase: Sync {
fn name(&self) -> &'static str;
@ -87,5 +93,6 @@ pub fn tests() -> Vec<&'static dyn TestCase> {
t0019_natural_scrolling,
t0020_surface_offset,
t0021_preferred_buffer_scale,
t0022_toplevel_suspended,
}
}

View file

@ -18,9 +18,9 @@ async fn test(run: Rc<TestRun>) -> Result<(), TestError> {
let window = client.create_window().await?;
window.map().await?;
tassert_eq!(window.tl.width.get(), 800);
tassert_eq!(window.tl.core.width.get(), 800);
tassert_eq!(
window.tl.height.get(),
window.tl.core.height.get(),
600 - 2 * (run.state.theme.sizes.title_height.get() + 1)
);
@ -29,8 +29,8 @@ async fn test(run: Rc<TestRun>) -> Result<(), TestError> {
Rect::new_sized(
0,
2 * (run.state.theme.sizes.title_height.get() + 1),
window.tl.width.get(),
window.tl.height.get(),
window.tl.core.width.get(),
window.tl.core.height.get(),
)
.unwrap()
);

View file

@ -35,7 +35,7 @@ async fn test(run: Rc<TestRun>) -> TestResult {
// | w_tiled | [ w_mono1 | w_mono2 ] | with w_mono2 visible and active
client.sync().await;
tassert_eq!(w_tiled.tl.width.get(), w_mono2.tl.width.get());
tassert_eq!(w_tiled.tl.core.width.get(), w_mono2.tl.core.width.get());
let enters = dss.kb.enter.expect()?;

View file

@ -0,0 +1,48 @@
use {
crate::{
ifs::wl_surface::xdg_surface::xdg_toplevel::STATE_SUSPENDED,
it::{
test_error::TestResult,
test_utils::{
test_ouput_node_ext::TestOutputNodeExt, test_toplevel_node_ext::TestToplevelNodeExt,
},
testrun::TestRun,
},
},
isnt::std_1::collections::IsntHashSet2Ext,
std::rc::Rc,
};
testcase!();
async fn test(run: Rc<TestRun>) -> TestResult {
let ds = run.create_default_setup().await?;
let client = run.create_client().await?;
let win1 = client.create_window().await?;
win1.set_color(255, 0, 0, 255);
win1.map2().await?;
let win2 = client.create_window().await?;
win2.set_color(0, 255, 0, 255);
win2.map2().await?;
let (x, y) = ds.output.first_toplevel()?.center();
ds.move_to(x, y);
tassert!(win2.tl.core.states.borrow().not_contains(&STATE_SUSPENDED));
client.sync().await;
run.cfg.set_mono(ds.seat.id(), true)?;
client.sync().await;
tassert!(win2.tl.core.states.borrow().contains(&STATE_SUSPENDED));
run.cfg.set_mono(ds.seat.id(), false)?;
client.sync().await;
tassert!(win2.tl.core.states.borrow().not_contains(&STATE_SUSPENDED));
Ok(())
}