Revision control
++ // Copyright (C) 2016 Kurt Pattyn <pattyn.kurt@gmail.com>.
++ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
++ #include <QtTest/QtTest>
++ #include <QtTest/qtestcase.h>
++ #include <QtEndian>
++
++ #include <QDebug>
++
++ #include "QtWebSockets/qwebsocketprotocol.h"
++ #include "private/qwebsocketprotocol_p.h"
++
++ QT_USE_NAMESPACE
++
++ Q_DECLARE_METATYPE(QWebSocketProtocol::CloseCode)
++ Q_DECLARE_METATYPE(QWebSocketProtocol::OpCode)
++ Q_DECLARE_METATYPE(QWebSocketProtocol::Version)
++
++ class tst_WebSocketProtocol : public QObject
++ {
++ Q_OBJECT
++
++ public:
++ tst_WebSocketProtocol();
++
++ private Q_SLOTS:
++ void initTestCase();
++ void cleanupTestCase();
++ void init();
++ void cleanup();
++
++ void tst_validMasks_data();
++ void tst_validMasks();
++
++ void tst_opCodes_data();
++ void tst_opCodes();
++
++ void tst_closeCodes_data();
++ void tst_closeCodes();
++
++ void tst_versionFromString_data();
++ void tst_versionFromString();
++ };
++
++ tst_WebSocketProtocol::tst_WebSocketProtocol()
++ {}
++
++ void tst_WebSocketProtocol::initTestCase()
++ {
++ }
++
++ void tst_WebSocketProtocol::cleanupTestCase()
++ {}
++
++ void tst_WebSocketProtocol::init()
++ {
++ qRegisterMetaType<QWebSocketProtocol::OpCode>("QWebSocketProtocol::OpCode");
++ qRegisterMetaType<QWebSocketProtocol::CloseCode>("QWebSocketProtocol::CloseCode");
++ }
++
++ void tst_WebSocketProtocol::cleanup()
++ {
++ }
++
++ void tst_WebSocketProtocol::tst_validMasks_data()
++ {
++ QTest::addColumn<quint32>("mask");
++ QTest::addColumn<QString>("inputdata");
++ QTest::addColumn<QByteArray>("result");
++
++ QTest::newRow("Empty payload") << 0x12345678u << QString() << QByteArray();
++ QTest::newRow("ASCII payload of 8 characters")
++ << 0x12345678u
++ << QStringLiteral("abcdefgh")
++ << QByteArrayLiteral("\x73\x56\x35\x1C\x77\x52\x31\x10");
++ QTest::newRow("ASCII payload of 9 characters")
++ << 0x12345678u
++ << QStringLiteral("abcdefghi")
++ << QByteArrayLiteral("\x73\x56\x35\x1C\x77\x52\x31\x10\x7B");
++ //MSVC doesn't like UTF-8 in source code;
++ //the following text is represented in the string below: ∫∂ƒ©øØ
++ QTest::newRow("UTF-8 payload")
++ << 0x12345678u
++ << QString::fromUtf8("\xE2\x88\xAB\xE2\x88\x82\xC6\x92\xC2\xA9\xC3\xB8\xC3\x98")
++ << QByteArrayLiteral("\x2D\x0B\x69\xD1\xEA\xEC");
++ }
++
++ void tst_WebSocketProtocol::tst_validMasks()
++ {
++ QFETCH(quint32, mask);
++ QFETCH(QString, inputdata);
++ QFETCH(QByteArray, result);
++
++ //put latin1 into an explicit array
++ //otherwise, the intermediate object is deleted and the data pointer becomes invalid
++ QByteArray latin1 = inputdata.toLatin1();
++ char *data = latin1.data();
++
++ QWebSocketProtocol::mask(data, inputdata.size(), mask);
++ QCOMPARE(QByteArray::fromRawData(data, inputdata.size()), result);
++ }
++
++ void tst_WebSocketProtocol::tst_opCodes_data()
++ {
++ QTest::addColumn<QWebSocketProtocol::OpCode>("opCode");
++ QTest::addColumn<bool>("isReserved");
++
++ QTest::newRow("OpCodeBinary") << QWebSocketProtocol::OpCodeBinary << false;
++ QTest::newRow("OpCodeClose") << QWebSocketProtocol::OpCodeClose << false;
++ QTest::newRow("OpCodeContinue") << QWebSocketProtocol::OpCodeContinue << false;
++ QTest::newRow("OpCodePing") << QWebSocketProtocol::OpCodePing << false;
++ QTest::newRow("OpCodePong") << QWebSocketProtocol::OpCodePong << false;
++ QTest::newRow("OpCodeReserved3") << QWebSocketProtocol::OpCodeReserved3 << true;
++ QTest::newRow("OpCodeReserved4") << QWebSocketProtocol::OpCodeReserved4 << true;
++ QTest::newRow("OpCodeReserved5") << QWebSocketProtocol::OpCodeReserved5 << true;
++ QTest::newRow("OpCodeReserved6") << QWebSocketProtocol::OpCodeReserved6 << true;
++ QTest::newRow("OpCodeReserved7") << QWebSocketProtocol::OpCodeReserved7 << true;
++ QTest::newRow("OpCodeReserved8") << QWebSocketProtocol::OpCodeReservedB << true;
++ QTest::newRow("OpCodeReservedC") << QWebSocketProtocol::OpCodeReservedC << true;
++ QTest::newRow("OpCodeReservedD") << QWebSocketProtocol::OpCodeReservedD << true;
++ QTest::newRow("OpCodeReservedE") << QWebSocketProtocol::OpCodeReservedE << true;
++ QTest::newRow("OpCodeReservedF") << QWebSocketProtocol::OpCodeReservedF << true;
++ QTest::newRow("OpCodeText") << QWebSocketProtocol::OpCodeText << false;
++ }
++
++ void tst_WebSocketProtocol::tst_opCodes()
++ {
++ QFETCH(QWebSocketProtocol::OpCode, opCode);
++ QFETCH(bool, isReserved);
++
++ bool result = QWebSocketProtocol::isOpCodeReserved(opCode);
++
++ QCOMPARE(result, isReserved);
++ }
++
++ void tst_WebSocketProtocol::tst_closeCodes_data()
++ {
++ QTest::addColumn<int>("closeCode");
++ QTest::addColumn<bool>("isValid");
++
++ for (int i = 0; i < 1000; ++i)
++ {
++ QTest::newRow(QStringLiteral("Close code %1").arg(i).toLatin1().constData()) << i << false;
++ }
++
++ for (int i = 1000; i < 1004; ++i)
++ {
++ QTest::newRow(QStringLiteral("Close code %1").arg(i).toLatin1().constData()) << i << true;
++ }
++
++ QTest::newRow("Close code 1004") << 1004 << false;
++ QTest::newRow("Close code 1005") << 1005 << false;
++ QTest::newRow("Close code 1006") << 1006 << false;
++
++ for (int i = 1007; i < 1012; ++i)
++ {
++ QTest::newRow(QStringLiteral("Close code %1").arg(i).toLatin1().constData()) << i << true;
++ }
++
++ for (int i = 1013; i < 3000; ++i)
++ {
++ QTest::newRow(QStringLiteral("Close code %1").arg(i).toLatin1().constData()) << i << false;
++ }
++
++ for (int i = 3000; i < 5000; ++i)
++ {
++ QTest::newRow(QStringLiteral("Close code %1").arg(i).toLatin1().constData()) << i << true;
++ }
++
++ QTest::newRow("Close code 5000") << 1004 << false;
++ QTest::newRow("Close code 6000") << 1004 << false;
++ QTest::newRow("Close code 7000") << 1004 << false;
++ }
++
++ void tst_WebSocketProtocol::tst_closeCodes()
++ {
++ QFETCH(int, closeCode);
++ QFETCH(bool, isValid);
++
++ bool result = QWebSocketProtocol::isCloseCodeValid(closeCode);
++
++ QCOMPARE(result, isValid);
++ }
++
++ void tst_WebSocketProtocol::tst_versionFromString_data()
++ {
++ QTest::addColumn<QWebSocketProtocol::Version>("version");
++ QTest::addColumn<QString>("versionString");
++
++ //happy flow; good data
++ QTest::newRow("Version 0")
++ << QWebSocketProtocol::Version0
++ << QStringLiteral("0");
++ QTest::newRow("Version 4")
++ << QWebSocketProtocol::Version4
++ << QStringLiteral("4");
++ QTest::newRow("Version 5")
++ << QWebSocketProtocol::Version5
++ << QStringLiteral("5");
++ QTest::newRow("Version 6")
++ << QWebSocketProtocol::Version6
++ << QStringLiteral("6");
++ QTest::newRow("Version 7")
++ << QWebSocketProtocol::Version7
++ << QStringLiteral("7");
++ QTest::newRow("Version 8")
++ << QWebSocketProtocol::Version8
++ << QStringLiteral("8");
++ QTest::newRow("Version 13")
++ << QWebSocketProtocol::Version13
++ << QStringLiteral("13");
++
++ //rainy flow; invalid data
++ QTest::newRow("Version -1")
++ << QWebSocketProtocol::VersionUnknown
++ << QStringLiteral("-1");
++ QTest::newRow("Version 1")
++ << QWebSocketProtocol::VersionUnknown
++ << QStringLiteral("1");
++ QTest::newRow("Version 2")
++ << QWebSocketProtocol::VersionUnknown
++ << QStringLiteral("2");
++ QTest::newRow("Version 3")
++ << QWebSocketProtocol::VersionUnknown
++ << QStringLiteral("3");
++ QTest::newRow("Version 9")
++ << QWebSocketProtocol::VersionUnknown
++ << QStringLiteral("9");
++ QTest::newRow("Version 10")
++ << QWebSocketProtocol::VersionUnknown
++ << QStringLiteral("10");
++ QTest::newRow("Version 11")
++ << QWebSocketProtocol::VersionUnknown
++ << QStringLiteral("11");
++ QTest::newRow("Version 12")
++ << QWebSocketProtocol::VersionUnknown
++ << QStringLiteral("12");
++ QTest::newRow("Version abcd")
++ << QWebSocketProtocol::VersionUnknown
++ << QStringLiteral("abcd");
++ QTest::newRow("Version 1.6")
++ << QWebSocketProtocol::VersionUnknown
++ << QStringLiteral("1.6");
++ QTest::newRow("Version empty")
++ << QWebSocketProtocol::VersionUnknown
++ << QString();
++ }
++
++ void tst_WebSocketProtocol::tst_versionFromString()
++ {
++ QFETCH(QWebSocketProtocol::Version, version);
++ QFETCH(QString, versionString);
++
++ QCOMPARE(QWebSocketProtocol::versionFromString(versionString), version);
++ }
++
++ QTEST_MAIN(tst_WebSocketProtocol)
++
++ #include "tst_websocketprotocol.moc"
++