Exemplo n.º 1
0
void TutorialManagerTest::testStart() {
    mTutorialManager->registerTutorial(mTutorial1);

    TutorialInformation* tutorialInformation2 =
        new TutorialInformation("secondIdentifier");
    MockTutorial* tutorial2 = new MockTutorial(tutorialInformation2);
    mTutorialManager->registerTutorial(tutorial2);

    Step* startStep = new Step("start");
    tutorial2->addStep(startStep);

    //Tutorial* must be registered in order to be used with QSignalSpy
    int tutorialStarType = qRegisterMetaType<Tutorial*>("Tutorial*");
    QSignalSpy startedSpy(mTutorialManager, SIGNAL(started(Tutorial*)));

    mTutorialManager->start("secondIdentifier");

    QCOMPARE(startedSpy.count(), 1);
    QVariant argument = startedSpy.at(0).at(0);
    QCOMPARE(argument.userType(), tutorialStarType);
    QCOMPARE(qvariant_cast<Tutorial*>(argument), tutorial2);
    QVERIFY(startStep->isActive());

    QSignalSpy finishedSpy(mTutorialManager, SIGNAL(finished()));

    tutorial2->emitFinished();

    QCOMPARE(finishedSpy.count(), 1);
}
void tst_QBluetoothDeviceDiscoveryAgent::tst_deviceDiscovery()
{
    {
        QFETCH(QBluetoothDeviceDiscoveryAgent::InquiryType, inquiryType);

        QBluetoothDeviceDiscoveryAgent discoveryAgent;
        QVERIFY(discoveryAgent.error() == discoveryAgent.NoError);
        QVERIFY(discoveryAgent.errorString().isEmpty());
        QVERIFY(!discoveryAgent.isActive());

        QVERIFY(discoveryAgent.discoveredDevices().isEmpty());

        QSignalSpy finishedSpy(&discoveryAgent, SIGNAL(finished()));
        QSignalSpy errorSpy(&discoveryAgent, SIGNAL(error(QBluetoothDeviceDiscoveryAgent::Error)));
        QSignalSpy discoveredSpy(&discoveryAgent, SIGNAL(deviceDiscovered(const QBluetoothDeviceInfo&)));
//        connect(&discoveryAgent, SIGNAL(finished()), this, SLOT(finished()));
//        connect(&discoveryAgent, SIGNAL(deviceDiscovered(const QBluetoothDeviceInfo&)),
//                this, SLOT(deviceDiscoveryDebug(const QBluetoothDeviceInfo&)));

        discoveryAgent.setInquiryType(inquiryType);
        discoveryAgent.start();

        QVERIFY(discoveryAgent.isActive());

        // Wait for up to MaxScanTime for the scan to finish
        int scanTime = MaxScanTime;
        while (finishedSpy.count() == 0 && scanTime > 0) {
            QTest::qWait(15000);
            scanTime -= 15000;
        }
        qDebug() << scanTime << MaxScanTime;
        // verify that we are finished
        QVERIFY(!discoveryAgent.isActive());
        // stop
        discoveryAgent.stop();
        QVERIFY(!discoveryAgent.isActive());
        qDebug() << "Scan time left:" << scanTime;
        // Expect finished signal with no error
        QVERIFY(finishedSpy.count() == 1);
        QVERIFY(errorSpy.isEmpty());
        QVERIFY(discoveryAgent.error() == discoveryAgent.NoError);
        QVERIFY(discoveryAgent.errorString().isEmpty());

        // verify that the list is as big as the signals received.
        QVERIFY(discoveredSpy.count() == discoveryAgent.discoveredDevices().length());
        // verify that there really was some devices in the array
        QVERIFY(discoveredSpy.count() > 0);

        // All returned QBluetoothDeviceInfo should be valid.
        while (!discoveredSpy.isEmpty()) {
            const QBluetoothDeviceInfo info =
                qvariant_cast<QBluetoothDeviceInfo>(discoveredSpy.takeFirst().at(0));
            QVERIFY(info.isValid());
        }
    }
}
Exemplo n.º 3
0
void TutorialManagerTest::testStartWithInvalidId() {
    mTutorialManager->registerTutorial(mTutorial1);
    mTutorialManager->registerTutorial(mTutorial2);

    QSignalSpy startedSpy(mTutorialManager, SIGNAL(started(Tutorial*)));
    QSignalSpy finishedSpy(mTutorialManager, SIGNAL(finished()));

    mTutorialManager->start("identifierNotRegistered");

    QCOMPARE(startedSpy.count(), 0);
    QCOMPARE(finishedSpy.count(), 1);
}
void tst_QBluetoothDeviceDiscoveryAgent::tst_startStopDeviceDiscoveries()
{
    {
        QBluetoothDeviceDiscoveryAgent::InquiryType inquiryType = QBluetoothDeviceDiscoveryAgent::GeneralUnlimitedInquiry;
        QBluetoothDeviceDiscoveryAgent discoveryAgent;

        QVERIFY(discoveryAgent.error() == discoveryAgent.NoError);
        QVERIFY(discoveryAgent.errorString().isEmpty());
        QVERIFY(!discoveryAgent.isActive());
        QVERIFY(discoveryAgent.discoveredDevices().isEmpty());

        QSignalSpy finishedSpy(&discoveryAgent, SIGNAL(finished()));
        QSignalSpy cancelSpy(&discoveryAgent, SIGNAL(canceled()));
        QSignalSpy errorSpy(&discoveryAgent, SIGNAL(error(QBluetoothDeviceDiscoveryAgent::Error)));
        QSignalSpy discoveredSpy(&discoveryAgent, SIGNAL(deviceDiscovered(const QBluetoothDeviceInfo&)));

        // Starting case 1: start-stop, expecting cancel signal
        discoveryAgent.setInquiryType(inquiryType);
        // we should have no errors at this point.
        QVERIFY(errorSpy.isEmpty());

        discoveryAgent.start();
        QVERIFY(discoveryAgent.isActive());
        QVERIFY(errorSpy.isEmpty());
        // cancel current request.
        discoveryAgent.stop();

        // Wait for up to MaxWaitTime for the cancel to finish
        int waitTime = MaxWaitTime;
        while (cancelSpy.count() == 0 && waitTime > 0) {
            QTest::qWait(100);
            waitTime-=100;
        }

        // we should not be active anymore
        QVERIFY(!discoveryAgent.isActive());        
        QVERIFY(errorSpy.isEmpty());
        QVERIFY(cancelSpy.count() == 1);
        cancelSpy.clear();
        // Starting case 2: start-start-stop, expecting cancel signal
        discoveryAgent.start();
        // we should be active now
        QVERIFY(discoveryAgent.isActive());
        QVERIFY(errorSpy.isEmpty());
        // start again. should this be error?
        discoveryAgent.start();
        QVERIFY(discoveryAgent.isActive());
        QVERIFY(errorSpy.isEmpty());
        // stop
        discoveryAgent.stop();               

        // Wait for up to MaxWaitTime for the cancel to finish
        waitTime = MaxWaitTime;
        while (cancelSpy.count() == 0 && waitTime > 0) {
            QTest::qWait(100);
            waitTime-=100;
        }

        // we should not be active anymore
        QVERIFY(!discoveryAgent.isActive());
        QVERIFY(errorSpy.isEmpty());
        QVERIFY(cancelSpy.count() == 1);
        cancelSpy.clear();

        //  Starting case 3: stop
        discoveryAgent.stop();
        QVERIFY(!discoveryAgent.isActive());
        QVERIFY(errorSpy.isEmpty());

        // Expect finished signal with no error
        QVERIFY(finishedSpy.count() == 0);
        QVERIFY(discoveryAgent.error() == discoveryAgent.NoError);
        QVERIFY(discoveryAgent.errorString().isEmpty());


        // Starting case 4: start-stop-start-stop, expecting only 1 cancel signal
        discoveryAgent.start();
        QVERIFY(discoveryAgent.isActive());
        QVERIFY(errorSpy.isEmpty());
        // cancel current request.
        discoveryAgent.stop();
        // start a new one
        discoveryAgent.start();
        // we should be active now
        QVERIFY(discoveryAgent.isActive());
        QVERIFY(errorSpy.isEmpty());
        // stop
        discoveryAgent.stop();

        // Wait for up to MaxWaitTime for the cancel to finish
        waitTime = MaxWaitTime;
        while (waitTime > 0) {
            QTest::qWait(100);
            waitTime-=100;
        }

        // we should not be active anymore
        QVERIFY(!discoveryAgent.isActive());
        QVERIFY(errorSpy.isEmpty());
        // should only have 1 cancel
        QVERIFY(cancelSpy.count() == 1);
        cancelSpy.clear();

        // Starting case 5: start-stop-start: expecting finished signal & no cancel
        discoveryAgent.start();
        QVERIFY(discoveryAgent.isActive());
        QVERIFY(errorSpy.isEmpty());
        // cancel current request.
        discoveryAgent.stop();
        // start a new one
        discoveryAgent.start();
        // we should be active now
        QVERIFY(discoveryAgent.isActive());
        QVERIFY(errorSpy.isEmpty());

        // Wait for up to MaxScanTime for the cancel to finish
        waitTime = MaxScanTime;
        while (finishedSpy.count() == 0 && waitTime > 0) {
            QTest::qWait(1000);
            waitTime-=1000;
        }

        // we should not be active anymore
        QVERIFY(!discoveryAgent.isActive());
        QVERIFY(errorSpy.isEmpty());
        // should only have 1 cancel
        QVERIFY(finishedSpy.count() == 1);
        QVERIFY(cancelSpy.isEmpty());
    }
}
void tst_QAudioDecoderBackend::fileTest()
{
    QAudioDecoder d;
    QAudioBuffer buffer;
    quint64 duration = 0;
    int byteCount = 0;
    int sampleCount = 0;

    QVERIFY(d.state() == QAudioDecoder::StoppedState);
    QVERIFY(d.bufferAvailable() == false);
    QCOMPARE(d.sourceFilename(), QString(""));
    QVERIFY(d.audioFormat() == QAudioFormat());

    // Test local file
    QFileInfo fileInfo(QFINDTESTDATA(TEST_FILE_NAME));
    d.setSourceFilename(fileInfo.absoluteFilePath());
    QVERIFY(d.state() == QAudioDecoder::StoppedState);
    QVERIFY(!d.bufferAvailable());
    QCOMPARE(d.sourceFilename(), fileInfo.absoluteFilePath());

    QSignalSpy readySpy(&d, SIGNAL(bufferReady()));
    QSignalSpy bufferChangedSpy(&d, SIGNAL(bufferAvailableChanged(bool)));
    QSignalSpy errorSpy(&d, SIGNAL(error(QAudioDecoder::Error)));
    QSignalSpy stateSpy(&d, SIGNAL(stateChanged(QAudioDecoder::State)));
    QSignalSpy durationSpy(&d, SIGNAL(durationChanged(qint64)));
    QSignalSpy finishedSpy(&d, SIGNAL(finished()));
    QSignalSpy positionSpy(&d, SIGNAL(positionChanged(qint64)));

    d.start();
    QTRY_VERIFY(d.state() == QAudioDecoder::DecodingState);
    QTRY_VERIFY(!stateSpy.isEmpty());
    QTRY_VERIFY(!readySpy.isEmpty());
    QTRY_VERIFY(!bufferChangedSpy.isEmpty());
    QVERIFY(d.bufferAvailable());
    QTRY_VERIFY(!durationSpy.isEmpty());
    QVERIFY(qAbs(d.duration() - 1000) < 20);

    buffer = d.read();
    QVERIFY(buffer.isValid());

    // Test file is 44.1K 16bit mono, 44094 samples
    QCOMPARE(buffer.format().channelCount(), 1);
    QCOMPARE(buffer.format().sampleRate(), 44100);
    QCOMPARE(buffer.format().sampleSize(), 16);
    QCOMPARE(buffer.format().sampleType(), QAudioFormat::SignedInt);
    QCOMPARE(buffer.format().codec(), QString("audio/pcm"));
    QCOMPARE(buffer.byteCount(), buffer.sampleCount() * 2); // 16bit mono

    // The decoder should still have no format set
    QVERIFY(d.audioFormat() == QAudioFormat());

    QVERIFY(errorSpy.isEmpty());

    duration += buffer.duration();
    sampleCount += buffer.sampleCount();
    byteCount += buffer.byteCount();

    // Now drain the decoder
    if (sampleCount < 44094) {
        QTRY_COMPARE(d.bufferAvailable(), true);
    }

    while (d.bufferAvailable()) {
        buffer = d.read();
        QVERIFY(buffer.isValid());
        QTRY_VERIFY(!positionSpy.isEmpty());
        QVERIFY(positionSpy.takeLast().at(0).toLongLong() == qint64(duration / 1000));

        duration += buffer.duration();
        sampleCount += buffer.sampleCount();
        byteCount += buffer.byteCount();

        if (sampleCount < 44094) {
            QTRY_COMPARE(d.bufferAvailable(), true);
        }
    }

    // Make sure the duration is roughly correct (+/- 20ms)
    QCOMPARE(sampleCount, 44094);
    QCOMPARE(byteCount, 44094 * 2);
    QVERIFY(qAbs(qint64(duration) - 1000000) < 20000);
    QVERIFY(qAbs((d.position() + (buffer.duration() / 1000)) - 1000) < 20);
    QTRY_COMPARE(finishedSpy.count(), 1);
    QVERIFY(!d.bufferAvailable());
    QTRY_COMPARE(d.state(), QAudioDecoder::StoppedState);

    d.stop();
    QTRY_COMPARE(d.state(), QAudioDecoder::StoppedState);
    QTRY_COMPARE(durationSpy.count(), 2);
    QCOMPARE(d.duration(), qint64(-1));
    QVERIFY(!d.bufferAvailable());
    readySpy.clear();
    bufferChangedSpy.clear();
    stateSpy.clear();
    durationSpy.clear();
    finishedSpy.clear();
    positionSpy.clear();

    // change output audio format
    QAudioFormat format;
    format.setChannelCount(2);
    format.setSampleSize(8);
    format.setSampleRate(11050);
    format.setCodec("audio/pcm");
    format.setSampleType(QAudioFormat::SignedInt);

    d.setAudioFormat(format);

    // We expect 1 second still, at 11050 * 2 samples == 22k samples.
    // (at 1 byte/sample -> 22kb)

    // Make sure it stuck
    QVERIFY(d.audioFormat() == format);

    duration = 0;
    sampleCount = 0;
    byteCount = 0;

    d.start();
    QTRY_VERIFY(d.state() == QAudioDecoder::DecodingState);
    QTRY_VERIFY(!stateSpy.isEmpty());
    QTRY_VERIFY(!readySpy.isEmpty());
    QTRY_VERIFY(!bufferChangedSpy.isEmpty());
    QVERIFY(d.bufferAvailable());
    QTRY_VERIFY(!durationSpy.isEmpty());
    QVERIFY(qAbs(d.duration() - 1000) < 20);

    buffer = d.read();
    QVERIFY(buffer.isValid());
    // See if we got the right format
    QVERIFY(buffer.format() == format);

    // The decoder should still have the same format
    QVERIFY(d.audioFormat() == format);

    QVERIFY(errorSpy.isEmpty());

    duration += buffer.duration();
    sampleCount += buffer.sampleCount();
    byteCount += buffer.byteCount();

    // Now drain the decoder
    if (duration < 998000) {
        QTRY_COMPARE(d.bufferAvailable(), true);
    }

    while (d.bufferAvailable()) {
        buffer = d.read();
        QVERIFY(buffer.isValid());
        QTRY_VERIFY(!positionSpy.isEmpty());
        QVERIFY(positionSpy.takeLast().at(0).toLongLong() == qint64(duration / 1000));
        QVERIFY(d.position() - (duration / 1000) < 20);

        duration += buffer.duration();
        sampleCount += buffer.sampleCount();
        byteCount += buffer.byteCount();

        if (duration < 998000) {
            QTRY_COMPARE(d.bufferAvailable(), true);
        }
    }

    // Resampling might end up with fewer or more samples
    // so be a bit sloppy
    QVERIFY(qAbs(sampleCount - 22047) < 100);
    QVERIFY(qAbs(byteCount - 22047) < 100);
    QVERIFY(qAbs(qint64(duration) - 1000000) < 20000);
    QVERIFY(qAbs((d.position() + (buffer.duration() / 1000)) - 1000) < 20);
    QTRY_COMPARE(finishedSpy.count(), 1);
    QVERIFY(!d.bufferAvailable());
    QTRY_COMPARE(d.state(), QAudioDecoder::StoppedState);

    d.stop();
    QTRY_COMPARE(d.state(), QAudioDecoder::StoppedState);
    QTRY_COMPARE(durationSpy.count(), 2);
    QCOMPARE(d.duration(), qint64(-1));
    QVERIFY(!d.bufferAvailable());
}
void tst_QAudioDecoderBackend::deviceTest()
{
    QAudioDecoder d;
    QAudioBuffer buffer;
    quint64 duration = 0;
    int sampleCount = 0;

    QSignalSpy readySpy(&d, SIGNAL(bufferReady()));
    QSignalSpy bufferChangedSpy(&d, SIGNAL(bufferAvailableChanged(bool)));
    QSignalSpy errorSpy(&d, SIGNAL(error(QAudioDecoder::Error)));
    QSignalSpy stateSpy(&d, SIGNAL(stateChanged(QAudioDecoder::State)));
    QSignalSpy durationSpy(&d, SIGNAL(durationChanged(qint64)));
    QSignalSpy finishedSpy(&d, SIGNAL(finished()));
    QSignalSpy positionSpy(&d, SIGNAL(positionChanged(qint64)));

    QVERIFY(d.state() == QAudioDecoder::StoppedState);
    QVERIFY(d.bufferAvailable() == false);
    QCOMPARE(d.sourceFilename(), QString(""));
    QVERIFY(d.audioFormat() == QAudioFormat());

    QFileInfo fileInfo(QFINDTESTDATA(TEST_FILE_NAME));
    QFile file(fileInfo.absoluteFilePath());
    QVERIFY(file.open(QIODevice::ReadOnly));
    d.setSourceDevice(&file);

    QVERIFY(d.sourceDevice() == &file);
    QVERIFY(d.sourceFilename().isEmpty());

    // We haven't set the format yet
    QVERIFY(d.audioFormat() == QAudioFormat());

    d.start();
    QTRY_VERIFY(d.state() == QAudioDecoder::DecodingState);
    QTRY_VERIFY(!stateSpy.isEmpty());
    QTRY_VERIFY(!readySpy.isEmpty());
    QTRY_VERIFY(!bufferChangedSpy.isEmpty());
    QVERIFY(d.bufferAvailable());
    QTRY_VERIFY(!durationSpy.isEmpty());
    QVERIFY(qAbs(d.duration() - 1000) < 20);

    buffer = d.read();
    QVERIFY(buffer.isValid());

    // Test file is 44.1K 16bit mono
    QCOMPARE(buffer.format().channelCount(), 1);
    QCOMPARE(buffer.format().sampleRate(), 44100);
    QCOMPARE(buffer.format().sampleSize(), 16);
    QCOMPARE(buffer.format().sampleType(), QAudioFormat::SignedInt);
    QCOMPARE(buffer.format().codec(), QString("audio/pcm"));

    QVERIFY(errorSpy.isEmpty());

    duration += buffer.duration();
    sampleCount += buffer.sampleCount();

    // Now drain the decoder
    if (sampleCount < 44094) {
        QTRY_COMPARE(d.bufferAvailable(), true);
    }

    while (d.bufferAvailable()) {
        buffer = d.read();
        QVERIFY(buffer.isValid());
        QTRY_VERIFY(!positionSpy.isEmpty());
        QVERIFY(positionSpy.takeLast().at(0).toLongLong() == qint64(duration / 1000));
        QVERIFY(d.position() - (duration / 1000) < 20);

        duration += buffer.duration();
        sampleCount += buffer.sampleCount();
        if (sampleCount < 44094) {
            QTRY_COMPARE(d.bufferAvailable(), true);
        }
    }

    // Make sure the duration is roughly correct (+/- 20ms)
    QCOMPARE(sampleCount, 44094);
    QVERIFY(qAbs(qint64(duration) - 1000000) < 20000);
    QVERIFY(qAbs((d.position() + (buffer.duration() / 1000)) - 1000) < 20);
    QTRY_COMPARE(finishedSpy.count(), 1);
    QVERIFY(!d.bufferAvailable());
    QTRY_COMPARE(d.state(), QAudioDecoder::StoppedState);

    d.stop();
    QTRY_COMPARE(d.state(), QAudioDecoder::StoppedState);
    QVERIFY(!d.bufferAvailable());
    QTRY_COMPARE(durationSpy.count(), 2);
    QCOMPARE(d.duration(), qint64(-1));
    readySpy.clear();
    bufferChangedSpy.clear();
    stateSpy.clear();
    durationSpy.clear();
    finishedSpy.clear();
    positionSpy.clear();

    // Now try changing formats
    QAudioFormat format;
    format.setChannelCount(2);
    format.setSampleSize(8);
    format.setSampleRate(8000);
    format.setCodec("audio/pcm");
    format.setSampleType(QAudioFormat::SignedInt);

    d.setAudioFormat(format);

    // Make sure it stuck
    QVERIFY(d.audioFormat() == format);

    d.start();
    QTRY_VERIFY(d.state() == QAudioDecoder::DecodingState);
    QTRY_VERIFY(!stateSpy.isEmpty());
    QTRY_VERIFY(!readySpy.isEmpty());
    QTRY_VERIFY(!bufferChangedSpy.isEmpty());
    QVERIFY(d.bufferAvailable());
    QTRY_VERIFY(!durationSpy.isEmpty());
    QVERIFY(qAbs(d.duration() - 1000) < 20);

    buffer = d.read();
    QVERIFY(buffer.isValid());
    // See if we got the right format
    QVERIFY(buffer.format() == format);

    // The decoder should still have the same format
    QVERIFY(d.audioFormat() == format);

    QVERIFY(errorSpy.isEmpty());

    d.stop();
    QTRY_COMPARE(d.state(), QAudioDecoder::StoppedState);
    QVERIFY(!d.bufferAvailable());
    QTRY_COMPARE(durationSpy.count(), 2);
    QCOMPARE(d.duration(), qint64(-1));
}
/*
 The corrupted file is generated by copying a few random numbers
 from /dev/random on a linux machine.
*/
void tst_QAudioDecoderBackend::corruptedFileTest()
{
    QAudioDecoder d;
    QAudioBuffer buffer;

    QVERIFY(d.state() == QAudioDecoder::StoppedState);
    QVERIFY(d.bufferAvailable() == false);
    QCOMPARE(d.sourceFilename(), QString(""));
    QVERIFY(d.audioFormat() == QAudioFormat());

    // Test local file
    QFileInfo fileInfo(QFINDTESTDATA(TEST_CORRUPTED_FILE_NAME));
    d.setSourceFilename(fileInfo.absoluteFilePath());
    QVERIFY(d.state() == QAudioDecoder::StoppedState);
    QVERIFY(!d.bufferAvailable());
    QCOMPARE(d.sourceFilename(), fileInfo.absoluteFilePath());

    QSignalSpy readySpy(&d, SIGNAL(bufferReady()));
    QSignalSpy bufferChangedSpy(&d, SIGNAL(bufferAvailableChanged(bool)));
    QSignalSpy errorSpy(&d, SIGNAL(error(QAudioDecoder::Error)));
    QSignalSpy stateSpy(&d, SIGNAL(stateChanged(QAudioDecoder::State)));
    QSignalSpy durationSpy(&d, SIGNAL(durationChanged(qint64)));
    QSignalSpy finishedSpy(&d, SIGNAL(finished()));
    QSignalSpy positionSpy(&d, SIGNAL(positionChanged(qint64)));

    d.start();
    QTRY_VERIFY(d.state() == QAudioDecoder::StoppedState);
    QVERIFY(!d.bufferAvailable());
    QCOMPARE(d.audioFormat(), QAudioFormat());
    QCOMPARE(d.duration(), qint64(-1));
    QCOMPARE(d.position(), qint64(-1));

    // Check the error code.
    QTRY_VERIFY(!errorSpy.isEmpty());

    // Have to use qvariant_cast, toInt will return 0 because unrecognized type;
    QAudioDecoder::Error errorCode = qvariant_cast<QAudioDecoder::Error>(errorSpy.takeLast().at(0));
    QCOMPARE(errorCode, QAudioDecoder::FormatError);
    QCOMPARE(d.error(), QAudioDecoder::FormatError);

    // Check all other spies.
    QVERIFY(readySpy.isEmpty());
    QVERIFY(bufferChangedSpy.isEmpty());
    QVERIFY(stateSpy.isEmpty());
    QVERIFY(finishedSpy.isEmpty());
    QVERIFY(positionSpy.isEmpty());
    QVERIFY(durationSpy.isEmpty());

    errorSpy.clear();

    // Try read even if the file is corrupted to test the robustness.
    buffer = d.read();
    QTRY_VERIFY(d.state() == QAudioDecoder::StoppedState);
    QVERIFY(!buffer.isValid());
    QVERIFY(!d.bufferAvailable());
    QCOMPARE(d.position(), qint64(-1));

    QVERIFY(errorSpy.isEmpty());
    QVERIFY(readySpy.isEmpty());
    QVERIFY(bufferChangedSpy.isEmpty());
    QVERIFY(stateSpy.isEmpty());
    QVERIFY(finishedSpy.isEmpty());
    QVERIFY(positionSpy.isEmpty());
    QVERIFY(durationSpy.isEmpty());


    d.stop();
    QTRY_COMPARE(d.state(), QAudioDecoder::StoppedState);
    QCOMPARE(d.duration(), qint64(-1));
    QVERIFY(!d.bufferAvailable());
}