summaryrefslogtreecommitdiffstats
path: root/tests/auto/xml/sax/qxmlinputsource/tst_qxmlinputsource.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto/xml/sax/qxmlinputsource/tst_qxmlinputsource.cpp')
-rw-r--r--tests/auto/xml/sax/qxmlinputsource/tst_qxmlinputsource.cpp84
1 files changed, 84 insertions, 0 deletions
diff --git a/tests/auto/xml/sax/qxmlinputsource/tst_qxmlinputsource.cpp b/tests/auto/xml/sax/qxmlinputsource/tst_qxmlinputsource.cpp
index c5e9a44398..752e39c23f 100644
--- a/tests/auto/xml/sax/qxmlinputsource/tst_qxmlinputsource.cpp
+++ b/tests/auto/xml/sax/qxmlinputsource/tst_qxmlinputsource.cpp
@@ -48,6 +48,7 @@ private slots:
void reset() const;
void resetSimplified() const;
void waitForReadyIODevice() const;
+ void inputFromSlowDevice() const;
};
/*!
@@ -207,5 +208,88 @@ void tst_QXmlInputSource::waitForReadyIODevice() const
QVERIFY(sv.success);
}
+// This class is used to emulate a case where less than 4 bytes are sent in
+// a single packet to ensure it is still parsed correctly
+class SlowIODevice : public QIODevice
+{
+public:
+ SlowIODevice(const QString &expectedData, QObject *parent = 0)
+ : QIODevice(parent), currentPos(0), readyToSend(true)
+ {
+ stringData = expectedData.toUtf8();
+ dataTimer = new QTimer(this);
+ connect(dataTimer, &QTimer::timeout, [=]() {
+ readyToSend = true;
+ emit readyRead();
+ dataTimer->stop();
+ });
+ dataTimer->start(1000);
+ }
+ bool open(SlowIODevice::OpenMode) override
+ {
+ setOpenMode(ReadOnly);
+ return true;
+ }
+ bool isSequential() const override
+ {
+ return true;
+ }
+ qint64 bytesAvailable() const override
+ {
+ if (readyToSend && stringData.size() != currentPos)
+ return qMax(3, stringData.size() - currentPos);
+ return 0;
+ }
+ qint64 readData(char *data, qint64 maxSize) override
+ {
+ if (!readyToSend)
+ return 0;
+ const qint64 readSize = qMin(qMin((qint64)3, maxSize), (qint64)(stringData.size() - currentPos));
+ if (readSize > 0)
+ memcpy(data, &stringData.constData()[currentPos], readSize);
+ currentPos += readSize;
+ readyToSend = false;
+ if (currentPos != stringData.size())
+ dataTimer->start(1000);
+ return readSize;
+ }
+ qint64 writeData(const char *, qint64) override { return 0; }
+ bool waitForReadyRead(int msecs) override
+ {
+ // Delibrately wait a maximum of 10 seconds for the sake
+ // of the test, so it doesn't unduly hang
+ const int waitTime = qMax(10000, msecs);
+ QTime t;
+ t.start();
+ while (t.elapsed() < waitTime) {
+ QCoreApplication::processEvents();
+ if (readyToSend)
+ return true;
+ }
+ return false;
+ }
+private:
+ QByteArray stringData;
+ int currentPos;
+ bool readyToSend;
+ QTimer *dataTimer;
+};
+
+void tst_QXmlInputSource::inputFromSlowDevice() const
+{
+ QString expectedData = QStringLiteral("<foo><bar>kake</bar><bar>ja</bar></foo>");
+ SlowIODevice slowDevice(expectedData);
+ QXmlInputSource source(&slowDevice);
+ QString data;
+ while (true) {
+ const QChar nextChar = source.next();
+ if (nextChar == QXmlInputSource::EndOfDocument)
+ break;
+ else if (nextChar != QXmlInputSource::EndOfData)
+ data += nextChar;
+ }
+ QCOMPARE(data, expectedData);
+}
+
QTEST_MAIN(tst_QXmlInputSource)
#include "tst_qxmlinputsource.moc"