// Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #include #include #include #define TESTFILE "testfile" class FindTestData: public QObject { Q_OBJECT private slots: void initTestCase(); void cleanupTestCase(); void paths(); private: bool touch(QString const&); }; void FindTestData::initTestCase() { // verify that our qt.conf is working as expected. QString app_path = QCoreApplication::applicationDirPath(); QString install_path = app_path #ifdef Q_OS_MAC + "/Contents" #endif + "/tests"; QVERIFY(QDir("/").mkpath(install_path)); QVERIFY(QDir("/").mkpath(install_path + "/findtestdata")); QCOMPARE(QLibraryInfo::path(QLibraryInfo::TestsPath), install_path); // make fake source and build directories QVERIFY(QDir("/").mkpath(app_path + "/fakesrc")); QVERIFY(QDir("/").mkpath(app_path + "/fakebuild")); } void FindTestData::cleanupTestCase() { QString app_path = QCoreApplication::applicationDirPath(); QFile(app_path + "/tests/findtestdata/" TESTFILE).remove(); QFile(app_path + "/tests/" TESTFILE).remove(); QFile(app_path + "/fakesrc/" TESTFILE).remove(); QDir("/").rmpath(app_path + "/tests/findtestdata"); QDir("/").rmpath(app_path + "/fakesrc"); QDir("/").rmpath(app_path + "/fakebuild"); } // Create an empty file at the specified path (or return false) bool FindTestData::touch(QString const& path) { QFile file(path); if (!file.open(QIODevice::WriteOnly)) { qWarning("Failed to create %s: %s", qPrintable(path), qPrintable(file.errorString())); return false; } return true; } void FindTestData::paths() { // There are three possible locations for the testdata. // In this test, we will put the testdata at all three locations, // then remove it from one location at a time and verify that // QFINDTESTDATA correctly falls back each time. // 1. relative to test binary. QString app_path = QCoreApplication::applicationDirPath(); QString testfile_path1 = app_path + "/" TESTFILE; QVERIFY(touch(testfile_path1)); // 2. at the test install path (faked via qt.conf) QString testfile_path2 = app_path #ifdef Q_OS_MAC + "/Contents" #endif + "/tests/findtestdata/" TESTFILE; QVERIFY(touch(testfile_path2)); // 3. at the source path (which we will fake later on) QString testfile_path3 = app_path + "/fakesrc/" TESTFILE; QVERIFY(touch(testfile_path3)); // OK, all testdata created. Verify that they are found in correct priority order. QCOMPARE(QFINDTESTDATA(TESTFILE), testfile_path1); QVERIFY(QFile(testfile_path1).remove()); QCOMPARE(QFINDTESTDATA(TESTFILE), testfile_path2); QVERIFY(QFile(testfile_path2).remove()); // We cannot reasonably redefine __FILE__, so we call the underlying function instead. // __FILE__ may be absolute or relative path; test both. // absolute: #if defined(Q_OS_WIN) QCOMPARE(QTest::qFindTestData(TESTFILE, qPrintable(app_path + "/fakesrc/fakefile.cpp"), __LINE__).toLower(), testfile_path3.toLower()); #else QCOMPARE(QTest::qFindTestData(TESTFILE, qPrintable(app_path + "/fakesrc/fakefile.cpp"), __LINE__), testfile_path3); #endif // relative: (pretend that we were compiled within fakebuild directory, pointing at files in ../fakesrc) #if defined(Q_OS_WIN) QCOMPARE(QTest::qFindTestData(TESTFILE, "../fakesrc/fakefile.cpp", __LINE__, qPrintable(app_path + "/fakebuild")).toLower(), testfile_path3.toLower()); #else QCOMPARE(QTest::qFindTestData(TESTFILE, "../fakesrc/fakefile.cpp", __LINE__, qPrintable(app_path + "/fakebuild")), testfile_path3); #endif QVERIFY(QFile(testfile_path3).remove()); #if !defined(Q_OS_WIN) struct ChdirOnReturn { ~ChdirOnReturn() { QDir::setCurrent(dir); } QString dir; }; // When cross-compiling from Windows to a *nix system the __FILE__ path's canonical path is an // empty string, which, when used as a prefix, would cause QFINDTESTDATA to look for files in // root ('/') when trying to look for files relative to the test source. QString usrPath = app_path + "/temp/usr/"; QVERIFY(QDir().mkpath(usrPath)); { ChdirOnReturn chdirObject{QDir::currentPath()}; QDir::setCurrent(app_path + "/temp"); QCOMPARE(QTest::qFindTestData("usr/", "C:\\path\\to\\source\\source.cpp", __LINE__, "C:\\path\\to\\build\\").toLower(), usrPath.toLower()); } QVERIFY(QDir().rmpath(usrPath)); #endif // Note, this is expected to generate a warning. // We can't use ignoreMessage, because the warning comes from testlib, // not via a "normal" qWarning. But it's OK, our caller (tst_selftests) // will verify that the warning is printed. QCOMPARE(QFINDTESTDATA(TESTFILE), QString()); } QTEST_MAIN(FindTestData) #include "findtestdata.moc"