QClipboard-test: Fix test

- Use QFINDTESTDATA to locate sub-executables
- Remove dependency on QtWidgets, use QGuiApplication everywhere.
- Improve error handling when running sub-executables, prevent
  hangs (Windows)

Change-Id: If8e3be82f855c8be6bdbfc9f9728e8490ed181f3
Reviewed-by: Rohan McGovern <rohan.mcgovern@nokia.com>
This commit is contained in:
Friedemann Kleint 2011-12-09 17:14:52 +01:00 committed by Qt by Nokia
parent 3c189d9b74
commit 1a5f5d0056
5 changed files with 122 additions and 72 deletions

View File

@ -3,7 +3,6 @@ TARGET =
DEPENDPATH += . DEPENDPATH += .
INCLUDEPATH += . INCLUDEPATH += .
CONFIG -= app_bundle CONFIG -= app_bundle
QT += widgets
win32: DESTDIR = ../copier win32: DESTDIR = ../copier
# Input # Input
SOURCES += main.cpp SOURCES += main.cpp

View File

@ -38,17 +38,19 @@
** $QT_END_LICENSE$ ** $QT_END_LICENSE$
** **
****************************************************************************/ ****************************************************************************/
#include <QApplication> #include <QtGui/QGuiApplication>
#include <QClipboard> #include <QtGui/QClipboard>
#include <QStringList> #include <QtCore/QStringList>
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
QApplication app(argc, argv); QGuiApplication app(argc, argv);
QClipboard *board = QApplication::clipboard(); QString paste = QStringLiteral("testString.!");
#ifdef Q_OS_WINCE #ifndef Q_OS_WINCE
board->setText(QLatin1String("testString.!")); const QStringList arguments = app.arguments();
#else if (arguments.size() > 1)
board->setText(app.arguments().at(1)); paste = arguments.at(1);
#endif #endif
QGuiApplication::clipboard()->setText(paste);
return 0; return 0;
} }

View File

@ -38,17 +38,18 @@
** $QT_END_LICENSE$ ** $QT_END_LICENSE$
** **
****************************************************************************/ ****************************************************************************/
#include <QApplication> #include <QtGui/QGuiApplication>
#include <QClipboard> #include <QtGui/QClipboard>
#include <QStringList> #include <QtCore/QStringList>
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
QApplication app(argc, argv); QGuiApplication app(argc, argv);
QClipboard *board = QApplication::clipboard(); QString expected = QStringLiteral("testString.!");
#ifdef Q_OS_WINCE #ifndef Q_OS_WINCE
return (board->text() == QLatin1String("testString.!")) ? 0 : 1; const QStringList arguments = app.arguments();
#else if (arguments.size() > 1)
return (board->text() == app.arguments().at(1)) ? 0 : 1; expected = arguments.at(1);
#endif #endif
return QGuiApplication::clipboard()->text() == expected ? 0 : 1;
} }

View File

@ -4,7 +4,6 @@ DEPENDPATH += .
INCLUDEPATH += . INCLUDEPATH += .
win32: DESTDIR = ../paster win32: DESTDIR = ../paster
CONFIG -= app_bundle CONFIG -= app_bundle
QT += widgets
# Input # Input
SOURCES += main.cpp SOURCES += main.cpp

View File

@ -42,7 +42,9 @@
#include <QtTest/QtTest> #include <QtTest/QtTest>
#include <QtCore/QDebug> #include <QtCore/QDebug>
#include <QtWidgets/QApplication> #include <QtCore/QFileInfo>
#include <QtCore/QDir>
#include <QtGui/QGuiApplication>
#include <QtGui/QClipboard> #include <QtGui/QClipboard>
#ifdef Q_WS_MAC #ifdef Q_WS_MAC
#include <Carbon/Carbon.h> #include <Carbon/Carbon.h>
@ -52,8 +54,9 @@ class tst_QClipboard : public QObject
{ {
Q_OBJECT Q_OBJECT
private slots: private slots:
void init();
void copy_exit_paste(); void copy_exit_paste();
void capabiliyFunctions(); void capabilityFunctions();
void modes(); void modes();
void testSignals(); void testSignals();
void setMimeData(); void setMimeData();
@ -63,6 +66,11 @@ private:
bool nativeClipboardWorking(); bool nativeClipboardWorking();
}; };
void tst_QClipboard::init()
{
const QString testdataDir = QFileInfo(QFINDTESTDATA("copier")).absolutePath();
QVERIFY2(QDir::setCurrent(testdataDir), qPrintable("Could not chdir to " + testdataDir));
}
bool tst_QClipboard::nativeClipboardWorking() bool tst_QClipboard::nativeClipboardWorking()
{ {
@ -82,9 +90,9 @@ Q_DECLARE_METATYPE(QClipboard::Mode)
Tests that the capability functions are implemented on all Tests that the capability functions are implemented on all
platforms. platforms.
*/ */
void tst_QClipboard::capabiliyFunctions() void tst_QClipboard::capabilityFunctions()
{ {
QClipboard * const clipboard = QApplication::clipboard(); QClipboard * const clipboard = QGuiApplication::clipboard();
clipboard->supportsSelection(); clipboard->supportsSelection();
clipboard->supportsFindBuffer(); clipboard->supportsFindBuffer();
@ -99,7 +107,7 @@ void tst_QClipboard::capabiliyFunctions()
*/ */
void tst_QClipboard::modes() void tst_QClipboard::modes()
{ {
QClipboard * const clipboard = QApplication::clipboard(); QClipboard * const clipboard = QGuiApplication::clipboard();
if (!nativeClipboardWorking()) if (!nativeClipboardWorking())
QSKIP("Native clipboard not working in this setup"); QSKIP("Native clipboard not working in this setup");
@ -124,7 +132,7 @@ void tst_QClipboard::modes()
} }
/* /*
Test that the appropriate signals are emitted when the cliboard Test that the appropriate signals are emitted when the clipboard
contents is changed by calling the qt functions. contents is changed by calling the qt functions.
*/ */
void tst_QClipboard::testSignals() void tst_QClipboard::testSignals()
@ -134,7 +142,7 @@ void tst_QClipboard::testSignals()
if (!nativeClipboardWorking()) if (!nativeClipboardWorking())
QSKIP("Native clipboard not working in this setup"); QSKIP("Native clipboard not working in this setup");
QClipboard * const clipboard = QApplication::clipboard(); QClipboard * const clipboard = QGuiApplication::clipboard();
QSignalSpy changedSpy(clipboard, SIGNAL(changed(QClipboard::Mode))); QSignalSpy changedSpy(clipboard, SIGNAL(changed(QClipboard::Mode)));
QSignalSpy dataChangedSpy(clipboard, SIGNAL(dataChanged())); QSignalSpy dataChangedSpy(clipboard, SIGNAL(dataChanged()));
@ -182,6 +190,44 @@ void tst_QClipboard::testSignals()
QCOMPARE(dataChangedSpy.count(), 1); QCOMPARE(dataChangedSpy.count(), 1);
} }
static bool runHelper(const QString &program, const QStringList &arguments, QByteArray *errorMessage)
{
QProcess process;
process.setReadChannelMode(QProcess::ForwardedChannels);
process.start(program, arguments);
if (!process.waitForStarted()) {
*errorMessage = "Unable to start '" + program.toLocal8Bit() + " ': "
+ process.errorString().toLocal8Bit();
return false;
}
// Windows: Due to implementation changes, the event loop needs
// to be spun since we ourselves also need to answer the
// WM_DRAWCLIPBOARD message as we are in the chain of clipboard
// viewers.
bool running = true;
for (int i = 0; i < 60 && running; ++i) {
QGuiApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
if (process.waitForFinished(500))
running = false;
}
if (running) {
process.kill();
*errorMessage = "Timeout running '" + program.toLocal8Bit() + '\'';
return false;
}
if (process.exitStatus() != QProcess::NormalExit) {
*errorMessage = "Process '" + program.toLocal8Bit() + "' crashed.";
return false;
}
if (process.exitCode()) {
*errorMessage = "Process '" + program.toLocal8Bit() + "' returns "
+ QByteArray::number(process.exitCode());
return false;
}
return true;
}
// Test that pasted text remains on the clipboard after a Qt application exits. // Test that pasted text remains on the clipboard after a Qt application exits.
void tst_QClipboard::copy_exit_paste() void tst_QClipboard::copy_exit_paste()
{ {
@ -192,13 +238,16 @@ void tst_QClipboard::copy_exit_paste()
#endif #endif
if (!nativeClipboardWorking()) if (!nativeClipboardWorking())
QSKIP("Native clipboard not working in this setup"); QSKIP("Native clipboard not working in this setup");
const QStringList stringArgument = QStringList() << "Test string."; const QStringList stringArgument(QStringLiteral("Test string."));
QCOMPARE(QProcess::execute("copier/copier", stringArgument), 0); QByteArray errorMessage;
QVERIFY2(runHelper(QStringLiteral("copier/copier"), stringArgument, &errorMessage),
errorMessage.constData());
#ifdef Q_OS_MAC #ifdef Q_OS_MAC
// The Pasteboard needs a moment to breathe (at least on older Macs). // The Pasteboard needs a moment to breathe (at least on older Macs).
QTest::qWait(100); QTest::qWait(100);
#endif #endif
QCOMPARE(QProcess::execute("paster/paster", stringArgument), 0); QVERIFY2(runHelper(QStringLiteral("paster/paster"), stringArgument, &errorMessage),
errorMessage.constData());
#endif #endif
} }
@ -214,33 +263,33 @@ void tst_QClipboard::setMimeData()
mimeData->setText(QLatin1String("Qt/CE foo")); mimeData->setText(QLatin1String("Qt/CE foo"));
#endif #endif
QApplication::clipboard()->setMimeData(mimeData); QGuiApplication::clipboard()->setMimeData(mimeData);
QCOMPARE(QApplication::clipboard()->mimeData(), (const QMimeData *)mimeData); QCOMPARE(QGuiApplication::clipboard()->mimeData(), (const QMimeData *)mimeData);
QCOMPARE(QApplication::clipboard()->mimeData()->objectName(), TestName); QCOMPARE(QGuiApplication::clipboard()->mimeData()->objectName(), TestName);
// set it to the same data again, it shouldn't delete mimeData (and crash as a result) // set it to the same data again, it shouldn't delete mimeData (and crash as a result)
QApplication::clipboard()->setMimeData(mimeData); QGuiApplication::clipboard()->setMimeData(mimeData);
QCOMPARE(QApplication::clipboard()->mimeData(), (const QMimeData *)mimeData); QCOMPARE(QGuiApplication::clipboard()->mimeData(), (const QMimeData *)mimeData);
QCOMPARE(QApplication::clipboard()->mimeData()->objectName(), TestName); QCOMPARE(QGuiApplication::clipboard()->mimeData()->objectName(), TestName);
QApplication::clipboard()->clear(); QGuiApplication::clipboard()->clear();
const QMimeData *appMimeData = QApplication::clipboard()->mimeData(); const QMimeData *appMimeData = QGuiApplication::clipboard()->mimeData();
QVERIFY(appMimeData != mimeData || appMimeData->objectName() != TestName); QVERIFY(appMimeData != mimeData || appMimeData->objectName() != TestName);
// check for crash when using the same mimedata object on several clipboards // check for crash when using the same mimedata object on several clipboards
QMimeData *data = new QMimeData; QMimeData *data = new QMimeData;
data->setText("foo"); data->setText("foo");
QApplication::clipboard()->setMimeData(data, QClipboard::Clipboard); QGuiApplication::clipboard()->setMimeData(data, QClipboard::Clipboard);
QApplication::clipboard()->setMimeData(data, QClipboard::Selection); QGuiApplication::clipboard()->setMimeData(data, QClipboard::Selection);
QApplication::clipboard()->setMimeData(data, QClipboard::FindBuffer); QGuiApplication::clipboard()->setMimeData(data, QClipboard::FindBuffer);
QSignalSpy spySelection(QApplication::clipboard(), SIGNAL(selectionChanged())); QSignalSpy spySelection(QGuiApplication::clipboard(), SIGNAL(selectionChanged()));
QSignalSpy spyData(QApplication::clipboard(), SIGNAL(dataChanged())); QSignalSpy spyData(QGuiApplication::clipboard(), SIGNAL(dataChanged()));
QSignalSpy spyFindBuffer(QApplication::clipboard(), SIGNAL(findBufferChanged())); QSignalSpy spyFindBuffer(QGuiApplication::clipboard(), SIGNAL(findBufferChanged()));
QApplication::clipboard()->clear(QClipboard::Clipboard); QGuiApplication::clipboard()->clear(QClipboard::Clipboard);
QApplication::clipboard()->clear(QClipboard::Selection); // used to crash on X11 QGuiApplication::clipboard()->clear(QClipboard::Selection); // used to crash on X11
QApplication::clipboard()->clear(QClipboard::FindBuffer); QGuiApplication::clipboard()->clear(QClipboard::FindBuffer);
#if defined(Q_WS_X11) #if defined(Q_WS_X11)
QCOMPARE(spySelection.count(), 1); QCOMPARE(spySelection.count(), 1);
@ -260,9 +309,9 @@ void tst_QClipboard::setMimeData()
data = new QMimeData; data = new QMimeData;
data->setText("foo"); data->setText("foo");
QApplication::clipboard()->setMimeData(data, QClipboard::Clipboard); QGuiApplication::clipboard()->setMimeData(data, QClipboard::Clipboard);
QApplication::clipboard()->setMimeData(data, QClipboard::Selection); QGuiApplication::clipboard()->setMimeData(data, QClipboard::Selection);
QApplication::clipboard()->setMimeData(data, QClipboard::FindBuffer); QGuiApplication::clipboard()->setMimeData(data, QClipboard::FindBuffer);
QMimeData *newData = new QMimeData; QMimeData *newData = new QMimeData;
newData->setText("bar"); newData->setText("bar");
@ -271,9 +320,9 @@ void tst_QClipboard::setMimeData()
spyData.clear(); spyData.clear();
spyFindBuffer.clear(); spyFindBuffer.clear();
QApplication::clipboard()->setMimeData(newData, QClipboard::Clipboard); QGuiApplication::clipboard()->setMimeData(newData, QClipboard::Clipboard);
QApplication::clipboard()->setMimeData(newData, QClipboard::Selection); // used to crash on X11 QGuiApplication::clipboard()->setMimeData(newData, QClipboard::Selection); // used to crash on X11
QApplication::clipboard()->setMimeData(newData, QClipboard::FindBuffer); QGuiApplication::clipboard()->setMimeData(newData, QClipboard::FindBuffer);
#if defined(Q_WS_X11) #if defined(Q_WS_X11)
QCOMPARE(spySelection.count(), 1); QCOMPARE(spySelection.count(), 1);
@ -292,7 +341,7 @@ void tst_QClipboard::setMimeData()
void tst_QClipboard::clearBeforeSetText() void tst_QClipboard::clearBeforeSetText()
{ {
QApplication::processEvents(); QGuiApplication::processEvents();
if (!nativeClipboardWorking()) if (!nativeClipboardWorking())
QSKIP("Native clipboard not working in this setup"); QSKIP("Native clipboard not working in this setup");
@ -300,30 +349,30 @@ void tst_QClipboard::clearBeforeSetText()
const QString text = "tst_QClipboard::clearBeforeSetText()"; const QString text = "tst_QClipboard::clearBeforeSetText()";
// setText() should work after processEvents() // setText() should work after processEvents()
QApplication::clipboard()->setText(text); QGuiApplication::clipboard()->setText(text);
QCOMPARE(QApplication::clipboard()->text(), text); QCOMPARE(QGuiApplication::clipboard()->text(), text);
QApplication::processEvents(); QGuiApplication::processEvents();
QCOMPARE(QApplication::clipboard()->text(), text); QCOMPARE(QGuiApplication::clipboard()->text(), text);
// same with clear() // same with clear()
QApplication::clipboard()->clear(); QGuiApplication::clipboard()->clear();
QVERIFY(QApplication::clipboard()->text().isEmpty()); QVERIFY(QGuiApplication::clipboard()->text().isEmpty());
QApplication::processEvents(); QGuiApplication::processEvents();
QVERIFY(QApplication::clipboard()->text().isEmpty()); QVERIFY(QGuiApplication::clipboard()->text().isEmpty());
// setText() again // setText() again
QApplication::clipboard()->setText(text); QGuiApplication::clipboard()->setText(text);
QCOMPARE(QApplication::clipboard()->text(), text); QCOMPARE(QGuiApplication::clipboard()->text(), text);
QApplication::processEvents(); QGuiApplication::processEvents();
QCOMPARE(QApplication::clipboard()->text(), text); QCOMPARE(QGuiApplication::clipboard()->text(), text);
// clear() immediately followed by setText() should still return the text // clear() immediately followed by setText() should still return the text
QApplication::clipboard()->clear(); QGuiApplication::clipboard()->clear();
QVERIFY(QApplication::clipboard()->text().isEmpty()); QVERIFY(QGuiApplication::clipboard()->text().isEmpty());
QApplication::clipboard()->setText(text); QGuiApplication::clipboard()->setText(text);
QCOMPARE(QApplication::clipboard()->text(), text); QCOMPARE(QGuiApplication::clipboard()->text(), text);
QApplication::processEvents(); QGuiApplication::processEvents();
QCOMPARE(QApplication::clipboard()->text(), text); QCOMPARE(QGuiApplication::clipboard()->text(), text);
} }
QTEST_MAIN(tst_QClipboard) QTEST_MAIN(tst_QClipboard)