1 /****************************************************************************
3 ** Copyright (C) 2014 Kurt Pattyn <pattyn.kurt@gmail.com>.
4 ** Contact: http://www.qt-project.org/legal
6 ** This file is part of the test suite of the Qt Toolkit.
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
40 ****************************************************************************/
41 #include <QtTest/QtTest>
42 #include <QtTest/qtestcase.h>
47 #include "QtWebSockets/qwebsocketprotocol.h"
48 #include "private/qwebsocketprotocol_p.h"
52 Q_DECLARE_METATYPE(QWebSocketProtocol::CloseCode)
53 Q_DECLARE_METATYPE(QWebSocketProtocol::OpCode)
54 Q_DECLARE_METATYPE(QWebSocketProtocol::Version)
56 class tst_WebSocketProtocol : public QObject
61 tst_WebSocketProtocol();
65 void cleanupTestCase();
69 void tst_validMasks_data();
70 void tst_validMasks();
72 void tst_opCodes_data();
75 void tst_closeCodes_data();
76 void tst_closeCodes();
78 void tst_versionFromString_data();
79 void tst_versionFromString();
82 tst_WebSocketProtocol::tst_WebSocketProtocol()
85 void tst_WebSocketProtocol::initTestCase()
89 void tst_WebSocketProtocol::cleanupTestCase()
92 void tst_WebSocketProtocol::init()
94 qRegisterMetaType<QWebSocketProtocol::OpCode>("QWebSocketProtocol::OpCode");
95 qRegisterMetaType<QWebSocketProtocol::CloseCode>("QWebSocketProtocol::CloseCode");
98 void tst_WebSocketProtocol::cleanup()
102 void tst_WebSocketProtocol::tst_validMasks_data()
104 QTest::addColumn<quint32>("mask");
105 QTest::addColumn<QString>("inputdata");
106 QTest::addColumn<QByteArray>("result");
108 QTest::newRow("Empty payload") << 0x12345678u << QString() << QByteArray();
109 QTest::newRow("ASCII payload of 8 characters")
111 << QStringLiteral("abcdefgh")
112 << QByteArrayLiteral("\x73\x56\x35\x1C\x77\x52\x31\x10");
113 QTest::newRow("ASCII payload of 9 characters")
115 << QStringLiteral("abcdefghi")
116 << QByteArrayLiteral("\x73\x56\x35\x1C\x77\x52\x31\x10\x7B");
117 //MSVC doesn't like UTF-8 in source code;
118 //the following text is represented in the string below: ∫∂ƒ©øØ
119 QTest::newRow("UTF-8 payload")
121 << QString::fromUtf8("\xE2\x88\xAB\xE2\x88\x82\xC6\x92\xC2\xA9\xC3\xB8\xC3\x98")
122 << QByteArrayLiteral("\x2D\x0B\x69\xD1\xEA\xEC");
125 void tst_WebSocketProtocol::tst_validMasks()
127 QFETCH(quint32, mask);
128 QFETCH(QString, inputdata);
129 QFETCH(QByteArray, result);
131 //put latin1 into an explicit array
132 //otherwise, the intermediate object is deleted and the data pointer becomes invalid
133 QByteArray latin1 = inputdata.toLatin1();
134 char *data = latin1.data();
136 QWebSocketProtocol::mask(data, inputdata.size(), mask);
137 QCOMPARE(QByteArray::fromRawData(data, inputdata.size()), result);
140 void tst_WebSocketProtocol::tst_opCodes_data()
142 QTest::addColumn<QWebSocketProtocol::OpCode>("opCode");
143 QTest::addColumn<bool>("isReserved");
145 QTest::newRow("OpCodeBinary") << QWebSocketProtocol::OpCodeBinary << false;
146 QTest::newRow("OpCodeClose") << QWebSocketProtocol::OpCodeClose << false;
147 QTest::newRow("OpCodeContinue") << QWebSocketProtocol::OpCodeContinue << false;
148 QTest::newRow("OpCodePing") << QWebSocketProtocol::OpCodePing << false;
149 QTest::newRow("OpCodePong") << QWebSocketProtocol::OpCodePong << false;
150 QTest::newRow("OpCodeReserved3") << QWebSocketProtocol::OpCodeReserved3 << true;
151 QTest::newRow("OpCodeReserved4") << QWebSocketProtocol::OpCodeReserved4 << true;
152 QTest::newRow("OpCodeReserved5") << QWebSocketProtocol::OpCodeReserved5 << true;
153 QTest::newRow("OpCodeReserved6") << QWebSocketProtocol::OpCodeReserved6 << true;
154 QTest::newRow("OpCodeReserved7") << QWebSocketProtocol::OpCodeReserved7 << true;
155 QTest::newRow("OpCodeReserved8") << QWebSocketProtocol::OpCodeReservedB << true;
156 QTest::newRow("OpCodeReservedC") << QWebSocketProtocol::OpCodeReservedC << true;
157 QTest::newRow("OpCodeReservedD") << QWebSocketProtocol::OpCodeReservedD << true;
158 QTest::newRow("OpCodeReservedE") << QWebSocketProtocol::OpCodeReservedE << true;
159 QTest::newRow("OpCodeReservedF") << QWebSocketProtocol::OpCodeReservedF << true;
160 QTest::newRow("OpCodeText") << QWebSocketProtocol::OpCodeText << false;
163 void tst_WebSocketProtocol::tst_opCodes()
165 QFETCH(QWebSocketProtocol::OpCode, opCode);
166 QFETCH(bool, isReserved);
168 bool result = QWebSocketProtocol::isOpCodeReserved(opCode);
170 QCOMPARE(result, isReserved);
173 void tst_WebSocketProtocol::tst_closeCodes_data()
175 QTest::addColumn<int>("closeCode");
176 QTest::addColumn<bool>("isValid");
178 for (int i = 0; i < 1000; ++i)
180 QTest::newRow(QStringLiteral("Close code %1").arg(i).toLatin1().constData()) << i << false;
183 for (int i = 1000; i < 1004; ++i)
185 QTest::newRow(QStringLiteral("Close code %1").arg(i).toLatin1().constData()) << i << true;
188 QTest::newRow("Close code 1004") << 1004 << false;
189 QTest::newRow("Close code 1005") << 1005 << false;
190 QTest::newRow("Close code 1006") << 1006 << false;
192 for (int i = 1007; i < 1012; ++i)
194 QTest::newRow(QStringLiteral("Close code %1").arg(i).toLatin1().constData()) << i << true;
197 for (int i = 1013; i < 3000; ++i)
199 QTest::newRow(QStringLiteral("Close code %1").arg(i).toLatin1().constData()) << i << false;
202 for (int i = 3000; i < 5000; ++i)
204 QTest::newRow(QStringLiteral("Close code %1").arg(i).toLatin1().constData()) << i << true;
207 QTest::newRow("Close code 5000") << 1004 << false;
208 QTest::newRow("Close code 6000") << 1004 << false;
209 QTest::newRow("Close code 7000") << 1004 << false;
212 void tst_WebSocketProtocol::tst_closeCodes()
214 QFETCH(int, closeCode);
215 QFETCH(bool, isValid);
217 bool result = QWebSocketProtocol::isCloseCodeValid(closeCode);
219 QCOMPARE(result, isValid);
222 void tst_WebSocketProtocol::tst_versionFromString_data()
224 QTest::addColumn<QWebSocketProtocol::Version>("version");
225 QTest::addColumn<QString>("versionString");
227 //happy flow; good data
228 QTest::newRow("Version 0")
229 << QWebSocketProtocol::Version0
230 << QStringLiteral("0");
231 QTest::newRow("Version 4")
232 << QWebSocketProtocol::Version4
233 << QStringLiteral("4");
234 QTest::newRow("Version 5")
235 << QWebSocketProtocol::Version5
236 << QStringLiteral("5");
237 QTest::newRow("Version 6")
238 << QWebSocketProtocol::Version6
239 << QStringLiteral("6");
240 QTest::newRow("Version 7")
241 << QWebSocketProtocol::Version7
242 << QStringLiteral("7");
243 QTest::newRow("Version 8")
244 << QWebSocketProtocol::Version8
245 << QStringLiteral("8");
246 QTest::newRow("Version 13")
247 << QWebSocketProtocol::Version13
248 << QStringLiteral("13");
250 //rainy flow; invalid data
251 QTest::newRow("Version -1")
252 << QWebSocketProtocol::VersionUnknown
253 << QStringLiteral("-1");
254 QTest::newRow("Version 1")
255 << QWebSocketProtocol::VersionUnknown
256 << QStringLiteral("1");
257 QTest::newRow("Version 2")
258 << QWebSocketProtocol::VersionUnknown
259 << QStringLiteral("2");
260 QTest::newRow("Version 3")
261 << QWebSocketProtocol::VersionUnknown
262 << QStringLiteral("3");
263 QTest::newRow("Version 9")
264 << QWebSocketProtocol::VersionUnknown
265 << QStringLiteral("9");
266 QTest::newRow("Version 10")
267 << QWebSocketProtocol::VersionUnknown
268 << QStringLiteral("10");
269 QTest::newRow("Version 11")
270 << QWebSocketProtocol::VersionUnknown
271 << QStringLiteral("11");
272 QTest::newRow("Version 12")
273 << QWebSocketProtocol::VersionUnknown
274 << QStringLiteral("12");
275 QTest::newRow("Version abcd")
276 << QWebSocketProtocol::VersionUnknown
277 << QStringLiteral("abcd");
278 QTest::newRow("Version 1.6")
279 << QWebSocketProtocol::VersionUnknown
280 << QStringLiteral("1.6");
281 QTest::newRow("Version empty")
282 << QWebSocketProtocol::VersionUnknown
286 void tst_WebSocketProtocol::tst_versionFromString()
288 QFETCH(QWebSocketProtocol::Version, version);
289 QFETCH(QString, versionString);
291 QCOMPARE(QWebSocketProtocol::versionFromString(versionString), version);
294 QTEST_MAIN(tst_WebSocketProtocol)
296 #include "tst_websocketprotocol.moc"