You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
259 lines
8.5 KiB
259 lines
8.5 KiB
/* |
|
SPDX-FileCopyrightText: 2014 Martin Gräßlin <mgraesslin@kde.org> |
|
|
|
SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL |
|
*/ |
|
// Qt |
|
#include <QMimeDatabase> |
|
#include <QSignalSpy> |
|
#include <QTemporaryFile> |
|
#include <QTest> |
|
|
|
#include "wayland/datadevicemanager.h" |
|
#include "wayland/datasource.h" |
|
#include "wayland/display.h" |
|
|
|
// KWayland |
|
#include "KWayland/Client/connection_thread.h" |
|
#include "KWayland/Client/datadevicemanager.h" |
|
#include "KWayland/Client/datasource.h" |
|
#include "KWayland/Client/event_queue.h" |
|
#include "KWayland/Client/registry.h" |
|
|
|
// Wayland |
|
#include <wayland-client.h> |
|
|
|
class TestDataSource : public QObject |
|
{ |
|
Q_OBJECT |
|
private Q_SLOTS: |
|
void init(); |
|
void cleanup(); |
|
|
|
void testOffer(); |
|
void testTargetAccepts_data(); |
|
void testTargetAccepts(); |
|
void testRequestSend(); |
|
void testCancel(); |
|
void testServerGet(); |
|
|
|
private: |
|
KWin::Display *m_display = nullptr; |
|
KWin::DataDeviceManagerInterface *m_dataDeviceManagerInterface = nullptr; |
|
KWayland::Client::ConnectionThread *m_connection = nullptr; |
|
KWayland::Client::DataDeviceManager *m_dataDeviceManager = nullptr; |
|
KWayland::Client::EventQueue *m_queue = nullptr; |
|
QThread *m_thread = nullptr; |
|
}; |
|
|
|
static const QString s_socketName = QStringLiteral("kwayland-test-wayland-datasource-0"); |
|
|
|
void TestDataSource::init() |
|
{ |
|
using namespace KWin; |
|
delete m_display; |
|
m_display = new KWin::Display(this); |
|
m_display->addSocketName(s_socketName); |
|
m_display->start(); |
|
QVERIFY(m_display->isRunning()); |
|
|
|
// setup connection |
|
m_connection = new KWayland::Client::ConnectionThread; |
|
QSignalSpy connectedSpy(m_connection, &KWayland::Client::ConnectionThread::connected); |
|
m_connection->setSocketName(s_socketName); |
|
|
|
m_thread = new QThread(this); |
|
m_connection->moveToThread(m_thread); |
|
m_thread->start(); |
|
|
|
m_connection->initConnection(); |
|
QVERIFY(connectedSpy.wait()); |
|
|
|
m_queue = new KWayland::Client::EventQueue(this); |
|
QVERIFY(!m_queue->isValid()); |
|
m_queue->setup(m_connection); |
|
QVERIFY(m_queue->isValid()); |
|
|
|
KWayland::Client::Registry registry; |
|
QSignalSpy dataDeviceManagerSpy(®istry, &KWayland::Client::Registry::dataDeviceManagerAnnounced); |
|
QVERIFY(!registry.eventQueue()); |
|
registry.setEventQueue(m_queue); |
|
QCOMPARE(registry.eventQueue(), m_queue); |
|
registry.create(m_connection->display()); |
|
QVERIFY(registry.isValid()); |
|
registry.setup(); |
|
|
|
m_dataDeviceManagerInterface = new DataDeviceManagerInterface(m_display, m_display); |
|
|
|
QVERIFY(dataDeviceManagerSpy.wait()); |
|
m_dataDeviceManager = |
|
registry.createDataDeviceManager(dataDeviceManagerSpy.first().first().value<quint32>(), dataDeviceManagerSpy.first().last().value<quint32>(), this); |
|
} |
|
|
|
void TestDataSource::cleanup() |
|
{ |
|
if (m_dataDeviceManager) { |
|
delete m_dataDeviceManager; |
|
m_dataDeviceManager = nullptr; |
|
} |
|
if (m_queue) { |
|
delete m_queue; |
|
m_queue = nullptr; |
|
} |
|
if (m_thread) { |
|
m_thread->quit(); |
|
m_thread->wait(); |
|
delete m_thread; |
|
m_thread = nullptr; |
|
} |
|
delete m_connection; |
|
m_connection = nullptr; |
|
|
|
delete m_display; |
|
m_display = nullptr; |
|
} |
|
|
|
void TestDataSource::testOffer() |
|
{ |
|
using namespace KWin; |
|
|
|
qRegisterMetaType<KWin::DataSourceInterface *>(); |
|
QSignalSpy dataSourceCreatedSpy(m_dataDeviceManagerInterface, &KWin::DataDeviceManagerInterface::dataSourceCreated); |
|
|
|
std::unique_ptr<KWayland::Client::DataSource> dataSource(m_dataDeviceManager->createDataSource()); |
|
QVERIFY(dataSource->isValid()); |
|
|
|
QVERIFY(dataSourceCreatedSpy.wait()); |
|
QCOMPARE(dataSourceCreatedSpy.count(), 1); |
|
|
|
QPointer<DataSourceInterface> serverDataSource = dataSourceCreatedSpy.first().first().value<DataSourceInterface *>(); |
|
QVERIFY(!serverDataSource.isNull()); |
|
QCOMPARE(serverDataSource->mimeTypes().count(), 0); |
|
|
|
QSignalSpy offeredSpy(serverDataSource.data(), &KWin::AbstractDataSource::mimeTypeOffered); |
|
|
|
const QString plain = QStringLiteral("text/plain"); |
|
QMimeDatabase db; |
|
dataSource->offer(db.mimeTypeForName(plain)); |
|
|
|
QVERIFY(offeredSpy.wait()); |
|
QCOMPARE(offeredSpy.count(), 1); |
|
QCOMPARE(offeredSpy.last().first().toString(), plain); |
|
QCOMPARE(serverDataSource->mimeTypes().count(), 1); |
|
QCOMPARE(serverDataSource->mimeTypes().first(), plain); |
|
|
|
const QString html = QStringLiteral("text/html"); |
|
dataSource->offer(db.mimeTypeForName(html)); |
|
|
|
QVERIFY(offeredSpy.wait()); |
|
QCOMPARE(offeredSpy.count(), 2); |
|
QCOMPARE(offeredSpy.first().first().toString(), plain); |
|
QCOMPARE(offeredSpy.last().first().toString(), html); |
|
QCOMPARE(serverDataSource->mimeTypes().count(), 2); |
|
QCOMPARE(serverDataSource->mimeTypes().first(), plain); |
|
QCOMPARE(serverDataSource->mimeTypes().last(), html); |
|
|
|
// try destroying the client side, should trigger a destroy of server side |
|
dataSource.reset(); |
|
QVERIFY(!serverDataSource.isNull()); |
|
wl_display_flush(m_connection->display()); |
|
QCoreApplication::processEvents(); |
|
QVERIFY(serverDataSource.isNull()); |
|
} |
|
|
|
void TestDataSource::testTargetAccepts_data() |
|
{ |
|
QTest::addColumn<QString>("mimeType"); |
|
|
|
QTest::newRow("empty") << QString(); |
|
QTest::newRow("text/plain") << QStringLiteral("text/plain"); |
|
} |
|
|
|
void TestDataSource::testTargetAccepts() |
|
{ |
|
using namespace KWin; |
|
|
|
QSignalSpy dataSourceCreatedSpy(m_dataDeviceManagerInterface, &KWin::DataDeviceManagerInterface::dataSourceCreated); |
|
|
|
std::unique_ptr<KWayland::Client::DataSource> dataSource(m_dataDeviceManager->createDataSource()); |
|
QVERIFY(dataSource->isValid()); |
|
|
|
QSignalSpy targetAcceptsSpy(dataSource.get(), &KWayland::Client::DataSource::targetAccepts); |
|
|
|
QVERIFY(dataSourceCreatedSpy.wait()); |
|
QCOMPARE(dataSourceCreatedSpy.count(), 1); |
|
|
|
QFETCH(QString, mimeType); |
|
dataSourceCreatedSpy.first().first().value<DataSourceInterface *>()->accept(mimeType); |
|
|
|
QVERIFY(targetAcceptsSpy.wait()); |
|
QCOMPARE(targetAcceptsSpy.count(), 1); |
|
QCOMPARE(targetAcceptsSpy.first().first().toString(), mimeType); |
|
} |
|
|
|
void TestDataSource::testRequestSend() |
|
{ |
|
using namespace KWin; |
|
|
|
QSignalSpy dataSourceCreatedSpy(m_dataDeviceManagerInterface, &KWin::DataDeviceManagerInterface::dataSourceCreated); |
|
|
|
std::unique_ptr<KWayland::Client::DataSource> dataSource(m_dataDeviceManager->createDataSource()); |
|
QVERIFY(dataSource->isValid()); |
|
QSignalSpy sendRequestedSpy(dataSource.get(), &KWayland::Client::DataSource::sendDataRequested); |
|
|
|
const QString plain = QStringLiteral("text/plain"); |
|
QVERIFY(dataSourceCreatedSpy.wait()); |
|
QCOMPARE(dataSourceCreatedSpy.count(), 1); |
|
QTemporaryFile file; |
|
QVERIFY(file.open()); |
|
dataSourceCreatedSpy.first().first().value<DataSourceInterface *>()->requestData(plain, file.handle()); |
|
|
|
QVERIFY(sendRequestedSpy.wait()); |
|
QCOMPARE(sendRequestedSpy.count(), 1); |
|
QCOMPARE(sendRequestedSpy.first().first().toString(), plain); |
|
QCOMPARE(sendRequestedSpy.first().last().value<qint32>(), file.handle()); |
|
QVERIFY(sendRequestedSpy.first().last().value<qint32>() != -1); |
|
|
|
QFile writeFile; |
|
QVERIFY(writeFile.open(sendRequestedSpy.first().last().value<qint32>(), QFile::WriteOnly, QFileDevice::AutoCloseHandle)); |
|
writeFile.close(); |
|
} |
|
|
|
void TestDataSource::testCancel() |
|
{ |
|
using namespace KWin; |
|
|
|
QSignalSpy dataSourceCreatedSpy(m_dataDeviceManagerInterface, &KWin::DataDeviceManagerInterface::dataSourceCreated); |
|
|
|
std::unique_ptr<KWayland::Client::DataSource> dataSource(m_dataDeviceManager->createDataSource()); |
|
QVERIFY(dataSource->isValid()); |
|
QSignalSpy cancelledSpy(dataSource.get(), &KWayland::Client::DataSource::cancelled); |
|
|
|
QVERIFY(dataSourceCreatedSpy.wait()); |
|
|
|
QCOMPARE(cancelledSpy.count(), 0); |
|
dataSourceCreatedSpy.first().first().value<DataSourceInterface *>()->cancel(); |
|
|
|
QVERIFY(cancelledSpy.wait()); |
|
QCOMPARE(cancelledSpy.count(), 1); |
|
} |
|
|
|
void TestDataSource::testServerGet() |
|
{ |
|
using namespace KWin; |
|
|
|
QSignalSpy dataSourceCreatedSpy(m_dataDeviceManagerInterface, &KWin::DataDeviceManagerInterface::dataSourceCreated); |
|
|
|
std::unique_ptr<KWayland::Client::DataSource> dataSource(m_dataDeviceManager->createDataSource()); |
|
QVERIFY(dataSource->isValid()); |
|
|
|
QVERIFY(!DataSourceInterface::get(nullptr)); |
|
QVERIFY(dataSourceCreatedSpy.wait()); |
|
auto d = dataSourceCreatedSpy.first().first().value<DataSourceInterface *>(); |
|
|
|
QCOMPARE(DataSourceInterface::get(d->resource()), d); |
|
QVERIFY(!DataSourceInterface::get(nullptr)); |
|
} |
|
|
|
QTEST_GUILESS_MAIN(TestDataSource) |
|
#include "test_datasource.moc"
|
|
|