Skip to content

Commit ec24947

Browse files
Johnson-zsdeepin-bot[bot]
authored andcommitted
test: enhance file sorting tests with directories and symlinks
Added comprehensive test cases for DFileSorter to better handle: 1. Sorting by size with directories (directories should have consistent effective size -1) 2. Size sorting in descending order (directories move to end) 3. Last modified time sorting with symlinks (use target file time) 4. Last read time sorting with symlinks (use target file time) The changes include new unit tests that verify: - Directory sorting behavior in size comparisons - Correct ordering in descending size sort - Proper handling of symbolic links when sorting by time attributes - Mixing of directories and files in different sort scenarios Influence: 1. Test file sorting by size with directories and mixed files 2. Verify descending size sorting places directories correctly 3. Check symlink time sorting uses target file times 4. Validate directory/file separation maintains correct order 5. Test various combinations of the above scenarios with different file sets test: 增强文件排序测试,支持目录和符号链接特殊情况 新增了针对DFileSorter的全面测试用例,主要涵盖: 1. 包含目录的按大小排序(目录始终使用-1作为有效大小) 2. 大小降序排序(目录应排在最后) 3. 带符号链接的按修改时间排序(使用目标文件时间) 4. 带符号链接的按访问时间排序(使用目标文件时间) 变更内容包括: - 验证目录在大小排序中的行为 - 降序排序时目录的正确位置 - 符号链接时间属性使用目标文件时间的处理 - 混合目录和文件在不同排序场景中的表现 Influence: 1. 测试包含目录的按大小文件排序 2. 验证降序大小排序中目录的位置是否正确 3. 检查符号链接时间排序是否使用目标文件时间 4. 验证目录和文件分离时是否保持正确顺序 5. 测试不同文件组合下的各种排序场景
1 parent 0ec3e8e commit ec24947

2 files changed

Lines changed: 347 additions & 25 deletions

File tree

autotests/dfm-io-tests/tst_dfilesorter.cpp

Lines changed: 244 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@
66
#include <QUrl>
77
#include <QCollator>
88
#include <QDebug>
9+
#include <QTemporaryDir>
10+
#include <QFile>
11+
#include <QFileDevice>
12+
#include <QDateTime>
913

1014
#include "sort/dfilesorter.h"
1115
#include "sort/dsortkeycache.h"
@@ -29,12 +33,16 @@ private Q_SLOTS:
2933
void fileSorter_sortByName();
3034
void fileSorter_sortByName_descending();
3135
void fileSorter_sortBySize();
36+
void fileSorter_sortBySize_withDirs();
37+
void fileSorter_sortBySize_descending();
3238
void fileSorter_sortByLastModified();
3339
void fileSorter_sortByLastRead();
3440
void fileSorter_mixDirAndFile();
3541
void fileSorter_separateDirAndFile();
3642
void fileSorter_emptyList();
3743
void fileSorter_singleItem();
44+
void fileSorter_sortByLastModified_withSymlink();
45+
void fileSorter_sortByLastRead_withSymlink();
3846
};
3947

4048
void tst_DFileSorter::initTestCase()
@@ -197,6 +205,117 @@ void tst_DFileSorter::fileSorter_sortBySize()
197205
QCOMPARE(sorted[2]->url.fileName(), QString("large.txt"));
198206
}
199207

208+
void tst_DFileSorter::fileSorter_sortBySize_withDirs()
209+
{
210+
// 测试按大小排序时,目录(有效大小 -1)始终排在前面(升序时)
211+
// 这与原 DLocalHelper::fileSizeByEnt 的行为一致
212+
DFileSorter::SortConfig config;
213+
config.role = DFileSorter::SortRole::Size;
214+
config.order = Qt::AscendingOrder;
215+
config.mixDirAndFile = true; // 混排模式
216+
217+
DFileSorter sorter(config);
218+
219+
QList<QSharedPointer<DEnumerator::SortFileInfo>> files;
220+
221+
// 目录:大小通常为 4096,但有效大小应为 -1
222+
auto dir1 = QSharedPointer<DEnumerator::SortFileInfo>::create();
223+
dir1->url = QUrl::fromLocalFile("/test/docs");
224+
dir1->isDir = true;
225+
dir1->isSymLink = false;
226+
dir1->filesize = 4096; // 实际大小
227+
files.append(dir1);
228+
229+
// 小文件:100 字节(小于 4096)
230+
auto file1 = QSharedPointer<DEnumerator::SortFileInfo>::create();
231+
file1->url = QUrl::fromLocalFile("/test/small.txt");
232+
file1->isDir = false;
233+
file1->filesize = 100;
234+
files.append(file1);
235+
236+
// 中等文件:2000 字节(小于 4096)
237+
auto file2 = QSharedPointer<DEnumerator::SortFileInfo>::create();
238+
file2->url = QUrl::fromLocalFile("/test/medium.txt");
239+
file2->isDir = false;
240+
file2->filesize = 2000;
241+
files.append(file2);
242+
243+
// 大文件:10000 字节(大于 4096)
244+
auto file3 = QSharedPointer<DEnumerator::SortFileInfo>::create();
245+
file3->url = QUrl::fromLocalFile("/test/large.txt");
246+
file3->isDir = false;
247+
file3->filesize = 10000;
248+
files.append(file3);
249+
250+
// 另一个目录
251+
auto dir2 = QSharedPointer<DEnumerator::SortFileInfo>::create();
252+
dir2->url = QUrl::fromLocalFile("/test/apps");
253+
dir2->isDir = true;
254+
dir2->isSymLink = false;
255+
dir2->filesize = 4096;
256+
files.append(dir2);
257+
258+
auto sorted = sorter.sort(std::move(files));
259+
260+
// 验证:升序时目录(有效大小 -1)在前,然后按文件大小排序
261+
QCOMPARE(sorted.size(), 5);
262+
// 目录在前(按名称排序,因为大小相同都是 -1)
263+
QCOMPARE(sorted[0]->isDir, true);
264+
QCOMPARE(sorted[0]->url.fileName(), QString("apps"));
265+
QCOMPARE(sorted[1]->isDir, true);
266+
QCOMPARE(sorted[1]->url.fileName(), QString("docs"));
267+
// 文件在后(按大小排序)
268+
QCOMPARE(sorted[2]->isDir, false);
269+
QCOMPARE(sorted[2]->url.fileName(), QString("small.txt"));
270+
QCOMPARE(sorted[3]->isDir, false);
271+
QCOMPARE(sorted[3]->url.fileName(), QString("medium.txt"));
272+
QCOMPARE(sorted[4]->isDir, false);
273+
QCOMPARE(sorted[4]->url.fileName(), QString("large.txt"));
274+
}
275+
276+
void tst_DFileSorter::fileSorter_sortBySize_descending()
277+
{
278+
// 测试按大小降序排序
279+
// 降序时,目录(有效大小 -1)会排到后面
280+
DFileSorter::SortConfig config;
281+
config.role = DFileSorter::SortRole::Size;
282+
config.order = Qt::DescendingOrder;
283+
config.mixDirAndFile = true;
284+
285+
DFileSorter sorter(config);
286+
287+
QList<QSharedPointer<DEnumerator::SortFileInfo>> files;
288+
289+
// 目录(有效大小 -1)
290+
auto dir1 = QSharedPointer<DEnumerator::SortFileInfo>::create();
291+
dir1->url = QUrl::fromLocalFile("/test/docs");
292+
dir1->isDir = true;
293+
dir1->isSymLink = false;
294+
dir1->filesize = 4096;
295+
files.append(dir1);
296+
297+
// 文件
298+
auto file1 = QSharedPointer<DEnumerator::SortFileInfo>::create();
299+
file1->url = QUrl::fromLocalFile("/test/small.txt");
300+
file1->isDir = false;
301+
file1->filesize = 100;
302+
files.append(file1);
303+
304+
auto file2 = QSharedPointer<DEnumerator::SortFileInfo>::create();
305+
file2->url = QUrl::fromLocalFile("/test/large.txt");
306+
file2->isDir = false;
307+
file2->filesize = 10000;
308+
files.append(file2);
309+
310+
auto sorted = sorter.sort(std::move(files));
311+
312+
// 降序:大文件 > 小文件 > 目录(-1 最小,反转后在最后)
313+
QCOMPARE(sorted.size(), 3);
314+
QCOMPARE(sorted[0]->url.fileName(), QString("large.txt")); // 大文件
315+
QCOMPARE(sorted[1]->url.fileName(), QString("small.txt")); // 小文件
316+
QCOMPARE(sorted[2]->isDir, true); // 目录在最后
317+
}
318+
200319
void tst_DFileSorter::fileSorter_sortByLastModified()
201320
{
202321
DFileSorter::SortConfig config;
@@ -386,6 +505,131 @@ void tst_DFileSorter::fileSorter_singleItem()
386505
QCOMPARE(sorted[0]->url.fileName(), QString("single.txt"));
387506
}
388507

508+
void tst_DFileSorter::fileSorter_sortByLastModified_withSymlink()
509+
{
510+
// 测试按修改时间排序时,符号链接使用其指向文件的时间
511+
// 需要创建临时文件来测试真实场景
512+
DFileSorter::SortConfig config;
513+
config.role = DFileSorter::SortRole::LastModified;
514+
config.order = Qt::AscendingOrder;
515+
config.mixDirAndFile = true;
516+
517+
DFileSorter sorter(config);
518+
519+
// 创建临时目录和文件
520+
QTemporaryDir tempDir;
521+
QVERIFY(tempDir.isValid());
522+
523+
QString oldFile = tempDir.path() + "/old_file.txt";
524+
QString newFile = tempDir.path() + "/new_file.txt";
525+
QString linkFile = tempDir.path() + "/link_to_old.txt";
526+
527+
// 创建文件
528+
{
529+
QFile f(oldFile);
530+
f.open(QIODevice::WriteOnly);
531+
f.setFileTime(QDateTime::fromSecsSinceEpoch(1000), QFileDevice::FileModificationTime);
532+
}
533+
{
534+
QFile f(newFile);
535+
f.open(QIODevice::WriteOnly);
536+
f.setFileTime(QDateTime::fromSecsSinceEpoch(3000), QFileDevice::FileModificationTime);
537+
}
538+
539+
// 创建符号链接指向旧文件
540+
QFile::link(oldFile, linkFile);
541+
542+
QList<QSharedPointer<DEnumerator::SortFileInfo>> files;
543+
544+
// 普通文件:new_file
545+
auto file1 = QSharedPointer<DEnumerator::SortFileInfo>::create();
546+
file1->url = QUrl::fromLocalFile(newFile);
547+
file1->isDir = false;
548+
file1->isSymLink = false;
549+
file1->lastModifed = 3000;
550+
file1->lastModifedNs = 0;
551+
files.append(file1);
552+
553+
// 符号链接:指向 old_file(时间 1000)
554+
auto symlink1 = QSharedPointer<DEnumerator::SortFileInfo>::create();
555+
symlink1->url = QUrl::fromLocalFile(linkFile);
556+
symlink1->isDir = false;
557+
symlink1->isSymLink = true;
558+
symlink1->symlinkUrl = QUrl::fromLocalFile(oldFile); // 指向目标文件
559+
symlink1->lastModifed = 2000; // 链接本身的时间(排序时应忽略,使用目标时间 1000)
560+
symlink1->lastModifedNs = 0;
561+
files.append(symlink1);
562+
563+
auto sorted = sorter.sort(std::move(files));
564+
565+
// 按修改时间升序:link_to_old(1000,目标文件时间) < new_file(3000)
566+
QCOMPARE(sorted.size(), 2);
567+
QCOMPARE(sorted[0]->url.fileName(), QString("link_to_old.txt"));
568+
QCOMPARE(sorted[1]->url.fileName(), QString("new_file.txt"));
569+
}
570+
571+
void tst_DFileSorter::fileSorter_sortByLastRead_withSymlink()
572+
{
573+
// 测试按访问时间排序时,符号链接使用其指向文件的时间
574+
DFileSorter::SortConfig config;
575+
config.role = DFileSorter::SortRole::LastRead;
576+
config.order = Qt::AscendingOrder;
577+
config.mixDirAndFile = true;
578+
579+
DFileSorter sorter(config);
580+
581+
// 创建临时目录和文件
582+
QTemporaryDir tempDir;
583+
QVERIFY(tempDir.isValid());
584+
585+
QString file1 = tempDir.path() + "/file1.txt";
586+
QString file2 = tempDir.path() + "/file2.txt";
587+
QString linkFile = tempDir.path() + "/link_to_file2.txt";
588+
589+
// 创建文件并设置访问时间
590+
{
591+
QFile f(file1);
592+
f.open(QIODevice::WriteOnly);
593+
f.setFileTime(QDateTime::fromSecsSinceEpoch(1000), QFileDevice::FileAccessTime);
594+
}
595+
{
596+
QFile f(file2);
597+
f.open(QIODevice::WriteOnly);
598+
f.setFileTime(QDateTime::fromSecsSinceEpoch(3000), QFileDevice::FileAccessTime);
599+
}
600+
601+
// 创建符号链接指向 file2
602+
QFile::link(file2, linkFile);
603+
604+
QList<QSharedPointer<DEnumerator::SortFileInfo>> files;
605+
606+
// 普通文件:file1(访问时间 1000)
607+
auto normalFile = QSharedPointer<DEnumerator::SortFileInfo>::create();
608+
normalFile->url = QUrl::fromLocalFile(file1);
609+
normalFile->isDir = false;
610+
normalFile->isSymLink = false;
611+
normalFile->lastRead = 1000;
612+
normalFile->lastReadNs = 0;
613+
files.append(normalFile);
614+
615+
// 符号链接:指向 file2(访问时间 3000)
616+
auto symlink1 = QSharedPointer<DEnumerator::SortFileInfo>::create();
617+
symlink1->url = QUrl::fromLocalFile(linkFile);
618+
symlink1->isDir = false;
619+
symlink1->isSymLink = true;
620+
symlink1->symlinkUrl = QUrl::fromLocalFile(file2); // 指向目标文件
621+
symlink1->lastRead = 2000; // 链接本身的时间(排序时应忽略,使用目标时间 3000)
622+
symlink1->lastReadNs = 0;
623+
files.append(symlink1);
624+
625+
auto sorted = sorter.sort(std::move(files));
626+
627+
// 按访问时间升序:file1(1000) < link_to_file2(3000,目标文件时间)
628+
QCOMPARE(sorted.size(), 2);
629+
QCOMPARE(sorted[0]->url.fileName(), QString("file1.txt"));
630+
QCOMPARE(sorted[1]->url.fileName(), QString("link_to_file2.txt"));
631+
}
632+
389633
int run_tst_DFileSorter(int argc, char *argv[])
390634
{
391635
tst_DFileSorter tc;

0 commit comments

Comments
 (0)