@@ -470,6 +470,85 @@ private Q_SLOTS:
470470 QVERIFY (inode.has_value ());
471471 QCOMPARE (fileInfo.inode (), inode.value ());
472472 }
473+
474+ void testCanonicalPath ()
475+ {
476+ // we compare .native() for std::fiileystem::path, else Qt does actual file comparison
477+ std::error_code ec;
478+ // our build dir might be symlinked, ensure the input path is already canonical
479+ auto path = OCC::FileSystem::fromFilesystemPath (std::filesystem::canonical (qApp->applicationFilePath ().toStdString (), ec));
480+ QVERIFY (ec.value () == 0 );
481+ QCOMPARE (OCC::FileSystem::canonicalPath (OCC::FileSystem::toFilesystemPath (path)).native (), OCC::FileSystem::toFilesystemPath (path).native ());
482+ QCOMPARE (path, OCC::FileSystem::canonicalPath (path));
483+
484+ #ifdef Q_OS_WIN
485+ path = u" C:/" _s;
486+ QCOMPARE (path, OCC::FileSystem::canonicalPath (path));
487+ QCOMPARE (OCC::FileSystem::toFilesystemPath (path).native (), OCC::FileSystem::canonicalPath (OCC::FileSystem::toFilesystemPath (path)).native ());
488+
489+ path = u" C:" _s;
490+ QCOMPARE (" C:/" _L1, OCC::FileSystem::canonicalPath (path));
491+ QCOMPARE (OCC::FileSystem::toFilesystemPath (path).native (), OCC::FileSystem::canonicalPath (OCC::FileSystem::toFilesystemPath (path)).native ());
492+
493+
494+ // test non-existing file, which relies on lexical normalization rather than actual canonical path
495+ path = u" C:/fooo_bar" _s;
496+ QVERIFY (!QFileInfo::exists (path));
497+ QCOMPARE (path, OCC::FileSystem::canonicalPath (path));
498+ QCOMPARE (OCC::FileSystem::toFilesystemPath (path).native (), OCC::FileSystem::canonicalPath (OCC::FileSystem::toFilesystemPath (path)).native ());
499+
500+ path = u" C:/fooo_bar/../foo/./../fooo_bar" _s;
501+ QVERIFY (!QFileInfo::exists (path));
502+ QCOMPARE (u" C:/fooo_bar" _s, OCC::FileSystem::canonicalPath (path));
503+ QCOMPARE (
504+ OCC::FileSystem::toFilesystemPath (u" C:/fooo_bar" _s).native (), OCC::FileSystem::canonicalPath (OCC::FileSystem::toFilesystemPath (path)).native ());
505+
506+ // test multiple consecutive slashes
507+ path = u" C:///fooo_bar//test///file" _s;
508+ QVERIFY (!QFileInfo::exists (path));
509+ QCOMPARE (u" C:/fooo_bar/test/file" _s, OCC::FileSystem::canonicalPath (path));
510+ QCOMPARE (OCC::FileSystem::toFilesystemPath (u" C:/fooo_bar/test/file" _s).native (),
511+ OCC::FileSystem::canonicalPath (OCC::FileSystem::toFilesystemPath (path)).native ());
512+
513+ // test trailing slashes
514+ path = u" C:/fooo_bar///" _s;
515+ QVERIFY (!QFileInfo::exists (path));
516+ QCOMPARE (u" C:/fooo_bar" _s, OCC::FileSystem::canonicalPath (path));
517+ QCOMPARE (
518+ OCC::FileSystem::toFilesystemPath (u" C:/fooo_bar" _s).native (), OCC::FileSystem::canonicalPath (OCC::FileSystem::toFilesystemPath (path)).native ());
519+
520+ // test dot segments in middle of path
521+ path = u" C:/fooo_bar/./test/./file" _s;
522+ QVERIFY (!QFileInfo::exists (path));
523+ QCOMPARE (u" C:/fooo_bar/test/file" _s, OCC::FileSystem::canonicalPath (path));
524+ QCOMPARE (OCC::FileSystem::toFilesystemPath (u" C:/fooo_bar/test/file" _s).native (),
525+ OCC::FileSystem::canonicalPath (OCC::FileSystem::toFilesystemPath (path)).native ());
526+
527+ // test mixed slashes on Windows
528+ path = u" C:\\ fooo_bar/test\\ file" _s;
529+ QVERIFY (!QFileInfo::exists (path));
530+ QCOMPARE (u" C:/fooo_bar/test/file" _s, OCC::FileSystem::canonicalPath (path));
531+ QCOMPARE (OCC::FileSystem::toFilesystemPath (u" C:/fooo_bar/test/file" _s).native (),
532+ OCC::FileSystem::canonicalPath (OCC::FileSystem::toFilesystemPath (path)).native ());
533+
534+ // test UNC path
535+ path = u" \\\\ server\\ share\\ path" _s;
536+ QCOMPARE (u" //server/share/path" _s, OCC::FileSystem::canonicalPath (path));
537+ QCOMPARE (OCC::FileSystem::toFilesystemPath (u" //server/share/path" _s).native (),
538+ OCC::FileSystem::canonicalPath (OCC::FileSystem::toFilesystemPath (path)).native ());
539+ #else
540+ // test non-existing file, which relies on lexical normalization rather than actual canonical path
541+ path = u" /fooo_bar" _s;
542+ QVERIFY (!QFileInfo::exists (path));
543+ QCOMPARE (path, OCC::FileSystem::canonicalPath (path));
544+ QCOMPARE (OCC::FileSystem::toFilesystemPath (path).native (), OCC::FileSystem::canonicalPath (OCC::FileSystem::toFilesystemPath (path)).native ());
545+
546+ path = u" /fooo_bar/../foo/./../fooo_bar" _s;
547+ QVERIFY (!QFileInfo::exists (path));
548+ QCOMPARE (u" /fooo_bar" _s, OCC::FileSystem::canonicalPath (path));
549+ QCOMPARE (OCC::FileSystem::toFilesystemPath (u" /fooo_bar" _s).native (), OCC::FileSystem::canonicalPath (OCC::FileSystem::toFilesystemPath (path)).native ());
550+ #endif
551+ }
473552};
474553
475554QTEST_GUILESS_MAIN (TestUtility)
0 commit comments