1 /****************************************************************************
3 ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
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)
55 class tst_WebSocketProtocol : public QObject
60 tst_WebSocketProtocol();
64 void cleanupTestCase();
68 void tst_validMasks_data();
69 void tst_validMasks();
71 void tst_opCodes_data();
74 void tst_closeCodes_data();
75 void tst_closeCodes();
77 void tst_versionFromString_data();
78 void tst_versionFromString();
81 tst_WebSocketProtocol::tst_WebSocketProtocol()
84 void tst_WebSocketProtocol::initTestCase()
88 void tst_WebSocketProtocol::cleanupTestCase()
91 void tst_WebSocketProtocol::init()
93 qRegisterMetaType<QWebSocketProtocol::OpCode>("QWebSocketProtocol::OpCode");
94 qRegisterMetaType<QWebSocketProtocol::CloseCode>("QWebSocketProtocol::CloseCode");
97 void tst_WebSocketProtocol::cleanup()
101 void tst_WebSocketProtocol::tst_validMasks_data()
103 QTest::addColumn<quint32>("mask");
104 QTest::addColumn<QString>("inputdata");
105 QTest::addColumn<QByteArray>("result");
107 QTest::newRow("Empty payload") << 0x12345678u << QString() << QByteArray();
108 QTest::newRow("ASCII payload of 8 characters")
110 << QStringLiteral("abcdefgh")
111 << QByteArrayLiteral("\x73\x56\x35\x1C\x77\x52\x31\x10");
112 QTest::newRow("ASCII payload of 9 characters")
114 << QStringLiteral("abcdefghi")
115 << QByteArrayLiteral("\x73\x56\x35\x1C\x77\x52\x31\x10\x7B");
116 //MSVC doesn't like UTF-8 in source code;
117 //the following text is represented in the string below: ∫∂ƒ©øØ
118 QTest::newRow("UTF-8 payload")
120 << QString::fromUtf8("\xE2\x88\xAB\xE2\x88\x82\xC6\x92\xC2\xA9\xC3\xB8\xC3\x98")
121 << QByteArrayLiteral("\x2D\x0B\x69\xD1\xEA\xEC");
124 void tst_WebSocketProtocol::tst_validMasks()
126 QFETCH(quint32, mask);
127 QFETCH(QString, inputdata);
128 QFETCH(QByteArray, result);
130 //put latin1 into an explicit array
131 //otherwise, the intermediate object is deleted and the data pointer becomes invalid
132 QByteArray latin1 = inputdata.toLatin1();
133 char *data = latin1.data();
135 QWebSocketProtocol::mask(data, inputdata.size(), mask);
136 QCOMPARE(QByteArray::fromRawData(data, inputdata.size()), result);
139 void tst_WebSocketProtocol::tst_opCodes_data()
141 QTest::addColumn<QWebSocketProtocol::OpCode>("opCode");
142 QTest::addColumn<bool>("isReserved");
144 QTest::newRow("OpCodeBinary") << QWebSocketProtocol::OpCodeBinary << false;
145 QTest::newRow("OpCodeClose") << QWebSocketProtocol::OpCodeClose << false;
146 QTest::newRow("OpCodeContinue") << QWebSocketProtocol::OpCodeContinue << false;
147 QTest::newRow("OpCodePing") << QWebSocketProtocol::OpCodePing << false;
148 QTest::newRow("OpCodePong") << QWebSocketProtocol::OpCodePong << false;
149 QTest::newRow("OpCodeReserved3") << QWebSocketProtocol::OpCodeReserved3 << true;
150 QTest::newRow("OpCodeReserved4") << QWebSocketProtocol::OpCodeReserved4 << true;
151 QTest::newRow("OpCodeReserved5") << QWebSocketProtocol::OpCodeReserved5 << true;
152 QTest::newRow("OpCodeReserved6") << QWebSocketProtocol::OpCodeReserved6 << true;
153 QTest::newRow("OpCodeReserved7") << QWebSocketProtocol::OpCodeReserved7 << true;
154 QTest::newRow("OpCodeReserved8") << QWebSocketProtocol::OpCodeReservedB << true;
155 QTest::newRow("OpCodeReservedC") << QWebSocketProtocol::OpCodeReservedC << true;
156 QTest::newRow("OpCodeReservedD") << QWebSocketProtocol::OpCodeReservedD << true;
157 QTest::newRow("OpCodeReservedE") << QWebSocketProtocol::OpCodeReservedE << true;
158 QTest::newRow("OpCodeReservedF") << QWebSocketProtocol::OpCodeReservedF << true;
159 QTest::newRow("OpCodeText") << QWebSocketProtocol::OpCodeText << false;
162 void tst_WebSocketProtocol::tst_opCodes()
164 QFETCH(QWebSocketProtocol::OpCode, opCode);
165 QFETCH(bool, isReserved);
167 bool result = QWebSocketProtocol::isOpCodeReserved(opCode);
169 QCOMPARE(result, isReserved);
172 void tst_WebSocketProtocol::tst_closeCodes_data()
174 QTest::addColumn<int>("closeCode");
175 QTest::addColumn<bool>("isValid");
177 for (int i = 0; i < 1000; ++i)
179 QTest::newRow(QStringLiteral("Close code %1").arg(i).toLatin1().constData()) << i << false;
182 for (int i = 1000; i < 1004; ++i)
184 QTest::newRow(QStringLiteral("Close code %1").arg(i).toLatin1().constData()) << i << true;
187 QTest::newRow("Close code 1004") << 1004 << false;
188 QTest::newRow("Close code 1005") << 1005 << false;
189 QTest::newRow("Close code 1006") << 1006 << false;
191 for (int i = 1007; i < 1012; ++i)
193 QTest::newRow(QStringLiteral("Close code %1").arg(i).toLatin1().constData()) << i << true;
196 for (int i = 1013; i < 3000; ++i)
198 QTest::newRow(QStringLiteral("Close code %1").arg(i).toLatin1().constData()) << i << false;
201 for (int i = 3000; i < 5000; ++i)
203 QTest::newRow(QStringLiteral("Close code %1").arg(i).toLatin1().constData()) << i << true;
206 QTest::newRow("Close code 5000") << 1004 << false;
207 QTest::newRow("Close code 6000") << 1004 << false;
208 QTest::newRow("Close code 7000") << 1004 << false;
211 void tst_WebSocketProtocol::tst_closeCodes()
213 QFETCH(int, closeCode);
214 QFETCH(bool, isValid);
216 bool result = QWebSocketProtocol::isCloseCodeValid(closeCode);
218 QCOMPARE(result, isValid);
221 void tst_WebSocketProtocol::tst_versionFromString_data()
223 QTest::addColumn<QWebSocketProtocol::Version>("version");
224 QTest::addColumn<QString>("versionString");
226 //happy flow; good data
227 QTest::newRow("Version 0")
228 << QWebSocketProtocol::Version0
229 << QStringLiteral("0");
230 QTest::newRow("Version 4")
231 << QWebSocketProtocol::Version4
232 << QStringLiteral("4");
233 QTest::newRow("Version 5")
234 << QWebSocketProtocol::Version5
235 << QStringLiteral("5");
236 QTest::newRow("Version 6")
237 << QWebSocketProtocol::Version6
238 << QStringLiteral("6");
239 QTest::newRow("Version 7")
240 << QWebSocketProtocol::Version7
241 << QStringLiteral("7");
242 QTest::newRow("Version 8")
243 << QWebSocketProtocol::Version8
244 << QStringLiteral("8");
245 QTest::newRow("Version 13")
246 << QWebSocketProtocol::Version13
247 << QStringLiteral("13");
249 //rainy flow; invalid data
250 QTest::newRow("Version -1")
251 << QWebSocketProtocol::VersionUnknown
252 << QStringLiteral("-1");
253 QTest::newRow("Version 1")
254 << QWebSocketProtocol::VersionUnknown
255 << QStringLiteral("1");
256 QTest::newRow("Version 2")
257 << QWebSocketProtocol::VersionUnknown
258 << QStringLiteral("2");
259 QTest::newRow("Version 3")
260 << QWebSocketProtocol::VersionUnknown
261 << QStringLiteral("3");
262 QTest::newRow("Version 9")
263 << QWebSocketProtocol::VersionUnknown
264 << QStringLiteral("9");
265 QTest::newRow("Version 10")
266 << QWebSocketProtocol::VersionUnknown
267 << QStringLiteral("10");
268 QTest::newRow("Version 11")
269 << QWebSocketProtocol::VersionUnknown
270 << QStringLiteral("11");
271 QTest::newRow("Version 12")
272 << QWebSocketProtocol::VersionUnknown
273 << QStringLiteral("12");
274 QTest::newRow("Version abcd")
275 << QWebSocketProtocol::VersionUnknown
276 << QStringLiteral("abcd");
277 QTest::newRow("Version 1.6")
278 << QWebSocketProtocol::VersionUnknown
279 << QStringLiteral("1.6");
280 QTest::newRow("Version empty")
281 << QWebSocketProtocol::VersionUnknown
285 void tst_WebSocketProtocol::tst_versionFromString()
287 QFETCH(QWebSocketProtocol::Version, version);
288 QFETCH(QString, versionString);
290 QCOMPARE(QWebSocketProtocol::versionFromString(versionString), version);
293 QTEST_MAIN(tst_WebSocketProtocol)
295 #include "tst_websocketprotocol.moc"