void Ut_NotificationPreviewPresenter::testUpdateNotificationRemovesNotificationFromQueueIfNotShowable()
{
    NotificationPreviewPresenter presenter;

    // Create two notifications
    LipstickNotification *notification1 = createNotification(1);
    LipstickNotification *notification2 = createNotification(2);
    presenter.updateNotification(1);
    presenter.updateNotification(2);

    // Update the notifications to have no summary or body
    QSignalSpy changedSpy(&presenter, SIGNAL(notificationChanged()));
    QSignalSpy presentedSpy(&presenter, SIGNAL(notificationPresented(uint)));
    notification1->setHints(QVariantHash());
    notification2->setHints(QVariantHash());
    presenter.updateNotification(1);
    presenter.updateNotification(2);

    // Check that the current notification is not removed
    QCOMPARE(changedSpy.count(), 0);

    // The notifications should be considered presented
    QCOMPARE(presentedSpy.count(), 2);

    // Check that the other notification is removed from the queue
    presenter.showNextNotification();
    QCOMPARE(changedSpy.count(), 1);
    QCOMPARE(presenter.notification(), (LipstickNotification *)0);
    QCOMPARE(presentedSpy.count(), 2);
}
void Ut_NotificationPreviewPresenter::testNotificationNotShownIfNoSummaryOrBody()
{
    QFETCH(QString, previewSummary);
    QFETCH(QString, previewBody);
    QFETCH(int, changedSignalCount);
    QFETCH(int, presentedSignalCount);
    QFETCH(bool, windowVisible);

    NotificationPreviewPresenter presenter;
    QSignalSpy changedSpy(&presenter, SIGNAL(notificationChanged()));
    QSignalSpy presentedSpy(&presenter, SIGNAL(notificationPresented(uint)));

    // Create notification
    LipstickNotification *notification = new LipstickNotification;
    QVariantHash hints;
    hints.insert(NotificationManager::HINT_PREVIEW_SUMMARY, previewSummary);
    hints.insert(NotificationManager::HINT_PREVIEW_BODY, previewBody);
    notification->setHints(hints);
    notificationManagerNotification.insert(1, notification);
    presenter.updateNotification(1);

    // Check whether the expected notification is signaled onwards
    QCOMPARE(changedSpy.count(), changedSignalCount);
    QCOMPARE(presentedSpy.count(), presentedSignalCount);

    QCOMPARE(homeWindowVisible.isEmpty(), !windowVisible);
    if (windowVisible) {
        // Check whether the window was shown
        QCOMPARE(homeWindowVisible[homeWindows.first()], windowVisible);
    }
}
void Ut_NotificationPreviewPresenter::testAddNotificationWhenWindowNotOpen()
{
    NotificationPreviewPresenter presenter;
    QSignalSpy changedSpy(&presenter, SIGNAL(notificationChanged()));
    QSignalSpy presentedSpy(&presenter, SIGNAL(notificationPresented(uint)));

    // Check that the window is not automatically created
    QCOMPARE(homeWindows.isEmpty(), true);

    // Check that the window is created when a notification is added
    LipstickNotification *notification = createNotification(1);
    presenter.updateNotification(1);
    QCOMPARE(homeWindows.count(), 1);

    // Check window properties
    QCOMPARE(homeWindowTitle[homeWindows.first()], QString("Notification"));
    QCOMPARE(homeWindowContextProperties[homeWindows.first()].value("initialSize").toSize(), QGuiApplication::primaryScreen()->size());
    QCOMPARE(homeWindowContextProperties[homeWindows.first()].value("notificationPreviewPresenter"), QVariant::fromValue(static_cast<QObject *>(&presenter)));
    QCOMPARE(homeWindowCategories[homeWindows.first()], QString("notification"));

    // Check that the window was shown
    QCOMPARE(homeWindowVisible[homeWindows.first()], true);

    // Check that the expected notification is signaled onwards
    QCOMPARE(changedSpy.count(), 1);
    QCOMPARE(presenter.notification(), notification);
    QCOMPARE(presentedSpy.count(), 1);
    QCOMPARE(presentedSpy.last().at(0).toUInt(), (uint)1);
}
void Ut_NotificationPreviewPresenter::testRemoveNotification()
{
    NotificationPreviewPresenter presenter;
    QSignalSpy changedSpy(&presenter, SIGNAL(notificationChanged()));

    // Create two notifications
    createNotification(1);
    createNotification(2);
    presenter.updateNotification(1);
    presenter.updateNotification(2);

    // Remove the first one
    presenter.removeNotification(1);

    // Check that an empty notification is signaled onwards
    QCOMPARE(changedSpy.count(), 2);
    QCOMPARE(presenter.notification(), (LipstickNotification *)0);

    // Show and remove the second one
    presenter.showNextNotification();
    presenter.removeNotification(2);

    // Check that an empty notification is signaled onwards
    QCOMPARE(changedSpy.count(), 4);
    QCOMPARE(presenter.notification(), (LipstickNotification *)0);

    // Check that the window is not yet hidden
    QCOMPARE(homeWindowVisible[homeWindows.first()], true);

    // Check that the window is hidden when it's time to show the next notification (which doesn't exist)
    presenter.showNextNotification();
    QCOMPARE(homeWindowVisible[homeWindows.first()], false);
}
void Ut_NotificationPreviewPresenter::testAddNotificationWhenWindowAlreadyOpen()
{
    NotificationPreviewPresenter presenter;
    QSignalSpy changedSpy(&presenter, SIGNAL(notificationChanged()));
    QSignalSpy presentedSpy(&presenter, SIGNAL(notificationPresented(uint)));

    // Create a notification: this will create a window
    createNotification(1);
    presenter.updateNotification(1);

    // Reset stubs to see what happens next
    homeWindows.clear();

    // Create another notification
    LipstickNotification *notification = createNotification(2);
    presenter.updateNotification(2);

    // The second notification should not be signaled onwards yet since the first one is being presented
    QCOMPARE(changedSpy.count(), 1);
    QCOMPARE(presentedSpy.count(), 1);
    QCOMPARE(presentedSpy.last().at(0).toUInt(), (uint)1);

    // Show the next notification
    presenter.showNextNotification();

    // Check that the window was not unnecessarily created again
    QCOMPARE(homeWindows.isEmpty(), true);

    // Check that the expected notification is signaled onwards
    QCOMPARE(changedSpy.count(), 2);
    QCOMPARE(presenter.notification(), notification);
    QCOMPARE(presentedSpy.count(), 2);
    QCOMPARE(presentedSpy.last().at(0).toUInt(), (uint)2);
}
void tst_QRegularExpressionValidator::validate()
{
    QFETCH(QRegularExpression, re);
    QFETCH(QString, value);

    QRegularExpressionValidator rv;

    // setting the same regexp won't emit signals
    const int signalCount = (rv.regularExpression() == re) ? 0 : 1;

    QSignalSpy spy(&rv, SIGNAL(regularExpressionChanged(QRegularExpression)));
    QSignalSpy changedSpy(&rv, SIGNAL(changed()));

    rv.setRegularExpression(re);
    QCOMPARE(rv.regularExpression(), re);

    int pos = -1;
    QValidator::State result = rv.validate(value, pos);

    QTEST(result, "state");
    if (result == QValidator::Invalid)
        QCOMPARE(pos, value.length());
    else
        QCOMPARE(pos, -1); // ensure pos is not modified if validate returned Acceptable or Intermediate

    QCOMPARE(spy.count(), signalCount);
    QCOMPARE(changedSpy.count(), signalCount);
}
示例#7
0
/*
    Test that the appropriate signals are emitted when the clipboard
    contents is changed by calling the qt functions.
*/
void tst_QClipboard::testSignals()
{
    qRegisterMetaType<QClipboard::Mode>("QClipboard::Mode");

    if (!PlatformClipboard::isAvailable())
        QSKIP("Native clipboard not working in this setup");

    QClipboard * const clipboard =  QGuiApplication::clipboard();

    QSignalSpy changedSpy(clipboard, SIGNAL(changed(QClipboard::Mode)));
    QSignalSpy dataChangedSpy(clipboard, SIGNAL(dataChanged()));
    QSignalSpy searchChangedSpy(clipboard, SIGNAL(findBufferChanged()));
    QSignalSpy selectionChangedSpy(clipboard, SIGNAL(selectionChanged()));

    const QString text = "clipboard text;";

    // Test the default mode signal.
    clipboard->setText(text);
    QCOMPARE(dataChangedSpy.count(), 1);
    QCOMPARE(searchChangedSpy.count(), 0);
    QCOMPARE(selectionChangedSpy.count(), 0);
    QCOMPARE(changedSpy.count(), 1);
    QCOMPARE(changedSpy.at(0).count(), 1);
    QCOMPARE(qvariant_cast<QClipboard::Mode>(changedSpy.at(0).at(0)), QClipboard::Clipboard);

    changedSpy.clear();

    // Test the selection mode signal.
    if (clipboard->supportsSelection()) {
        clipboard->setText(text, QClipboard::Selection);
        QCOMPARE(selectionChangedSpy.count(), 1);
        QCOMPARE(changedSpy.count(), 1);
        QCOMPARE(changedSpy.at(0).count(), 1);
        QCOMPARE(qvariant_cast<QClipboard::Mode>(changedSpy.at(0).at(0)), QClipboard::Selection);
    } else {
        QCOMPARE(selectionChangedSpy.count(), 0);
    }
    QCOMPARE(dataChangedSpy.count(), 1);
    QCOMPARE(searchChangedSpy.count(), 0);

    changedSpy.clear();

    // Test the search mode signal.
    if (clipboard->supportsFindBuffer()) {
        clipboard->setText(text, QClipboard::FindBuffer);
        QCOMPARE(searchChangedSpy.count(), 1);
        QCOMPARE(changedSpy.count(), 1);
        QCOMPARE(changedSpy.at(0).count(), 1);
        QCOMPARE(qvariant_cast<QClipboard::Mode>(changedSpy.at(0).at(0)), QClipboard::FindBuffer);
    } else {
        QCOMPARE(searchChangedSpy.count(), 0);
    }
    QCOMPARE(dataChangedSpy.count(), 1);
}
void tst_QRegExpValidator::validate()
{
    QFETCH( QString, rx );
    QFETCH( QString, value );
    QFETCH( int, state );

    QRegExpValidator rv( 0 );
    QSignalSpy spy(&rv, SIGNAL(regExpChanged(const QRegExp&)));
    QSignalSpy changedSpy(&rv, SIGNAL(changed()));

    rv.setRegExp( QRegExp( rx ) );
    int dummy;
    QCOMPARE( (int)rv.validate( value, dummy ), state );
    QCOMPARE(spy.count(), 1);
    QCOMPARE(changedSpy.count(), 1);
}
void Ut_NotificationPreviewPresenter::testNotificationNotShownIfTouchScreenIsLockedAndDisplayIsOff()
{
    QFETCH(MeeGo::QmDisplayState::DisplayState, displayState);
    QFETCH(MeeGo::QmLocks::State, lockState);
    QFETCH(int, notifications);
    QFETCH(int, presentedCount);

    gQmDisplayStateStub->stubSetReturnValue("get", displayState);
    gQmLocksStub->stubSetReturnValue("getState", lockState);

    NotificationPreviewPresenter presenter;
    QSignalSpy changedSpy(&presenter, SIGNAL(notificationChanged()));
    QSignalSpy presentedSpy(&presenter, SIGNAL(notificationPresented(uint)));

    createNotification(1, 2);
    presenter.updateNotification(1);
    QCOMPARE(homeWindows.count(), notifications);
    QCOMPARE(changedSpy.count(), notifications);
    QCOMPARE(presentedSpy.count(), presentedCount);
}
void Ut_NotificationPreviewPresenter::testUpdateNotification()
{
    NotificationPreviewPresenter presenter;

    // Create two notifications
    createNotification(1);
    createNotification(2);
    presenter.updateNotification(1);
    presenter.updateNotification(2);

    // Update both notifications
    QSignalSpy changedSpy(&presenter, SIGNAL(notificationChanged()));
    QSignalSpy presentedSpy(&presenter, SIGNAL(notificationPresented(uint)));
    presenter.updateNotification(1);
    presenter.updateNotification(2);

    // Check that no signals were sent
    QCOMPARE(changedSpy.count(), 0);
    QCOMPARE(presentedSpy.count(), 0);
}
void Ut_NotificationPreviewPresenter::testNotificationNotShownIfHidden()
{
    NotificationPreviewPresenter presenter;
    QSignalSpy changedSpy(&presenter, SIGNAL(notificationChanged()));
    QSignalSpy presentedSpy(&presenter, SIGNAL(notificationPresented(uint)));

    // Create notification
    QVariantHash hints;
    hints.insert(NotificationManager::HINT_PREVIEW_SUMMARY, "previewSummary");
    hints.insert(NotificationManager::HINT_PREVIEW_BODY, "previewBody");
    hints.insert(NotificationManager::HINT_HIDDEN, true);
    LipstickNotification *notification = new LipstickNotification("ut_notificationpreviewpresenter", 1, "", "", "", QStringList(), hints, -1);
    notificationManagerNotification.insert(1, notification);
    presenter.updateNotification(1);

    QCOMPARE(changedSpy.count(), 0);
    QCOMPARE(homeWindowVisible.isEmpty(), true);

    // The notification should be considered presented
    QCOMPARE(presentedSpy.count(), 1);
    QCOMPARE(presentedSpy.last().at(0).toUInt(), (uint)1);
}
void Ut_NotificationPreviewPresenter::testShowingOnlyCriticalNotifications()
{
    NotificationPreviewPresenter presenter;
    QSignalSpy changedSpy(&presenter, SIGNAL(notificationChanged()));
    QSignalSpy presentedSpy(&presenter, SIGNAL(notificationPresented(uint)));

    // Create normal urgency notification
    LipstickNotification *notification = new LipstickNotification;
    QVariantHash hints;
    hints.insert(NotificationManager::HINT_PREVIEW_SUMMARY, "previewSummary");
    hints.insert(NotificationManager::HINT_PREVIEW_BODY, "previewBody");
    hints.insert(NotificationManager::HINT_URGENCY, 1);
    notification->setHints(hints);
    notificationManagerNotification.insert(1, notification);
    QCOMPARE(homeWindowVisible.isEmpty(), true);

    // When the screen or device is locked and the urgency is not high enough, so the notification shouldn't be shown
    gQmLocksStub->stubSetReturnValue("getState", MeeGo::QmLocks::Locked);
    presenter.updateNotification(1);
    QCOMPARE(changedSpy.count(), 0);
    QCOMPARE(homeWindowVisible.isEmpty(), true);

    // The notification should be considered presented
    QCOMPARE(presentedSpy.count(), 1);
    QCOMPARE(presentedSpy.last().at(0).toUInt(), (uint)1);

    // Urgency set to critical, so the notification should be shown
    hints.insert(NotificationManager::HINT_URGENCY, 2);
    notification->setHints(hints);
    presenter.updateNotification(1);
    QCOMPARE(changedSpy.count(), 1);
    QCOMPARE(homeWindowVisible.isEmpty(), false);
    QCOMPARE(homeWindowVisible[homeWindows.first()], true);
    QCOMPARE(presentedSpy.count(), 2);
    QCOMPARE(presentedSpy.last().at(0).toUInt(), (uint)1);
}
void tst_QDoubleValidator::notifySignals()
{
    QLocale::setDefault(QLocale("C"));

    QDoubleValidator dv(0.1, 0.9, 10, 0);
    QSignalSpy topSpy(&dv, SIGNAL(topChanged(double)));
    QSignalSpy bottomSpy(&dv, SIGNAL(bottomChanged(double)));
    QSignalSpy decSpy(&dv, SIGNAL(decimalsChanged(int)));
    QSignalSpy changedSpy(&dv, SIGNAL(changed()));

    qRegisterMetaType<QDoubleValidator::Notation>("QDoubleValidator::Notation");
    QSignalSpy notSpy(&dv, SIGNAL(notationChanged(QDoubleValidator::Notation)));

    dv.setTop(0.8);
    QCOMPARE(topSpy.count(), 1);
    QCOMPARE(changedSpy.count(), 1);
    QVERIFY(dv.top() == 0.8);
    dv.setBottom(0.2);
    QCOMPARE(bottomSpy.count(), 1);
    QCOMPARE(changedSpy.count(), 2);
    QVERIFY(dv.bottom() == 0.2);

    dv.setRange(0.2, 0.7);
    QCOMPARE(topSpy.count(), 2);
    QCOMPARE(bottomSpy.count(), 1);
    QCOMPARE(decSpy.count(), 1);
    QCOMPARE(changedSpy.count(), 3);
    QVERIFY(dv.bottom() == 0.2);
    QVERIFY(dv.top() == 0.7);
    QVERIFY(dv.decimals() == 0.);

    dv.setRange(0.3, 0.7);
    QCOMPARE(topSpy.count(), 2);
    QCOMPARE(bottomSpy.count(), 2);
    QCOMPARE(changedSpy.count(), 4);
    QVERIFY(dv.bottom() == 0.3);
    QVERIFY(dv.top() == 0.7);
    QVERIFY(dv.decimals() == 0.);

    dv.setRange(0.4, 0.6);
    QCOMPARE(topSpy.count(), 3);
    QCOMPARE(bottomSpy.count(), 3);
    QCOMPARE(changedSpy.count(), 5);
    QVERIFY(dv.bottom() == 0.4);
    QVERIFY(dv.top() == 0.6);
    QVERIFY(dv.decimals() == 0.);

    dv.setDecimals(10);
    QCOMPARE(decSpy.count(), 2);
    QCOMPARE(changedSpy.count(), 6);
    QVERIFY(dv.decimals() == 10.);


    dv.setRange(0.4, 0.6, 100);
    QCOMPARE(topSpy.count(), 3);
    QCOMPARE(bottomSpy.count(), 3);
    QCOMPARE(decSpy.count(), 3);
    QCOMPARE(changedSpy.count(), 7);
    QVERIFY(dv.bottom() == 0.4);
    QVERIFY(dv.top() == 0.6);
    QVERIFY(dv.decimals() == 100.);

    dv.setNotation(QDoubleValidator::StandardNotation);
    QCOMPARE(notSpy.count(), 1);
    QCOMPARE(changedSpy.count(), 8);
    QVERIFY(dv.notation() == QDoubleValidator::StandardNotation);

    dv.setRange(dv.bottom(), dv.top(), dv.decimals());
    QCOMPARE(topSpy.count(), 3);
    QCOMPARE(bottomSpy.count(), 3);
    QCOMPARE(decSpy.count(), 3);
    QCOMPARE(changedSpy.count(), 8);

    dv.setNotation(dv.notation());
    QCOMPARE(notSpy.count(), 1);
    QCOMPARE(changedSpy.count(), 8);

    dv.setLocale(QLocale("C"));
    QCOMPARE(changedSpy.count(), 8);

    dv.setLocale(QLocale("en"));
    QCOMPARE(changedSpy.count(), 9);
}
示例#14
0
void TestLogData::changingFile()
{
    char newLine[90];
    LogData logData;

    QSignalSpy finishedSpy( &logData, SIGNAL( loadingFinished( bool ) ) );
    QSignalSpy progressSpy( &logData, SIGNAL( loadingProgressed( int ) ) );
    QSignalSpy changedSpy( &logData,
                           SIGNAL( fileChanged( LogData::MonitoredFileStatus ) ) );

    // Register for notification file is loaded
    connect( &logData, SIGNAL( loadingFinished( bool ) ),
             this, SLOT( loadingFinished() ) );

    // Generate a small file
    QFile file( TMPDIR "/changingfile.txt" );
    if ( file.open( QIODevice::WriteOnly ) ) {
        for (int i = 0; i < 200; i++) {
            snprintf(newLine, 89, sl_format, i);
            file.write( newLine, qstrlen(newLine) );
        }
    }
    file.close();

    // Start loading it
    logData.attachFile( TMPDIR "/changingfile.txt" );

    // and wait for the signal
    QApplication::exec();

    // Check we have the small file
    QCOMPARE( finishedSpy.count(), 1 );
    QCOMPARE( logData.getNbLine(), 200LL );
    QCOMPARE( logData.getMaxLength(), SL_LINE_LENGTH );
    QCOMPARE( logData.getFileSize(), 200 * (SL_LINE_LENGTH+1LL) );

    // Add some data to it
    if ( file.open( QIODevice::Append ) ) {
        for (int i = 0; i < 200; i++) {
            snprintf(newLine, 89, sl_format, i);
            file.write( newLine, qstrlen(newLine) );
        }
        // To test the edge case when the final line is not complete
        file.write( partial_line_begin, qstrlen( partial_line_begin ) );
    }
    file.close();

    // and wait for the signals
    QApplication::exec();

    // Check we have a bigger file
    QCOMPARE( changedSpy.count(), 1 );
    QCOMPARE( finishedSpy.count(), 2 );
    QCOMPARE( logData.getNbLine(), 401LL );
    QCOMPARE( logData.getMaxLength(), SL_LINE_LENGTH );
    QCOMPARE( logData.getFileSize(), (qint64) (400 * (SL_LINE_LENGTH+1LL)
              + strlen( partial_line_begin ) ) );

    // Add a couple more lines, including the end of the unfinished one.
    if ( file.open( QIODevice::Append ) ) {
        file.write( partial_line_end, qstrlen( partial_line_end ) );
        for (int i = 0; i < 20; i++) {
            snprintf(newLine, 89, sl_format, i);
            file.write( newLine, qstrlen(newLine) );
        }
    }
    file.close();

    // and wait for the signals
    QApplication::exec();

    // Check we have a bigger file
    QCOMPARE( changedSpy.count(), 2 );
    QCOMPARE( finishedSpy.count(), 3 );
    QCOMPARE( logData.getNbLine(), 421LL );
    QCOMPARE( logData.getMaxLength(), SL_LINE_LENGTH );
    QCOMPARE( logData.getFileSize(), (qint64) ( 420 * (SL_LINE_LENGTH+1LL)
              + strlen( partial_line_begin ) + strlen( partial_line_end ) ) );

    // Truncate the file
    QVERIFY( file.open( QIODevice::WriteOnly ) );
    file.close();

    // and wait for the signals
    QApplication::exec();

    // Check we have an empty file
    QCOMPARE( changedSpy.count(), 3 );
    QCOMPARE( finishedSpy.count(), 4 );
    QCOMPARE( logData.getNbLine(), 0LL );
    QCOMPARE( logData.getMaxLength(), 0 );
    QCOMPARE( logData.getFileSize(), 0LL );
}
void tst_QQmlMetaObject::property()
{
    QFETCH(QString, testFile);
    QFETCH(QByteArray, cppTypeName);
    QFETCH(int, cppType);
    QFETCH(bool, isDefault);
    QFETCH(QVariant, expectedValue);
    QFETCH(bool, isWritable);
    QFETCH(QVariant, newValue);

    QQmlEngine engine;
    QQmlComponent component(&engine, testFileUrl(testFile));
    QObject *object = component.create();
    QVERIFY(object != 0);

    const QMetaObject *mo = object->metaObject();
    QVERIFY(mo->superClass() != 0);
    QVERIFY(QByteArray(mo->className()).contains("_QML_"));
    QCOMPARE(mo->propertyOffset(), mo->superClass()->propertyCount());
    QCOMPARE(mo->propertyCount(), mo->superClass()->propertyCount() + 1);

    QMetaProperty prop = mo->property(mo->propertyOffset());
    QCOMPARE(prop.name(), "test");

    QCOMPARE(QByteArray(prop.typeName()), cppTypeName);
    if (prop.userType() < QMetaType::User)
        QCOMPARE(prop.type(), QVariant::Type(cppType));
    else
        QCOMPARE(prop.type(), QVariant::UserType);
    QCOMPARE(prop.userType(), cppType);

    QVERIFY(!prop.isConstant());
    QVERIFY(!prop.isDesignable());
    QVERIFY(!prop.isEnumType());
    QVERIFY(!prop.isFinal());
    QVERIFY(!prop.isFlagType());
    QVERIFY(prop.isReadable());
    QVERIFY(!prop.isResettable());
    QVERIFY(prop.isScriptable());
    QVERIFY(!prop.isStored());
    QVERIFY(!prop.isUser());
    QVERIFY(prop.isValid());
    QCOMPARE(prop.isWritable(), isWritable);

    QCOMPARE(mo->classInfoOffset(), mo->superClass()->classInfoCount());
    QCOMPARE(mo->classInfoCount(), mo->superClass()->classInfoCount() + (isDefault ? 1 : 0));
    if (isDefault) {
        QMetaClassInfo info = mo->classInfo(mo->classInfoOffset());
        QCOMPARE(info.name(), "DefaultProperty");
        QCOMPARE(info.value(), "test");
    }

    QCOMPARE(mo->methodOffset(), mo->superClass()->methodCount());
    QCOMPARE(mo->methodCount(), mo->superClass()->methodCount() + 1); // the signal

    QVERIFY(prop.notifySignalIndex() != -1);
    QMetaMethod signal = prop.notifySignal();
    QCOMPARE(signal.methodType(), QMetaMethod::Signal);
    QCOMPARE(signal.name(), QByteArray("testChanged"));
    QCOMPARE(signal.methodSignature(), QByteArray("testChanged()"));
    QCOMPARE(signal.access(), QMetaMethod::Public);
    QCOMPARE(signal.parameterCount(), 0);
    QCOMPARE(signal.parameterTypes(), QList<QByteArray>());
    QCOMPARE(signal.parameterNames(), QList<QByteArray>());
    QCOMPARE(signal.tag(), "");
    QCOMPARE(signal.typeName(), "void");
    QCOMPARE(signal.returnType(), int(QMetaType::Void));

    QSignalSpy changedSpy(object, SIGNAL(testChanged()));
    QObject::connect(object, SIGNAL(testChanged()), object, SLOT(deleteLater()));

    if (expectedValue.isValid())
        QCOMPARE(prop.read(object), expectedValue);
    else
        QVERIFY(prop.read(object).isValid());
    QCOMPARE(changedSpy.count(), 0);

    if (isWritable) {
        QVERIFY(prop.write(object, newValue));
        QCOMPARE(changedSpy.count(), 1);
        QCOMPARE(prop.read(object), newValue);
    } else {
        QVERIFY(!prop.write(object, prop.read(object)));
        QCOMPARE(changedSpy.count(), 0);
    }

    delete object;
}