/****************************************************************************
**
** Copyright (C) 2014 Denis Shienkov <denis.shienkov@gmail.com>
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtSerialPort module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include <QtTest/QtTest>
#include <QtSerialPort/QSerialPort>
#include <QtSerialPort/QSerialPortInfo>

#include <QThread>

Q_DECLARE_METATYPE(QSerialPort::SerialPortError);
Q_DECLARE_METATYPE(QSerialPort::BaudRate);
Q_DECLARE_METATYPE(QSerialPort::DataBits);
Q_DECLARE_METATYPE(QSerialPort::Parity);
Q_DECLARE_METATYPE(QSerialPort::StopBits);
Q_DECLARE_METATYPE(QSerialPort::FlowControl);
Q_DECLARE_METATYPE(QIODevice::OpenMode);
Q_DECLARE_METATYPE(QIODevice::OpenModeFlag);
Q_DECLARE_METATYPE(Qt::ConnectionType);

class tst_QSerialPort : public QObject
{
    Q_OBJECT
public:
    explicit tst_QSerialPort();

    static void enterLoop(int secs)
    {
        ++loopLevel;
        QTestEventLoop::instance().enterLoop(secs);
        --loopLevel;
    }

    static void enterLoopMsecs(int msecs)
    {
        ++loopLevel;
        QTestEventLoop::instance().enterLoopMSecs(msecs);
        --loopLevel;
    }

    static void exitLoop()
    {
        if (loopLevel > 0)
            QTestEventLoop::instance().exitLoop();
    }

    static bool timeout()
    {
        return QTestEventLoop::instance().timeout();
    }

private slots:
    void initTestCase();

    void defaultConstruct();
    void constructByName();
    void constructByInfo();

    void openExisting_data();
    void openExisting();
    void openNotExisting_data();
    void openNotExisting();

    void baudRate_data();
    void baudRate();
    void dataBits_data();
    void dataBits();
    void parity_data();
    void parity();
    void stopBits_data();
    void stopBits();
    void flowControl_data();
    void flowControl();

    void rts();
    void dtr();
    void independenceRtsAndDtr();

    void flush();
    void doubleFlush();

    void waitForBytesWritten();

    void waitForReadyReadWithTimeout();
    void waitForReadyReadWithOneByte();
    void waitForReadyReadWithAlphabet();

    void twoStageSynchronousLoopback();

    void synchronousReadWrite();

    void asynchronousWriteByBytesWritten_data();
    void asynchronousWriteByBytesWritten();

    void asynchronousWriteByTimer_data();
    void asynchronousWriteByTimer();

    void asyncReadWithLimitedReadBufferSize();

    void readBufferOverflow();
    void readAfterInputClear();
    void synchronousReadWriteAfterAsynchronousReadWrite();

    void controlBreak();

    void clearAfterOpen();

    void readWriteWithDifferentBaudRate_data();
    void readWriteWithDifferentBaudRate();

protected slots:
    void handleBytesWrittenAndExitLoopSlot(qint64 bytesWritten);
    void handleBytesWrittenAndExitLoopSlot2(qint64 bytesWritten);

private:
    QString m_senderPortName;
    QString m_receiverPortName;
    QStringList m_availablePortNames;

    static int loopLevel;
    static const QByteArray alphabetArray;
    static const QByteArray newlineArray;
};

int tst_QSerialPort::loopLevel = 0;

const QByteArray tst_QSerialPort::alphabetArray("ABCDEFGHIJKLMNOPQRSTUVWXUZ");
const QByteArray tst_QSerialPort::newlineArray("\n\r");

tst_QSerialPort::tst_QSerialPort()
{
    qRegisterMetaType<QSerialPort::SerialPortError>("QSerialPort::SerialPortError");
}

void tst_QSerialPort::initTestCase()
{
    m_senderPortName = QString::fromLocal8Bit(qgetenv("QTEST_SERIALPORT_SENDER"));
    m_receiverPortName = QString::fromLocal8Bit(qgetenv("QTEST_SERIALPORT_RECEIVER"));
    if (m_senderPortName.isEmpty() || m_receiverPortName.isEmpty()) {
        static const char message[] =
              "Test doesn't work because the names of serial ports aren't found in env.\n"
              "Please set environment variables:\n"
              " QTEST_SERIALPORT_SENDER to name of output serial port\n"
              " QTEST_SERIALPORT_RECEIVER to name of input serial port\n"
              "Specify short names of port"
#if defined(Q_OS_UNIX)
              ", like: ttyS0\n";
#elif defined(Q_OS_WIN32)
              ", like: COM1\n";
#else
              "\n";
#endif

        QSKIP(message);
    } else {
        m_availablePortNames << m_senderPortName << m_receiverPortName;
    }
}

void tst_QSerialPort::defaultConstruct()
{
    QSerialPort serialPort;

    QCOMPARE(serialPort.error(), QSerialPort::NoError);
    QVERIFY(!serialPort.errorString().isEmpty());

    // properties
    const qint32 defaultBaudRate = static_cast<qint32>(QSerialPort::Baud9600);
    QCOMPARE(serialPort.baudRate(), defaultBaudRate);
    QCOMPARE(serialPort.baudRate(QSerialPort::Input), defaultBaudRate);
    QCOMPARE(serialPort.baudRate(QSerialPort::Output), defaultBaudRate);
    QCOMPARE(serialPort.dataBits(), QSerialPort::Data8);
    QCOMPARE(serialPort.parity(), QSerialPort::NoParity);
    QCOMPARE(serialPort.stopBits(), QSerialPort::OneStop);
    QCOMPARE(serialPort.flowControl(), QSerialPort::NoFlowControl);

    QCOMPARE(serialPort.pinoutSignals(), QSerialPort::NoSignal);
    QCOMPARE(serialPort.isRequestToSend(), false);
    QCOMPARE(serialPort.isDataTerminalReady(), false);

    // QIODevice
    QCOMPARE(serialPort.openMode(), QIODevice::NotOpen);
    QVERIFY(!serialPort.isOpen());
    QVERIFY(!serialPort.isReadable());
    QVERIFY(!serialPort.isWritable());
    QVERIFY(serialPort.isSequential());
    QCOMPARE(serialPort.canReadLine(), false);
    QCOMPARE(serialPort.pos(), qlonglong(0));
    QCOMPARE(serialPort.size(), qlonglong(0));
    QVERIFY(serialPort.atEnd());
    QCOMPARE(serialPort.bytesAvailable(), qlonglong(0));
    QCOMPARE(serialPort.bytesToWrite(), qlonglong(0));

    char c;
    QCOMPARE(serialPort.read(&c, 1), qlonglong(-1));
    QCOMPARE(serialPort.write(&c, 1), qlonglong(-1));
}

void tst_QSerialPort::constructByName()
{
    QSerialPort serialPort(m_senderPortName);
    QCOMPARE(serialPort.portName(), m_senderPortName);
    serialPort.setPortName(m_receiverPortName);
    QCOMPARE(serialPort.portName(), m_receiverPortName);
}

void tst_QSerialPort::constructByInfo()
{
    QSerialPortInfo senderPortInfo(m_senderPortName);
    QSerialPortInfo receiverPortInfo(m_receiverPortName);

#if defined(Q_OS_UNIX)
    if (senderPortInfo.isNull() || receiverPortInfo.isNull()) {
        static const char message[] =
                "Test doesn't work because the specified serial ports aren't"
                " found in system and can't be constructed by QSerialPortInfo.\n";
        QSKIP(message);
    }
#endif

    QSerialPort serialPort(senderPortInfo);
    QCOMPARE(serialPort.portName(), m_senderPortName);
    serialPort.setPort(receiverPortInfo);
    QCOMPARE(serialPort.portName(), m_receiverPortName);
}

void tst_QSerialPort::openExisting_data()
{
    QTest::addColumn<int>("openMode");
    QTest::addColumn<bool>("openResult");
    QTest::addColumn<QSerialPort::SerialPortError>("errorCode");

    QTest::newRow("NotOpen") << int(QIODevice::NotOpen) << false << QSerialPort::UnsupportedOperationError;
    QTest::newRow("ReadOnly") << int(QIODevice::ReadOnly) << true << QSerialPort::NoError;
    QTest::newRow("WriteOnly") << int(QIODevice::WriteOnly) << true << QSerialPort::NoError;
    QTest::newRow("ReadWrite") << int(QIODevice::ReadWrite) << true << QSerialPort::NoError;
    QTest::newRow("Append") << int(QIODevice::Append) << false << QSerialPort::UnsupportedOperationError;
    QTest::newRow("Truncate") << int(QIODevice::Truncate) << false << QSerialPort::UnsupportedOperationError;
    QTest::newRow("Text") << int(QIODevice::Text) << false << QSerialPort::UnsupportedOperationError;
    QTest::newRow("Unbuffered") << int(QIODevice::Unbuffered) << false << QSerialPort::UnsupportedOperationError;
}

void tst_QSerialPort::openExisting()
{
    QFETCH(int, openMode);
    QFETCH(bool, openResult);
    QFETCH(QSerialPort::SerialPortError, errorCode);

    for (const QString &serialPortName : qAsConst(m_availablePortNames)) {
        QSerialPort serialPort(serialPortName);
        QSignalSpy errorSpy(&serialPort, &QSerialPort::errorOccurred);
        QVERIFY(errorSpy.isValid());

        QCOMPARE(serialPort.portName(), serialPortName);
        QCOMPARE(serialPort.open(QIODevice::OpenMode(openMode)), openResult);
        QCOMPARE(serialPort.isOpen(), openResult);
        QCOMPARE(serialPort.error(), errorCode);

        QCOMPARE(errorSpy.count(), 1);
        QCOMPARE(qvariant_cast<QSerialPort::SerialPortError>(errorSpy.at(0).at(0)), errorCode);
    }
}

void tst_QSerialPort::openNotExisting_data()
{
    QTest::addColumn<QString>("serialPortName");
    QTest::addColumn<bool>("openResult");
    QTest::addColumn<QSerialPort::SerialPortError>("errorCode");

    QTest::newRow("Empty") << QString("") << false << QSerialPort::DeviceNotFoundError;
    QTest::newRow("Null") << QString() << false << QSerialPort::DeviceNotFoundError;
    QTest::newRow("NotExists") << QString("ABCDEF") << false << QSerialPort::DeviceNotFoundError;
}

void tst_QSerialPort::openNotExisting()
{
    QFETCH(QString, serialPortName);
    QFETCH(bool, openResult);
    //QFETCH(QSerialPort::SerialPortError, errorCode);

    QSerialPort serialPort(serialPortName);

    QSignalSpy errorSpy(&serialPort, &QSerialPort::errorOccurred);
    QVERIFY(errorSpy.isValid());

    QCOMPARE(serialPort.portName(), serialPortName);
    QCOMPARE(serialPort.open(QIODevice::ReadOnly), openResult);
    QCOMPARE(serialPort.isOpen(), openResult);
    //QCOMPARE(serialPort.error(), errorCode);

    //QCOMPARE(errorSpy.count(), 1);
    //QCOMPARE(qvariant_cast<QSerialPort::SerialPortError>(errorSpy.at(0).at(0)), errorCode);
}

void tst_QSerialPort::baudRate_data()
{
    QTest::addColumn<qint32>("baudrate");
    QTest::newRow("Baud1200") << static_cast<qint32>(QSerialPort::Baud1200);
    QTest::newRow("Baud2400") << static_cast<qint32>(QSerialPort::Baud2400);
    QTest::newRow("Baud4800") << static_cast<qint32>(QSerialPort::Baud4800);
    QTest::newRow("Baud9600") << static_cast<qint32>(QSerialPort::Baud9600);
    QTest::newRow("Baud19200") << static_cast<qint32>(QSerialPort::Baud19200);
    QTest::newRow("Baud38400") << static_cast<qint32>(QSerialPort::Baud38400);
    QTest::newRow("Baud57600") << static_cast<qint32>(QSerialPort::Baud57600);
    QTest::newRow("Baud115200") << static_cast<qint32>(QSerialPort::Baud115200);

    QTest::newRow("31250") << 31250; // custom baudrate (MIDI)
}

void tst_QSerialPort::baudRate()
{
    QFETCH(qint32, baudrate);

    {
        // setup before opening
        QSerialPort serialPort(m_senderPortName);
        QVERIFY(serialPort.setBaudRate(baudrate));
        QCOMPARE(serialPort.baudRate(), baudrate);
        QVERIFY(serialPort.open(QIODevice::ReadWrite));
    }

    {
        // setup after opening
        QSerialPort serialPort(m_senderPortName);
        QVERIFY(serialPort.open(QIODevice::ReadWrite));
        QVERIFY(serialPort.setBaudRate(baudrate));
        QCOMPARE(serialPort.baudRate(), baudrate);
    }
}

void tst_QSerialPort::dataBits_data()
{
    QTest::addColumn<QSerialPort::DataBits>("databits");
    QTest::newRow("Data5") << QSerialPort::Data5;
    QTest::newRow("Data6") << QSerialPort::Data6;
    QTest::newRow("Data7") << QSerialPort::Data7;
    QTest::newRow("Data8") << QSerialPort::Data8;
}

void tst_QSerialPort::dataBits()
{
    QFETCH(QSerialPort::DataBits, databits);

    {
        // setup before opening
        QSerialPort serialPort(m_senderPortName);
        QVERIFY(serialPort.setDataBits(databits));
        QCOMPARE(serialPort.dataBits(), databits);
        QVERIFY(serialPort.open(QIODevice::ReadWrite));
    }

    {
        // setup after opening
        QSerialPort serialPort(m_senderPortName);
        QVERIFY(serialPort.open(QIODevice::ReadWrite));
        QVERIFY(serialPort.setDataBits(databits));
        QCOMPARE(serialPort.dataBits(), databits);
    }
}

void tst_QSerialPort::parity_data()
{
    QTest::addColumn<QSerialPort::Parity>("parity");
    QTest::newRow("NoParity") << QSerialPort::NoParity;
    QTest::newRow("EvenParity") << QSerialPort::EvenParity;
    QTest::newRow("OddParity") << QSerialPort::OddParity;
    QTest::newRow("SpaceParity") << QSerialPort::SpaceParity;
    QTest::newRow("MarkParity") << QSerialPort::MarkParity;
}

void tst_QSerialPort::parity()
{
    QFETCH(QSerialPort::Parity, parity);

    {
        // setup before opening
        QSerialPort serialPort(m_senderPortName);
        QVERIFY(serialPort.setParity(parity));
        QCOMPARE(serialPort.parity(), parity);
        QVERIFY(serialPort.open(QIODevice::ReadWrite));
    }

    {
        // setup after opening
        QSerialPort serialPort(m_senderPortName);
        QVERIFY(serialPort.open(QIODevice::ReadWrite));
        QVERIFY(serialPort.setParity(parity));
        QCOMPARE(serialPort.parity(), parity);
    }
}

void tst_QSerialPort::stopBits_data()
{
    QTest::addColumn<QSerialPort::StopBits>("stopbits");
    QTest::newRow("OneStop") << QSerialPort::OneStop;
#ifdef Q_OS_WIN
    QTest::newRow("OneAndHalfStop") << QSerialPort::OneAndHalfStop;
#endif
    QTest::newRow("TwoStop") << QSerialPort::TwoStop;
}

void tst_QSerialPort::stopBits()
{
    QFETCH(QSerialPort::StopBits, stopbits);

    {
        // setup before opening
        QSerialPort serialPort(m_senderPortName);
        QVERIFY(serialPort.setStopBits(stopbits));
        QCOMPARE(serialPort.stopBits(), stopbits);
        QVERIFY(serialPort.open(QIODevice::ReadWrite));
    }

    {
        // setup after opening
        QSerialPort serialPort(m_senderPortName);
        QVERIFY(serialPort.open(QIODevice::ReadWrite));
        QVERIFY(serialPort.setStopBits(stopbits));
        QCOMPARE(serialPort.stopBits(), stopbits);
    }
}

void tst_QSerialPort::flowControl_data()
{
    QTest::addColumn<QSerialPort::FlowControl>("flowcontrol");
    QTest::newRow("NoFlowControl") << QSerialPort::NoFlowControl;
    QTest::newRow("HardwareControl") << QSerialPort::HardwareControl;
    QTest::newRow("SoftwareControl") << QSerialPort::SoftwareControl;
}

void tst_QSerialPort::flowControl()
{
    QFETCH(QSerialPort::FlowControl, flowcontrol);

    {
        // setup before opening
        QSerialPort serialPort(m_senderPortName);
        QVERIFY(serialPort.setFlowControl(flowcontrol));
        QCOMPARE(serialPort.flowControl(), flowcontrol);
        QVERIFY(serialPort.open(QIODevice::ReadWrite));
    }

    {
        // setup after opening
        QSerialPort serialPort(m_senderPortName);
        QVERIFY(serialPort.open(QIODevice::ReadWrite));
        QVERIFY(serialPort.setFlowControl(flowcontrol));
        QCOMPARE(serialPort.flowControl(), flowcontrol);
    }
}

void tst_QSerialPort::rts()
{
    QSerialPort serialPort(m_senderPortName);

    QSignalSpy errorSpy(&serialPort, &QSerialPort::errorOccurred);
    QVERIFY(errorSpy.isValid());
    QSignalSpy rtsSpy(&serialPort, &QSerialPort::requestToSendChanged);
    QVERIFY(rtsSpy.isValid());

    QVERIFY(serialPort.open(QIODevice::ReadWrite));

    // no flow control
    QVERIFY(serialPort.setFlowControl(QSerialPort::NoFlowControl));
    const bool toggle1 = !serialPort.isRequestToSend();
    QVERIFY(serialPort.setRequestToSend(toggle1));
    QCOMPARE(serialPort.isRequestToSend(), toggle1);

    // software flow control
    QVERIFY(serialPort.setFlowControl(QSerialPort::SoftwareControl));
    const bool toggle2 = !serialPort.isRequestToSend();
    QVERIFY(serialPort.setRequestToSend(toggle2));
    QCOMPARE(serialPort.isRequestToSend(), toggle2);

    // hardware flow control
    QVERIFY(serialPort.setFlowControl(QSerialPort::HardwareControl));
    const bool toggle3 = !serialPort.isRequestToSend();
    QVERIFY(!serialPort.setRequestToSend(toggle3)); // not allowed
    QCOMPARE(serialPort.isRequestToSend(), !toggle3); // same as before
    QCOMPARE(serialPort.error(), QSerialPort::UnsupportedOperationError);

    QCOMPARE(errorSpy.count(), 2);
    QCOMPARE(qvariant_cast<QSerialPort::SerialPortError>(errorSpy.at(0).at(0)), QSerialPort::NoError);
    QCOMPARE(qvariant_cast<QSerialPort::SerialPortError>(errorSpy.at(1).at(0)), QSerialPort::UnsupportedOperationError);

    QCOMPARE(rtsSpy.count(), 2);
    QCOMPARE(qvariant_cast<bool>(rtsSpy.at(0).at(0)), toggle1);
    QCOMPARE(qvariant_cast<bool>(rtsSpy.at(1).at(0)), toggle2);
}

void tst_QSerialPort::dtr()
{
    QSerialPort serialPort(m_senderPortName);

    QSignalSpy errorSpy(&serialPort, &QSerialPort::errorOccurred);
    QVERIFY(errorSpy.isValid());
    QSignalSpy dtrSpy(&serialPort, &QSerialPort::dataTerminalReadyChanged);
    QVERIFY(dtrSpy.isValid());

    QVERIFY(serialPort.open(QIODevice::ReadWrite));

    // no flow control
    QVERIFY(serialPort.setFlowControl(QSerialPort::NoFlowControl));
    const bool toggle1 = !serialPort.isDataTerminalReady();
    QVERIFY(serialPort.setDataTerminalReady(toggle1));
    QCOMPARE(serialPort.isDataTerminalReady(), toggle1);

    // software flow control
    QVERIFY(serialPort.setFlowControl(QSerialPort::SoftwareControl));
    const bool toggle2 = !serialPort.isDataTerminalReady();
    QVERIFY(serialPort.setDataTerminalReady(toggle2));
    QCOMPARE(serialPort.isDataTerminalReady(), toggle2);

    // hardware flow control
    QVERIFY(serialPort.setFlowControl(QSerialPort::HardwareControl));
    const bool toggle3 = !serialPort.isDataTerminalReady();
    QVERIFY(serialPort.setDataTerminalReady(toggle3));
    QCOMPARE(serialPort.isDataTerminalReady(), toggle3);

    QCOMPARE(errorSpy.count(), 1);
    QCOMPARE(qvariant_cast<QSerialPort::SerialPortError>(errorSpy.at(0).at(0)), QSerialPort::NoError);

    QCOMPARE(dtrSpy.count(), 3);
    QCOMPARE(qvariant_cast<bool>(dtrSpy.at(0).at(0)), toggle1);
    QCOMPARE(qvariant_cast<bool>(dtrSpy.at(1).at(0)), toggle2);
    QCOMPARE(qvariant_cast<bool>(dtrSpy.at(2).at(0)), toggle3);
}

void tst_QSerialPort::independenceRtsAndDtr()
{
    QSerialPort serialPort(m_senderPortName);
    QVERIFY(serialPort.open(QIODevice::ReadWrite)); // No flow control by default!

    QVERIFY(serialPort.setDataTerminalReady(true));
    QVERIFY(serialPort.setRequestToSend(true));
    QVERIFY(serialPort.isDataTerminalReady());
    QVERIFY(serialPort.isRequestToSend());

    // check that DTR changing does not change RTS
    QVERIFY(serialPort.setDataTerminalReady(false));
    QVERIFY(!serialPort.isDataTerminalReady());
    QVERIFY(serialPort.isRequestToSend());
    QVERIFY(serialPort.setDataTerminalReady(true));
    QVERIFY(serialPort.isDataTerminalReady());
    QVERIFY(serialPort.isRequestToSend());

    // check that RTS changing does not change DTR
    QVERIFY(serialPort.setRequestToSend(false));
    QVERIFY(!serialPort.isRequestToSend());
    QVERIFY(serialPort.isDataTerminalReady());
    QVERIFY(serialPort.setRequestToSend(true));
    QVERIFY(serialPort.isRequestToSend());
    QVERIFY(serialPort.isDataTerminalReady());

    // check that baud rate changing does not change DTR or RTS
    QVERIFY(serialPort.setBaudRate(115200));
    QVERIFY(serialPort.isRequestToSend());
    QVERIFY(serialPort.isDataTerminalReady());

    // check that data bits changing does not change DTR or RTS
    QVERIFY(serialPort.setDataBits(QSerialPort::Data7));
    QVERIFY(serialPort.isRequestToSend());
    QVERIFY(serialPort.isDataTerminalReady());

    // check that parity changing does not change DTR or RTS
    QVERIFY(serialPort.setParity(QSerialPort::EvenParity));
    QVERIFY(serialPort.isRequestToSend());
    QVERIFY(serialPort.isDataTerminalReady());

    // check that stop bits changing does not change DTR or RTS
    QVERIFY(serialPort.setStopBits(QSerialPort::TwoStop));
    QVERIFY(serialPort.isRequestToSend());
    QVERIFY(serialPort.isDataTerminalReady());

    // check that software flow control changing does not change DTR or RTS
    QVERIFY(serialPort.setFlowControl(QSerialPort::SoftwareControl));
    QVERIFY(serialPort.isRequestToSend());
    QVERIFY(serialPort.isDataTerminalReady());
}

void tst_QSerialPort::handleBytesWrittenAndExitLoopSlot(qint64 bytesWritten)
{
    QCOMPARE(bytesWritten, qint64(alphabetArray.size() + newlineArray.size()));
    exitLoop();
}

void tst_QSerialPort::flush()
{
#ifdef Q_OS_WIN
    QSKIP("flush() does not work on Windows");
#endif

    // the dummy device on other side also has to be open
    QSerialPort dummySerialPort(m_receiverPortName);
    QVERIFY(dummySerialPort.open(QIODevice::ReadOnly));

    QSerialPort serialPort(m_senderPortName);
    connect(&serialPort, &QSerialPort::bytesWritten, this, &tst_QSerialPort::handleBytesWrittenAndExitLoopSlot);
    QSignalSpy bytesWrittenSpy(&serialPort, &QSerialPort::bytesWritten);

    QVERIFY(serialPort.open(QIODevice::WriteOnly));
    serialPort.write(alphabetArray + newlineArray);
    QCOMPARE(serialPort.bytesToWrite(), qint64(alphabetArray.size() + newlineArray.size()));
    serialPort.flush();
    QCOMPARE(serialPort.bytesToWrite(), qint64(0));
    enterLoop(1);
    QVERIFY2(!timeout(), "Timed out when waiting for the bytesWritten(qint64) signal.");
    QCOMPARE(bytesWrittenSpy.count(), 1);
}

void tst_QSerialPort::handleBytesWrittenAndExitLoopSlot2(qint64 bytesWritten)
{
    static qint64 bytes = 0;
    bytes += bytesWritten;

    QVERIFY(bytesWritten == newlineArray.size() || bytesWritten == alphabetArray.size());

    if (bytes == (alphabetArray.size() + newlineArray.size()))
        exitLoop();
}

void tst_QSerialPort::doubleFlush()
{
#ifdef Q_OS_WIN
    QSKIP("flush() does not work on Windows");
#endif

    // the dummy device on other side also has to be open
    QSerialPort dummySerialPort(m_receiverPortName);
    QVERIFY(dummySerialPort.open(QIODevice::ReadOnly));

    QSerialPort serialPort(m_senderPortName);
    connect(&serialPort, &QSerialPort::bytesWritten, this, &tst_QSerialPort::handleBytesWrittenAndExitLoopSlot2);
    QSignalSpy bytesWrittenSpy(&serialPort, &QSerialPort::bytesWritten);

    QVERIFY(serialPort.open(QIODevice::WriteOnly));
    serialPort.write(alphabetArray);
    QCOMPARE(serialPort.bytesToWrite(), qint64(alphabetArray.size()));
    serialPort.flush();
    QCOMPARE(serialPort.bytesToWrite(), qint64(0));
    serialPort.write(newlineArray);
    QCOMPARE(serialPort.bytesToWrite(), qint64(newlineArray.size()));
    serialPort.flush();
    QCOMPARE(serialPort.bytesToWrite(), qint64(0));

    enterLoop(1);
    QVERIFY2(!timeout(), "Timed out when waiting for the bytesWritten(qint64) signal.");
    QCOMPARE(bytesWrittenSpy.count(), 2);
}

void tst_QSerialPort::waitForBytesWritten()
{
    // the dummy device on other side also has to be open
    QSerialPort dummySerialPort(m_receiverPortName);
    QVERIFY(dummySerialPort.open(QIODevice::ReadOnly));

    QSerialPort serialPort(m_senderPortName);
    QVERIFY(serialPort.open(QIODevice::WriteOnly));
    serialPort.write(alphabetArray);
    const qint64 toWrite = serialPort.bytesToWrite();
    QVERIFY(serialPort.waitForBytesWritten(1000));
    QVERIFY(toWrite > serialPort.bytesToWrite());
}

void tst_QSerialPort::waitForReadyReadWithTimeout()
{
    // the dummy device on other side also has to be open
    QSerialPort dummySerialPort(m_senderPortName);
    QVERIFY(dummySerialPort.open(QIODevice::WriteOnly));

    QSerialPort receiverSerialPort(m_receiverPortName);
    QVERIFY(receiverSerialPort.open(QIODevice::ReadOnly));
    QVERIFY(!receiverSerialPort.waitForReadyRead(5));
    QCOMPARE(receiverSerialPort.bytesAvailable(), qint64(0));
    QCOMPARE(receiverSerialPort.error(), QSerialPort::TimeoutError);
}

void tst_QSerialPort::waitForReadyReadWithOneByte()
{
    const qint64 oneByte = 1;
    const int waitMsecs = 50;

    QSerialPort senderSerialPort(m_senderPortName);
    QVERIFY(senderSerialPort.open(QIODevice::WriteOnly));
    QSerialPort receiverSerialPort(m_receiverPortName);
    QSignalSpy readyReadSpy(&receiverSerialPort, &QSerialPort::readyRead);
    QVERIFY(readyReadSpy.isValid());
    QVERIFY(receiverSerialPort.open(QIODevice::ReadOnly));
    QCOMPARE(senderSerialPort.write(alphabetArray.constData(), oneByte), oneByte);
    QVERIFY(senderSerialPort.waitForBytesWritten(waitMsecs));
    QVERIFY(receiverSerialPort.waitForReadyRead(waitMsecs));
    QCOMPARE(receiverSerialPort.bytesAvailable(), oneByte);
    QCOMPARE(receiverSerialPort.error(), QSerialPort::NoError);
    QCOMPARE(readyReadSpy.count(), 1);
}

void tst_QSerialPort::waitForReadyReadWithAlphabet()
{
    const int waitMsecs = 50;

    QSerialPort senderSerialPort(m_senderPortName);
    QVERIFY(senderSerialPort.open(QIODevice::WriteOnly));
    QSerialPort receiverSerialPort(m_receiverPortName);
    QSignalSpy readyReadSpy(&receiverSerialPort, &QSerialPort::readyRead);
    QVERIFY(readyReadSpy.isValid());
    QVERIFY(receiverSerialPort.open(QIODevice::ReadOnly));
    QCOMPARE(senderSerialPort.write(alphabetArray), qint64(alphabetArray.size()));
    QVERIFY(senderSerialPort.waitForBytesWritten(waitMsecs));

    do {
        QVERIFY(receiverSerialPort.waitForReadyRead(waitMsecs));
    } while (receiverSerialPort.bytesAvailable() < qint64(alphabetArray.size()));

    QCOMPARE(receiverSerialPort.error(), QSerialPort::NoError);
    QVERIFY(readyReadSpy.count() > 0);
}

void tst_QSerialPort::twoStageSynchronousLoopback()
{
    QSerialPort senderPort(m_senderPortName);
    QVERIFY(senderPort.open(QSerialPort::ReadWrite));

    QSerialPort receiverPort(m_receiverPortName);
    QVERIFY(receiverPort.open(QSerialPort::ReadWrite));

    const int waitMsecs = 50;

    // first stage
    senderPort.write(newlineArray);
    senderPort.waitForBytesWritten(waitMsecs);
    QTest::qSleep(waitMsecs);
    receiverPort.waitForReadyRead(waitMsecs);
    QCOMPARE(receiverPort.bytesAvailable(), qint64(newlineArray.size()));

    receiverPort.write(receiverPort.readAll());
    receiverPort.waitForBytesWritten(waitMsecs);
    QTest::qSleep(waitMsecs);
    senderPort.waitForReadyRead(waitMsecs);
    QCOMPARE(senderPort.bytesAvailable(), qint64(newlineArray.size()));
    QCOMPARE(senderPort.readAll(), newlineArray);

    // second stage
    senderPort.write(newlineArray);
    senderPort.waitForBytesWritten(waitMsecs);
    QTest::qSleep(waitMsecs);
    receiverPort.waitForReadyRead(waitMsecs);
    QCOMPARE(receiverPort.bytesAvailable(), qint64(newlineArray.size()));
    receiverPort.write(receiverPort.readAll());
    receiverPort.waitForBytesWritten(waitMsecs);
    QTest::qSleep(waitMsecs);
    senderPort.waitForReadyRead(waitMsecs);
    QCOMPARE(senderPort.bytesAvailable(), qint64(newlineArray.size()));
    QCOMPARE(senderPort.readAll(), newlineArray);
}

void tst_QSerialPort::synchronousReadWrite()
{
    QSerialPort senderPort(m_senderPortName);
    QVERIFY(senderPort.open(QSerialPort::WriteOnly));

    QSerialPort receiverPort(m_receiverPortName);
    QVERIFY(receiverPort.open(QSerialPort::ReadOnly));

    QByteArray writeData;
    for (int i = 0; i < 1024; ++i)
        writeData.append(static_cast<char>(i));

    senderPort.write(writeData);
    senderPort.waitForBytesWritten(-1);

    QByteArray readData;
    while ((readData.size() < writeData.size()) && receiverPort.waitForReadyRead(100))
        readData.append(receiverPort.readAll());

    QCOMPARE(readData, writeData);
}

class AsyncReader : public QObject
{
    Q_OBJECT
public:
    explicit AsyncReader(QSerialPort &port, Qt::ConnectionType connectionType, int expectedBytesCount)
        : serialPort(port), expectedBytesCount(expectedBytesCount)
    {
        connect(&serialPort, &QSerialPort::readyRead, this, &AsyncReader::receive, connectionType);
    }

private slots:
    void receive()
    {
        if (serialPort.bytesAvailable() < expectedBytesCount)
            return;
        tst_QSerialPort::exitLoop();
    }

private:
    QSerialPort &serialPort;
    const int expectedBytesCount;
};

class AsyncWriterByBytesWritten : public QObject
{
    Q_OBJECT
public:
    explicit AsyncWriterByBytesWritten(
            QSerialPort &port, Qt::ConnectionType connectionType, const QByteArray &dataToWrite)
        : serialPort(port), writeChunkSize(0)
    {
        writeBuffer.setData(dataToWrite);
        writeBuffer.open(QIODevice::ReadOnly);
        connect(&serialPort, &QSerialPort::bytesWritten, this, &AsyncWriterByBytesWritten::send, connectionType);
        send();
    }

private slots:
    void send()
    {
        if (writeBuffer.bytesAvailable() > 0)
            serialPort.write(writeBuffer.read(++writeChunkSize));
    }

private:
    QSerialPort &serialPort;
    QBuffer writeBuffer;
    int writeChunkSize;
};

void tst_QSerialPort::asynchronousWriteByBytesWritten_data()
{
    QTest::addColumn<Qt::ConnectionType>("readConnectionType");
    QTest::addColumn<Qt::ConnectionType>("writeConnectionType");

    QTest::newRow("BothQueued") << Qt::QueuedConnection << Qt::QueuedConnection;
    QTest::newRow("BothDirect") << Qt::DirectConnection << Qt::DirectConnection;
    QTest::newRow("ReadDirectWriteQueued") << Qt::DirectConnection << Qt::QueuedConnection;
    QTest::newRow("ReadQueuedWriteDirect") << Qt::QueuedConnection << Qt::DirectConnection;
}

void tst_QSerialPort::asynchronousWriteByBytesWritten()
{
    QFETCH(Qt::ConnectionType, readConnectionType);
    QFETCH(Qt::ConnectionType, writeConnectionType);

    QSerialPort receiverPort(m_receiverPortName);
    QVERIFY(receiverPort.open(QSerialPort::ReadOnly));
    AsyncReader reader(receiverPort, readConnectionType, alphabetArray.size());

    QSerialPort senderPort(m_senderPortName);
    QVERIFY(senderPort.open(QSerialPort::WriteOnly));
    AsyncWriterByBytesWritten writer(senderPort, writeConnectionType, alphabetArray);

    enterLoop(1);
    QVERIFY2(!timeout(), "Timed out when waiting for the read or write.");
    QCOMPARE(receiverPort.bytesAvailable(), qint64(alphabetArray.size()));
    QCOMPARE(receiverPort.readAll(), alphabetArray);
}

class AsyncWriterByTimer : public QObject
{
    Q_OBJECT
public:
    explicit AsyncWriterByTimer(
            QSerialPort &port, Qt::ConnectionType connectionType, const QByteArray &dataToWrite)
        : serialPort(port), writeChunkSize(0)
    {
        writeBuffer.setData(dataToWrite);
        writeBuffer.open(QIODevice::ReadOnly);
        connect(&timer, &QTimer::timeout, this, &AsyncWriterByTimer::send, connectionType);
        timer.start(0);
    }

private slots:
    void send()
    {
        if (writeBuffer.bytesAvailable() > 0)
            serialPort.write(writeBuffer.read(++writeChunkSize));
        else
            timer.stop();
    }

private:
    QSerialPort &serialPort;
    QBuffer writeBuffer;
    int writeChunkSize;
    QTimer timer;
};

void tst_QSerialPort::asynchronousWriteByTimer_data()
{
    QTest::addColumn<Qt::ConnectionType>("readConnectionType");
    QTest::addColumn<Qt::ConnectionType>("writeConnectionType");

    QTest::newRow("BothQueued") << Qt::QueuedConnection << Qt::QueuedConnection;
    QTest::newRow("BothDirect") << Qt::DirectConnection << Qt::DirectConnection;
    QTest::newRow("ReadDirectWriteQueued") << Qt::DirectConnection << Qt::QueuedConnection;
    QTest::newRow("ReadQueuedWriteDirect") << Qt::QueuedConnection << Qt::DirectConnection;
}

void tst_QSerialPort::asynchronousWriteByTimer()
{
    QFETCH(Qt::ConnectionType, readConnectionType);
    QFETCH(Qt::ConnectionType, writeConnectionType);

    QSerialPort receiverPort(m_receiverPortName);
    QVERIFY(receiverPort.open(QSerialPort::ReadOnly));
    AsyncReader reader(receiverPort, readConnectionType, alphabetArray.size());

    QSerialPort senderPort(m_senderPortName);
    QVERIFY(senderPort.open(QSerialPort::WriteOnly));
    AsyncWriterByTimer writer(senderPort, writeConnectionType, alphabetArray);

    enterLoop(1);
    QVERIFY2(!timeout(), "Timed out when waiting for the read or write.");
    QCOMPARE(receiverPort.bytesAvailable(), qint64(alphabetArray.size()));
    QCOMPARE(receiverPort.readAll(), alphabetArray);
}

class AsyncReader2 : public QObject
{
    Q_OBJECT
public:
    explicit AsyncReader2(QSerialPort &port, const QByteArray &expectedData)
        : serialPort(port), expectedData(expectedData)
    {
        connect(&serialPort, &QSerialPort::readyRead, this, &AsyncReader2::receive);
    }

private slots:
    void receive()
    {
        receivedData.append(serialPort.readAll());
        if (receivedData == expectedData)
            tst_QSerialPort::exitLoop();
    }

private:
    QSerialPort &serialPort;
    const QByteArray expectedData;
    QByteArray receivedData;
};

void tst_QSerialPort::asyncReadWithLimitedReadBufferSize()
{
    QSerialPort senderPort(m_senderPortName);
    QVERIFY(senderPort.open(QSerialPort::WriteOnly));

    QSerialPort receiverPort(m_receiverPortName);
    QVERIFY(receiverPort.open(QSerialPort::ReadOnly));

    receiverPort.setReadBufferSize(1);
    QCOMPARE(receiverPort.readBufferSize(), qint64(1));

    AsyncReader2 reader(receiverPort, alphabetArray);

    QCOMPARE(senderPort.write(alphabetArray), qint64(alphabetArray.size()));

    enterLoop(1);
    QVERIFY2(!timeout(), "Timed out when waiting for the read or write.");
}

void tst_QSerialPort::readBufferOverflow()
{
    QSerialPort senderPort(m_senderPortName);
    QVERIFY(senderPort.open(QSerialPort::WriteOnly));

    QSerialPort receiverPort(m_receiverPortName);
    QVERIFY(receiverPort.open(QSerialPort::ReadOnly));

    const int readBufferSize = alphabetArray.size() / 2;
    receiverPort.setReadBufferSize(readBufferSize);
    QCOMPARE(receiverPort.readBufferSize(), qint64(readBufferSize));

    QCOMPARE(senderPort.write(alphabetArray), qint64(alphabetArray.size()));
    QVERIFY2(senderPort.waitForBytesWritten(100), "Waiting for bytes written failed");

    QByteArray readData;
    while (receiverPort.waitForReadyRead(100)) {
        QVERIFY(receiverPort.bytesAvailable() > 0);
        readData += receiverPort.readAll();
    }

    QCOMPARE(readData, alphabetArray);

    // No more bytes available
    QVERIFY(receiverPort.bytesAvailable() == 0);
}

void tst_QSerialPort::readAfterInputClear()
{
    QSerialPort senderPort(m_senderPortName);
    QVERIFY(senderPort.open(QSerialPort::WriteOnly));

    QSerialPort receiverPort(m_receiverPortName);
    QVERIFY(receiverPort.open(QSerialPort::ReadOnly));

    const int readBufferSize = alphabetArray.size() / 2;
    receiverPort.setReadBufferSize(readBufferSize);
    QCOMPARE(receiverPort.readBufferSize(), qint64(readBufferSize));

    const int waitMsecs = 100;

    // First write more than read buffer size
    QCOMPARE(senderPort.write(alphabetArray), qint64(alphabetArray.size()));
    QVERIFY2(senderPort.waitForBytesWritten(waitMsecs), "Waiting for bytes written failed");

    // Wait for first part of data into read buffer
    while (receiverPort.waitForReadyRead(waitMsecs));
    QCOMPARE(receiverPort.bytesAvailable(), qint64(readBufferSize));
    // Wait for second part of data into driver's FIFO
    QTest::qSleep(waitMsecs);

    QVERIFY(receiverPort.clear(QSerialPort::Input));
    QCOMPARE(receiverPort.bytesAvailable(), qint64(0));

    // Second write less than read buffer size
    QCOMPARE(senderPort.write(newlineArray), qint64(newlineArray.size()));
    QVERIFY2(senderPort.waitForBytesWritten(waitMsecs), "Waiting for bytes written failed");

    while (receiverPort.waitForReadyRead(waitMsecs));
    QCOMPARE(receiverPort.bytesAvailable(), qint64(newlineArray.size()));
    QCOMPARE(receiverPort.readAll(), newlineArray);

    // No more bytes available
    QVERIFY(receiverPort.bytesAvailable() == 0);
}

class MasterTransactor : public QObject
{
    Q_OBJECT
public:
    explicit MasterTransactor(const QString &name)
        : serialPort(name)
    {
    }

public slots:
    void open()
    {
        if (serialPort.open(QSerialPort::ReadWrite)) {
            createAsynchronousConnection();
            serialPort.write("A", 1);
        }
    }

private slots:
    void synchronousTransaction()
    {
        serialPort.write("B", 1);
        if (serialPort.waitForBytesWritten(100)) {
            if (serialPort.waitForReadyRead(100))
                tst_QSerialPort::exitLoop();
        }
    }

    void transaction()
    {
        deleteAsyncronousConnection();
        synchronousTransaction();
    }

private:
    void createAsynchronousConnection()
    {
        connect(&serialPort, &QSerialPort::readyRead, this, &MasterTransactor::transaction);
    }

    void deleteAsyncronousConnection()
    {
        serialPort.disconnect();
    }

    QSerialPort serialPort;
};

class SlaveTransactor : public QObject
{
    Q_OBJECT
public:
    explicit SlaveTransactor(const QString &name)
        : serialPort(new QSerialPort(name, this))
    {
        connect(serialPort, &QSerialPort::readyRead, this, &SlaveTransactor::transaction);
    }

public slots:
    void open()
    {
        if (serialPort->open(QSerialPort::ReadWrite))
            emit ready();
    }

signals:
    void ready();

private slots:
    void transaction()
    {
        serialPort->write("Z", 1);
    }

private:
    QSerialPort *serialPort;
};

void tst_QSerialPort::synchronousReadWriteAfterAsynchronousReadWrite()
{
    MasterTransactor master(m_senderPortName);
    auto slave = new SlaveTransactor(m_receiverPortName);

    QThread thread;
    slave->moveToThread(&thread);
    thread.start();

    QObject::connect(&thread, &QThread::finished, slave, &SlaveTransactor::deleteLater);
    QObject::connect(slave, &SlaveTransactor::ready, &master, &MasterTransactor::open);

    QMetaObject::invokeMethod(slave, "open", Qt::QueuedConnection);

    tst_QSerialPort::enterLoopMsecs(2000);

    thread.quit();
    thread.wait();

    QVERIFY2(!timeout(), "Timed out when testing of transactions.");
}

class BreakReader : public QObject
{
    Q_OBJECT
public:
    explicit BreakReader(QSerialPort &port)
        : serialPort(port)
    {
        connect(&serialPort, &QSerialPort::readyRead, this, &BreakReader::receive);
    }

private slots:
    void receive()
    {
        tst_QSerialPort::exitLoop();
    }

private:
    QSerialPort &serialPort;
};

void tst_QSerialPort::controlBreak()
{
    QSerialPort senderPort(m_senderPortName);
    QVERIFY(senderPort.open(QSerialPort::WriteOnly));
    QCOMPARE(senderPort.isBreakEnabled(), false);

    QSignalSpy breakSpy(&senderPort, &QSerialPort::breakEnabledChanged);
    QVERIFY(breakSpy.isValid());

    QSerialPort receiverPort(m_receiverPortName);
    QVERIFY(receiverPort.open(QSerialPort::ReadOnly));

    BreakReader reader(receiverPort);

    QVERIFY(senderPort.setBreakEnabled(true));
    QCOMPARE(senderPort.isBreakEnabled(), true);

    enterLoop(1);
    QVERIFY2(!timeout(), "Timed out when waiting for the read of break state.");
    QVERIFY(receiverPort.bytesAvailable() > 0);

    const QByteArray actual = receiverPort.readAll();
    const QByteArray expected(actual.size(), '\0');
    QCOMPARE(actual, expected);

    QVERIFY(senderPort.setBreakEnabled(false));
    QCOMPARE(senderPort.isBreakEnabled(), false);

    QCOMPARE(breakSpy.count(), 2);
    QCOMPARE(qvariant_cast<bool>(breakSpy.at(0).at(0)), true);
    QCOMPARE(qvariant_cast<bool>(breakSpy.at(1).at(0)), false);
}

void tst_QSerialPort::clearAfterOpen()
{
    QSerialPort senderPort(m_senderPortName);
    QVERIFY(senderPort.open(QSerialPort::ReadWrite));
    QCOMPARE(senderPort.error(), QSerialPort::NoError);
    QVERIFY(senderPort.clear());
    QCOMPARE(senderPort.error(), QSerialPort::NoError);
}

void tst_QSerialPort::readWriteWithDifferentBaudRate_data()
{
    QTest::addColumn<int>("senderBaudRate");
    QTest::addColumn<int>("receiverBaudRate");
    QTest::addColumn<bool>("expectedResult");

    QTest::newRow("9600, 9600") << 9600 << 9600 << true;
    QTest::newRow("115200, 115200") << 115200 << 115200 << true;
    QTest::newRow("9600, 115200") << 9600 << 115200 << false;

    QTest::newRow("31250, 31250") << 31250 << 31250 << true; // custom baudrate (MIDI)
    QTest::newRow("31250, 115200") << 31250 << 115200 << false;

#ifdef Q_OS_LINUX
    QTest::newRow("14400, 14400") << 14400 << 14400 << true; // custom baudrate for Linux
    QTest::newRow("14400, 115200") << 14400 << 115200 << false;
#endif
}

void tst_QSerialPort::readWriteWithDifferentBaudRate()
{
    QFETCH(int, senderBaudRate);
    QFETCH(int, receiverBaudRate);
    QFETCH(bool, expectedResult);

    {
        // setup before opening
        QSerialPort senderSerialPort(m_senderPortName);
        QVERIFY(senderSerialPort.setBaudRate(senderBaudRate));
        QCOMPARE(senderSerialPort.baudRate(), senderBaudRate);
        QVERIFY(senderSerialPort.open(QSerialPort::ReadWrite));
        QSerialPort receiverSerialPort(m_receiverPortName);
        QVERIFY(receiverSerialPort.setBaudRate(receiverBaudRate));
        QCOMPARE(receiverSerialPort.baudRate(), receiverBaudRate);
        QVERIFY(receiverSerialPort.open(QSerialPort::ReadWrite));

        QCOMPARE(senderSerialPort.write(alphabetArray), qint64(alphabetArray.size()));
        QVERIFY(senderSerialPort.waitForBytesWritten(500));

        do {
            QVERIFY(receiverSerialPort.waitForReadyRead(500));
        } while (receiverSerialPort.bytesAvailable() < alphabetArray.size());

        if (expectedResult)
            QVERIFY(receiverSerialPort.readAll() == alphabetArray);
        else
            QVERIFY(receiverSerialPort.readAll() != alphabetArray);
    }

    {
        // setup after opening
        QSerialPort senderSerialPort(m_senderPortName);
        QVERIFY(senderSerialPort.open(QSerialPort::ReadWrite));
        QVERIFY(senderSerialPort.setBaudRate(senderBaudRate));
        QCOMPARE(senderSerialPort.baudRate(), senderBaudRate);
        QSerialPort receiverSerialPort(m_receiverPortName);
        QVERIFY(receiverSerialPort.open(QSerialPort::ReadWrite));
        QVERIFY(receiverSerialPort.setBaudRate(receiverBaudRate));
        QCOMPARE(receiverSerialPort.baudRate(), receiverBaudRate);

        QCOMPARE(senderSerialPort.write(alphabetArray), qint64(alphabetArray.size()));
        QVERIFY(senderSerialPort.waitForBytesWritten(500));

        do {
            QVERIFY(receiverSerialPort.waitForReadyRead(500));
        } while (receiverSerialPort.bytesAvailable() < alphabetArray.size());

        if (expectedResult)
            QVERIFY(receiverSerialPort.readAll() == alphabetArray);
        else
            QVERIFY(receiverSerialPort.readAll() != alphabetArray);
    }
}

QTEST_MAIN(tst_QSerialPort)
#include "tst_qserialport.moc"
