1 | /**************************************************************************** |
2 | ** |
3 | ** Copyright (C) 2016 The Qt Company Ltd. |
4 | ** Contact: https://www.qt.io/licensing/ |
5 | ** |
6 | ** This file is part of the test suite of the Qt Toolkit. |
7 | ** |
8 | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$ |
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 The Qt Company. For licensing terms |
14 | ** and conditions see https://www.qt.io/terms-conditions. For further |
15 | ** information use the contact form at https://www.qt.io/contact-us. |
16 | ** |
17 | ** GNU General Public License Usage |
18 | ** Alternatively, this file may be used under the terms of the GNU |
19 | ** General Public License version 3 as published by the Free Software |
20 | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT |
21 | ** included in the packaging of this file. Please review the following |
22 | ** information to ensure the GNU General Public License requirements will |
23 | ** be met: https://www.gnu.org/licenses/gpl-3.0.html. |
24 | ** |
25 | ** $QT_END_LICENSE$ |
26 | ** |
27 | ****************************************************************************/ |
28 | |
29 | #include <QtCore/QTemporaryDir> |
30 | #include <QtTest/QtTest> |
31 | #include <QtGui/qevent.h> |
32 | |
33 | class tst_qfileopenevent : public QObject |
34 | { |
35 | Q_OBJECT |
36 | public: |
37 | tst_qfileopenevent(){} |
38 | ~tst_qfileopenevent(); |
39 | |
40 | public slots: |
41 | void initTestCase(); |
42 | void cleanupTestCase(); |
43 | |
44 | private slots: |
45 | void constructor(); |
46 | void fileOpen(); |
47 | void handleLifetime(); |
48 | void multiOpen(); |
49 | void sendAndReceive(); |
50 | |
51 | private: |
52 | void createFile(const QString &filename, const QByteArray &content); |
53 | QFileOpenEvent * createFileAndEvent(const QString &filename, const QByteArray &content); |
54 | void checkReadAndWrite(QFileOpenEvent& event, const QByteArray& readContent, const QByteArray& writeContent, bool writeOk); |
55 | QByteArray readFileContent(QFileOpenEvent& event); |
56 | bool appendFileContent(QFileOpenEvent& event, const QByteArray& writeContent); |
57 | |
58 | bool event(QEvent *); |
59 | |
60 | QTemporaryDir m_temporaryDir; |
61 | QString m_originalCurrent; |
62 | }; |
63 | |
64 | tst_qfileopenevent::~tst_qfileopenevent() |
65 | { |
66 | }; |
67 | |
68 | void tst_qfileopenevent::initTestCase() |
69 | { |
70 | m_originalCurrent = QDir::currentPath(); |
71 | QDir::setCurrent(m_temporaryDir.path()); |
72 | } |
73 | |
74 | void tst_qfileopenevent::cleanupTestCase() |
75 | { |
76 | QDir::setCurrent(m_originalCurrent); |
77 | } |
78 | |
79 | void tst_qfileopenevent::createFile(const QString &filename, const QByteArray &content) |
80 | { |
81 | QFile file(filename); |
82 | file.open(flags: QFile::WriteOnly); |
83 | file.write(data: content); |
84 | file.close(); |
85 | } |
86 | |
87 | QFileOpenEvent * tst_qfileopenevent::createFileAndEvent(const QString &filename, const QByteArray &content) |
88 | { |
89 | createFile(filename, content); |
90 | return new QFileOpenEvent(filename); |
91 | } |
92 | |
93 | void tst_qfileopenevent::constructor() |
94 | { |
95 | // check that filename get/set works |
96 | QFileOpenEvent nameTest(QLatin1String("fileNameTest" )); |
97 | QCOMPARE(nameTest.file(), QLatin1String("fileNameTest" )); |
98 | |
99 | // check that url get/set works |
100 | QFileOpenEvent urlTest(QUrl(QLatin1String("file:///urlNameTest" ))); |
101 | QCOMPARE(urlTest.url().toString(), QLatin1String("file:///urlNameTest" )); |
102 | } |
103 | |
104 | QByteArray tst_qfileopenevent::readFileContent(QFileOpenEvent& event) |
105 | { |
106 | QFile file; |
107 | event.openFile(file, flags: QFile::ReadOnly); |
108 | file.seek(offset: 0); |
109 | QByteArray data = file.readAll(); |
110 | return data; |
111 | } |
112 | |
113 | bool tst_qfileopenevent::appendFileContent(QFileOpenEvent& event, const QByteArray& writeContent) |
114 | { |
115 | QFile file; |
116 | bool ok = event.openFile(file, flags: QFile::Append | QFile::Unbuffered); |
117 | if (ok) |
118 | ok = file.write(data: writeContent) == writeContent.size(); |
119 | return ok; |
120 | } |
121 | |
122 | void tst_qfileopenevent::checkReadAndWrite(QFileOpenEvent& event, const QByteArray& readContent, const QByteArray& writeContent, bool writeOk) |
123 | { |
124 | QCOMPARE(readFileContent(event), readContent); |
125 | QCOMPARE(appendFileContent(event, writeContent), writeOk); |
126 | QCOMPARE(readFileContent(event), writeOk ? readContent+writeContent : readContent); |
127 | } |
128 | |
129 | void tst_qfileopenevent::fileOpen() |
130 | { |
131 | createFile(filename: QLatin1String("testFileOpen" ), content: QByteArray("test content+RFileWrite" )); |
132 | |
133 | // filename event |
134 | QUrl fileUrl; // need to get the URL during the file test, for use in the URL test |
135 | { |
136 | QFileOpenEvent nameTest(QLatin1String("testFileOpen" )); |
137 | fileUrl = nameTest.url(); |
138 | checkReadAndWrite(event&: nameTest, readContent: QByteArray("test content+RFileWrite" ), writeContent: QByteArray("+nameWrite" ), writeOk: true); |
139 | } |
140 | |
141 | // url event |
142 | { |
143 | QFileOpenEvent urlTest(fileUrl); |
144 | checkReadAndWrite(event&: urlTest, readContent: QByteArray("test content+RFileWrite+nameWrite" ), writeContent: QByteArray("+urlWrite" ), writeOk: true); |
145 | } |
146 | |
147 | QFile::remove(fileName: QLatin1String("testFileOpen" )); |
148 | } |
149 | |
150 | void tst_qfileopenevent::handleLifetime() |
151 | { |
152 | QScopedPointer<QFileOpenEvent> event(createFileAndEvent(filename: QLatin1String("testHandleLifetime" ), content: QByteArray("test content" ))); |
153 | |
154 | // open a QFile after the original RFile is closed |
155 | QFile qFile; |
156 | QCOMPARE(event->openFile(qFile, QFile::Append | QFile::Unbuffered), true); |
157 | event.reset(other: 0); |
158 | |
159 | // write to the QFile after the event is closed |
160 | QString writeContent(QLatin1String("+closed original handles" )); |
161 | QCOMPARE(int(qFile.write(writeContent.toUtf8())), writeContent.size()); |
162 | qFile.close(); |
163 | |
164 | // check the content |
165 | QFile checkContent("testHandleLifetime" ); |
166 | checkContent.open(flags: QFile::ReadOnly); |
167 | QString content(checkContent.readAll()); |
168 | QCOMPARE(content, QLatin1String("test content+closed original handles" )); |
169 | checkContent.close(); |
170 | |
171 | QFile::remove(fileName: QLatin1String("testHandleLifetime" )); |
172 | } |
173 | |
174 | void tst_qfileopenevent::multiOpen() |
175 | { |
176 | QScopedPointer<QFileOpenEvent> event(createFileAndEvent(filename: QLatin1String("testMultiOpen" ), content: QByteArray("itlum" ))); |
177 | |
178 | QFile files[5]; |
179 | for (int i=0; i<5; i++) { |
180 | QCOMPARE(event->openFile(files[i], QFile::ReadOnly), true); |
181 | } |
182 | for (int i=0; i<5; i++) |
183 | files[i].seek(offset: i); |
184 | QString str; |
185 | for (int i=4; i>=0; i--) { |
186 | char c; |
187 | files[i].getChar(c: &c); |
188 | str.append(c); |
189 | files[i].close(); |
190 | } |
191 | QCOMPARE(str, QLatin1String("multi" )); |
192 | |
193 | QFile::remove(fileName: QLatin1String("testMultiOpen" )); |
194 | } |
195 | |
196 | bool tst_qfileopenevent::event(QEvent *event) |
197 | { |
198 | if (event->type() != QEvent::FileOpen) |
199 | return QObject::event(event); |
200 | QFileOpenEvent* fileOpenEvent = static_cast<QFileOpenEvent *>(event); |
201 | appendFileContent(event&: *fileOpenEvent, writeContent: "+received" ); |
202 | return true; |
203 | } |
204 | |
205 | void tst_qfileopenevent::sendAndReceive() |
206 | { |
207 | QScopedPointer<QFileOpenEvent> event(createFileAndEvent(filename: QLatin1String("testSendAndReceive" ), content: QByteArray("sending" ))); |
208 | |
209 | QCoreApplication::instance()->postEvent(receiver: this, event: event.take()); |
210 | QCoreApplication::instance()->processEvents(); |
211 | |
212 | // QTBUG-17468: On Mac, processEvents doesn't always process posted events |
213 | QCoreApplication::instance()->sendPostedEvents(); |
214 | |
215 | // check the content |
216 | QFile checkContent("testSendAndReceive" ); |
217 | QCOMPARE(checkContent.open(QFile::ReadOnly), true); |
218 | QString content(checkContent.readAll()); |
219 | QCOMPARE(content, QLatin1String("sending+received" )); |
220 | checkContent.close(); |
221 | |
222 | QFile::remove(fileName: QLatin1String("testSendAndReceive" )); |
223 | } |
224 | |
225 | QTEST_MAIN(tst_qfileopenevent) |
226 | #include "tst_qfileopenevent.moc" |
227 | |