it: test suspended state
This commit is contained in:
parent
3f4386609e
commit
91022cd1c8
12 changed files with 119 additions and 33 deletions
|
|
@ -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;
|
||||
|
|
|
|||
10
src/it.rs
10
src/it.rs
|
|
@ -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), _)) => {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 {}
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
);
|
||||
|
|
|
|||
|
|
@ -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()?;
|
||||
|
||||
|
|
|
|||
48
src/it/tests/t0022_toplevel_suspended.rs
Normal file
48
src/it/tests/t0022_toplevel_suspended.rs
Normal 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(())
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue