1
0
Fork 0
forked from wry/wry

it: test wlr-data-control

This commit is contained in:
Julian Orth 2024-04-03 13:47:07 +02:00
parent fd056c5361
commit 5c80d940af
11 changed files with 437 additions and 2 deletions

View file

@ -0,0 +1,111 @@
use {
crate::{
it::{
test_error::{TestError, TestResult},
test_ifs::{
test_data_control_offer::TestDataControlOffer,
test_data_control_source::TestDataControlSource,
},
test_object::TestObject,
test_transport::TestTransport,
test_utils::test_expected_event::TEEH,
testrun::ParseFull,
},
utils::{buffd::MsgParser, copyhashmap::CopyHashMap},
wire::{
zwlr_data_control_device_v1::*, ZwlrDataControlDeviceV1Id, ZwlrDataControlOfferV1Id,
},
},
std::{cell::Cell, rc::Rc},
};
pub struct TestDataControlDevice {
pub id: ZwlrDataControlDeviceV1Id,
pub tran: Rc<TestTransport>,
pub destroyed: Cell<bool>,
pub pending_offer: CopyHashMap<ZwlrDataControlOfferV1Id, Rc<TestDataControlOffer>>,
pub selection: TEEH<Option<Rc<TestDataControlOffer>>>,
pub primary_selection: TEEH<Option<Rc<TestDataControlOffer>>>,
}
impl TestDataControlDevice {
#[allow(dead_code)]
pub fn destroy(&self) -> TestResult {
if !self.destroyed.replace(true) {
self.tran.send(Destroy { self_id: self.id })?;
}
Ok(())
}
pub fn set_selection(&self, source: &TestDataControlSource) -> TestResult {
self.tran.send(SetSelection {
self_id: self.id,
source: source.id,
})?;
Ok(())
}
#[allow(dead_code)]
pub fn set_primary_selection(&self, source: &TestDataControlSource) -> TestResult {
self.tran.send(SetPrimarySelection {
self_id: self.id,
source: source.id,
})?;
Ok(())
}
fn handle_data_offer(&self, parser: MsgParser<'_, '_>) -> Result<(), TestError> {
let ev = DataOffer::parse_full(parser)?;
let obj = Rc::new(TestDataControlOffer {
id: ev.id,
tran: self.tran.clone(),
destroyed: Cell::new(false),
offers: Default::default(),
});
self.tran.add_obj(obj.clone())?;
self.pending_offer.set(obj.id, obj);
Ok(())
}
fn take_offer(
&self,
id: ZwlrDataControlOfferV1Id,
) -> TestResult<Option<Rc<TestDataControlOffer>>> {
if id.is_none() {
Ok(None)
} else {
match self.pending_offer.remove(&id) {
Some(o) => Ok(Some(o)),
_ => bail!("Unknown offer {}", id),
}
}
}
fn handle_selection(&self, parser: MsgParser<'_, '_>) -> Result<(), TestError> {
let ev = Selection::parse_full(parser)?;
self.selection.push(self.take_offer(ev.id)?);
Ok(())
}
fn handle_primary_selection(&self, parser: MsgParser<'_, '_>) -> Result<(), TestError> {
let ev = PrimarySelection::parse_full(parser)?;
self.primary_selection.push(self.take_offer(ev.id)?);
Ok(())
}
fn handle_finished(&self, parser: MsgParser<'_, '_>) -> Result<(), TestError> {
let _ev = Finished::parse_full(parser)?;
Ok(())
}
}
test_object! {
TestDataControlDevice, ZwlrDataControlDeviceV1;
DATA_OFFER => handle_data_offer,
SELECTION => handle_selection,
FINISHED => handle_finished,
PRIMARY_SELECTION => handle_primary_selection,
}
impl TestObject for TestDataControlDevice {}

View file

@ -0,0 +1,84 @@
use {
crate::{
it::{
test_error::TestResult,
test_ifs::{
test_data_control_device::TestDataControlDevice,
test_data_control_source::TestDataControlSource, test_seat::TestSeat,
},
test_object::TestObject,
test_transport::TestTransport,
},
wire::{zwlr_data_control_manager_v1::*, ZwlrDataControlManagerV1Id},
},
std::{cell::Cell, rc::Rc},
};
pub struct TestDataControlManager {
pub id: ZwlrDataControlManagerV1Id,
pub tran: Rc<TestTransport>,
pub destroyed: Cell<bool>,
}
impl TestDataControlManager {
pub fn new(tran: &Rc<TestTransport>) -> Self {
Self {
id: tran.id(),
tran: tran.clone(),
destroyed: Cell::new(false),
}
}
pub fn create_data_source(&self) -> TestResult<Rc<TestDataControlSource>> {
let obj = Rc::new(TestDataControlSource {
id: self.tran.id(),
tran: self.tran.clone(),
destroyed: Cell::new(false),
cancelled: Cell::new(false),
sends: Default::default(),
});
self.tran.add_obj(obj.clone())?;
self.tran.send(CreateDataSource {
self_id: self.id,
id: obj.id,
})?;
Ok(obj)
}
pub fn get_data_device(&self, seat: &TestSeat) -> TestResult<Rc<TestDataControlDevice>> {
let obj = Rc::new(TestDataControlDevice {
id: self.tran.id(),
tran: self.tran.clone(),
destroyed: Cell::new(false),
pending_offer: Default::default(),
selection: Default::default(),
primary_selection: Default::default(),
});
self.tran.add_obj(obj.clone())?;
self.tran.send(GetDataDevice {
self_id: self.id,
id: obj.id,
seat: seat.id,
})?;
Ok(obj)
}
pub fn destroy(&self) -> TestResult {
if !self.destroyed.replace(true) {
self.tran.send(Destroy { self_id: self.id })?;
}
Ok(())
}
}
impl Drop for TestDataControlManager {
fn drop(&mut self) {
let _ = self.destroy();
}
}
test_object! {
TestDataControlManager, ZwlrDataControlManagerV1;
}
impl TestObject for TestDataControlManager {}

View file

@ -0,0 +1,64 @@
use {
crate::{
it::{
test_error::{TestError, TestResult},
test_object::TestObject,
test_transport::TestTransport,
testrun::ParseFull,
},
utils::buffd::MsgParser,
wire::{zwlr_data_control_offer_v1::*, ZwlrDataControlOfferV1Id},
},
ahash::AHashSet,
std::{
cell::{Cell, RefCell},
rc::Rc,
},
uapi::{c, OwnedFd},
};
pub struct TestDataControlOffer {
pub id: ZwlrDataControlOfferV1Id,
pub tran: Rc<TestTransport>,
pub destroyed: Cell<bool>,
pub offers: RefCell<AHashSet<String>>,
}
impl TestDataControlOffer {
pub fn destroy(&self) -> TestResult {
if !self.destroyed.replace(true) {
self.tran.send(Destroy { self_id: self.id })?;
}
Ok(())
}
pub fn receive(&self, mime_type: &str) -> TestResult<Rc<OwnedFd>> {
let (read, write) = uapi::pipe2(c::O_CLOEXEC)?;
self.tran.send(Receive {
self_id: self.id,
mime_type,
fd: Rc::new(write),
})?;
Ok(Rc::new(read))
}
fn handle_offer(&self, parser: MsgParser<'_, '_>) -> Result<(), TestError> {
let ev = Offer::parse_full(parser)?;
self.offers.borrow_mut().insert(ev.mime_type.to_string());
Ok(())
}
}
impl Drop for TestDataControlOffer {
fn drop(&mut self) {
let _ = self.destroy();
}
}
test_object! {
TestDataControlOffer, ZwlrDataControlOfferV1;
OFFER => handle_offer,
}
impl TestObject for TestDataControlOffer {}

View file

@ -0,0 +1,67 @@
use {
crate::{
it::{
test_error::{TestError, TestResult},
test_object::TestObject,
test_transport::TestTransport,
test_utils::test_expected_event::TEEH,
testrun::ParseFull,
},
utils::buffd::MsgParser,
wire::{zwlr_data_control_source_v1::*, ZwlrDataControlSourceV1Id},
},
std::{cell::Cell, rc::Rc},
uapi::OwnedFd,
};
pub struct TestDataControlSource {
pub id: ZwlrDataControlSourceV1Id,
pub tran: Rc<TestTransport>,
pub destroyed: Cell<bool>,
pub cancelled: Cell<bool>,
pub sends: TEEH<(String, Rc<OwnedFd>)>,
}
impl TestDataControlSource {
pub fn destroy(&self) -> TestResult {
if !self.destroyed.replace(true) {
self.tran.send(Destroy { self_id: self.id })?;
}
Ok(())
}
pub fn offer(&self, mime_type: &str) -> TestResult {
self.tran.send(Offer {
self_id: self.id,
mime_type,
})?;
Ok(())
}
fn handle_send(&self, parser: MsgParser<'_, '_>) -> Result<(), TestError> {
let ev = Send::parse_full(parser)?;
self.sends.push((ev.mime_type.to_string(), ev.fd));
Ok(())
}
fn handle_cancelled(&self, parser: MsgParser<'_, '_>) -> Result<(), TestError> {
let _ev = Cancelled::parse_full(parser)?;
self.cancelled.set(true);
Ok(())
}
}
impl Drop for TestDataControlSource {
fn drop(&mut self) {
let _ = self.destroy();
}
}
test_object! {
TestDataControlSource, ZwlrDataControlSourceV1;
SEND => handle_send,
CANCELLED => handle_cancelled,
}
impl TestObject for TestDataControlSource {}

View file

@ -32,6 +32,7 @@ impl TestDataDeviceManager {
id: self.tran.id(),
tran: self.tran.clone(),
destroyed: Cell::new(false),
sends: Rc::new(Default::default()),
});
self.tran.add_obj(data_source.clone())?;
self.tran.send(CreateDataSource {

View file

@ -2,18 +2,20 @@ use {
crate::{
it::{
test_error::TestResult, test_object::TestObject, test_transport::TestTransport,
testrun::ParseFull,
test_utils::test_expected_event::TEEH, testrun::ParseFull,
},
utils::buffd::MsgParser,
wire::{wl_data_source::*, WlDataSourceId},
},
std::{cell::Cell, rc::Rc},
uapi::OwnedFd,
};
pub struct TestDataSource {
pub id: WlDataSourceId,
pub tran: Rc<TestTransport>,
pub destroyed: Cell<bool>,
pub sends: TEEH<(String, Rc<OwnedFd>)>,
}
impl TestDataSource {
@ -48,7 +50,8 @@ impl TestDataSource {
}
fn handle_send(&self, parser: MsgParser<'_, '_>) -> TestResult {
let _ev = Send::parse_full(parser)?;
let ev = Send::parse_full(parser)?;
self.sends.push((ev.mime_type.to_string(), ev.fd));
Ok(())
}

View file

@ -7,6 +7,7 @@ use {
test_ifs::{
test_compositor::TestCompositor, test_content_type_manager::TestContentTypeManager,
test_cursor_shape_manager::TestCursorShapeManager,
test_data_control_manager::TestDataControlManager,
test_data_device_manager::TestDataDeviceManager,
test_ext_foreign_toplevel_list::TestExtForeignToplevelList,
test_jay_compositor::TestJayCompositor, test_shm::TestShm,
@ -45,6 +46,7 @@ pub struct TestRegistrySingletons {
pub wp_cursor_shape_manager_v1: u32,
pub wp_linux_drm_syncobj_manager_v1: u32,
pub wp_content_type_manager_v1: u32,
pub zwlr_data_control_manager_v1: u32,
}
pub struct TestRegistry {
@ -65,6 +67,7 @@ pub struct TestRegistry {
pub cursor_shape_manager: CloneCell<Option<Rc<TestCursorShapeManager>>>,
pub syncobj_manager: CloneCell<Option<Rc<TestSyncobjManager>>>,
pub content_type_manager: CloneCell<Option<Rc<TestContentTypeManager>>>,
pub data_control_manager: CloneCell<Option<Rc<TestDataControlManager>>>,
pub seats: CopyHashMap<GlobalName, Rc<WlSeatGlobal>>,
}
@ -129,6 +132,7 @@ impl TestRegistry {
wp_cursor_shape_manager_v1,
wp_linux_drm_syncobj_manager_v1,
wp_content_type_manager_v1,
zwlr_data_control_manager_v1,
};
self.singletons.set(Some(singletons.clone()));
Ok(singletons)
@ -201,6 +205,13 @@ impl TestRegistry {
1,
TestContentTypeManager
);
create_singleton!(
get_data_control_manager,
data_control_manager,
zwlr_data_control_manager_v1,
2,
TestDataControlManager
);
pub fn bind<O: TestObject>(
&self,