|
1 /**************************************************************************** |
|
2 ** |
|
3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
4 ** All rights reserved. |
|
5 ** Contact: Nokia Corporation (qt-info@nokia.com) |
|
6 ** |
|
7 ** This file is part of the test suite of the Qt Toolkit. |
|
8 ** |
|
9 ** $QT_BEGIN_LICENSE:LGPL$ |
|
10 ** No Commercial Usage |
|
11 ** This file contains pre-release code and may not be distributed. |
|
12 ** You may use this file in accordance with the terms and conditions |
|
13 ** contained in the Technology Preview License Agreement accompanying |
|
14 ** this package. |
|
15 ** |
|
16 ** GNU Lesser General Public License Usage |
|
17 ** Alternatively, this file may be used under the terms of the GNU Lesser |
|
18 ** General Public License version 2.1 as published by the Free Software |
|
19 ** Foundation and appearing in the file LICENSE.LGPL included in the |
|
20 ** packaging of this file. Please review the following information to |
|
21 ** ensure the GNU Lesser General Public License version 2.1 requirements |
|
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. |
|
23 ** |
|
24 ** In addition, as a special exception, Nokia gives you certain additional |
|
25 ** rights. These rights are described in the Nokia Qt LGPL Exception |
|
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. |
|
27 ** |
|
28 ** If you have questions regarding the use of this file, please contact |
|
29 ** Nokia at qt-info@nokia.com. |
|
30 ** |
|
31 ** |
|
32 ** |
|
33 ** |
|
34 ** |
|
35 ** |
|
36 ** |
|
37 ** |
|
38 ** $QT_END_LICENSE$ |
|
39 ** |
|
40 ****************************************************************************/ |
|
41 |
|
42 |
|
43 #include <QtTest/QtTest> |
|
44 #include <qplatformdefs.h> |
|
45 |
|
46 #include <QAbstractFileEngine> |
|
47 #include <QFSFileEngine> |
|
48 #include <QCoreApplication> |
|
49 #include <QDebug> |
|
50 #include <QDir> |
|
51 #include <QFile> |
|
52 #include <QFileInfo> |
|
53 #if !defined(Q_OS_WINCE) && !defined(Q_OS_SYMBIAN) |
|
54 #include <QHostInfo> |
|
55 #endif |
|
56 #include <QProcess> |
|
57 #ifndef Q_OS_WIN |
|
58 # include <sys/types.h> |
|
59 # include <unistd.h> |
|
60 #endif |
|
61 #ifdef Q_OS_MAC |
|
62 # include <sys/mount.h> |
|
63 #elif defined(Q_OS_LINUX) |
|
64 # include <sys/vfs.h> |
|
65 #elif defined(Q_OS_FREEBSD) |
|
66 # include <sys/param.h> |
|
67 # include <sys/mount.h> |
|
68 #elif defined(Q_OS_IRIX) |
|
69 # include <sys/statfs.h> |
|
70 #elif defined(Q_OS_WINCE) |
|
71 # include <qplatformdefs.h> |
|
72 # include <private/qfsfileengine_p.h> |
|
73 #endif |
|
74 |
|
75 #include <stdio.h> |
|
76 #include "../network-settings.h" |
|
77 |
|
78 #if defined(Q_OS_SYMBIAN) |
|
79 # define SRCDIR "" |
|
80 #endif |
|
81 |
|
82 Q_DECLARE_METATYPE(QFile::FileError) |
|
83 |
|
84 //TESTED_CLASS= |
|
85 //TESTED_FILES= |
|
86 |
|
87 class tst_QFile : public QObject |
|
88 { |
|
89 Q_OBJECT |
|
90 |
|
91 public: |
|
92 tst_QFile(); |
|
93 virtual ~tst_QFile(); |
|
94 |
|
95 |
|
96 public slots: |
|
97 void init(); |
|
98 void cleanup(); |
|
99 private slots: |
|
100 void initTestCase(); |
|
101 void cleanupTestCase(); |
|
102 void exists(); |
|
103 void open_data(); |
|
104 void open(); |
|
105 void openUnbuffered(); |
|
106 void size_data(); |
|
107 void size(); |
|
108 void seek(); |
|
109 void setSize(); |
|
110 void setSizeSeek(); |
|
111 void atEnd(); |
|
112 void readLine(); |
|
113 void readLine2(); |
|
114 void readLineNullInLine(); |
|
115 void readAllStdin(); |
|
116 void readLineStdin(); |
|
117 void readLineStdin_lineByLine(); |
|
118 void text(); |
|
119 void missingEndOfLine(); |
|
120 void readBlock(); |
|
121 void getch(); |
|
122 void ungetChar(); |
|
123 void createFile(); |
|
124 void append(); |
|
125 void permissions_data(); |
|
126 void permissions(); |
|
127 void setPermissions(); |
|
128 void copy(); |
|
129 void copyAfterFail(); |
|
130 void copyRemovesTemporaryFile() const; |
|
131 void copyShouldntOverwrite(); |
|
132 void copyFallback(); |
|
133 void link(); |
|
134 void linkToDir(); |
|
135 void absolutePathLinkToRelativePath(); |
|
136 void readBrokenLink(); |
|
137 void readTextFile_data(); |
|
138 void readTextFile(); |
|
139 void readTextFile2(); |
|
140 void writeTextFile_data(); |
|
141 void writeTextFile(); |
|
142 /* void largeFileSupport(); */ |
|
143 #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) |
|
144 void largeUncFileSupport(); |
|
145 #endif |
|
146 void tailFile(); |
|
147 void flush(); |
|
148 void bufferedRead(); |
|
149 void isSequential(); |
|
150 void encodeName(); |
|
151 void truncate(); |
|
152 void seekToPos(); |
|
153 void FILEReadWrite(); |
|
154 void i18nFileName_data(); |
|
155 void i18nFileName(); |
|
156 void longFileName_data(); |
|
157 void longFileName(); |
|
158 void fileEngineHandler(); |
|
159 void useQFileInAFileHandler(); |
|
160 void getCharFF(); |
|
161 void remove_and_exists(); |
|
162 void removeOpenFile(); |
|
163 void fullDisk(); |
|
164 void writeLargeDataBlock_data(); |
|
165 void writeLargeDataBlock(); |
|
166 void readFromWriteOnlyFile(); |
|
167 void writeToReadOnlyFile(); |
|
168 void virtualFile(); |
|
169 void textFile(); |
|
170 void rename_data(); |
|
171 void rename(); |
|
172 void renameWithAtEndSpecialFile() const; |
|
173 void renameFallback(); |
|
174 void renameMultiple(); |
|
175 void appendAndRead(); |
|
176 void miscWithUncPathAsCurrentDir(); |
|
177 void standarderror(); |
|
178 void handle(); |
|
179 |
|
180 void readEof_data(); |
|
181 void readEof(); |
|
182 |
|
183 void map_data(); |
|
184 void map(); |
|
185 void mapResource_data(); |
|
186 void mapResource(); |
|
187 void mapOpenMode_data(); |
|
188 void mapOpenMode(); |
|
189 |
|
190 // --- Task related tests below this line |
|
191 void task167217(); |
|
192 |
|
193 void openDirectory(); |
|
194 |
|
195 public: |
|
196 // disabled this test for the moment... it hangs |
|
197 void invalidFile_data(); |
|
198 void invalidFile(); |
|
199 }; |
|
200 |
|
201 tst_QFile::tst_QFile() |
|
202 { |
|
203 } |
|
204 |
|
205 tst_QFile::~tst_QFile() |
|
206 { |
|
207 |
|
208 } |
|
209 |
|
210 void tst_QFile::init() |
|
211 { |
|
212 // TODO: Add initialization code here. |
|
213 // This will be executed immediately before each test is run. |
|
214 } |
|
215 |
|
216 void tst_QFile::cleanup() |
|
217 { |
|
218 // TODO: Add cleanup code here. |
|
219 // This will be executed immediately after each test is run. |
|
220 |
|
221 // for copyFallback() |
|
222 if (QFile::exists("file-copy-destination.txt")) { |
|
223 QFile::setPermissions("file-copy-destination.txt", |
|
224 QFile::ReadOwner | QFile::WriteOwner); |
|
225 QFile::remove("file-copy-destination.txt"); |
|
226 } |
|
227 |
|
228 // for renameFallback() |
|
229 QFile::remove("file-rename-destination.txt"); |
|
230 |
|
231 // for copyAfterFail() |
|
232 QFile::remove("file-to-be-copied.txt"); |
|
233 QFile::remove("existing-file.txt"); |
|
234 QFile::remove("copied-file-1.txt"); |
|
235 QFile::remove("copied-file-2.txt"); |
|
236 |
|
237 // for renameMultiple() |
|
238 QFile::remove("file-to-be-renamed.txt"); |
|
239 QFile::remove("existing-file.txt"); |
|
240 QFile::remove("file-renamed-once.txt"); |
|
241 QFile::remove("file-renamed-twice.txt"); |
|
242 } |
|
243 |
|
244 void tst_QFile::initTestCase() |
|
245 { |
|
246 QFile::remove("noreadfile"); |
|
247 |
|
248 // create a file and make it read-only |
|
249 QFile file("readonlyfile"); |
|
250 file.open(QFile::WriteOnly); |
|
251 file.write("a", 1); |
|
252 file.close(); |
|
253 file.setPermissions(QFile::ReadOwner); |
|
254 |
|
255 // create another file and make it not readable |
|
256 file.setFileName("noreadfile"); |
|
257 file.open(QFile::WriteOnly); |
|
258 file.write("b", 1); |
|
259 file.close(); |
|
260 file.setPermissions(0); |
|
261 } |
|
262 |
|
263 void tst_QFile::cleanupTestCase() |
|
264 { |
|
265 // clean up the files we created |
|
266 QFile::remove("readonlyfile"); |
|
267 QFile::remove("noreadfile"); |
|
268 QFile::remove("myLink.lnk"); |
|
269 QFile::remove("appendme.txt"); |
|
270 QFile::remove("createme.txt"); |
|
271 QFile::remove("file.txt"); |
|
272 QFile::remove("genfile.txt"); |
|
273 QFile::remove("seekToPos.txt"); |
|
274 QFile::remove("setsizeseek.txt"); |
|
275 QFile::remove("stdfile.txt"); |
|
276 QFile::remove("textfile.txt"); |
|
277 QFile::remove("truncate.txt"); |
|
278 QFile::remove("winfile.txt"); |
|
279 QFile::remove("writeonlyfile"); |
|
280 QFile::remove("largeblockfile.txt"); |
|
281 QFile::remove("tst_qfile_copy.cpp"); |
|
282 QFile::remove("nullinline.txt"); |
|
283 QFile::remove("myLink2.lnk"); |
|
284 QFile::remove("resources"); |
|
285 QFile::remove("qfile_map_testfile"); |
|
286 } |
|
287 |
|
288 //------------------------------------------ |
|
289 // The 'testfile' is currently just a |
|
290 // testfile. The path of this file, the |
|
291 // attributes and the contents itself |
|
292 // will be changed as far as we have a |
|
293 // proper way to handle files in the |
|
294 // testing enviroment. |
|
295 //------------------------------------------ |
|
296 |
|
297 void tst_QFile::exists() |
|
298 { |
|
299 QFile f( SRCDIR "testfile.txt" ); |
|
300 QCOMPARE( f.exists(), (bool)TRUE ); |
|
301 |
|
302 QFile file("nobodyhassuchafile"); |
|
303 file.remove(); |
|
304 QVERIFY(!file.exists()); |
|
305 |
|
306 QFile file2("nobodyhassuchafile"); |
|
307 QVERIFY(file2.open(QIODevice::WriteOnly)); |
|
308 file2.close(); |
|
309 |
|
310 QVERIFY(file.exists()); |
|
311 |
|
312 QVERIFY(file.open(QIODevice::WriteOnly)); |
|
313 file.close(); |
|
314 QVERIFY(file.exists()); |
|
315 |
|
316 file.remove(); |
|
317 QVERIFY(!file.exists()); |
|
318 |
|
319 #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) |
|
320 QFile unc("//" + QtNetworkSettings::winServerName() + "/testshare/readme.txt"); |
|
321 QVERIFY(unc.exists()); |
|
322 #endif |
|
323 } |
|
324 |
|
325 void tst_QFile::open_data() |
|
326 { |
|
327 QTest::addColumn<QString>("filename"); |
|
328 QTest::addColumn<int>("mode"); |
|
329 QTest::addColumn<bool>("ok"); |
|
330 QTest::addColumn<QFile::FileError>("status"); |
|
331 |
|
332 #ifdef Q_OS_MAC |
|
333 static const QString denied("Operation not permitted"); |
|
334 #else |
|
335 static const QString denied("Permission denied"); |
|
336 #endif |
|
337 QTest::newRow( "exist_readOnly" ) |
|
338 << QString(SRCDIR "testfile.txt") << int(QIODevice::ReadOnly) |
|
339 << (bool)TRUE << QFile::NoError; |
|
340 |
|
341 QTest::newRow( "exist_writeOnly" ) |
|
342 << QString("readonlyfile") |
|
343 << int(QIODevice::WriteOnly) |
|
344 << (bool)FALSE |
|
345 << QFile::OpenError; |
|
346 |
|
347 QTest::newRow( "exist_append" ) |
|
348 << QString("readonlyfile") << int(QIODevice::Append) |
|
349 << (bool)FALSE << QFile::OpenError; |
|
350 |
|
351 QTest::newRow( "nonexist_readOnly" ) |
|
352 << QString("nonExist.txt") << int(QIODevice::ReadOnly) |
|
353 << (bool)FALSE << QFile::OpenError; |
|
354 |
|
355 QTest::newRow("emptyfile") |
|
356 << QString("") |
|
357 << int(QIODevice::ReadOnly) |
|
358 << (bool)FALSE |
|
359 << QFile::OpenError; |
|
360 |
|
361 QTest::newRow("nullfile") << QString() << int(QIODevice::ReadOnly) << (bool)FALSE |
|
362 << QFile::OpenError; |
|
363 |
|
364 QTest::newRow("two-dots") << QString(SRCDIR "two.dots.file") << int(QIODevice::ReadOnly) << (bool)TRUE |
|
365 << QFile::NoError; |
|
366 |
|
367 QTest::newRow("readonlyfile") << QString("readonlyfile") << int(QIODevice::WriteOnly) |
|
368 << (bool)FALSE << QFile::OpenError; |
|
369 QTest::newRow("noreadfile") << QString("noreadfile") << int(QIODevice::ReadOnly) |
|
370 << (bool)FALSE << QFile::OpenError; |
|
371 #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) |
|
372 QTest::newRow("//./PhysicalDrive0") << QString("//./PhysicalDrive0") << int(QIODevice::ReadOnly) |
|
373 << (bool)TRUE << QFile::NoError; |
|
374 QTest::newRow("uncFile") << "//" + QtNetworkSettings::winServerName() + "/testsharewritable/test.pri" << int(QIODevice::ReadOnly) |
|
375 << true << QFile::NoError; |
|
376 #endif |
|
377 } |
|
378 |
|
379 void tst_QFile::open() |
|
380 { |
|
381 QFETCH( QString, filename ); |
|
382 QFETCH( int, mode ); |
|
383 |
|
384 QFile f( filename ); |
|
385 |
|
386 QFETCH( bool, ok ); |
|
387 |
|
388 #if defined(Q_OS_SYMBIAN) |
|
389 if (qstrcmp(QTest::currentDataTag(), "noreadfile") == 0) |
|
390 QSKIP("Symbian does not support non-readable files", SkipSingle); |
|
391 #elif defined(Q_OS_UNIX) |
|
392 if (::getuid() == 0) |
|
393 // root and Chuck Norris don't care for file permissions. Skip. |
|
394 QSKIP("Running this test as root doesn't make sense", SkipAll); |
|
395 #endif |
|
396 |
|
397 #if defined(Q_OS_WIN32) || defined(Q_OS_WINCE) |
|
398 QEXPECT_FAIL("noreadfile", "Windows does not currently support non-readable files.", Abort); |
|
399 #endif |
|
400 if (filename.isEmpty()) |
|
401 QTest::ignoreMessage(QtWarningMsg, "QFSFileEngine::open: No file name specified"); |
|
402 |
|
403 QCOMPARE(f.open( QIODevice::OpenMode(mode) ), ok); |
|
404 |
|
405 QTEST( f.error(), "status" ); |
|
406 } |
|
407 |
|
408 void tst_QFile::openUnbuffered() |
|
409 { |
|
410 QFile file(SRCDIR "testfile.txt"); |
|
411 QVERIFY(file.open(QIODevice::ReadOnly | QIODevice::Unbuffered)); |
|
412 char c = '\0'; |
|
413 QVERIFY(file.seek(1)); |
|
414 QCOMPARE(file.pos(), qint64(1)); |
|
415 QVERIFY(file.getChar(&c)); |
|
416 QCOMPARE(file.pos(), qint64(2)); |
|
417 char d = '\0'; |
|
418 QVERIFY(file.seek(3)); |
|
419 QCOMPARE(file.pos(), qint64(3)); |
|
420 QVERIFY(file.getChar(&d)); |
|
421 QCOMPARE(file.pos(), qint64(4)); |
|
422 QVERIFY(file.seek(1)); |
|
423 QCOMPARE(file.pos(), qint64(1)); |
|
424 char c2 = '\0'; |
|
425 QVERIFY(file.getChar(&c2)); |
|
426 QCOMPARE(file.pos(), qint64(2)); |
|
427 QVERIFY(file.seek(3)); |
|
428 QCOMPARE(file.pos(), qint64(3)); |
|
429 char d2 = '\0'; |
|
430 QVERIFY(file.getChar(&d2)); |
|
431 QCOMPARE(file.pos(), qint64(4)); |
|
432 QCOMPARE(c, c2); |
|
433 QCOMPARE(d, d2); |
|
434 QCOMPARE(c, '-'); |
|
435 QCOMPARE(d, '-'); |
|
436 } |
|
437 |
|
438 void tst_QFile::size_data() |
|
439 { |
|
440 QTest::addColumn<QString>("filename"); |
|
441 QTest::addColumn<int>("size"); |
|
442 |
|
443 QTest::newRow( "exist01" ) << QString(SRCDIR "testfile.txt") << 245; |
|
444 QTest::newRow( "nonexist01" ) << QString("foo.txt") << 0; |
|
445 #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) |
|
446 // Only test UNC on Windows./ |
|
447 QTest::newRow("unc") << "//" + QString(QtNetworkSettings::winServerName() + "/testsharewritable/test.pri") << 34; |
|
448 #endif |
|
449 } |
|
450 |
|
451 void tst_QFile::size() |
|
452 { |
|
453 QFETCH( QString, filename ); |
|
454 QFile f( filename ); |
|
455 QTEST( (int)f.size(), "size" ); |
|
456 if (f.open(QFile::ReadOnly)) |
|
457 QTEST( (int)f.size(), "size" ); |
|
458 } |
|
459 |
|
460 void tst_QFile::seek() |
|
461 { |
|
462 QFile::remove("newfile.txt"); |
|
463 QFile file("newfile.txt"); |
|
464 file.open(QIODevice::WriteOnly); |
|
465 QCOMPARE(file.size(), qint64(0)); |
|
466 QCOMPARE(file.pos(), qint64(0)); |
|
467 QVERIFY(file.seek(10)); |
|
468 QCOMPARE(file.pos(), qint64(10)); |
|
469 QCOMPARE(file.size(), qint64(0)); |
|
470 QFile::remove("newfile.txt"); |
|
471 } |
|
472 |
|
473 void tst_QFile::setSize() |
|
474 { |
|
475 DEPENDS_ON( "size" ); |
|
476 |
|
477 if ( QFile::exists( "createme.txt" ) ) |
|
478 QFile::remove( "createme.txt" ); |
|
479 QVERIFY( !QFile::exists( "createme.txt" ) ); |
|
480 |
|
481 QFile f("createme.txt"); |
|
482 QVERIFY(f.open(QIODevice::Truncate | QIODevice::ReadWrite)); |
|
483 f.putChar('a'); |
|
484 |
|
485 f.seek(0); |
|
486 char c = '\0'; |
|
487 f.getChar(&c); |
|
488 QCOMPARE(c, 'a'); |
|
489 |
|
490 QCOMPARE(f.size(), (qlonglong)1); |
|
491 bool ok = f.resize(99); |
|
492 QVERIFY(ok); |
|
493 QCOMPARE(f.size(), (qlonglong)99); |
|
494 |
|
495 f.seek(0); |
|
496 c = '\0'; |
|
497 f.getChar(&c); |
|
498 QCOMPARE(c, 'a'); |
|
499 |
|
500 QVERIFY(f.resize(1)); |
|
501 QCOMPARE(f.size(), (qlonglong)1); |
|
502 |
|
503 f.seek(0); |
|
504 c = '\0'; |
|
505 f.getChar(&c); |
|
506 QCOMPARE(c, 'a'); |
|
507 |
|
508 f.close(); |
|
509 |
|
510 QCOMPARE(f.size(), (qlonglong)1); |
|
511 QVERIFY(f.resize(100)); |
|
512 QCOMPARE(f.size(), (qlonglong)100); |
|
513 QVERIFY(f.resize(50)); |
|
514 QCOMPARE(f.size(), (qlonglong)50); |
|
515 } |
|
516 |
|
517 void tst_QFile::setSizeSeek() |
|
518 { |
|
519 QFile::remove("setsizeseek.txt"); |
|
520 QFile f("setsizeseek.txt"); |
|
521 QVERIFY(f.open(QFile::WriteOnly)); |
|
522 f.write("ABCD"); |
|
523 |
|
524 QCOMPARE(f.pos(), qint64(4)); |
|
525 f.resize(2); |
|
526 QCOMPARE(f.pos(), qint64(2)); |
|
527 f.resize(4); |
|
528 QCOMPARE(f.pos(), qint64(2)); |
|
529 f.resize(0); |
|
530 QCOMPARE(f.pos(), qint64(0)); |
|
531 f.resize(4); |
|
532 QCOMPARE(f.pos(), qint64(0)); |
|
533 |
|
534 f.seek(3); |
|
535 QCOMPARE(f.pos(), qint64(3)); |
|
536 f.resize(2); |
|
537 QCOMPARE(f.pos(), qint64(2)); |
|
538 } |
|
539 |
|
540 void tst_QFile::atEnd() |
|
541 { |
|
542 QFile f( SRCDIR "testfile.txt" ); |
|
543 QVERIFY(f.open( QIODevice::ReadOnly )); |
|
544 |
|
545 int size = f.size(); |
|
546 f.seek( size ); |
|
547 |
|
548 bool end = f.atEnd(); |
|
549 f.close(); |
|
550 QCOMPARE( end, (bool)TRUE ); |
|
551 } |
|
552 |
|
553 void tst_QFile::readLine() |
|
554 { |
|
555 QFile f( SRCDIR "testfile.txt" ); |
|
556 QVERIFY(f.open( QIODevice::ReadOnly )); |
|
557 |
|
558 int i = 0; |
|
559 char p[128]; |
|
560 int foo; |
|
561 while ( (foo=f.readLine( p, 128 )) > 0 ) { |
|
562 ++i; |
|
563 if ( i == 5 ) { |
|
564 QCOMPARE( p[0], 'T' ); |
|
565 QCOMPARE( p[3], 's' ); |
|
566 QCOMPARE( p[11], 'i' ); |
|
567 } |
|
568 } |
|
569 f.close(); |
|
570 QCOMPARE( i, 6 ); |
|
571 } |
|
572 |
|
573 void tst_QFile::readLine2() |
|
574 { |
|
575 QFile f( SRCDIR "testfile.txt" ); |
|
576 f.open( QIODevice::ReadOnly ); |
|
577 |
|
578 char p[128]; |
|
579 QCOMPARE(f.readLine(p, 60), qlonglong(59)); |
|
580 QCOMPARE(f.readLine(p, 60), qlonglong(59)); |
|
581 memset(p, '@', sizeof(p)); |
|
582 QCOMPARE(f.readLine(p, 60), qlonglong(59)); |
|
583 |
|
584 QCOMPARE(p[57], '-'); |
|
585 QCOMPARE(p[58], '\n'); |
|
586 QCOMPARE(p[59], '\0'); |
|
587 QCOMPARE(p[60], '@'); |
|
588 } |
|
589 |
|
590 void tst_QFile::readLineNullInLine() |
|
591 { |
|
592 QFile::remove("nullinline.txt"); |
|
593 QFile file("nullinline.txt"); |
|
594 QVERIFY(file.open(QIODevice::ReadWrite)); |
|
595 QVERIFY(file.write("linewith\0null\nanotherline\0withnull\n\0\nnull\0", 42) > 0); |
|
596 QVERIFY(file.flush()); |
|
597 file.reset(); |
|
598 |
|
599 QCOMPARE(file.readLine(), QByteArray("linewith\0null\n", 14)); |
|
600 QCOMPARE(file.readLine(), QByteArray("anotherline\0withnull\n", 21)); |
|
601 QCOMPARE(file.readLine(), QByteArray("\0\n", 2)); |
|
602 QCOMPARE(file.readLine(), QByteArray("null\0", 5)); |
|
603 QCOMPARE(file.readLine(), QByteArray()); |
|
604 } |
|
605 |
|
606 void tst_QFile::readAllStdin() |
|
607 { |
|
608 #if defined(Q_OS_WINCE) || defined(Q_OS_SYMBIAN) |
|
609 QSKIP("Currently no stdin/out supported for Windows CE or Symbian", SkipAll); |
|
610 #endif |
|
611 #if defined(QT_NO_PROCESS) |
|
612 QSKIP("Qt was compiled with QT_NO_PROCESS", SkipAll); |
|
613 #else |
|
614 QByteArray lotsOfData(1024, '@'); // 10 megs |
|
615 |
|
616 QProcess process; |
|
617 process.start("stdinprocess/stdinprocess all"); |
|
618 for (int i = 0; i < 5; ++i) { |
|
619 QTest::qWait(1000); |
|
620 process.write(lotsOfData); |
|
621 while (process.bytesToWrite() > 0) { |
|
622 QVERIFY(process.waitForBytesWritten()); |
|
623 } |
|
624 } |
|
625 |
|
626 process.closeWriteChannel(); |
|
627 process.waitForFinished(); |
|
628 QCOMPARE(process.readAll().size(), lotsOfData.size() * 5); |
|
629 #endif |
|
630 } |
|
631 |
|
632 void tst_QFile::readLineStdin() |
|
633 { |
|
634 #if defined(Q_OS_WINCE) || defined(Q_OS_SYMBIAN) |
|
635 QSKIP("Currently no stdin/out supported for Windows CE or Symbian", SkipAll); |
|
636 #endif |
|
637 #if defined(QT_NO_PROCESS) |
|
638 QSKIP("Qt was compiled with QT_NO_PROCESS", SkipAll); |
|
639 #else |
|
640 |
|
641 QByteArray lotsOfData(1024, '@'); // 10 megs |
|
642 for (int i = 0; i < lotsOfData.size(); ++i) { |
|
643 if ((i % 32) == 31) |
|
644 lotsOfData[i] = '\n'; |
|
645 else |
|
646 lotsOfData[i] = char('0' + i % 32); |
|
647 } |
|
648 |
|
649 for (int i = 0; i < 2; ++i) { |
|
650 QProcess process; |
|
651 process.start(QString("stdinprocess/stdinprocess line %1").arg(i), QIODevice::Text | QIODevice::ReadWrite); |
|
652 for (int i = 0; i < 5; ++i) { |
|
653 QTest::qWait(1000); |
|
654 process.write(lotsOfData); |
|
655 while (process.bytesToWrite() > 0) { |
|
656 QVERIFY(process.waitForBytesWritten()); |
|
657 } |
|
658 } |
|
659 |
|
660 process.closeWriteChannel(); |
|
661 QVERIFY(process.waitForFinished(5000)); |
|
662 |
|
663 QByteArray array = process.readAll(); |
|
664 QCOMPARE(array.size(), lotsOfData.size() * 5); |
|
665 for (int i = 0; i < array.size(); ++i) { |
|
666 if ((i % 32) == 31) |
|
667 QCOMPARE(char(array[i]), '\n'); |
|
668 else |
|
669 QCOMPARE(char(array[i]), char('0' + i % 32)); |
|
670 } |
|
671 } |
|
672 #endif |
|
673 } |
|
674 |
|
675 void tst_QFile::readLineStdin_lineByLine() |
|
676 { |
|
677 #if defined(Q_OS_WINCE) || defined(Q_OS_SYMBIAN) |
|
678 QSKIP("Currently no stdin/out supported for Windows CE", SkipAll); |
|
679 #endif |
|
680 #if defined(QT_NO_PROCESS) |
|
681 QSKIP("Qt was compiled with QT_NO_PROCESS", SkipAll); |
|
682 #else |
|
683 for (int i = 0; i < 2; ++i) { |
|
684 QProcess process; |
|
685 process.start(QString("stdinprocess/stdinprocess line %1").arg(i), QIODevice::Text | QIODevice::ReadWrite); |
|
686 QVERIFY(process.waitForStarted()); |
|
687 |
|
688 for (int j = 0; j < 3; ++j) { |
|
689 QByteArray line = "line " + QByteArray::number(j) + "\n"; |
|
690 QCOMPARE(process.write(line), qint64(line.size())); |
|
691 QVERIFY(process.waitForBytesWritten(2000)); |
|
692 if (process.bytesAvailable() == 0) |
|
693 QVERIFY(process.waitForReadyRead(2000)); |
|
694 QCOMPARE(process.readAll(), line); |
|
695 } |
|
696 |
|
697 process.closeWriteChannel(); |
|
698 QVERIFY(process.waitForFinished(5000)); |
|
699 } |
|
700 #endif |
|
701 } |
|
702 |
|
703 void tst_QFile::text() |
|
704 { |
|
705 // dosfile.txt is a binary CRLF file |
|
706 QFile file(SRCDIR "dosfile.txt"); |
|
707 QVERIFY(file.open(QFile::Text | QFile::ReadOnly)); |
|
708 QCOMPARE(file.readLine(), |
|
709 QByteArray("/dev/system/root / reiserfs acl,user_xattr 1 1\n")); |
|
710 QCOMPARE(file.readLine(), |
|
711 QByteArray("/dev/sda1 /boot ext3 acl,user_xattr 1 2\n")); |
|
712 file.ungetChar('\n'); |
|
713 file.ungetChar('2'); |
|
714 QCOMPARE(file.readLine().constData(), QByteArray("2\n").constData()); |
|
715 } |
|
716 |
|
717 void tst_QFile::missingEndOfLine() |
|
718 { |
|
719 QFile file(SRCDIR "noendofline.txt"); |
|
720 QVERIFY(file.open(QFile::ReadOnly)); |
|
721 |
|
722 int nlines = 0; |
|
723 while (!file.atEnd()) { |
|
724 ++nlines; |
|
725 file.readLine(); |
|
726 } |
|
727 |
|
728 QCOMPARE(nlines, 3); |
|
729 } |
|
730 |
|
731 void tst_QFile::readBlock() |
|
732 { |
|
733 QFile f( SRCDIR "testfile.txt" ); |
|
734 f.open( QIODevice::ReadOnly ); |
|
735 |
|
736 int length = 0; |
|
737 char p[256]; |
|
738 length = f.read( p, 256 ); |
|
739 f.close(); |
|
740 QCOMPARE( length, 245 ); |
|
741 QCOMPARE( p[59], 'D' ); |
|
742 QCOMPARE( p[178], 'T' ); |
|
743 QCOMPARE( p[199], 'l' ); |
|
744 } |
|
745 |
|
746 void tst_QFile::getch() |
|
747 { |
|
748 QFile f( SRCDIR "testfile.txt" ); |
|
749 f.open( QIODevice::ReadOnly ); |
|
750 |
|
751 char c; |
|
752 int i = 0; |
|
753 while (f.getChar(&c)) { |
|
754 QCOMPARE(f.pos(), qint64(i + 1)); |
|
755 if ( i == 59 ) |
|
756 QCOMPARE( c, 'D' ); |
|
757 ++i; |
|
758 } |
|
759 f.close(); |
|
760 QCOMPARE( i, 245 ); |
|
761 } |
|
762 |
|
763 void tst_QFile::ungetChar() |
|
764 { |
|
765 QFile f(SRCDIR "testfile.txt"); |
|
766 QVERIFY(f.open(QIODevice::ReadOnly)); |
|
767 |
|
768 QByteArray array = f.readLine(); |
|
769 QCOMPARE(array.constData(), "----------------------------------------------------------\n"); |
|
770 f.ungetChar('\n'); |
|
771 |
|
772 array = f.readLine(); |
|
773 QCOMPARE(array.constData(), "\n"); |
|
774 |
|
775 f.ungetChar('\n'); |
|
776 f.ungetChar('-'); |
|
777 f.ungetChar('-'); |
|
778 |
|
779 array = f.readLine(); |
|
780 QCOMPARE(array.constData(), "--\n"); |
|
781 |
|
782 QFile::remove("genfile.txt"); |
|
783 QFile out("genfile.txt"); |
|
784 QVERIFY(out.open(QIODevice::ReadWrite)); |
|
785 out.write("123"); |
|
786 out.seek(0); |
|
787 QCOMPARE(out.readAll().constData(), "123"); |
|
788 out.ungetChar('3'); |
|
789 out.write("4"); |
|
790 out.seek(0); |
|
791 QCOMPARE(out.readAll().constData(), "124"); |
|
792 out.ungetChar('4'); |
|
793 out.ungetChar('2'); |
|
794 out.ungetChar('1'); |
|
795 char buf[3]; |
|
796 QCOMPARE(out.read(buf, sizeof(buf)), qint64(3)); |
|
797 QCOMPARE(buf[0], '1'); |
|
798 QCOMPARE(buf[1], '2'); |
|
799 QCOMPARE(buf[2], '4'); |
|
800 } |
|
801 |
|
802 void tst_QFile::invalidFile_data() |
|
803 { |
|
804 QTest::addColumn<QString>("fileName"); |
|
805 #if !defined(Q_WS_WIN) && !defined(Q_OS_SYMBIAN) |
|
806 QTest::newRow( "x11" ) << QString( "qwe//" ); |
|
807 #else |
|
808 QTest::newRow( "colon1" ) << QString( "fail:invalid" ); |
|
809 QTest::newRow( "colon2" ) << QString( "f:ail:invalid" ); |
|
810 QTest::newRow( "colon3" ) << QString( ":failinvalid" ); |
|
811 QTest::newRow( "forwardslash" ) << QString( "fail/invalid" ); |
|
812 QTest::newRow( "asterisk" ) << QString( "fail*invalid" ); |
|
813 QTest::newRow( "questionmark" ) << QString( "fail?invalid" ); |
|
814 QTest::newRow( "quote" ) << QString( "fail\"invalid" ); |
|
815 QTest::newRow( "lt" ) << QString( "fail<invalid" ); |
|
816 QTest::newRow( "gt" ) << QString( "fail>invalid" ); |
|
817 QTest::newRow( "pipe" ) << QString( "fail|invalid" ); |
|
818 #endif |
|
819 } |
|
820 |
|
821 void tst_QFile::invalidFile() |
|
822 { |
|
823 QFETCH( QString, fileName ); |
|
824 QFile f( fileName ); |
|
825 QVERIFY( !f.open( QIODevice::ReadWrite ) ); |
|
826 } |
|
827 |
|
828 void tst_QFile::createFile() |
|
829 { |
|
830 if ( QFile::exists( "createme.txt" ) ) |
|
831 QFile::remove( "createme.txt" ); |
|
832 QVERIFY( !QFile::exists( "createme.txt" ) ); |
|
833 |
|
834 QFile f( "createme.txt" ); |
|
835 QVERIFY( f.open( QIODevice::WriteOnly ) ); |
|
836 f.close(); |
|
837 QVERIFY( QFile::exists( "createme.txt" ) ); |
|
838 } |
|
839 |
|
840 void tst_QFile::append() |
|
841 { |
|
842 const QString name("appendme.txt"); |
|
843 if (QFile::exists(name)) |
|
844 QFile::remove(name); |
|
845 QVERIFY(!QFile::exists(name)); |
|
846 |
|
847 QFile f(name); |
|
848 QVERIFY(f.open(QIODevice::WriteOnly | QIODevice::Truncate)); |
|
849 f.putChar('a'); |
|
850 f.close(); |
|
851 |
|
852 QVERIFY(f.open(QIODevice::Append)); |
|
853 QVERIFY(f.pos() == 1); |
|
854 f.putChar('a'); |
|
855 f.close(); |
|
856 QCOMPARE(int(f.size()), 2); |
|
857 } |
|
858 |
|
859 void tst_QFile::permissions_data() |
|
860 { |
|
861 QTest::addColumn<QString>("file"); |
|
862 QTest::addColumn<uint>("perms"); |
|
863 QTest::addColumn<bool>("expected"); |
|
864 |
|
865 QTest::newRow("data0") << QCoreApplication::instance()->applicationFilePath() << uint(QFile::ExeUser) << true; |
|
866 QTest::newRow("data1") << SRCDIR "tst_qfile.cpp" << uint(QFile::ReadUser) << true; |
|
867 // QTest::newRow("data2") << "tst_qfile.cpp" << int(QFile::WriteUser) << false; |
|
868 QTest::newRow("resource1") << ":/tst_qfileinfo/resources/file1.ext1" << uint(QFile::ReadUser) << true; |
|
869 QTest::newRow("resource2") << ":/tst_qfileinfo/resources/file1.ext1" << uint(QFile::WriteUser) << false; |
|
870 QTest::newRow("resource3") << ":/tst_qfileinfo/resources/file1.ext1" << uint(QFile::ExeUser) << false; |
|
871 } |
|
872 |
|
873 void tst_QFile::permissions() |
|
874 { |
|
875 #if defined(Q_OS_SYMBIAN) |
|
876 if (qstrcmp(QTest::currentDataTag(), "data0") == 0) |
|
877 QSKIP("Symbian does not have execution permissions", SkipSingle); |
|
878 #endif |
|
879 QFETCH(QString, file); |
|
880 QFETCH(uint, perms); |
|
881 QFETCH(bool, expected); |
|
882 QFile f(file); |
|
883 QCOMPARE(((f.permissions() & perms) == QFile::Permissions(perms)), expected); |
|
884 } |
|
885 |
|
886 void tst_QFile::setPermissions() |
|
887 { |
|
888 DEPENDS_ON( "permissions" ); //if that doesn't work... |
|
889 |
|
890 if ( QFile::exists( "createme.txt" ) ) |
|
891 QFile::remove( "createme.txt" ); |
|
892 QVERIFY( !QFile::exists( "createme.txt" ) ); |
|
893 |
|
894 QFile f("createme.txt"); |
|
895 QVERIFY(f.open(QIODevice::WriteOnly | QIODevice::Truncate)); |
|
896 f.putChar('a'); |
|
897 f.close(); |
|
898 |
|
899 QFile::Permissions perms(QFile::WriteUser | QFile::ReadUser); |
|
900 QVERIFY(f.setPermissions(perms)); |
|
901 QVERIFY((f.permissions() & perms) == perms); |
|
902 |
|
903 } |
|
904 |
|
905 void tst_QFile::copy() |
|
906 { |
|
907 QFile::setPermissions("tst_qfile_copy.cpp", QFile::WriteUser); |
|
908 QFile::remove("tst_qfile_copy.cpp"); |
|
909 QFile::remove("test2"); |
|
910 QVERIFY(QFile::copy(SRCDIR "tst_qfile.cpp", "tst_qfile_copy.cpp")); |
|
911 QFile in1(SRCDIR "tst_qfile.cpp"), in2("tst_qfile_copy.cpp"); |
|
912 QVERIFY(in1.open(QFile::ReadOnly)); |
|
913 QVERIFY(in2.open(QFile::ReadOnly)); |
|
914 QByteArray data1 = in1.readAll(), data2 = in2.readAll(); |
|
915 QCOMPARE(data1, data2); |
|
916 QFile::remove( "main_copy.cpp" ); |
|
917 |
|
918 QFile::copy(QDir::currentPath(), QDir::currentPath() + QLatin1String("/test2")); |
|
919 } |
|
920 |
|
921 void tst_QFile::copyAfterFail() |
|
922 { |
|
923 QFile file1("file-to-be-copied.txt"); |
|
924 QFile file2("existing-file.txt"); |
|
925 |
|
926 QVERIFY(file1.open(QIODevice::ReadWrite) && "(test-precondition)"); |
|
927 QVERIFY(file2.open(QIODevice::ReadWrite) && "(test-precondition)"); |
|
928 file2.close(); |
|
929 QVERIFY(!QFile::exists("copied-file-1.txt") && "(test-precondition)"); |
|
930 QVERIFY(!QFile::exists("copied-file-2.txt") && "(test-precondition)"); |
|
931 |
|
932 QVERIFY(!file1.copy("existing-file.txt")); |
|
933 QCOMPARE(file1.error(), QFile::CopyError); |
|
934 |
|
935 QVERIFY(file1.copy("copied-file-1.txt")); |
|
936 QVERIFY(!file1.isOpen()); |
|
937 QCOMPARE(file1.error(), QFile::NoError); |
|
938 |
|
939 QVERIFY(!file1.copy("existing-file.txt")); |
|
940 QCOMPARE(file1.error(), QFile::CopyError); |
|
941 |
|
942 QVERIFY(file1.copy("copied-file-2.txt")); |
|
943 QVERIFY(!file1.isOpen()); |
|
944 QCOMPARE(file1.error(), QFile::NoError); |
|
945 |
|
946 QVERIFY(QFile::exists("copied-file-1.txt")); |
|
947 QVERIFY(QFile::exists("copied-file-2.txt")); |
|
948 |
|
949 QVERIFY(QFile::remove("file-to-be-copied.txt") && "(test-cleanup)"); |
|
950 QVERIFY(QFile::remove("existing-file.txt") && "(test-cleanup)"); |
|
951 QVERIFY(QFile::remove("copied-file-1.txt") && "(test-cleanup)"); |
|
952 QVERIFY(QFile::remove("copied-file-2.txt") && "(test-cleanup)"); |
|
953 } |
|
954 |
|
955 void tst_QFile::copyRemovesTemporaryFile() const |
|
956 { |
|
957 const QString newName(QLatin1String("copyRemovesTemporaryFile")); |
|
958 QVERIFY(QFile::copy(SRCDIR "forCopying.txt", newName)); |
|
959 |
|
960 QVERIFY(!QFile::exists(QLatin1String( SRCDIR "qt_temp.XXXXXX"))); |
|
961 QVERIFY(QFile::remove(newName)); |
|
962 } |
|
963 |
|
964 void tst_QFile::copyShouldntOverwrite() |
|
965 { |
|
966 // Copy should not overwrite existing files. |
|
967 QFile::remove("tst_qfile.cpy"); |
|
968 QFile file(SRCDIR "tst_qfile.cpp"); |
|
969 QVERIFY(file.copy("tst_qfile.cpy")); |
|
970 #if defined(Q_OS_SYMBIAN) |
|
971 bool ok = QFile::setPermissions("tst_qfile.cpy", QFile::WriteUser); |
|
972 #else |
|
973 bool ok = QFile::setPermissions("tst_qfile.cpy", QFile::WriteOther); |
|
974 #endif |
|
975 QVERIFY(ok); |
|
976 QVERIFY(!file.copy("tst_qfile.cpy")); |
|
977 QFile::remove("tst_qfile.cpy"); |
|
978 } |
|
979 |
|
980 void tst_QFile::copyFallback() |
|
981 { |
|
982 // Using a resource file to trigger QFile::copy's fallback handling |
|
983 QFile file(":/copy-fallback.qrc"); |
|
984 QFile::remove("file-copy-destination.txt"); |
|
985 |
|
986 QVERIFY2(file.exists(), "test precondition"); |
|
987 QVERIFY2(!QFile::exists("file-copy-destination.txt"), "test precondition"); |
|
988 |
|
989 // Fallback copy of closed file. |
|
990 QVERIFY(file.copy("file-copy-destination.txt")); |
|
991 QVERIFY(QFile::exists("file-copy-destination.txt")); |
|
992 QVERIFY(!file.isOpen()); |
|
993 |
|
994 // Need to reset permissions on Windows to be able to delete |
|
995 QVERIFY(QFile::setPermissions("file-copy-destination.txt", |
|
996 QFile::ReadOwner | QFile::WriteOwner)); |
|
997 QVERIFY(QFile::remove("file-copy-destination.txt")); |
|
998 |
|
999 // Fallback copy of open file. |
|
1000 QVERIFY(file.open(QIODevice::ReadOnly)); |
|
1001 QVERIFY(file.copy("file-copy-destination.txt")); |
|
1002 QVERIFY(QFile::exists("file-copy-destination.txt")); |
|
1003 QVERIFY(!file.isOpen()); |
|
1004 |
|
1005 QFile::remove("file-copy-destination.txt"); |
|
1006 } |
|
1007 |
|
1008 #ifdef Q_OS_WIN |
|
1009 #include <objbase.h> |
|
1010 #include <shlobj.h> |
|
1011 #endif |
|
1012 |
|
1013 #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) |
|
1014 static QString getWorkingDirectoryForLink(const QString &linkFileName) |
|
1015 { |
|
1016 bool neededCoInit = false; |
|
1017 QString ret; |
|
1018 |
|
1019 IShellLink *psl; |
|
1020 HRESULT hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (void **)&psl); |
|
1021 if (hres == CO_E_NOTINITIALIZED) { // COM was not initialized |
|
1022 neededCoInit = true; |
|
1023 CoInitialize(NULL); |
|
1024 hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (void **)&psl); |
|
1025 } |
|
1026 |
|
1027 if (SUCCEEDED(hres)) { // Get pointer to the IPersistFile interface. |
|
1028 IPersistFile *ppf; |
|
1029 hres = psl->QueryInterface(IID_IPersistFile, (LPVOID *)&ppf); |
|
1030 if (SUCCEEDED(hres)) { |
|
1031 hres = ppf->Load((LPOLESTR)linkFileName.utf16(), STGM_READ); |
|
1032 //The original path of the link is retrieved. If the file/folder |
|
1033 //was moved, the return value still have the old path. |
|
1034 if(SUCCEEDED(hres)) { |
|
1035 wchar_t szGotPath[MAX_PATH]; |
|
1036 if (psl->GetWorkingDirectory(szGotPath, MAX_PATH) == NOERROR) |
|
1037 ret = QString::fromWCharArray(szGotPath); |
|
1038 } |
|
1039 ppf->Release(); |
|
1040 } |
|
1041 psl->Release(); |
|
1042 } |
|
1043 |
|
1044 if (neededCoInit) { |
|
1045 CoUninitialize(); |
|
1046 } |
|
1047 |
|
1048 return ret; |
|
1049 } |
|
1050 #endif |
|
1051 |
|
1052 void tst_QFile::link() |
|
1053 { |
|
1054 QFile::remove("myLink.lnk"); |
|
1055 QFileInfo info1("tst_qfile.cpp"); |
|
1056 QVERIFY(QFile::link("tst_qfile.cpp", "myLink.lnk")); |
|
1057 QFileInfo info2("myLink.lnk"); |
|
1058 QVERIFY(info2.isSymLink()); |
|
1059 QCOMPARE(info2.symLinkTarget(), info1.absoluteFilePath()); |
|
1060 |
|
1061 #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) |
|
1062 QString wd = getWorkingDirectoryForLink(info2.absoluteFilePath()); |
|
1063 QCOMPARE(QDir::fromNativeSeparators(wd), info1.absolutePath()); |
|
1064 #endif |
|
1065 QVERIFY(QFile::remove(info2.absoluteFilePath())); |
|
1066 } |
|
1067 |
|
1068 void tst_QFile::linkToDir() |
|
1069 { |
|
1070 #if defined(Q_OS_SYMBIAN) |
|
1071 QSKIP("Symbian does not support linking to directories", SkipAll); |
|
1072 #endif |
|
1073 QFile::remove("myLinkToDir.lnk"); |
|
1074 QDir dir; |
|
1075 dir.mkdir("myDir"); |
|
1076 QFileInfo info1("myDir"); |
|
1077 QVERIFY(QFile::link("myDir", "myLinkToDir.lnk")); |
|
1078 QFileInfo info2("myLinkToDir.lnk"); |
|
1079 #if !(defined Q_OS_HPUX && defined(__ia64)) |
|
1080 // absurd HP-UX filesystem bug on gravlaks - checking if a symlink |
|
1081 // resolves or not alters the file system to make the broken symlink |
|
1082 // later fail... |
|
1083 QVERIFY(info2.isSymLink()); |
|
1084 #endif |
|
1085 QCOMPARE(info2.symLinkTarget(), info1.absoluteFilePath()); |
|
1086 QVERIFY(QFile::remove(info2.absoluteFilePath())); |
|
1087 QFile::remove("myLinkToDir.lnk"); |
|
1088 dir.rmdir("myDir"); |
|
1089 } |
|
1090 |
|
1091 void tst_QFile::absolutePathLinkToRelativePath() |
|
1092 { |
|
1093 QFile::remove("myDir/test.txt"); |
|
1094 QFile::remove("myDir/myLink.lnk"); |
|
1095 QDir dir; |
|
1096 dir.mkdir("myDir"); |
|
1097 QFile("myDir/test.txt").open(QFile::WriteOnly); |
|
1098 |
|
1099 #ifdef Q_OS_WIN |
|
1100 QVERIFY(QFile::link("test.txt", "myDir/myLink.lnk")); |
|
1101 #else |
|
1102 QVERIFY(QFile::link("myDir/test.txt", "myDir/myLink.lnk")); |
|
1103 #endif |
|
1104 QEXPECT_FAIL("", "Symlinking using relative paths is currently different on Windows and Unix/Symbian", Continue); |
|
1105 QCOMPARE(QFileInfo(QFile(QFileInfo("myDir/myLink.lnk").absoluteFilePath()).symLinkTarget()).absoluteFilePath(), |
|
1106 QFileInfo("myDir/test.txt").absoluteFilePath()); |
|
1107 |
|
1108 QFile::remove("myDir/test.txt"); |
|
1109 QFile::remove("myDir/myLink.lnk"); |
|
1110 dir.rmdir("myDir"); |
|
1111 } |
|
1112 |
|
1113 void tst_QFile::readBrokenLink() |
|
1114 { |
|
1115 QFile::remove("myLink2.lnk"); |
|
1116 QFileInfo info1("file12"); |
|
1117 #if defined(Q_OS_SYMBIAN) |
|
1118 // In Symbian can't link to nonexisting file directly, so create the file temporarily |
|
1119 QFile tempFile("file12"); |
|
1120 tempFile.open(QIODevice::WriteOnly); |
|
1121 tempFile.link("myLink2.lnk"); |
|
1122 tempFile.remove(); |
|
1123 #else |
|
1124 QVERIFY(QFile::link("file12", "myLink2.lnk")); |
|
1125 #endif |
|
1126 QFileInfo info2("myLink2.lnk"); |
|
1127 QVERIFY(info2.isSymLink()); |
|
1128 QCOMPARE(info2.symLinkTarget(), info1.absoluteFilePath()); |
|
1129 QVERIFY(QFile::remove(info2.absoluteFilePath())); |
|
1130 |
|
1131 #if !defined(Q_OS_SYMBIAN) |
|
1132 QVERIFY(QFile::link("ole/..", "myLink2.lnk")); |
|
1133 QCOMPARE(QFileInfo("myLink2.lnk").symLinkTarget(), QDir::currentPath()); |
|
1134 #endif |
|
1135 } |
|
1136 |
|
1137 void tst_QFile::readTextFile_data() |
|
1138 { |
|
1139 QTest::addColumn<QByteArray>("in"); |
|
1140 QTest::addColumn<QByteArray>("out"); |
|
1141 |
|
1142 QTest::newRow("empty") << QByteArray() << QByteArray(); |
|
1143 QTest::newRow("a") << QByteArray("a") << QByteArray("a"); |
|
1144 QTest::newRow("a\\rb") << QByteArray("a\rb") << QByteArray("ab"); |
|
1145 QTest::newRow("\\n") << QByteArray("\n") << QByteArray("\n"); |
|
1146 QTest::newRow("\\r\\n") << QByteArray("\r\n") << QByteArray("\n"); |
|
1147 QTest::newRow("\\r") << QByteArray("\r") << QByteArray(); |
|
1148 QTest::newRow("twolines") << QByteArray("Hello\r\nWorld\r\n") << QByteArray("Hello\nWorld\n"); |
|
1149 QTest::newRow("twolines no endline") << QByteArray("Hello\r\nWorld") << QByteArray("Hello\nWorld"); |
|
1150 } |
|
1151 |
|
1152 void tst_QFile::readTextFile() |
|
1153 { |
|
1154 QFETCH(QByteArray, in); |
|
1155 QFETCH(QByteArray, out); |
|
1156 |
|
1157 QFile winfile("winfile.txt"); |
|
1158 QVERIFY(winfile.open(QFile::WriteOnly | QFile::Truncate)); |
|
1159 winfile.write(in); |
|
1160 winfile.close(); |
|
1161 |
|
1162 QVERIFY(winfile.open(QFile::ReadOnly)); |
|
1163 QCOMPARE(winfile.readAll(), in); |
|
1164 winfile.close(); |
|
1165 |
|
1166 QVERIFY(winfile.open(QFile::ReadOnly | QFile::Text)); |
|
1167 QCOMPARE(winfile.readAll(), out); |
|
1168 } |
|
1169 |
|
1170 void tst_QFile::readTextFile2() |
|
1171 { |
|
1172 { |
|
1173 QFile file(SRCDIR "testlog.txt"); |
|
1174 QVERIFY(file.open(QIODevice::ReadOnly)); |
|
1175 file.read(4097); |
|
1176 } |
|
1177 |
|
1178 { |
|
1179 QFile file(SRCDIR "testlog.txt"); |
|
1180 QVERIFY(file.open(QIODevice::ReadOnly | QIODevice::Text)); |
|
1181 file.read(4097); |
|
1182 } |
|
1183 } |
|
1184 |
|
1185 void tst_QFile::writeTextFile_data() |
|
1186 { |
|
1187 QTest::addColumn<QByteArray>("in"); |
|
1188 |
|
1189 QTest::newRow("empty") << QByteArray(); |
|
1190 QTest::newRow("a") << QByteArray("a"); |
|
1191 QTest::newRow("a\\rb") << QByteArray("a\rb"); |
|
1192 QTest::newRow("\\n") << QByteArray("\n"); |
|
1193 QTest::newRow("\\r\\n") << QByteArray("\r\n"); |
|
1194 QTest::newRow("\\r") << QByteArray("\r"); |
|
1195 QTest::newRow("twolines crlf") << QByteArray("Hello\r\nWorld\r\n"); |
|
1196 QTest::newRow("twolines crlf no endline") << QByteArray("Hello\r\nWorld"); |
|
1197 QTest::newRow("twolines lf") << QByteArray("Hello\nWorld\n"); |
|
1198 QTest::newRow("twolines lf no endline") << QByteArray("Hello\nWorld"); |
|
1199 QTest::newRow("mixed") << QByteArray("this\nis\r\na\nmixed\r\nfile\n"); |
|
1200 } |
|
1201 |
|
1202 void tst_QFile::writeTextFile() |
|
1203 { |
|
1204 QFETCH(QByteArray, in); |
|
1205 |
|
1206 QFile file("textfile.txt"); |
|
1207 QVERIFY(file.open(QFile::WriteOnly | QFile::Truncate | QFile::Text)); |
|
1208 QByteArray out = in; |
|
1209 #ifdef Q_OS_WIN |
|
1210 out.replace('\n', "\r\n"); |
|
1211 #endif |
|
1212 QCOMPARE(file.write(in), qlonglong(in.size())); |
|
1213 file.close(); |
|
1214 |
|
1215 file.open(QFile::ReadOnly); |
|
1216 QCOMPARE(file.readAll(), out); |
|
1217 } |
|
1218 |
|
1219 #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) |
|
1220 void tst_QFile::largeUncFileSupport() |
|
1221 { |
|
1222 qint64 size = Q_INT64_C(8589934592); |
|
1223 qint64 dataOffset = Q_INT64_C(8589914592); |
|
1224 QByteArray knownData("LargeFile content at offset 8589914592"); |
|
1225 QString largeFile("//" + QtNetworkSettings::winServerName() + "/testsharelargefile/file.bin"); |
|
1226 |
|
1227 { |
|
1228 // 1) Native file handling. |
|
1229 QFile file(largeFile); |
|
1230 QCOMPARE(file.size(), size); |
|
1231 QVERIFY(file.open(QIODevice::ReadOnly)); |
|
1232 QCOMPARE(file.size(), size); |
|
1233 QVERIFY(file.seek(dataOffset)); |
|
1234 QCOMPARE(file.read(knownData.size()), knownData); |
|
1235 } |
|
1236 { |
|
1237 // 2) stdlib file handling. |
|
1238 #if _MSC_VER <= 1310 |
|
1239 QSKIP("platform SDK for MSVC 2003 does not support large files", SkipAll); |
|
1240 #endif |
|
1241 QFile file; |
|
1242 FILE *fh = fopen(QFile::encodeName(largeFile).data(), "rb"); |
|
1243 QVERIFY(file.open(fh, QIODevice::ReadOnly)); |
|
1244 QCOMPARE(file.size(), size); |
|
1245 QVERIFY(file.seek(dataOffset)); |
|
1246 QCOMPARE(file.read(knownData.size()), knownData); |
|
1247 fclose(fh); |
|
1248 } |
|
1249 { |
|
1250 // 3) stdio file handling. |
|
1251 QFile file; |
|
1252 FILE *fh = fopen(QFile::encodeName(largeFile).data(), "rb"); |
|
1253 int fd = int(_fileno(fh)); |
|
1254 QVERIFY(file.open(fd, QIODevice::ReadOnly)); |
|
1255 QCOMPARE(file.size(), size); |
|
1256 QVERIFY(file.seek(dataOffset)); |
|
1257 QCOMPARE(file.read(knownData.size()), knownData); |
|
1258 fclose(fh); |
|
1259 } |
|
1260 } |
|
1261 #endif |
|
1262 |
|
1263 void tst_QFile::tailFile() |
|
1264 { |
|
1265 QSKIP("File change notifications are so far unsupported.", SkipAll); |
|
1266 |
|
1267 QFile file("tail.txt"); |
|
1268 QVERIFY(file.open(QFile::WriteOnly | QFile::Append)); |
|
1269 |
|
1270 QFile tailFile("tail.txt"); |
|
1271 QVERIFY(tailFile.open(QFile::ReadOnly)); |
|
1272 tailFile.seek(file.size()); |
|
1273 |
|
1274 QSignalSpy readSignal(&tailFile, SIGNAL(readyRead())); |
|
1275 |
|
1276 file.write("", 1); |
|
1277 |
|
1278 QTestEventLoop::instance().enterLoop(5); |
|
1279 |
|
1280 QVERIFY(!QTestEventLoop::instance().timeout()); |
|
1281 QCOMPARE(readSignal.count(), 1); |
|
1282 } |
|
1283 |
|
1284 void tst_QFile::flush() |
|
1285 { |
|
1286 QString fileName("stdfile.txt"); |
|
1287 |
|
1288 QFile::remove(fileName); |
|
1289 |
|
1290 { |
|
1291 QFile file(fileName); |
|
1292 QVERIFY(file.open(QFile::WriteOnly)); |
|
1293 QCOMPARE(file.write("abc", 3),qint64(3)); |
|
1294 } |
|
1295 |
|
1296 { |
|
1297 QFile file(fileName); |
|
1298 QVERIFY(file.open(QFile::WriteOnly | QFile::Append)); |
|
1299 QCOMPARE(file.pos(), qlonglong(3)); |
|
1300 QCOMPARE(file.write("def", 3), qlonglong(3)); |
|
1301 QCOMPARE(file.pos(), qlonglong(6)); |
|
1302 } |
|
1303 |
|
1304 { |
|
1305 QFile file("stdfile.txt"); |
|
1306 QVERIFY(file.open(QFile::ReadOnly)); |
|
1307 QCOMPARE(file.readAll(), QByteArray("abcdef")); |
|
1308 } |
|
1309 |
|
1310 QFile::remove(fileName); |
|
1311 } |
|
1312 |
|
1313 void tst_QFile::bufferedRead() |
|
1314 { |
|
1315 QFile::remove("stdfile.txt"); |
|
1316 |
|
1317 QFile file("stdfile.txt"); |
|
1318 QVERIFY(file.open(QFile::WriteOnly)); |
|
1319 file.write("abcdef"); |
|
1320 file.close(); |
|
1321 |
|
1322 #if defined(Q_OS_WINCE) |
|
1323 FILE *stdFile = fopen((QCoreApplication::applicationDirPath() + "/stdfile.txt").toAscii() , "r"); |
|
1324 #else |
|
1325 FILE *stdFile = fopen("stdfile.txt", "r"); |
|
1326 #endif |
|
1327 QVERIFY(stdFile); |
|
1328 char c; |
|
1329 QCOMPARE(int(fread(&c, 1, 1, stdFile)), 1); |
|
1330 QCOMPARE(c, 'a'); |
|
1331 QCOMPARE(int(ftell(stdFile)), 1); |
|
1332 |
|
1333 { |
|
1334 QFile file; |
|
1335 QVERIFY(file.open(stdFile, QFile::ReadOnly)); |
|
1336 QCOMPARE(file.pos(), qlonglong(1)); |
|
1337 QCOMPARE(file.read(&c, 1), qlonglong(1)); |
|
1338 QCOMPARE(c, 'b'); |
|
1339 QCOMPARE(file.pos(), qlonglong(2)); |
|
1340 } |
|
1341 |
|
1342 fclose(stdFile); |
|
1343 } |
|
1344 |
|
1345 void tst_QFile::isSequential() |
|
1346 { |
|
1347 #if defined (Q_OS_WIN) || defined(Q_OS_SYMBIAN) |
|
1348 QSKIP("Unix only test.", SkipAll); |
|
1349 #endif |
|
1350 |
|
1351 QFile zero("/dev/null"); |
|
1352 QVERIFY(zero.open(QFile::ReadOnly)); |
|
1353 QVERIFY(zero.isSequential()); |
|
1354 } |
|
1355 |
|
1356 void tst_QFile::encodeName() |
|
1357 { |
|
1358 QCOMPARE(QFile::encodeName(QString::null), QByteArray()); |
|
1359 } |
|
1360 |
|
1361 void tst_QFile::truncate() |
|
1362 { |
|
1363 for (int i = 0; i < 2; ++i) { |
|
1364 QFile file("truncate.txt"); |
|
1365 QVERIFY(file.open(QFile::WriteOnly)); |
|
1366 file.write(QByteArray(200, '@')); |
|
1367 file.close(); |
|
1368 |
|
1369 QVERIFY(file.open((i ? QFile::WriteOnly : QFile::ReadWrite) | QFile::Truncate)); |
|
1370 file.write(QByteArray(100, '$')); |
|
1371 file.close(); |
|
1372 |
|
1373 QVERIFY(file.open(QFile::ReadOnly)); |
|
1374 QCOMPARE(file.readAll(), QByteArray(100, '$')); |
|
1375 } |
|
1376 } |
|
1377 |
|
1378 void tst_QFile::seekToPos() |
|
1379 { |
|
1380 { |
|
1381 QFile file("seekToPos.txt"); |
|
1382 QVERIFY(file.open(QFile::WriteOnly)); |
|
1383 file.write("a\r\nb\r\nc\r\n"); |
|
1384 file.flush(); |
|
1385 } |
|
1386 |
|
1387 QFile file("seekToPos.txt"); |
|
1388 QVERIFY(file.open(QFile::ReadOnly | QFile::Text)); |
|
1389 file.seek(1); |
|
1390 char c; |
|
1391 QVERIFY(file.getChar(&c)); |
|
1392 QCOMPARE(c, '\n'); |
|
1393 |
|
1394 QCOMPARE(file.pos(), qint64(3)); |
|
1395 file.seek(file.pos()); |
|
1396 QCOMPARE(file.pos(), qint64(3)); |
|
1397 |
|
1398 file.seek(1); |
|
1399 file.seek(file.pos()); |
|
1400 QCOMPARE(file.pos(), qint64(1)); |
|
1401 |
|
1402 } |
|
1403 |
|
1404 |
|
1405 void tst_QFile::FILEReadWrite() |
|
1406 { |
|
1407 // Tests modifing a file. First creates it then reads in 4 bytes and then overwrites these |
|
1408 // 4 bytes with new values. At the end check to see the file contains the new values. |
|
1409 |
|
1410 QFile::remove("FILEReadWrite.txt"); |
|
1411 |
|
1412 // create test file |
|
1413 { |
|
1414 QFile f("FILEReadWrite.txt"); |
|
1415 QVERIFY(f.open(QFile::WriteOnly)); |
|
1416 QDataStream ds(&f); |
|
1417 qint8 c = 0; |
|
1418 ds << c; |
|
1419 c = 1; |
|
1420 ds << c; |
|
1421 c = 2; |
|
1422 ds << c; |
|
1423 c = 3; |
|
1424 ds << c; |
|
1425 c = 4; |
|
1426 ds << c; |
|
1427 c = 5; |
|
1428 ds << c; |
|
1429 c = 6; |
|
1430 ds << c; |
|
1431 c = 7; |
|
1432 ds << c; |
|
1433 c = 8; |
|
1434 ds << c; |
|
1435 c = 9; |
|
1436 ds << c; |
|
1437 c = 10; |
|
1438 ds << c; |
|
1439 c = 11; |
|
1440 ds << c; |
|
1441 f.close(); |
|
1442 } |
|
1443 |
|
1444 #ifdef Q_OS_WINCE |
|
1445 FILE *fp = fopen(qPrintable(QCoreApplication::applicationDirPath() + "\\FILEReadWrite.txt"), "r+b"); |
|
1446 #else |
|
1447 FILE *fp = fopen("FILEReadWrite.txt", "r+b"); |
|
1448 #endif |
|
1449 QVERIFY(fp); |
|
1450 QFile file; |
|
1451 QVERIFY(file.open(fp, QFile::ReadWrite)); |
|
1452 QDataStream sfile(&file) ; |
|
1453 |
|
1454 qint8 var1,var2,var3,var4; |
|
1455 while (!sfile.atEnd()) |
|
1456 { |
|
1457 qint64 base = file.pos(); |
|
1458 |
|
1459 QCOMPARE(file.pos(), base + 0); |
|
1460 sfile >> var1; |
|
1461 QCOMPARE(file.pos(), base + 1); |
|
1462 file.flush(); // flushing should not change the base |
|
1463 QCOMPARE(file.pos(), base + 1); |
|
1464 sfile >> var2; |
|
1465 QCOMPARE(file.pos(), base + 2); |
|
1466 sfile >> var3; |
|
1467 QCOMPARE(file.pos(), base + 3); |
|
1468 sfile >> var4; |
|
1469 QCOMPARE(file.pos(), base + 4); |
|
1470 file.seek(file.pos() - 4) ; // Move it back 4, for we are going to write new values based on old ones |
|
1471 QCOMPARE(file.pos(), base + 0); |
|
1472 sfile << qint8(var1 + 5); |
|
1473 QCOMPARE(file.pos(), base + 1); |
|
1474 sfile << qint8(var2 + 5); |
|
1475 QCOMPARE(file.pos(), base + 2); |
|
1476 sfile << qint8(var3 + 5); |
|
1477 QCOMPARE(file.pos(), base + 3); |
|
1478 sfile << qint8(var4 + 5); |
|
1479 QCOMPARE(file.pos(), base + 4); |
|
1480 |
|
1481 } |
|
1482 file.close(); |
|
1483 fclose(fp); |
|
1484 |
|
1485 // check modified file |
|
1486 { |
|
1487 QFile f("FILEReadWrite.txt"); |
|
1488 QVERIFY(f.open(QFile::ReadOnly)); |
|
1489 QDataStream ds(&f); |
|
1490 qint8 c = 0; |
|
1491 ds >> c; |
|
1492 QCOMPARE(c, (qint8)5); |
|
1493 ds >> c; |
|
1494 QCOMPARE(c, (qint8)6); |
|
1495 ds >> c; |
|
1496 QCOMPARE(c, (qint8)7); |
|
1497 ds >> c; |
|
1498 QCOMPARE(c, (qint8)8); |
|
1499 ds >> c; |
|
1500 QCOMPARE(c, (qint8)9); |
|
1501 ds >> c; |
|
1502 QCOMPARE(c, (qint8)10); |
|
1503 ds >> c; |
|
1504 QCOMPARE(c, (qint8)11); |
|
1505 ds >> c; |
|
1506 QCOMPARE(c, (qint8)12); |
|
1507 ds >> c; |
|
1508 QCOMPARE(c, (qint8)13); |
|
1509 ds >> c; |
|
1510 QCOMPARE(c, (qint8)14); |
|
1511 ds >> c; |
|
1512 QCOMPARE(c, (qint8)15); |
|
1513 ds >> c; |
|
1514 QCOMPARE(c, (qint8)16); |
|
1515 f.close(); |
|
1516 } |
|
1517 |
|
1518 QFile::remove("FILEReadWrite.txt"); |
|
1519 } |
|
1520 |
|
1521 |
|
1522 /* |
|
1523 #include <qglobal.h> |
|
1524 #define BUFFSIZE 1 |
|
1525 #define FILESIZE 0x10000000f |
|
1526 void tst_QFile::largeFileSupport() |
|
1527 { |
|
1528 #ifdef Q_OS_SOLARIS |
|
1529 QSKIP("Solaris does not support statfs", SkipAll); |
|
1530 #else |
|
1531 qlonglong sizeNeeded = 2147483647; |
|
1532 sizeNeeded *= 2; |
|
1533 sizeNeeded += 1024; |
|
1534 qlonglong freespace = qlonglong(0); |
|
1535 #ifdef Q_WS_WIN |
|
1536 _ULARGE_INTEGER free; |
|
1537 if (::GetDiskFreeSpaceEx((wchar_t*)QDir::currentPath().utf16(), &free, 0, 0)) |
|
1538 freespace = free.QuadPart; |
|
1539 if (freespace != 0) { |
|
1540 #elif defined(Q_OS_IRIX) |
|
1541 struct statfs info; |
|
1542 if (statfs(QDir::currentPath().local8Bit(), &info, sizeof(struct statfs), 0) == 0) { |
|
1543 freespace = qlonglong(info.f_bfree * info.f_bsize); |
|
1544 #else |
|
1545 struct statfs info; |
|
1546 if (statfs(const_cast<char *>(QDir::currentPath().toLocal8Bit().constData()), &info) == 0) { |
|
1547 freespace = qlonglong(info.f_bavail * info.f_bsize); |
|
1548 #endif |
|
1549 if (freespace > sizeNeeded) { |
|
1550 QFile bigFile("bigfile"); |
|
1551 if (bigFile.open(QFile::ReadWrite)) { |
|
1552 char c[BUFFSIZE] = {'a'}; |
|
1553 QVERIFY(bigFile.write(c, BUFFSIZE) == BUFFSIZE); |
|
1554 qlonglong oldPos = bigFile.pos(); |
|
1555 QVERIFY(bigFile.resize(sizeNeeded)); |
|
1556 QCOMPARE(oldPos, bigFile.pos()); |
|
1557 QVERIFY(bigFile.seek(sizeNeeded - BUFFSIZE)); |
|
1558 QVERIFY(bigFile.write(c, BUFFSIZE) == BUFFSIZE); |
|
1559 |
|
1560 bigFile.close(); |
|
1561 if (bigFile.open(QFile::ReadOnly)) { |
|
1562 QVERIFY(bigFile.read(c, BUFFSIZE) == BUFFSIZE); |
|
1563 int i = 0; |
|
1564 for (i=0; i<BUFFSIZE; i++) |
|
1565 QCOMPARE(c[i], 'a'); |
|
1566 QVERIFY(bigFile.seek(sizeNeeded - BUFFSIZE)); |
|
1567 QVERIFY(bigFile.read(c, BUFFSIZE) == BUFFSIZE); |
|
1568 for (i=0; i<BUFFSIZE; i++) |
|
1569 QCOMPARE(c[i], 'a'); |
|
1570 bigFile.close(); |
|
1571 QVERIFY(bigFile.remove()); |
|
1572 } else { |
|
1573 QVERIFY(bigFile.remove()); |
|
1574 QFAIL("Could not reopen file"); |
|
1575 } |
|
1576 } else { |
|
1577 QFAIL("Could not open file"); |
|
1578 } |
|
1579 } else { |
|
1580 QSKIP("Not enough space to run test", SkipSingle); |
|
1581 } |
|
1582 } else { |
|
1583 QFAIL("Could not determin disk space"); |
|
1584 } |
|
1585 #endif |
|
1586 } |
|
1587 */ |
|
1588 |
|
1589 void tst_QFile::i18nFileName_data() |
|
1590 { |
|
1591 QTest::addColumn<QString>("fileName"); |
|
1592 |
|
1593 QTest::newRow( "01" ) << QString::fromUtf8("xxxxxxx.txt"); |
|
1594 } |
|
1595 |
|
1596 void tst_QFile::i18nFileName() |
|
1597 { |
|
1598 QFETCH(QString, fileName); |
|
1599 if (QFile::exists(fileName)) { |
|
1600 QVERIFY(QFile::remove(fileName)); |
|
1601 } |
|
1602 { |
|
1603 QFile file(fileName); |
|
1604 QVERIFY(file.open(QFile::WriteOnly | QFile::Text)); |
|
1605 QTextStream ts(&file); |
|
1606 ts.setCodec("UTF-8"); |
|
1607 ts << fileName << endl; |
|
1608 } |
|
1609 { |
|
1610 QFile file(fileName); |
|
1611 QVERIFY(file.open(QFile::ReadOnly | QFile::Text)); |
|
1612 QTextStream ts(&file); |
|
1613 ts.setCodec("UTF-8"); |
|
1614 QString line = ts.readLine(); |
|
1615 QCOMPARE(line, fileName); |
|
1616 } |
|
1617 QVERIFY(QFile::remove(fileName)); |
|
1618 } |
|
1619 |
|
1620 |
|
1621 void tst_QFile::longFileName_data() |
|
1622 { |
|
1623 QTest::addColumn<QString>("fileName"); |
|
1624 |
|
1625 QTest::newRow( "16 chars" ) << QString::fromLatin1("longFileName.txt"); |
|
1626 QTest::newRow( "52 chars" ) << QString::fromLatin1("longFileNamelongFileNamelongFileNamelongFileName.txt"); |
|
1627 QTest::newRow( "148 chars" ) << QString::fromLatin1("longFileNamelongFileNamelongFileNamelongFileName" |
|
1628 "longFileNamelongFileNamelongFileNamelongFileName" |
|
1629 "longFileNamelongFileNamelongFileNamelongFileName.txt"); |
|
1630 QTest::newRow( "244 chars" ) << QString::fromLatin1("longFileNamelongFileNamelongFileNamelongFileName" |
|
1631 "longFileNamelongFileNamelongFileNamelongFileName" |
|
1632 "longFileNamelongFileNamelongFileNamelongFileName" |
|
1633 "longFileNamelongFileNamelongFileNamelongFileName" |
|
1634 "longFileNamelongFileNamelongFileNamelongFileName.txt"); |
|
1635 QTest::newRow( "244 chars to absolutepath" ) << QFileInfo(QString::fromLatin1("longFileNamelongFileNamelongFileNamelongFileName" |
|
1636 "longFileNamelongFileNamelongFileNamelongFileName" |
|
1637 "longFileNamelongFileNamelongFileNamelongFileName" |
|
1638 "longFileNamelongFileNamelongFileNamelongFileName" |
|
1639 "longFileNamelongFileNamelongFileNamelongFileName.txt")).absoluteFilePath(); |
|
1640 /* needs to be put on a windows 2000 > test machine |
|
1641 QTest::newRow( "244 chars on UNC" ) << QString::fromLatin1("//arsia/D/troll/tmp/longFileNamelongFileNamelongFileNamelongFileName" |
|
1642 "longFileNamelongFileNamelongFileNamelongFileName" |
|
1643 "longFileNamelongFileNamelongFileNamelongFileName" |
|
1644 "longFileNamelongFileNamelongFileNamelongFileName" |
|
1645 "longFileNamelongFileNamelongFileNamelongFileName.txt");*/ |
|
1646 } |
|
1647 |
|
1648 void tst_QFile::longFileName() |
|
1649 { |
|
1650 QFETCH(QString, fileName); |
|
1651 if (QFile::exists(fileName)) { |
|
1652 QVERIFY(QFile::remove(fileName)); |
|
1653 } |
|
1654 { |
|
1655 QFile file(fileName); |
|
1656 #if defined(Q_OS_WINCE) || defined(Q_OS_SYMBIAN) |
|
1657 QEXPECT_FAIL("244 chars", "Full pathname must be less than 260 chars", Abort); |
|
1658 QEXPECT_FAIL("244 chars to absolutepath", "Full pathname must be less than 260 chars", Abort); |
|
1659 #endif |
|
1660 QVERIFY(file.open(QFile::WriteOnly | QFile::Text)); |
|
1661 QTextStream ts(&file); |
|
1662 ts << fileName << endl; |
|
1663 } |
|
1664 { |
|
1665 QFile file(fileName); |
|
1666 QVERIFY(file.open(QFile::ReadOnly | QFile::Text)); |
|
1667 QTextStream ts(&file); |
|
1668 QString line = ts.readLine(); |
|
1669 QCOMPARE(line, fileName); |
|
1670 } |
|
1671 QString newName = fileName + QLatin1String("1"); |
|
1672 { |
|
1673 QVERIFY(QFile::copy(fileName, newName)); |
|
1674 QFile file(newName); |
|
1675 QVERIFY(file.open(QFile::ReadOnly | QFile::Text)); |
|
1676 QTextStream ts(&file); |
|
1677 QString line = ts.readLine(); |
|
1678 QCOMPARE(line, fileName); |
|
1679 |
|
1680 } |
|
1681 QVERIFY(QFile::remove(newName)); |
|
1682 { |
|
1683 QVERIFY(QFile::rename(fileName, newName)); |
|
1684 QFile file(newName); |
|
1685 QVERIFY(file.open(QFile::ReadOnly | QFile::Text)); |
|
1686 QTextStream ts(&file); |
|
1687 QString line = ts.readLine(); |
|
1688 QCOMPARE(line, fileName); |
|
1689 } |
|
1690 QVERIFY(QFile::exists(newName)); |
|
1691 QVERIFY(QFile::remove(newName)); |
|
1692 } |
|
1693 |
|
1694 class MyEngine : public QAbstractFileEngine |
|
1695 { |
|
1696 public: |
|
1697 MyEngine(int n) { number = n; } |
|
1698 virtual ~MyEngine() {} |
|
1699 |
|
1700 void setFileName(const QString &) {} |
|
1701 bool open(int ) { return false; } |
|
1702 bool close() { return false; } |
|
1703 bool flush() { return false; } |
|
1704 qint64 size() const { return 123 + number; } |
|
1705 qint64 at() const { return -1; } |
|
1706 bool seek(qint64) { return false; } |
|
1707 bool isSequential() const { return false; } |
|
1708 qint64 read(char *, qint64) { return -1; } |
|
1709 qint64 write(const char *, qint64) { return -1; } |
|
1710 bool remove() { return false; } |
|
1711 bool copy(const QString &) { return false; } |
|
1712 bool rename(const QString &) { return false; } |
|
1713 bool link(const QString &) { return false; } |
|
1714 bool mkdir(const QString &, bool) const { return false; } |
|
1715 bool rmdir(const QString &, bool) const { return false; } |
|
1716 bool setSize(qint64) { return false; } |
|
1717 QStringList entryList(QDir::Filters, const QStringList &) const { return QStringList(); } |
|
1718 bool caseSensitive() const { return false; } |
|
1719 bool isRelativePath() const { return false; } |
|
1720 FileFlags fileFlags(FileFlags) const { return 0; } |
|
1721 bool chmod(uint) { return false; } |
|
1722 QString fileName(FileName) const { return name; } |
|
1723 uint ownerId(FileOwner) const { return 0; } |
|
1724 QString owner(FileOwner) const { return QString(); } |
|
1725 QDateTime fileTime(FileTime) const { return QDateTime(); } |
|
1726 |
|
1727 private: |
|
1728 int number; |
|
1729 QString name; |
|
1730 }; |
|
1731 |
|
1732 class MyHandler : public QAbstractFileEngineHandler |
|
1733 { |
|
1734 public: |
|
1735 inline QAbstractFileEngine *create(const QString &) const |
|
1736 { |
|
1737 return new MyEngine(1); |
|
1738 } |
|
1739 }; |
|
1740 |
|
1741 class MyHandler2 : public QAbstractFileEngineHandler |
|
1742 { |
|
1743 public: |
|
1744 inline QAbstractFileEngine *create(const QString &) const |
|
1745 { |
|
1746 return new MyEngine(2); |
|
1747 } |
|
1748 }; |
|
1749 |
|
1750 void tst_QFile::fileEngineHandler() |
|
1751 { |
|
1752 // A file that does not exist has a size of 0. |
|
1753 QFile::remove("ole.bull"); |
|
1754 QFile file("ole.bull"); |
|
1755 QCOMPARE(file.size(), qint64(0)); |
|
1756 |
|
1757 // Instantiating our handler will enable the new engine. |
|
1758 MyHandler handler; |
|
1759 file.setFileName("ole.bull"); |
|
1760 QCOMPARE(file.size(), qint64(124)); |
|
1761 |
|
1762 // A new, identical handler should take preference over the last one. |
|
1763 MyHandler2 handler2; |
|
1764 file.setFileName("ole.bull"); |
|
1765 QCOMPARE(file.size(), qint64(125)); |
|
1766 |
|
1767 } |
|
1768 |
|
1769 class MyRecursiveHandler : public QAbstractFileEngineHandler |
|
1770 { |
|
1771 public: |
|
1772 inline QAbstractFileEngine *create(const QString &fileName) const |
|
1773 { |
|
1774 if (fileName.startsWith(":!")) { |
|
1775 QDir dir; |
|
1776 QString realFile = SRCDIR + fileName.mid(2); |
|
1777 if (dir.exists(realFile)) |
|
1778 return new QFSFileEngine(realFile); |
|
1779 } |
|
1780 return 0; |
|
1781 } |
|
1782 }; |
|
1783 |
|
1784 void tst_QFile::useQFileInAFileHandler() |
|
1785 { |
|
1786 // This test should not dead-lock |
|
1787 MyRecursiveHandler handler; |
|
1788 QFile file(":!tst_qfile.cpp"); |
|
1789 QVERIFY(file.exists()); |
|
1790 } |
|
1791 |
|
1792 void tst_QFile::getCharFF() |
|
1793 { |
|
1794 QFile file("file.txt"); |
|
1795 file.open(QFile::ReadWrite); |
|
1796 file.write("\xff\xff\xff"); |
|
1797 file.flush(); |
|
1798 file.seek(0); |
|
1799 |
|
1800 char c; |
|
1801 QVERIFY(file.getChar(&c)); |
|
1802 QVERIFY(file.getChar(&c)); |
|
1803 QVERIFY(file.getChar(&c)); |
|
1804 } |
|
1805 |
|
1806 void tst_QFile::remove_and_exists() |
|
1807 { |
|
1808 QFile::remove("tull_i_grunn.txt"); |
|
1809 QFile f("tull_i_grunn.txt"); |
|
1810 |
|
1811 QVERIFY(!f.exists()); |
|
1812 |
|
1813 bool opened = f.open(QIODevice::WriteOnly); |
|
1814 QVERIFY(opened); |
|
1815 |
|
1816 f.write(QString("testing that remove/exists work...").toLatin1()); |
|
1817 f.close(); |
|
1818 |
|
1819 QVERIFY(f.exists()); |
|
1820 |
|
1821 f.remove(); |
|
1822 QVERIFY(!f.exists()); |
|
1823 } |
|
1824 |
|
1825 void tst_QFile::removeOpenFile() |
|
1826 { |
|
1827 { |
|
1828 // remove an opened, write-only file |
|
1829 QFile::remove("remove_unclosed.txt"); |
|
1830 QFile f("remove_unclosed.txt"); |
|
1831 |
|
1832 QVERIFY(!f.exists()); |
|
1833 bool opened = f.open(QIODevice::WriteOnly); |
|
1834 QVERIFY(opened); |
|
1835 f.write(QString("testing that remove closes the file first...").toLatin1()); |
|
1836 |
|
1837 bool removed = f.remove(); // remove should both close and remove the file |
|
1838 QVERIFY(removed); |
|
1839 QVERIFY(!f.isOpen()); |
|
1840 QVERIFY(!f.exists()); |
|
1841 QVERIFY(f.error() == QFile::NoError); |
|
1842 } |
|
1843 |
|
1844 { |
|
1845 // remove an opened, read-only file |
|
1846 QFile::remove("remove_unclosed.txt"); |
|
1847 |
|
1848 // first, write a file that we can remove |
|
1849 { |
|
1850 QFile f("remove_unclosed.txt"); |
|
1851 QVERIFY(!f.exists()); |
|
1852 bool opened = f.open(QIODevice::WriteOnly); |
|
1853 QVERIFY(opened); |
|
1854 f.write(QString("testing that remove closes the file first...").toLatin1()); |
|
1855 f.close(); |
|
1856 } |
|
1857 |
|
1858 QFile f("remove_unclosed.txt"); |
|
1859 bool opened = f.open(QIODevice::ReadOnly); |
|
1860 QVERIFY(opened); |
|
1861 f.readAll(); |
|
1862 // this used to only fail on FreeBSD (and Mac OS X) |
|
1863 QVERIFY(f.flush()); |
|
1864 bool removed = f.remove(); // remove should both close and remove the file |
|
1865 QVERIFY(removed); |
|
1866 QVERIFY(!f.isOpen()); |
|
1867 QVERIFY(!f.exists()); |
|
1868 QVERIFY(f.error() == QFile::NoError); |
|
1869 } |
|
1870 } |
|
1871 |
|
1872 void tst_QFile::fullDisk() |
|
1873 { |
|
1874 QFile file("/dev/full"); |
|
1875 if (!file.exists()) |
|
1876 QSKIP("/dev/full doesn't exist on this system", SkipAll); |
|
1877 |
|
1878 QVERIFY(file.open(QIODevice::WriteOnly)); |
|
1879 file.write("foobar", 6); |
|
1880 |
|
1881 QVERIFY(!file.flush()); |
|
1882 QCOMPARE(file.error(), QFile::ResourceError); |
|
1883 QVERIFY(!file.flush()); |
|
1884 QCOMPARE(file.error(), QFile::ResourceError); |
|
1885 |
|
1886 char c = 0; |
|
1887 file.write(&c, 0); |
|
1888 QVERIFY(!file.flush()); |
|
1889 QCOMPARE(file.error(), QFile::ResourceError); |
|
1890 file.write(&c, 1); |
|
1891 QVERIFY(!file.flush()); |
|
1892 QCOMPARE(file.error(), QFile::ResourceError); |
|
1893 |
|
1894 file.close(); |
|
1895 QVERIFY(!file.isOpen()); |
|
1896 QCOMPARE(file.error(), QFile::ResourceError); |
|
1897 file.open(QIODevice::WriteOnly); |
|
1898 QCOMPARE(file.error(), QFile::NoError); |
|
1899 file.close(); |
|
1900 QCOMPARE(file.error(), QFile::NoError); |
|
1901 |
|
1902 // try again without flush: |
|
1903 QVERIFY(file.open(QIODevice::WriteOnly)); |
|
1904 file.write("foobar", 6); |
|
1905 file.close(); |
|
1906 QVERIFY(file.error() != QFile::NoError); |
|
1907 } |
|
1908 |
|
1909 void tst_QFile::writeLargeDataBlock_data() |
|
1910 { |
|
1911 QTest::addColumn<QString>("fileName"); |
|
1912 |
|
1913 QTest::newRow("localfile") << QString("./largeblockfile.txt"); |
|
1914 #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) |
|
1915 // Some semi-randomness to avoid collisions. |
|
1916 QTest::newRow("unc file") |
|
1917 << QString("//" + QtNetworkSettings::winServerName() + "/TESTSHAREWRITABLE/largefile-%1-%2.txt") |
|
1918 .arg(QHostInfo::localHostName()) |
|
1919 .arg(QTime::currentTime().msec()); |
|
1920 #endif |
|
1921 } |
|
1922 |
|
1923 void tst_QFile::writeLargeDataBlock() |
|
1924 { |
|
1925 QFETCH(QString, fileName); |
|
1926 |
|
1927 // Generate a 64MB array with well defined contents. |
|
1928 QByteArray array; |
|
1929 #if defined(Q_OS_WINCE) || defined(Q_OS_SYMBIAN) |
|
1930 int resizeSize = 1024 * 1024; // WinCE and Symbian do not have much space |
|
1931 #else |
|
1932 int resizeSize = 64 * 1024 * 1024; |
|
1933 #endif |
|
1934 array.resize(resizeSize); |
|
1935 for (int i = 0; i < array.size(); ++i) |
|
1936 array[i] = uchar(i); |
|
1937 |
|
1938 // Remove and open the target file |
|
1939 QFile file(fileName); |
|
1940 file.remove(); |
|
1941 if (file.open(QFile::WriteOnly)) { |
|
1942 QCOMPARE(file.write(array), qint64(array.size())); |
|
1943 file.close(); |
|
1944 QVERIFY(file.open(QFile::ReadOnly)); |
|
1945 array.clear(); |
|
1946 array = file.readAll(); |
|
1947 file.remove(); |
|
1948 } else { |
|
1949 QFAIL(qPrintable(QString("Couldn't open file for writing: [%1]").arg(fileName))); |
|
1950 } |
|
1951 // Check that we got the right content |
|
1952 QCOMPARE(array.size(), resizeSize); |
|
1953 for (int i = 0; i < array.size(); ++i) { |
|
1954 if (array[i] != char(i)) { |
|
1955 QFAIL(qPrintable(QString("Wrong contents! Char at %1 = %2, expected %3") |
|
1956 .arg(i).arg(int(uchar(array[i]))).arg(int(uchar(i))))); |
|
1957 } |
|
1958 } |
|
1959 } |
|
1960 |
|
1961 void tst_QFile::readFromWriteOnlyFile() |
|
1962 { |
|
1963 QFile file("writeonlyfile"); |
|
1964 QVERIFY(file.open(QFile::WriteOnly)); |
|
1965 char c; |
|
1966 QTest::ignoreMessage(QtWarningMsg, "QIODevice::read: WriteOnly device"); |
|
1967 QCOMPARE(file.read(&c, 1), qint64(-1)); |
|
1968 } |
|
1969 |
|
1970 void tst_QFile::writeToReadOnlyFile() |
|
1971 { |
|
1972 QFile file("readonlyfile"); |
|
1973 QVERIFY(file.open(QFile::ReadOnly)); |
|
1974 char c = 0; |
|
1975 QTest::ignoreMessage(QtWarningMsg, "QIODevice::write: ReadOnly device"); |
|
1976 QCOMPARE(file.write(&c, 1), qint64(-1)); |
|
1977 } |
|
1978 |
|
1979 void tst_QFile::virtualFile() |
|
1980 { |
|
1981 // test if QFile works with virtual files |
|
1982 QString fname; |
|
1983 #if defined(Q_OS_LINUX) |
|
1984 fname = "/proc/self/maps"; |
|
1985 #elif defined(Q_OS_AIX) |
|
1986 fname = QString("/proc/%1/map").arg(getpid()); |
|
1987 #elif defined(Q_OS_FREEBSD) || defined(Q_OS_NETBSD) |
|
1988 fname = "/proc/curproc/map"; |
|
1989 #else |
|
1990 QSKIP("This platform does not have 0-sized virtual files", SkipAll); |
|
1991 #endif |
|
1992 |
|
1993 // consistency check |
|
1994 QFileInfo fi(fname); |
|
1995 QVERIFY(fi.exists()); |
|
1996 QVERIFY(fi.isFile()); |
|
1997 QCOMPARE(fi.size(), Q_INT64_C(0)); |
|
1998 |
|
1999 // open the file |
|
2000 QFile f(fname); |
|
2001 QVERIFY(f.open(QIODevice::ReadOnly)); |
|
2002 QCOMPARE(f.size(), Q_INT64_C(0)); |
|
2003 QVERIFY(f.atEnd()); |
|
2004 |
|
2005 // read data |
|
2006 QByteArray data = f.read(16); |
|
2007 QCOMPARE(data.size(), 16); |
|
2008 QCOMPARE(f.pos(), Q_INT64_C(16)); |
|
2009 |
|
2010 // line-reading |
|
2011 data = f.readLine(); |
|
2012 QVERIFY(!data.isEmpty()); |
|
2013 |
|
2014 // read all: |
|
2015 data = f.readAll(); |
|
2016 QVERIFY(f.pos() != 0); |
|
2017 QVERIFY(!data.isEmpty()); |
|
2018 |
|
2019 // seeking |
|
2020 QVERIFY(f.seek(1)); |
|
2021 QCOMPARE(f.pos(), Q_INT64_C(1)); |
|
2022 } |
|
2023 |
|
2024 void tst_QFile::textFile() |
|
2025 { |
|
2026 #if defined(Q_OS_WINCE) |
|
2027 FILE *fs = ::fopen((QCoreApplication::applicationDirPath() + "/writeabletextfile").toAscii() , "wt"); |
|
2028 #elif defined(Q_OS_WIN) |
|
2029 FILE *fs = ::fopen("writeabletextfile", "wt"); |
|
2030 #else |
|
2031 FILE *fs = ::fopen("writeabletextfile", "w"); |
|
2032 #endif |
|
2033 QFile f; |
|
2034 QByteArray part1("This\nis\na\nfile\nwith\nnewlines\n"); |
|
2035 QByteArray part2("Add\nsome\nmore\nnewlines\n"); |
|
2036 |
|
2037 QVERIFY(f.open(fs, QIODevice::WriteOnly)); |
|
2038 f.write(part1); |
|
2039 f.write(part2); |
|
2040 f.close(); |
|
2041 ::fclose(fs); |
|
2042 |
|
2043 QFile file("writeabletextfile"); |
|
2044 QVERIFY(file.open(QIODevice::ReadOnly)); |
|
2045 |
|
2046 QByteArray data = file.readAll(); |
|
2047 |
|
2048 QByteArray expected = part1 + part2; |
|
2049 #ifdef Q_OS_WIN |
|
2050 expected.replace("\n", "\015\012"); |
|
2051 #endif |
|
2052 QCOMPARE(data, expected); |
|
2053 file.close(); |
|
2054 file.remove(); |
|
2055 } |
|
2056 |
|
2057 void tst_QFile::rename_data() |
|
2058 { |
|
2059 QTest::addColumn<QString>("source"); |
|
2060 QTest::addColumn<QString>("destination"); |
|
2061 QTest::addColumn<bool>("result"); |
|
2062 |
|
2063 QTest::newRow("a -> b") << QString("a") << QString("b") << false; |
|
2064 QTest::newRow("a -> .") << QString("a") << QString(".") << false; |
|
2065 QTest::newRow("renamefile -> renamefile") << QString("renamefile") << QString("renamefile") << false; |
|
2066 QTest::newRow("renamefile -> Makefile") << QString("renamefile") << QString("Makefile") << false; |
|
2067 #if defined(Q_OS_UNIX) && !defined(Q_OS_SYMBIAN) |
|
2068 QTest::newRow("renamefile -> /etc/renamefile") << QString("renamefile") << QString("/etc/renamefile") << false; |
|
2069 #endif |
|
2070 QTest::newRow("renamefile -> renamedfile") << QString("renamefile") << QString("renamedfile") << true; |
|
2071 QTest::newRow("renamefile -> ..") << QString("renamefile") << QString("..") << false; |
|
2072 } |
|
2073 |
|
2074 void tst_QFile::rename() |
|
2075 { |
|
2076 QFETCH(QString, source); |
|
2077 QFETCH(QString, destination); |
|
2078 QFETCH(bool, result); |
|
2079 |
|
2080 QFile::remove("renamedfile"); |
|
2081 QFile f("renamefile"); |
|
2082 f.open(QFile::WriteOnly); |
|
2083 f.close(); |
|
2084 |
|
2085 QFile file(source); |
|
2086 QCOMPARE(file.rename(destination), result); |
|
2087 if (result) |
|
2088 QCOMPARE(file.error(), QFile::NoError); |
|
2089 else |
|
2090 QCOMPARE(file.error(), QFile::RenameError); |
|
2091 |
|
2092 QFile::remove("renamefile"); |
|
2093 } |
|
2094 |
|
2095 /*! |
|
2096 \since 4.5 |
|
2097 |
|
2098 Some special files have QFile::atEnd() returning true, even though there is |
|
2099 more data available. True for corner cases, as well as some mounts on OS X. |
|
2100 |
|
2101 Here, we reproduce that condition by having a QFile sub-class with this |
|
2102 peculiar atEnd() behavior. |
|
2103 |
|
2104 See task 231583. |
|
2105 */ |
|
2106 void tst_QFile::renameWithAtEndSpecialFile() const |
|
2107 { |
|
2108 class PeculiarAtEnd : public QFile |
|
2109 { |
|
2110 public: |
|
2111 virtual bool atEnd() const |
|
2112 { |
|
2113 return true; |
|
2114 } |
|
2115 }; |
|
2116 |
|
2117 const QString newName(QLatin1String("newName.txt")); |
|
2118 /* Cleanup, so we're a bit more robust. */ |
|
2119 QFile::remove(newName); |
|
2120 |
|
2121 const QString originalName(QString(SRCDIR "forRenaming.txt")); |
|
2122 |
|
2123 PeculiarAtEnd file; |
|
2124 file.setFileName(originalName); |
|
2125 QVERIFY(file.open(QIODevice::ReadOnly)); |
|
2126 |
|
2127 QVERIFY(file.rename(newName)); |
|
2128 |
|
2129 file.close(); |
|
2130 /* Guess what, we have to rename it back, otherwise we'll fail on second |
|
2131 * invocation. */ |
|
2132 QVERIFY(QFile::rename(newName, originalName)); |
|
2133 } |
|
2134 |
|
2135 void tst_QFile::renameFallback() |
|
2136 { |
|
2137 // Using a resource file both to trigger QFile::rename's fallback handling |
|
2138 // and as a *read-only* source whose move should fail. |
|
2139 QFile file(":/rename-fallback.qrc"); |
|
2140 QVERIFY(file.exists() && "(test-precondition)"); |
|
2141 QFile::remove("file-rename-destination.txt"); |
|
2142 |
|
2143 QVERIFY(!file.rename("file-rename-destination.txt")); |
|
2144 QVERIFY(!QFile::exists("file-rename-destination.txt")); |
|
2145 QVERIFY(!file.isOpen()); |
|
2146 } |
|
2147 |
|
2148 void tst_QFile::renameMultiple() |
|
2149 { |
|
2150 // create the file if it doesn't exist |
|
2151 QFile file("file-to-be-renamed.txt"); |
|
2152 QFile file2("existing-file.txt"); |
|
2153 QVERIFY(file.open(QIODevice::ReadWrite) && "(test-precondition)"); |
|
2154 QVERIFY(file2.open(QIODevice::ReadWrite) && "(test-precondition)"); |
|
2155 |
|
2156 // any stale files from previous test failures? |
|
2157 QFile::remove("file-renamed-once.txt"); |
|
2158 QFile::remove("file-renamed-twice.txt"); |
|
2159 |
|
2160 // begin testing |
|
2161 QVERIFY(QFile::exists("existing-file.txt")); |
|
2162 QVERIFY(!file.rename("existing-file.txt")); |
|
2163 QCOMPARE(file.error(), QFile::RenameError); |
|
2164 QCOMPARE(file.fileName(), QString("file-to-be-renamed.txt")); |
|
2165 |
|
2166 QVERIFY(file.rename("file-renamed-once.txt")); |
|
2167 QVERIFY(!file.isOpen()); |
|
2168 QCOMPARE(file.fileName(), QString("file-renamed-once.txt")); |
|
2169 |
|
2170 QVERIFY(QFile::exists("existing-file.txt")); |
|
2171 QVERIFY(!file.rename("existing-file.txt")); |
|
2172 QCOMPARE(file.error(), QFile::RenameError); |
|
2173 QCOMPARE(file.fileName(), QString("file-renamed-once.txt")); |
|
2174 |
|
2175 QVERIFY(file.rename("file-renamed-twice.txt")); |
|
2176 QVERIFY(!file.isOpen()); |
|
2177 QCOMPARE(file.fileName(), QString("file-renamed-twice.txt")); |
|
2178 |
|
2179 QVERIFY(QFile::exists("existing-file.txt")); |
|
2180 QVERIFY(!QFile::exists("file-to-be-renamed.txt")); |
|
2181 QVERIFY(!QFile::exists("file-renamed-once.txt")); |
|
2182 QVERIFY(QFile::exists("file-renamed-twice.txt")); |
|
2183 |
|
2184 file.remove(); |
|
2185 file2.remove(); |
|
2186 QVERIFY(!QFile::exists("file-renamed-twice.txt")); |
|
2187 QVERIFY(!QFile::exists("existing-file.txt")); |
|
2188 } |
|
2189 |
|
2190 void tst_QFile::appendAndRead() |
|
2191 { |
|
2192 QFile writeFile(QLatin1String("appendfile.txt")); |
|
2193 QVERIFY(writeFile.open(QIODevice::WriteOnly | QIODevice::Truncate)); |
|
2194 |
|
2195 QFile readFile(QLatin1String("appendfile.txt")); |
|
2196 QVERIFY(readFile.open(QIODevice::ReadOnly)); |
|
2197 |
|
2198 // Write to the end of the file, then read that character back, and so on. |
|
2199 for (int i = 0; i < 100; ++i) { |
|
2200 char c = '\0'; |
|
2201 writeFile.putChar(char(i % 256)); |
|
2202 writeFile.flush(); |
|
2203 QVERIFY(readFile.getChar(&c)); |
|
2204 QCOMPARE(c, char(i % 256)); |
|
2205 QCOMPARE(readFile.pos(), writeFile.pos()); |
|
2206 } |
|
2207 |
|
2208 // Write blocks and read them back |
|
2209 for (int j = 0; j < 18; ++j) { |
|
2210 writeFile.write(QByteArray(1 << j, '@')); |
|
2211 writeFile.flush(); |
|
2212 QCOMPARE(readFile.read(1 << j).size(), 1 << j); |
|
2213 } |
|
2214 |
|
2215 QFile::remove(QLatin1String("appendfile.txt")); |
|
2216 } |
|
2217 |
|
2218 void tst_QFile::miscWithUncPathAsCurrentDir() |
|
2219 { |
|
2220 #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) |
|
2221 QString current = QDir::currentPath(); |
|
2222 QVERIFY(QDir::setCurrent("//" + QtNetworkSettings::winServerName() + "/testsharewritable")); |
|
2223 QFile file("test.pri"); |
|
2224 QVERIFY(file.exists()); |
|
2225 QCOMPARE(int(file.size()), 34); |
|
2226 QVERIFY(file.open(QIODevice::ReadOnly)); |
|
2227 QVERIFY(QDir::setCurrent(current)); |
|
2228 #endif |
|
2229 } |
|
2230 |
|
2231 void tst_QFile::standarderror() |
|
2232 { |
|
2233 QFile f; |
|
2234 bool ok = f.open(stderr, QFile::WriteOnly); |
|
2235 QVERIFY(ok); |
|
2236 f.close(); |
|
2237 } |
|
2238 |
|
2239 void tst_QFile::handle() |
|
2240 { |
|
2241 #ifndef Q_OS_WINCE |
|
2242 QFile file(SRCDIR "tst_qfile.cpp"); |
|
2243 QVERIFY(file.open(QIODevice::ReadOnly)); |
|
2244 int fd = int(file.handle()); |
|
2245 QVERIFY(fd > 2); |
|
2246 QCOMPARE(int(file.handle()), fd); |
|
2247 char c = '\0'; |
|
2248 QT_READ(int(file.handle()), &c, 1); |
|
2249 QCOMPARE(c, '/'); |
|
2250 |
|
2251 // test if the QFile and the handle remain in sync |
|
2252 QVERIFY(file.getChar(&c)); |
|
2253 QCOMPARE(c, '*'); |
|
2254 |
|
2255 // same, but read from QFile first now |
|
2256 file.close(); |
|
2257 QVERIFY(file.open(QIODevice::ReadOnly | QIODevice::Unbuffered)); |
|
2258 fd = int(file.handle()); |
|
2259 QVERIFY(fd > 2); |
|
2260 QVERIFY(file.getChar(&c)); |
|
2261 QCOMPARE(c, '/'); |
|
2262 #ifdef Q_OS_UNIX |
|
2263 QCOMPARE(QT_READ(fd, &c, 1), ssize_t(1)); |
|
2264 #else |
|
2265 QCOMPARE(QT_READ(fd, &c, 1), 1); |
|
2266 #endif |
|
2267 |
|
2268 QCOMPARE(c, '*'); |
|
2269 #endif |
|
2270 |
|
2271 QFile file2; |
|
2272 FILE *fp = fopen(SRCDIR "tst_qfile.cpp", "r"); |
|
2273 file2.open(fp, QIODevice::ReadOnly); |
|
2274 QCOMPARE(int(file2.handle()), int(fileno(fp))); |
|
2275 QCOMPARE(int(file2.handle()), int(fileno(fp))); |
|
2276 fclose(fp); |
|
2277 |
|
2278 #ifdef Q_OS_UNIX |
|
2279 QFile file3; |
|
2280 fd = QT_OPEN(SRCDIR "tst_qfile.cpp", QT_OPEN_RDONLY); |
|
2281 file3.open(fd, QIODevice::ReadOnly); |
|
2282 QCOMPARE(int(file3.handle()), fd); |
|
2283 QT_CLOSE(fd); |
|
2284 #endif |
|
2285 } |
|
2286 |
|
2287 void tst_QFile::readEof_data() |
|
2288 { |
|
2289 QTest::addColumn<QString>("filename"); |
|
2290 QTest::addColumn<int>("imode"); |
|
2291 |
|
2292 QTest::newRow("buffered") << SRCDIR "testfile.txt" << 0; |
|
2293 QTest::newRow("unbuffered") << SRCDIR "testfile.txt" << int(QIODevice::Unbuffered); |
|
2294 |
|
2295 #if defined(Q_OS_UNIX) && !defined(Q_OS_SYMBIAN) |
|
2296 QTest::newRow("sequential,buffered") << "/dev/null" << 0; |
|
2297 QTest::newRow("sequential,unbuffered") << "/dev/null" << int(QIODevice::Unbuffered); |
|
2298 #endif |
|
2299 } |
|
2300 |
|
2301 void tst_QFile::readEof() |
|
2302 { |
|
2303 QFETCH(QString, filename); |
|
2304 QFETCH(int, imode); |
|
2305 QIODevice::OpenMode mode = QIODevice::OpenMode(imode); |
|
2306 |
|
2307 { |
|
2308 QFile file(filename); |
|
2309 QVERIFY(file.open(QIODevice::ReadOnly | mode)); |
|
2310 bool isSequential = file.isSequential(); |
|
2311 if (!isSequential) { |
|
2312 QVERIFY(file.seek(245)); |
|
2313 QVERIFY(file.atEnd()); |
|
2314 } |
|
2315 |
|
2316 char buf[10]; |
|
2317 int ret = file.read(buf, sizeof buf); |
|
2318 QCOMPARE(ret, 0); |
|
2319 QVERIFY(file.error() == QFile::NoError); |
|
2320 QVERIFY(file.atEnd()); |
|
2321 |
|
2322 // Do it again to ensure that we get the same result |
|
2323 ret = file.read(buf, sizeof buf); |
|
2324 QCOMPARE(ret, 0); |
|
2325 QVERIFY(file.error() == QFile::NoError); |
|
2326 QVERIFY(file.atEnd()); |
|
2327 } |
|
2328 |
|
2329 { |
|
2330 QFile file(filename); |
|
2331 QVERIFY(file.open(QIODevice::ReadOnly | mode)); |
|
2332 bool isSequential = file.isSequential(); |
|
2333 if (!isSequential) { |
|
2334 QVERIFY(file.seek(245)); |
|
2335 QVERIFY(file.atEnd()); |
|
2336 } |
|
2337 |
|
2338 QByteArray ret = file.read(10); |
|
2339 QVERIFY(ret.isNull()); |
|
2340 QVERIFY(file.error() == QFile::NoError); |
|
2341 QVERIFY(file.atEnd()); |
|
2342 |
|
2343 // Do it again to ensure that we get the same result |
|
2344 ret = file.read(10); |
|
2345 QVERIFY(ret.isNull()); |
|
2346 QVERIFY(file.error() == QFile::NoError); |
|
2347 QVERIFY(file.atEnd()); |
|
2348 } |
|
2349 |
|
2350 { |
|
2351 QFile file(filename); |
|
2352 QVERIFY(file.open(QIODevice::ReadOnly | mode)); |
|
2353 bool isSequential = file.isSequential(); |
|
2354 if (!isSequential) { |
|
2355 QVERIFY(file.seek(245)); |
|
2356 QVERIFY(file.atEnd()); |
|
2357 } |
|
2358 |
|
2359 char buf[10]; |
|
2360 int ret = file.readLine(buf, sizeof buf); |
|
2361 QCOMPARE(ret, -1); |
|
2362 QVERIFY(file.error() == QFile::NoError); |
|
2363 QVERIFY(file.atEnd()); |
|
2364 |
|
2365 // Do it again to ensure that we get the same result |
|
2366 ret = file.readLine(buf, sizeof buf); |
|
2367 QCOMPARE(ret, -1); |
|
2368 QVERIFY(file.error() == QFile::NoError); |
|
2369 QVERIFY(file.atEnd()); |
|
2370 } |
|
2371 |
|
2372 { |
|
2373 QFile file(filename); |
|
2374 QVERIFY(file.open(QIODevice::ReadOnly | mode)); |
|
2375 bool isSequential = file.isSequential(); |
|
2376 if (!isSequential) { |
|
2377 QVERIFY(file.seek(245)); |
|
2378 QVERIFY(file.atEnd()); |
|
2379 } |
|
2380 |
|
2381 QByteArray ret = file.readLine(); |
|
2382 QVERIFY(ret.isNull()); |
|
2383 QVERIFY(file.error() == QFile::NoError); |
|
2384 QVERIFY(file.atEnd()); |
|
2385 |
|
2386 // Do it again to ensure that we get the same result |
|
2387 ret = file.readLine(); |
|
2388 QVERIFY(ret.isNull()); |
|
2389 QVERIFY(file.error() == QFile::NoError); |
|
2390 QVERIFY(file.atEnd()); |
|
2391 } |
|
2392 |
|
2393 { |
|
2394 QFile file(filename); |
|
2395 QVERIFY(file.open(QIODevice::ReadOnly | mode)); |
|
2396 bool isSequential = file.isSequential(); |
|
2397 if (!isSequential) { |
|
2398 QVERIFY(file.seek(245)); |
|
2399 QVERIFY(file.atEnd()); |
|
2400 } |
|
2401 |
|
2402 char c; |
|
2403 QVERIFY(!file.getChar(&c)); |
|
2404 QVERIFY(file.error() == QFile::NoError); |
|
2405 QVERIFY(file.atEnd()); |
|
2406 |
|
2407 // Do it again to ensure that we get the same result |
|
2408 QVERIFY(!file.getChar(&c)); |
|
2409 QVERIFY(file.error() == QFile::NoError); |
|
2410 QVERIFY(file.atEnd()); |
|
2411 } |
|
2412 } |
|
2413 |
|
2414 void tst_QFile::task167217() |
|
2415 { |
|
2416 // Regression introduced in 4.3.0; after a failed stat, pos() could no |
|
2417 // longer be calculated correctly. |
|
2418 QFile::remove("tmp.txt"); |
|
2419 QFile file("tmp.txt"); |
|
2420 QVERIFY(!file.exists()); |
|
2421 QVERIFY(file.open(QIODevice::Append)); |
|
2422 QVERIFY(file.exists()); |
|
2423 file.write("qt430", 5); |
|
2424 QVERIFY(!file.isSequential()); |
|
2425 QCOMPARE(file.pos(), qint64(5)); |
|
2426 file.remove(); |
|
2427 } |
|
2428 |
|
2429 #define FILESIZE 65536 * 3 |
|
2430 |
|
2431 void tst_QFile::map_data() |
|
2432 { |
|
2433 QTest::addColumn<int>("fileSize"); |
|
2434 QTest::addColumn<int>("offset"); |
|
2435 QTest::addColumn<int>("size"); |
|
2436 QTest::addColumn<QFile::FileError>("error"); |
|
2437 |
|
2438 QTest::newRow("zero") << FILESIZE << 0 << FILESIZE << QFile::NoError; |
|
2439 QTest::newRow("small, but 0") << FILESIZE << 30 << FILESIZE - 30 << QFile::NoError; |
|
2440 QTest::newRow("a page") << FILESIZE << 4096 << FILESIZE - 4096 << QFile::NoError; |
|
2441 QTest::newRow("+page") << FILESIZE << 5000 << FILESIZE - 5000 << QFile::NoError; |
|
2442 QTest::newRow("++page") << FILESIZE << 65576 << FILESIZE - 65576 << QFile::NoError; |
|
2443 QTest::newRow("bad size") << FILESIZE << 0 << -1 << QFile::ResourceError; |
|
2444 QTest::newRow("bad offset") << FILESIZE << -1 << 1 << QFile::UnspecifiedError; |
|
2445 QTest::newRow("zerozero") << FILESIZE << 0 << 0 << QFile::UnspecifiedError; |
|
2446 } |
|
2447 |
|
2448 void tst_QFile::map() |
|
2449 { |
|
2450 QFETCH(int, fileSize); |
|
2451 QFETCH(int, offset); |
|
2452 QFETCH(int, size); |
|
2453 QFETCH(QFile::FileError, error); |
|
2454 |
|
2455 QString fileName = QDir::currentPath() + '/' + "qfile_map_testfile"; |
|
2456 if (QFile::exists(fileName)) { |
|
2457 QVERIFY(QFile::setPermissions(fileName, |
|
2458 QFile::WriteOwner | QFile::ReadOwner | QFile::WriteUser | QFile::ReadUser)); |
|
2459 QFile::remove(fileName); |
|
2460 } |
|
2461 QFile file(fileName); |
|
2462 |
|
2463 // invalid, not open |
|
2464 uchar *memory = file.map(0, size); |
|
2465 QVERIFY(!memory); |
|
2466 QCOMPARE(file.error(), QFile::PermissionsError); |
|
2467 QVERIFY(!file.unmap(memory)); |
|
2468 QCOMPARE(file.error(), QFile::PermissionsError); |
|
2469 |
|
2470 // make a file |
|
2471 QVERIFY(file.open(QFile::ReadWrite)); |
|
2472 QVERIFY(file.resize(fileSize)); |
|
2473 QVERIFY(file.flush()); |
|
2474 file.close(); |
|
2475 QVERIFY(file.open(QFile::ReadWrite)); |
|
2476 memory = file.map(offset, size); |
|
2477 if (error != QFile::NoError) { |
|
2478 |
|
2479 QVERIFY(file.error() != QFile::NoError); |
|
2480 return; |
|
2481 } |
|
2482 |
|
2483 QCOMPARE(file.error(), error); |
|
2484 QVERIFY(memory); |
|
2485 memory[0] = 'Q'; |
|
2486 QVERIFY(file.unmap(memory)); |
|
2487 QCOMPARE(file.error(), QFile::NoError); |
|
2488 |
|
2489 // Verify changes were saved |
|
2490 memory = file.map(offset, size); |
|
2491 QCOMPARE(file.error(), QFile::NoError); |
|
2492 QVERIFY(memory); |
|
2493 QVERIFY(memory[0] == 'Q'); |
|
2494 QVERIFY(file.unmap(memory)); |
|
2495 QCOMPARE(file.error(), QFile::NoError); |
|
2496 |
|
2497 // hpux wont let you map multiple times. |
|
2498 #if !defined(Q_OS_HPUX) && !defined(Q_USE_DEPRECATED_MAP_API) |
|
2499 // exotic test to make sure that multiple maps work |
|
2500 uchar *memory1 = file.map(0, file.size()); |
|
2501 QCOMPARE(file.error(), QFile::NoError); |
|
2502 uchar *memory2 = file.map(0, file.size()); |
|
2503 QCOMPARE(file.error(), QFile::NoError); |
|
2504 QVERIFY(memory1); |
|
2505 QVERIFY(memory2); |
|
2506 QVERIFY(file.unmap(memory1)); |
|
2507 QCOMPARE(file.error(), QFile::NoError); |
|
2508 QVERIFY(file.unmap(memory2)); |
|
2509 QCOMPARE(file.error(), QFile::NoError); |
|
2510 memory1 = file.map(0, file.size()); |
|
2511 QCOMPARE(file.error(), QFile::NoError); |
|
2512 QVERIFY(memory1); |
|
2513 QVERIFY(file.unmap(memory1)); |
|
2514 QCOMPARE(file.error(), QFile::NoError); |
|
2515 #endif |
|
2516 |
|
2517 file.close(); |
|
2518 |
|
2519 #if defined(Q_OS_SYMBIAN) |
|
2520 if (false) // No permissions for user makes no sense in Symbian |
|
2521 #elif defined(Q_OS_UNIX) |
|
2522 if (::getuid() != 0) |
|
2523 // root always has permissions |
|
2524 #endif |
|
2525 { |
|
2526 // Change permissions on a file, just to confirm it would fail |
|
2527 QFile::Permissions originalPermissions = file.permissions(); |
|
2528 QVERIFY(file.setPermissions(QFile::ReadOther)); |
|
2529 QVERIFY(!file.open(QFile::ReadWrite)); |
|
2530 memory = file.map(offset, size); |
|
2531 QCOMPARE(file.error(), QFile::PermissionsError); |
|
2532 QVERIFY(!memory); |
|
2533 QVERIFY(file.setPermissions(originalPermissions)); |
|
2534 } |
|
2535 |
|
2536 QVERIFY(file.remove()); |
|
2537 } |
|
2538 |
|
2539 void tst_QFile::mapResource_data() |
|
2540 { |
|
2541 QTest::addColumn<int>("offset"); |
|
2542 QTest::addColumn<int>("size"); |
|
2543 QTest::addColumn<QFile::FileError>("error"); |
|
2544 QTest::addColumn<QString>("fileName"); |
|
2545 |
|
2546 QString validFile = ":/tst_qfileinfo/resources/file1.ext1"; |
|
2547 QString invalidFile = ":/tst_qfileinfo/resources/filefoo.ext1"; |
|
2548 |
|
2549 for (int i = 0; i < 2; ++i) { |
|
2550 QString file = (i == 0) ? validFile : invalidFile; |
|
2551 QTest::newRow("0, 0") << 0 << 0 << QFile::UnspecifiedError << file; |
|
2552 QTest::newRow("0, BIG") << 0 << 4096 << QFile::UnspecifiedError << file; |
|
2553 QTest::newRow("-1, 0") << -1 << 0 << QFile::UnspecifiedError << file; |
|
2554 QTest::newRow("0, -1") << 0 << -1 << QFile::UnspecifiedError << file; |
|
2555 } |
|
2556 |
|
2557 QTest::newRow("0, 1") << 0 << 1 << QFile::NoError << validFile; |
|
2558 } |
|
2559 |
|
2560 void tst_QFile::mapResource() |
|
2561 { |
|
2562 QFETCH(QString, fileName); |
|
2563 QFETCH(int, offset); |
|
2564 QFETCH(int, size); |
|
2565 QFETCH(QFile::FileError, error); |
|
2566 |
|
2567 QFile file(fileName); |
|
2568 uchar *memory = file.map(offset, size); |
|
2569 QCOMPARE(file.error(), error); |
|
2570 QVERIFY((error == QFile::NoError) ? (memory != 0) : (memory == 0)); |
|
2571 if (error == QFile::NoError) |
|
2572 QCOMPARE(QString(memory[0]), QString::number(offset + 1)); |
|
2573 QVERIFY(file.unmap(memory)); |
|
2574 } |
|
2575 |
|
2576 void tst_QFile::mapOpenMode_data() |
|
2577 { |
|
2578 QTest::addColumn<int>("openMode"); |
|
2579 |
|
2580 QTest::newRow("ReadOnly") << int(QIODevice::ReadOnly); |
|
2581 //QTest::newRow("WriteOnly") << int(QIODevice::WriteOnly); // this doesn't make sense |
|
2582 QTest::newRow("ReadWrite") << int(QIODevice::ReadWrite); |
|
2583 QTest::newRow("ReadOnly,Unbuffered") << int(QIODevice::ReadOnly | QIODevice::Unbuffered); |
|
2584 QTest::newRow("ReadWrite,Unbuffered") << int(QIODevice::ReadWrite | QIODevice::Unbuffered); |
|
2585 } |
|
2586 |
|
2587 void tst_QFile::mapOpenMode() |
|
2588 { |
|
2589 QFETCH(int, openMode); |
|
2590 static const qint64 fileSize = 4096; |
|
2591 QByteArray pattern(fileSize, 'A'); |
|
2592 |
|
2593 QString fileName = QDir::currentPath() + '/' + "qfile_map_testfile"; |
|
2594 if (QFile::exists(fileName)) { |
|
2595 QVERIFY(QFile::setPermissions(fileName, |
|
2596 QFile::WriteOwner | QFile::ReadOwner | QFile::WriteUser | QFile::ReadUser)); |
|
2597 QFile::remove(fileName); |
|
2598 } |
|
2599 QFile file(fileName); |
|
2600 |
|
2601 // make a file |
|
2602 QVERIFY(file.open(QFile::ReadWrite)); |
|
2603 QVERIFY(file.write(pattern)); |
|
2604 QVERIFY(file.flush()); |
|
2605 file.close(); |
|
2606 |
|
2607 // open according to our mode |
|
2608 QVERIFY(file.open(QIODevice::OpenMode(openMode))); |
|
2609 |
|
2610 uchar *memory = file.map(0, fileSize); |
|
2611 QVERIFY(memory); |
|
2612 QVERIFY(memcmp(memory, pattern, fileSize) == 0); |
|
2613 |
|
2614 if (openMode & QIODevice::WriteOnly) { |
|
2615 // try to write to the file |
|
2616 *memory = 'a'; |
|
2617 file.unmap(memory); |
|
2618 file.close(); |
|
2619 file.open(QIODevice::OpenMode(openMode)); |
|
2620 file.seek(0); |
|
2621 char c; |
|
2622 QVERIFY(file.getChar(&c)); |
|
2623 QCOMPARE(c, 'a'); |
|
2624 } |
|
2625 |
|
2626 file.close(); |
|
2627 } |
|
2628 |
|
2629 void tst_QFile::openDirectory() |
|
2630 { |
|
2631 QFile f1("resources"); |
|
2632 QVERIFY(!f1.open(QIODevice::ReadOnly)); |
|
2633 f1.close(); |
|
2634 QVERIFY(!f1.open(QIODevice::ReadOnly|QIODevice::Unbuffered)); |
|
2635 } |
|
2636 |
|
2637 QTEST_MAIN(tst_QFile) |
|
2638 #include "tst_qfile.moc" |