diff options
Diffstat (limited to 'tests/auto/quickdialogs/qquickfiledialogimpl/tst_qquickfiledialogimpl.cpp')
| -rw-r--r-- | tests/auto/quickdialogs/qquickfiledialogimpl/tst_qquickfiledialogimpl.cpp | 231 |
1 files changed, 130 insertions, 101 deletions
diff --git a/tests/auto/quickdialogs/qquickfiledialogimpl/tst_qquickfiledialogimpl.cpp b/tests/auto/quickdialogs/qquickfiledialogimpl/tst_qquickfiledialogimpl.cpp index a42ea91b6d..6b81b9abbb 100644 --- a/tests/auto/quickdialogs/qquickfiledialogimpl/tst_qquickfiledialogimpl.cpp +++ b/tests/auto/quickdialogs/qquickfiledialogimpl/tst_qquickfiledialogimpl.cpp @@ -104,9 +104,13 @@ private: QStringList tempSubDirExpectedVisibleFiles(DelegateOrderPolicy order) const; QTemporaryDir tempDir; + QString tempDirCanonicalPath; QScopedPointer<QFile> tempFile1; + QString tempFile1CanonicalPath; QScopedPointer<QFile> tempFile2; + QString tempFile2CanonicalPath; QDir tempSubDir; + QString tempSubDirCanonicalPath; QDir tempSubSubDir; QScopedPointer<QFile> tempSubFile1; QScopedPointer<QFile> tempSubFile2; @@ -114,6 +118,7 @@ private: QTemporaryDir largeTempDir; QStringList largeTempDirPaths; QDir largeTempDirLargeSubDir; + QString largeTempDirLargeSubDirCanonicalPath; const int largeTempDirLargeSubDirIndex = 80; QDir oldCurrentDir; @@ -125,8 +130,8 @@ private: QStringList tst_QQuickFileDialogImpl::tempDirExpectedVisibleFiles(DelegateOrderPolicy order) const { return order == ShowDirectoriesFirst - ? QStringList { tempSubDir.path(), tempFile1->fileName(), tempFile2->fileName() } - : QStringList { tempFile1->fileName(), tempFile2->fileName(), tempSubDir.path() }; + ? QStringList { tempSubDirCanonicalPath, tempFile1CanonicalPath, tempFile2CanonicalPath } + : QStringList { tempFile1CanonicalPath, tempFile2CanonicalPath, tempSubDirCanonicalPath }; } QStringList tst_QQuickFileDialogImpl::tempSubDirExpectedVisibleFiles(DelegateOrderPolicy order) const @@ -150,12 +155,17 @@ void tst_QQuickFileDialogImpl::initTestCase() qputenv("QT_QUICK_DIALOGS_PRESELECT_FIRST_FILE", "1"); + // Ensure that each test starts off in the temporary directory. + oldCurrentDir = QDir::current(); + QDir::setCurrent(tempDir.path()); + QVERIFY2(tempDir.isValid(), qPrintable(tempDir.errorString())); + tempDirCanonicalPath = QFileInfo(tempDir.path()).canonicalFilePath(); // QTEST_QUICKCONTROLS_MAIN constructs the test case object once, // and then calls qRun() for each style, and qRun() calls initTestCase(). // So, we need to check if we've already made the temporary directory. // Note that this is only necessary if the test is run with more than one style. - if (!QDir(tempDir.path()).isEmpty()) + if (!QDir(tempDirCanonicalPath).isEmpty()) return; /* @@ -169,29 +179,35 @@ void tst_QQuickFileDialogImpl::initTestCase() ├── file1.txt (tempFile1) └── file2.txt (tempFile2) */ - tempSubDir = QDir(tempDir.path()); + tempSubDir = QDir(tempDirCanonicalPath); QVERIFY2(tempSubDir.mkdir("sub-dir"), qPrintable(QString::fromLatin1( "Failed to make sub-directory \"sub-dir\" in %1. Permissions are: %2") - .arg(tempDir.path()).arg(QDebug::toString(QFileInfo(tempDir.path()).permissions())))); + .arg(tempDirCanonicalPath).arg(QDebug::toString(QFileInfo(tempDirCanonicalPath).permissions())))); QVERIFY(tempSubDir.cd("sub-dir")); + tempSubDirCanonicalPath = tempSubDir.canonicalPath(); + QVERIFY(!tempSubDirCanonicalPath.isEmpty()); - tempSubSubDir = QDir(tempSubDir.path()); + tempSubSubDir = QDir(tempSubDirCanonicalPath); QVERIFY2(tempSubSubDir.mkdir("sub-sub-dir"), qPrintable(QString::fromLatin1( "Failed to make sub-directory \"sub-sub-dir\" in %1. Permissions are: %2") - .arg(tempSubDir.path()).arg(QDebug::toString(QFileInfo(tempSubDir.path()).permissions())))); + .arg(tempSubDirCanonicalPath).arg(QDebug::toString(QFileInfo(tempSubDirCanonicalPath).permissions())))); QVERIFY(tempSubSubDir.cd("sub-sub-dir")); - tempSubFile1.reset(new QFile(tempSubDir.path() + "/sub-file1.txt")); + tempSubFile1.reset(new QFile(tempSubDirCanonicalPath + "/sub-file1.txt")); QVERIFY(tempSubFile1->open(QIODevice::ReadWrite)); - tempSubFile2.reset(new QFile(tempSubDir.path() + "/sub-file2.txt")); + tempSubFile2.reset(new QFile(tempSubDirCanonicalPath + "/sub-file2.txt")); QVERIFY(tempSubFile2->open(QIODevice::ReadWrite)); - tempFile1.reset(new QFile(tempDir.path() + "/file1.txt")); + tempFile1.reset(new QFile(tempDirCanonicalPath + "/file1.txt")); QVERIFY(tempFile1->open(QIODevice::ReadWrite)); + tempFile1CanonicalPath = QFileInfo(tempFile1->fileName()).canonicalFilePath(); + QVERIFY(!tempFile1CanonicalPath.isEmpty()); - tempFile2.reset(new QFile(tempDir.path() + "/file2.txt")); + tempFile2.reset(new QFile(tempDirCanonicalPath + "/file2.txt")); QVERIFY(tempFile2->open(QIODevice::ReadWrite)); + tempFile2CanonicalPath = QFileInfo(tempFile2->fileName()).canonicalFilePath(); + QVERIFY(!tempFile1CanonicalPath.isEmpty()); /* Create another temporary directory that contains a large amount of folders. @@ -199,11 +215,12 @@ void tst_QQuickFileDialogImpl::initTestCase() QVERIFY2(largeTempDir.isValid(), qPrintable(largeTempDir.errorString())); const static int largeFileCount = 100; const QDir largeTempDirectory(largeTempDir.path()); + const QString largeTempDirectoryCanonicalPath = largeTempDirectory.canonicalPath(); for (int i = 0; i < largeFileCount; ++i) { // Pad with zeroes so that the directories are ordered as we expect. const QString dirName = QString::fromLatin1("dir%1").arg(i, 3, 10, QLatin1Char('0')); QVERIFY(largeTempDirectory.mkdir(dirName)); - largeTempDirPaths.append(largeTempDirectory.filePath(dirName)); + largeTempDirPaths.append(largeTempDirectoryCanonicalPath + '/' + dirName); } // ... and within one of those folders, more folders. @@ -213,10 +230,7 @@ void tst_QQuickFileDialogImpl::initTestCase() const QDir largeTempSubDirectory = QDir(largeTempDirLargeSubDir.path()); for (int i = 0; i < largeFileCount; ++i) QVERIFY(largeTempSubDirectory.mkdir(QString::fromLatin1("sub-dir%1").arg(i, 3, 10, QLatin1Char('0')))); - - // Ensure that each test starts off in the temporary directory. - oldCurrentDir = QDir::current(); - QDir::setCurrent(tempDir.path()); + largeTempDirLargeSubDirCanonicalPath = largeTempDirLargeSubDir.canonicalPath(); } void tst_QQuickFileDialogImpl::init() @@ -322,7 +336,8 @@ void tst_QQuickFileDialogImpl::defaults() QTRY_VERIFY(dialogHelper.isQuickDialogOpen()); QQuickFileDialogImpl *quickDialog = dialogHelper.window()->findChild<QQuickFileDialogImpl*>(); QVERIFY(quickDialog); - VERIFY_FILE_SELECTED_AND_FOCUSED(QUrl::fromLocalFile(QDir().absolutePath()), QUrl::fromLocalFile(tempSubDir.path()), 0); + VERIFY_FILE_SELECTED_AND_FOCUSED(QUrl::fromLocalFile(QDir().absolutePath()), + QUrl::fromLocalFile(tempSubDirCanonicalPath), 0); QCOMPARE(quickDialog->title(), QString()); } @@ -340,9 +355,10 @@ void tst_QQuickFileDialogImpl::chooseFileViaStandardButtons() QQuickFileDialogDelegate *delegate = nullptr; QTRY_VERIFY(findViewDelegateItem(dialogHelper.fileDialogListView, 2, delegate)); - COMPARE_URL(delegate->file(), QUrl::fromLocalFile(tempFile2->fileName())); + COMPARE_URL(delegate->file(), QUrl::fromLocalFile(tempFile2CanonicalPath)); QVERIFY(clickButton(delegate)); - VERIFY_FILE_SELECTED_AND_FOCUSED(QUrl::fromLocalFile(tempDir.path()), QUrl::fromLocalFile(tempFile2->fileName()), 2); + VERIFY_FILE_SELECTED_AND_FOCUSED(QUrl::fromLocalFile(tempDirCanonicalPath), + QUrl::fromLocalFile(tempFile2CanonicalPath), 2); QCOMPARE(dialogSelectedFileChangedSpy.size(), 1); QCOMPARE(dialogCurrentFileChangedSpy.size(), 1); @@ -353,9 +369,9 @@ void tst_QQuickFileDialogImpl::chooseFileViaStandardButtons() QQuickAbstractButton* openButton = findDialogButton(dialogButtonBox, "Open"); QVERIFY(openButton); QVERIFY(clickButton(openButton)); - COMPARE_URL(dialogHelper.dialog->selectedFile(), QUrl::fromLocalFile(tempFile2->fileName())); - COMPARE_URLS(dialogHelper.dialog->selectedFiles(), { QUrl::fromLocalFile(tempFile2->fileName()) }); - COMPARE_URL(dialogHelper.quickDialog->selectedFile(), QUrl::fromLocalFile(tempFile2->fileName())); + COMPARE_URL(dialogHelper.dialog->selectedFile(), QUrl::fromLocalFile(tempFile2CanonicalPath)); + COMPARE_URLS(dialogHelper.dialog->selectedFiles(), { QUrl::fromLocalFile(tempFile2CanonicalPath) }); + COMPARE_URL(dialogHelper.quickDialog->selectedFile(), QUrl::fromLocalFile(tempFile2CanonicalPath)); QCOMPARE(dialogSelectedFileChangedSpy.size(), 1); QCOMPARE(dialogCurrentFileChangedSpy.size(), 1); QTRY_VERIFY(!dialogHelper.quickDialog->isVisible()); @@ -371,12 +387,12 @@ void tst_QQuickFileDialogImpl::chooseFileViaDoubleClick() // Select the delegate by double-clicking. QQuickFileDialogDelegate *delegate = nullptr; QTRY_VERIFY(findViewDelegateItem(dialogHelper.fileDialogListView, 2, delegate)); - COMPARE_URL(delegate->file(), QUrl::fromLocalFile(tempFile2->fileName())) + COMPARE_URL(delegate->file(), QUrl::fromLocalFile(tempFile2CanonicalPath)) QVERIFY(doubleClickButton(delegate)); - COMPARE_URL(dialogHelper.dialog->currentFile(), QUrl::fromLocalFile(tempFile2->fileName())) - COMPARE_URLS(dialogHelper.dialog->currentFiles(), { QUrl::fromLocalFile(tempFile2->fileName()) }) - COMPARE_URL(dialogHelper.dialog->selectedFile(), QUrl::fromLocalFile(tempFile2->fileName())) - COMPARE_URLS(dialogHelper.dialog->selectedFiles(), { QUrl::fromLocalFile(tempFile2->fileName()) }) + COMPARE_URL(dialogHelper.dialog->currentFile(), QUrl::fromLocalFile(tempFile2CanonicalPath)) + COMPARE_URLS(dialogHelper.dialog->currentFiles(), { QUrl::fromLocalFile(tempFile2CanonicalPath) }) + COMPARE_URL(dialogHelper.dialog->selectedFile(), QUrl::fromLocalFile(tempFile2CanonicalPath)) + COMPARE_URLS(dialogHelper.dialog->selectedFiles(), { QUrl::fromLocalFile(tempFile2CanonicalPath) }) QVERIFY(!dialogHelper.dialog->isVisible()); QTRY_VERIFY(!dialogHelper.quickDialog->isVisible()); } @@ -390,7 +406,8 @@ void tst_QQuickFileDialogImpl::chooseFileViaTextEdit() // on the current item when we set it in setFileDialogListViewCurrentIndex(), // which can make the TextField's visibility check // below fail due to it being hidden when it loses activeFocus. - VERIFY_FILE_SELECTED_AND_FOCUSED(QUrl::fromLocalFile(tempDir.path()), QUrl::fromLocalFile(tempSubDir.path()), 0); + VERIFY_FILE_SELECTED_AND_FOCUSED(QUrl::fromLocalFile(tempDirCanonicalPath), + QUrl::fromLocalFile(tempSubDir.path()), 0); // Get the text edit visible with Ctrl+L. QTest::keySequence(dialogHelper.window(), editPathKeySequence); @@ -401,14 +418,14 @@ void tst_QQuickFileDialogImpl::chooseFileViaTextEdit() QCOMPARE(breadcrumbBar->textField()->selectedText(), breadcrumbBar->textField()->text()); // Enter the path to the file in the text edit. - enterText(dialogHelper.window(), tempFile2->fileName()); - QCOMPARE(breadcrumbBar->textField()->text(), tempFile2->fileName()); + enterText(dialogHelper.window(), tempFile2CanonicalPath); + QCOMPARE(breadcrumbBar->textField()->text(), tempFile2CanonicalPath); // Hit enter to accept. QTest::keyClick(dialogHelper.window(), Qt::Key_Return); - COMPARE_URL(dialogHelper.quickDialog->selectedFile(), QUrl::fromLocalFile(tempFile2->fileName())); - COMPARE_URL(dialogHelper.dialog->selectedFile(), QUrl::fromLocalFile(tempFile2->fileName())); - COMPARE_URLS(dialogHelper.dialog->selectedFiles(), { QUrl::fromLocalFile(tempFile2->fileName()) }); + COMPARE_URL(dialogHelper.quickDialog->selectedFile(), QUrl::fromLocalFile(tempFile2CanonicalPath)); + COMPARE_URL(dialogHelper.dialog->selectedFile(), QUrl::fromLocalFile(tempFile2CanonicalPath)); + COMPARE_URLS(dialogHelper.dialog->selectedFiles(), { QUrl::fromLocalFile(tempFile2CanonicalPath) }); QVERIFY(!dialogHelper.dialog->isVisible()); QTRY_VERIFY(!dialogHelper.quickDialog->isVisible()); } @@ -420,16 +437,17 @@ void tst_QQuickFileDialogImpl::chooseFileViaEnter() OPEN_QUICK_DIALOG(); // Before moving down, the first delegate in the view should be selected and have focus. - VERIFY_FILE_SELECTED_AND_FOCUSED(QUrl::fromLocalFile(tempDir.path()), QUrl::fromLocalFile(tempSubDir.path()), 0); + VERIFY_FILE_SELECTED_AND_FOCUSED(QUrl::fromLocalFile(tempDirCanonicalPath), + QUrl::fromLocalFile(tempSubDirCanonicalPath), 0); // Select the first file in the view by navigating with the down key. QTest::keyClick(dialogHelper.window(), Qt::Key_Down); - COMPARE_URL(dialogHelper.dialog->currentFile(), QUrl::fromLocalFile(tempFile1->fileName())); + COMPARE_URL(dialogHelper.dialog->currentFile(), QUrl::fromLocalFile(tempFile1CanonicalPath)); // Select the delegate by pressing enter. QTest::keyClick(dialogHelper.window(), Qt::Key_Return); - COMPARE_URL(dialogHelper.dialog->selectedFile(), QUrl::fromLocalFile(tempFile1->fileName())); - COMPARE_URLS(dialogHelper.dialog->selectedFiles(), { QUrl::fromLocalFile(tempFile1->fileName()) }); + COMPARE_URL(dialogHelper.dialog->selectedFile(), QUrl::fromLocalFile(tempFile1CanonicalPath)); + COMPARE_URLS(dialogHelper.dialog->selectedFiles(), { QUrl::fromLocalFile(tempFile1CanonicalPath) }); QVERIFY(!dialogHelper.dialog->isVisible()); QTRY_VERIFY(!dialogHelper.quickDialog->isVisible()); QCOMPARE(dialogHelper.dialog->result(), QQuickFileDialog::Accepted); @@ -441,8 +459,8 @@ void tst_QQuickFileDialogImpl::bindCurrentFolder_data() QTest::addColumn<QUrl>("expectedFolder"); QTest::addColumn<QStringList>("expectedVisibleFiles"); - const auto currentDirUrl = QUrl::fromLocalFile(QDir::current().path()); - const auto tempSubDirUrl = QUrl::fromLocalFile(tempSubDir.path()); + const auto currentDirUrl = QUrl::fromLocalFile(QDir::current().canonicalPath()); + const auto tempSubDirUrl = QUrl::fromLocalFile(tempSubDirCanonicalPath); const auto tempSubFile1Url = QUrl::fromLocalFile(tempSubFile1->fileName()); const QStringList currentDirFiles = tempDirExpectedVisibleFiles(ShowDirectoriesFirst); @@ -470,7 +488,8 @@ void tst_QQuickFileDialogImpl::bindCurrentFolder() // Even waiting for ListView polish and that the FolderListModel's status is ready aren't enough // on Windows, apparently, as sometimes there just aren't any delegates by the time we do the check. // So, we use QTRY_VERIFY2 each time we call this function just to be safe. - QTRY_VERIFY2(verifyFileDialogDelegates(dialogHelper.fileDialogListView, expectedVisibleFiles, failureMessage), qPrintable(failureMessage)); + QTRY_VERIFY2(verifyFileDialogDelegates(dialogHelper.fileDialogListView, expectedVisibleFiles, failureMessage), + qPrintable(failureMessage)); // Check that the breadcrumb bar is correct by constructing the expected files from the expectedFolder. auto breadcrumbBar = dialogHelper.quickDialog->findChild<QQuickFolderBreadcrumbBar*>(); @@ -487,10 +506,11 @@ void tst_QQuickFileDialogImpl::changeFolderViaStandardButtons() // Select the delegate by clicking once. QQuickFileDialogDelegate *delegate = nullptr; QTRY_VERIFY(findViewDelegateItem(dialogHelper.fileDialogListView, 0, delegate)); - COMPARE_URL(delegate->file(), QUrl::fromLocalFile(tempSubDir.path())); + COMPARE_URL(delegate->file(), QUrl::fromLocalFile(tempSubDirCanonicalPath)); QVERIFY(clickButton(delegate)); // The selectedFile should change, but not currentFolder. - VERIFY_FILE_SELECTED_AND_FOCUSED(QUrl::fromLocalFile(tempDir.path()), QUrl::fromLocalFile(tempSubDir.path()), 0); + VERIFY_FILE_SELECTED_AND_FOCUSED(QUrl::fromLocalFile(tempDirCanonicalPath), + QUrl::fromLocalFile(tempSubDirCanonicalPath), 0); // Click the "Open" button. The dialog should navigate to that directory, but still be open. QVERIFY(dialogHelper.quickDialog->footer()); @@ -500,7 +520,7 @@ void tst_QQuickFileDialogImpl::changeFolderViaStandardButtons() QVERIFY(openButton); QVERIFY(clickButton(openButton)); COMPARE_URL(dialogHelper.dialog->selectedFile(), QUrl::fromLocalFile(tempSubSubDir.path())); - COMPARE_URL(dialogHelper.dialog->currentFolder(), QUrl::fromLocalFile(tempSubDir.path())); + COMPARE_URL(dialogHelper.dialog->currentFolder(), QUrl::fromLocalFile(tempSubDirCanonicalPath)); QVERIFY(dialogHelper.dialog->isVisible()); dialogHelper.dialog->close(); @@ -530,14 +550,14 @@ void tst_QQuickFileDialogImpl::changeFolderViaDoubleClick() QQuickFileDialogDelegate *subDirDelegate = nullptr; const int subDirIndex = showDirsFirst ? 0 : 2; QTRY_VERIFY(findViewDelegateItem(dialogHelper.fileDialogListView, subDirIndex, subDirDelegate)); - COMPARE_URL(subDirDelegate->file(), QUrl::fromLocalFile(tempSubDir.path())); + COMPARE_URL(subDirDelegate->file(), QUrl::fromLocalFile(tempSubDirCanonicalPath)); QVERIFY(doubleClickButton(subDirDelegate)); const QStringList expectedVisibleFiles = tempSubDirExpectedVisibleFiles(showDirsFirst ? ShowDirectoriesFirst : ShowFilesFirst); QString failureMessage; QTRY_VERIFY2(verifyFileDialogDelegates(dialogHelper.fileDialogListView, expectedVisibleFiles, failureMessage), qPrintable(failureMessage)); // The first file in the directory should now be selected. const QUrl firstFileUrl = showDirsFirst ? QUrl::fromLocalFile(tempSubSubDir.path()) : QUrl::fromLocalFile(tempSubFile1->fileName()); - VERIFY_FILE_SELECTED_AND_FOCUSED(QUrl::fromLocalFile(tempSubDir.path()), firstFileUrl, 0); + VERIFY_FILE_SELECTED_AND_FOCUSED(QUrl::fromLocalFile(tempSubDirCanonicalPath), firstFileUrl, 0); // Since we only chose a folder, the dialog should still be open. QVERIFY(dialogHelper.dialog->isVisible()); @@ -552,7 +572,8 @@ void tst_QQuickFileDialogImpl::chooseFolderViaTextEdit() FileDialogTestHelper dialogHelper(this, "fileDialog.qml"); OPEN_QUICK_DIALOG(); // See comment in chooseFileViaTextEdit for why we check for this. - VERIFY_FILE_SELECTED_AND_FOCUSED(QUrl::fromLocalFile(tempDir.path()), QUrl::fromLocalFile(tempSubDir.path()), 0); + VERIFY_FILE_SELECTED_AND_FOCUSED(QUrl::fromLocalFile(tempDirCanonicalPath), + QUrl::fromLocalFile(tempSubDirCanonicalPath), 0); // Get the text edit visible with Ctrl+L. const auto editPathKeySequence = QKeySequence(Qt::CTRL | Qt::Key_L); @@ -564,8 +585,8 @@ void tst_QQuickFileDialogImpl::chooseFolderViaTextEdit() QCOMPARE(breadcrumbBar->textField()->selectedText(), breadcrumbBar->textField()->text()); // Enter the path to the folder in the text edit. - enterText(dialogHelper.window(), tempSubDir.path()); - QCOMPARE(breadcrumbBar->textField()->text(), tempSubDir.path()); + enterText(dialogHelper.window(), tempSubDirCanonicalPath); + QCOMPARE(breadcrumbBar->textField()->text(), tempSubDirCanonicalPath); // Hit enter to accept. QTest::keyClick(dialogHelper.window(), Qt::Key_Return); @@ -574,7 +595,7 @@ void tst_QQuickFileDialogImpl::chooseFolderViaTextEdit() tempSubDirExpectedVisibleFiles(ShowDirectoriesFirst), failureMessage), qPrintable(failureMessage)); // The first file in the directory should be selected, which is "sub-sub-dir". // Note that the TextEdit will still have focus, so we can't use VERIFY_FILE_SELECTED_AND_FOCUSED. - VERIFY_FILE_SELECTED(QUrl::fromLocalFile(tempSubDir.path()), QUrl::fromLocalFile(tempSubSubDir.path())); + VERIFY_FILE_SELECTED(QUrl::fromLocalFile(tempSubDirCanonicalPath), QUrl::fromLocalFile(tempSubSubDir.path())); VERIFY_DELEGATE_CURRENT(QUrl::fromLocalFile(tempSubSubDir.path()), 0) QVERIFY(dialogHelper.dialog->isVisible()); @@ -590,7 +611,8 @@ void tst_QQuickFileDialogImpl::chooseFolderViaEnter() OPEN_QUICK_DIALOG(); // The first delegate in the view should be selected and have focus. - VERIFY_FILE_SELECTED_AND_FOCUSED(QUrl::fromLocalFile(tempDir.path()), QUrl::fromLocalFile(tempSubDir.path()), 0); + VERIFY_FILE_SELECTED_AND_FOCUSED(QUrl::fromLocalFile(tempDirCanonicalPath), + QUrl::fromLocalFile(tempSubDirCanonicalPath), 0); // Select the delegate by pressing enter. QTest::keyClick(dialogHelper.window(), Qt::Key_Return); @@ -598,7 +620,8 @@ void tst_QQuickFileDialogImpl::chooseFolderViaEnter() QTRY_VERIFY2(verifyFileDialogDelegates(dialogHelper.fileDialogListView, tempSubDirExpectedVisibleFiles(ShowDirectoriesFirst), failureMessage), qPrintable(failureMessage)); // The first file in the new directory should be selected, which is "sub-sub-dir". - VERIFY_FILE_SELECTED_AND_FOCUSED(QUrl::fromLocalFile(tempSubDir.path()), QUrl::fromLocalFile(tempSubSubDir.path()), 0); + VERIFY_FILE_SELECTED_AND_FOCUSED(QUrl::fromLocalFile(tempSubDirCanonicalPath), + QUrl::fromLocalFile(tempSubSubDir.path()), 0); // Since we only chose a folder, the dialog should still be open. QVERIFY(dialogHelper.dialog->isVisible()); @@ -613,7 +636,8 @@ void tst_QQuickFileDialogImpl::chooseFileAndThenFolderViaTextEdit() FileDialogTestHelper dialogHelper(this, "fileDialog.qml"); OPEN_QUICK_DIALOG(); // See comment in chooseFileViaTextEdit for why we check for this. - VERIFY_FILE_SELECTED_AND_FOCUSED(QUrl::fromLocalFile(tempDir.path()), QUrl::fromLocalFile(tempSubDir.path()), 0); + VERIFY_FILE_SELECTED_AND_FOCUSED(QUrl::fromLocalFile(tempDirCanonicalPath), + QUrl::fromLocalFile(tempSubDirCanonicalPath), 0); // Get the text edit visible with Ctrl+L. QTest::keySequence(dialogHelper.window(), editPathKeySequence); @@ -624,14 +648,14 @@ void tst_QQuickFileDialogImpl::chooseFileAndThenFolderViaTextEdit() QCOMPARE(breadcrumbBar->textField()->selectedText(), breadcrumbBar->textField()->text()); // Enter the path to the file in the text edit. - enterText(dialogHelper.window(), tempFile2->fileName()); - QCOMPARE(breadcrumbBar->textField()->text(), tempFile2->fileName()); + enterText(dialogHelper.window(), tempFile2CanonicalPath); + QCOMPARE(breadcrumbBar->textField()->text(), tempFile2CanonicalPath); // Hit enter to accept. QTest::keyClick(dialogHelper.window(), Qt::Key_Return); - COMPARE_URL(dialogHelper.quickDialog->selectedFile(), QUrl::fromLocalFile(tempFile2->fileName())); - COMPARE_URL(dialogHelper.dialog->selectedFile(), QUrl::fromLocalFile(tempFile2->fileName())); - COMPARE_URLS(dialogHelper.dialog->selectedFiles(), { QUrl::fromLocalFile(tempFile2->fileName()) }); + COMPARE_URL(dialogHelper.quickDialog->selectedFile(), QUrl::fromLocalFile(tempFile2CanonicalPath)); + COMPARE_URL(dialogHelper.dialog->selectedFile(), QUrl::fromLocalFile(tempFile2CanonicalPath)); + COMPARE_URLS(dialogHelper.dialog->selectedFiles(), { QUrl::fromLocalFile(tempFile2CanonicalPath) }); QVERIFY(!dialogHelper.dialog->isVisible()); QTRY_VERIFY(!dialogHelper.quickDialog->isVisible()); // Check that the text edit is hidden and breadcrumbs are shown instead. @@ -647,12 +671,12 @@ void tst_QQuickFileDialogImpl::chooseFileAndThenFolderViaTextEdit() QTest::keySequence(dialogHelper.window(), editPathKeySequence); QVERIFY(breadcrumbBar->textField()->isVisible()); // The text edit should show the directory that contains the last file that was selected. - QCOMPARE(breadcrumbBar->textField()->text(), tempDir.path()); + QCOMPARE(breadcrumbBar->textField()->text(), tempDirCanonicalPath); QCOMPARE(breadcrumbBar->textField()->selectedText(), breadcrumbBar->textField()->text()); // Enter the path to the folder in the text edit. - enterText(dialogHelper.window(), tempSubDir.path()); - QCOMPARE(breadcrumbBar->textField()->text(), tempSubDir.path()); + enterText(dialogHelper.window(), tempSubDirCanonicalPath); + QCOMPARE(breadcrumbBar->textField()->text(), tempSubDirCanonicalPath); // Hit enter to accept. QTest::keyClick(dialogHelper.window(), Qt::Key_Return); @@ -661,7 +685,7 @@ void tst_QQuickFileDialogImpl::chooseFileAndThenFolderViaTextEdit() tempSubDirExpectedVisibleFiles(ShowDirectoriesFirst), failureMessage), qPrintable(failureMessage)); // The first file in the directory should be selected, which is "sub-sub-dir". // Note that the TextEdit will still have focus, so we can't use VERIFY_FILE_SELECTED_AND_FOCUSED. - VERIFY_FILE_SELECTED(QUrl::fromLocalFile(tempSubDir.path()), QUrl::fromLocalFile(tempSubSubDir.path())); + VERIFY_FILE_SELECTED(QUrl::fromLocalFile(tempSubDirCanonicalPath), QUrl::fromLocalFile(tempSubSubDir.path())); VERIFY_DELEGATE_CURRENT(QUrl::fromLocalFile(tempSubSubDir.path()), 0) // Close the dialog. @@ -676,7 +700,8 @@ void tst_QQuickFileDialogImpl::cancelDialogWhileTextEditHasFocus() FileDialogTestHelper dialogHelper(this, "fileDialog.qml"); OPEN_QUICK_DIALOG(); // See comment in chooseFileViaTextEdit for why we check for this. - VERIFY_FILE_SELECTED_AND_FOCUSED(QUrl::fromLocalFile(tempDir.path()), QUrl::fromLocalFile(tempSubDir.path()), 0); + VERIFY_FILE_SELECTED_AND_FOCUSED(QUrl::fromLocalFile(tempDirCanonicalPath), + QUrl::fromLocalFile(tempSubDirCanonicalPath), 0); // Get the text edit visible with Ctrl+L. QTest::keySequence(dialogHelper.window(), editPathKeySequence); @@ -744,12 +769,12 @@ void tst_QQuickFileDialogImpl::goUp() // Open the dialog. Start off in "sub-dir". FileDialogTestHelper dialogHelper(this, "bindCurrentFolder.qml", {}, - {{ "initialFolder", QUrl::fromLocalFile(tempSubDir.path()) }}); + {{ "initialFolder", QUrl::fromLocalFile(tempSubDirCanonicalPath) }}); OPEN_QUICK_DIALOG(); // Go up a directory via the button next to the breadcrumb bar. - qCDebug(lcTest) << "going up to" << tempDir.path() << "- files in that dir:\n" - << QQuickFileDialogImplPrivate::get(dialogHelper.quickDialog)->fileList(QDir(tempDir.path())); + qCDebug(lcTest) << "going up to" << tempDirCanonicalPath << "- files in that dir:\n" + << QQuickFileDialogImplPrivate::get(dialogHelper.quickDialog)->fileList(QDir(tempDirCanonicalPath)); auto breadcrumbBar = dialogHelper.quickDialog->findChild<QQuickFolderBreadcrumbBar*>(); QVERIFY(breadcrumbBar); auto barListView = qobject_cast<QQuickListView*>(breadcrumbBar->contentItem()); @@ -762,19 +787,21 @@ void tst_QQuickFileDialogImpl::goUp() QTRY_VERIFY2(verifyFileDialogDelegates(dialogHelper.fileDialogListView, tempDirExpectedVisibleFiles(showDirsFirst ? ShowDirectoriesFirst : ShowFilesFirst), failureMessage), qPrintable(failureMessage)); int expectedCurrentIndex = showDirsFirst ? 0 : 2; - VERIFY_FILE_SELECTED_AND_FOCUSED(QUrl::fromLocalFile(tempDir.path()), QUrl::fromLocalFile(tempSubDir.path()), expectedCurrentIndex); + VERIFY_FILE_SELECTED_AND_FOCUSED(QUrl::fromLocalFile(tempDirCanonicalPath), + QUrl::fromLocalFile(tempSubDirCanonicalPath), expectedCurrentIndex); // Go up a directory via the keyboard shortcut. - QDir tempParentDir(tempDir.path()); + QDir tempParentDir(tempDirCanonicalPath); QVERIFY(tempParentDir.cdUp()); const auto filesInTempParentDir = QQuickFileDialogImplPrivate::get(dialogHelper.quickDialog)->fileList(tempParentDir); qCDebug(lcTest) << "going up to" << tempParentDir.path() << "- files in that dir:\n" << filesInTempParentDir; QTest::keySequence(dialogHelper.window(), goUpKeySequence); // Ubuntu on QEMU arm shows no files in /tmp even if there are. if (!filesInTempParentDir.isEmpty()) { - expectedCurrentIndex = filesInTempParentDir.indexOf(QFileInfo(tempDir.path())); + expectedCurrentIndex = filesInTempParentDir.indexOf(QFileInfo(tempDirCanonicalPath)); QVERIFY(expectedCurrentIndex != -1); - VERIFY_FILE_SELECTED_AND_FOCUSED(QUrl::fromLocalFile(tempParentDir.path()), QUrl::fromLocalFile(tempDir.path()), expectedCurrentIndex); + VERIFY_FILE_SELECTED_AND_FOCUSED(QUrl::fromLocalFile(tempParentDir.path()), + QUrl::fromLocalFile(tempDirCanonicalPath), expectedCurrentIndex); } } @@ -782,10 +809,11 @@ void tst_QQuickFileDialogImpl::goUpWhileTextEditHasFocus() { // Open the dialog. FileDialogTestHelper dialogHelper(this, "bindCurrentFolder.qml", {}, - {{ "initialFolder", QUrl::fromLocalFile(tempSubDir.path()) }}); + {{ "initialFolder", QUrl::fromLocalFile(tempSubDirCanonicalPath) }}); OPEN_QUICK_DIALOG(); // See comment in chooseFileViaTextEdit for why we check for this. - VERIFY_FILE_SELECTED_AND_FOCUSED(QUrl::fromLocalFile(tempSubDir.path()), QUrl::fromLocalFile(tempSubSubDir.path()), 0); + VERIFY_FILE_SELECTED_AND_FOCUSED(QUrl::fromLocalFile(tempSubDirCanonicalPath), + QUrl::fromLocalFile(tempSubSubDir.path()), 0); // Get the text edit visible with Ctrl+L. QTest::keySequence(dialogHelper.window(), editPathKeySequence); @@ -800,7 +828,7 @@ void tst_QQuickFileDialogImpl::goUpWhileTextEditHasFocus() QVERIFY(QQuickTest::qWaitForPolish(barListView)); QVERIFY(clickButton(breadcrumbBar->upButton())); // The path should have changed to the parent directory. - COMPARE_URL(dialogHelper.dialog->currentFolder(), QUrl::fromLocalFile(tempDir.path())); + COMPARE_URL(dialogHelper.dialog->currentFolder(), QUrl::fromLocalFile(tempDirCanonicalPath)); // The text edit should be hidden when it loses focus. QVERIFY(!breadcrumbBar->textField()->hasActiveFocus()); QVERIFY(!breadcrumbBar->textField()->isVisible()); @@ -869,7 +897,8 @@ void tst_QQuickFileDialogImpl::keyAndShortcutHandling() // Open the dialog. FileDialogTestHelper dialogHelper(this, "fileDialog.qml"); OPEN_QUICK_DIALOG(); - VERIFY_FILE_SELECTED_AND_FOCUSED(QUrl::fromLocalFile(tempDir.path()), QUrl::fromLocalFile(tempSubDir.path()), 0); + VERIFY_FILE_SELECTED_AND_FOCUSED(QUrl::fromLocalFile(tempDirCanonicalPath), + QUrl::fromLocalFile(tempSubDirCanonicalPath), 0); // Get the text edit visible with Ctrl+L. QTest::keySequence(dialogHelper.window(), editPathKeySequence); @@ -983,8 +1012,8 @@ void tst_QQuickFileDialogImpl::changeNameFilters() QTRY_VERIFY(!comboBox->popup()->isVisible()); // Use QTRY_VERIFY2 here to fix a failure on QEMU armv7 (QT_QPA_PLATFORM=offscreen). // Not sure why it's necessary. - QTRY_VERIFY2(verifyFileDialogDelegates(dialogHelper.fileDialogListView, { tempSubDir.path() }, failureMessage), qPrintable(failureMessage)); - + QTRY_VERIFY2(verifyFileDialogDelegates(dialogHelper.fileDialogListView, + { tempSubDirCanonicalPath }, failureMessage), qPrintable(failureMessage)); // Open the popup again. QTest::mouseClick(dialogHelper.window(), Qt::LeftButton, Qt::NoModifier, comboBoxCenterPos); QTRY_VERIFY(comboBox->popup()->isOpened()); @@ -1014,8 +1043,8 @@ void tst_QQuickFileDialogImpl::changeNameFiltersAfterChangingFolder() QQuickFileDialogDelegate *subDirDelegate = nullptr; QTRY_VERIFY(findViewDelegateItem(dialogHelper.fileDialogListView, 0, subDirDelegate)); QVERIFY(doubleClickButton(subDirDelegate)); - COMPARE_URL(dialogHelper.dialog->currentFolder(), QUrl::fromLocalFile(tempSubDir.path())); - COMPARE_URL(dialogHelper.quickDialog->currentFolder(), QUrl::fromLocalFile(tempSubDir.path())); + COMPARE_URL(dialogHelper.dialog->currentFolder(), QUrl::fromLocalFile(tempSubDirCanonicalPath)); + COMPARE_URL(dialogHelper.quickDialog->currentFolder(), QUrl::fromLocalFile(tempSubDirCanonicalPath)); // Open the ComboBox's popup. const QQuickComboBox *comboBox = dialogHelper.quickDialog->findChild<QQuickComboBox*>(); @@ -1222,10 +1251,10 @@ void tst_QQuickFileDialogImpl::fileMode() // Select the first file (not a directory). QQuickFileDialogDelegate *tempFile1Delegate = nullptr; QTRY_VERIFY(findViewDelegateItem(dialogHelper.fileDialogListView, 1, tempFile1Delegate)); - COMPARE_URL(tempFile1Delegate->file(), QUrl::fromLocalFile(tempFile1->fileName())); + COMPARE_URL(tempFile1Delegate->file(), QUrl::fromLocalFile(tempFile1CanonicalPath)); QVERIFY(clickButton(tempFile1Delegate)); - COMPARE_URL(dialogHelper.dialog->currentFile(), QUrl::fromLocalFile(tempFile1->fileName())); - COMPARE_URLS(dialogHelper.dialog->currentFiles(), { QUrl::fromLocalFile(tempFile1->fileName()) }); + COMPARE_URL(dialogHelper.dialog->currentFile(), QUrl::fromLocalFile(tempFile1CanonicalPath)); + COMPARE_URLS(dialogHelper.dialog->currentFiles(), { QUrl::fromLocalFile(tempFile1CanonicalPath) }); // All modes should support opening an existing file, so the accept button should be enabled. QVERIFY(dialogHelper.quickDialog->footer()); @@ -1238,21 +1267,21 @@ void tst_QQuickFileDialogImpl::fileMode() // Only the OpenFiles mode should allow multiple files to be selected, however. QQuickFileDialogDelegate *tempFile2Delegate = nullptr; QTRY_VERIFY(findViewDelegateItem(dialogHelper.fileDialogListView, 2, tempFile2Delegate)); - COMPARE_URL(tempFile2Delegate->file(), QUrl::fromLocalFile(tempFile2->fileName())); + COMPARE_URL(tempFile2Delegate->file(), QUrl::fromLocalFile(tempFile2CanonicalPath)); QTest::keyPress(dialogHelper.window(), Qt::Key_Shift); QVERIFY(clickButton(tempFile2Delegate)); QTest::keyRelease(dialogHelper.window(), Qt::Key_Shift); if (fileMode == QQuickFileDialog::OpenFiles) { // currentFile() always points to the first file in the list of selected files. - COMPARE_URL(dialogHelper.dialog->currentFile(), QUrl::fromLocalFile(tempFile1->fileName())); + COMPARE_URL(dialogHelper.dialog->currentFile(), QUrl::fromLocalFile(tempFile1CanonicalPath)); const QList<QUrl> expectedSelectedFiles = { - QUrl::fromLocalFile(tempFile1->fileName()), QUrl::fromLocalFile(tempFile2->fileName()) }; + QUrl::fromLocalFile(tempFile1CanonicalPath), QUrl::fromLocalFile(tempFile2CanonicalPath) }; COMPARE_URLS(dialogHelper.dialog->currentFiles(), expectedSelectedFiles); } else { // OpenFile and SaveFile dialogs should have tempFile2 selected since it was clicked, // but the shift should do nothing, so tempFile1 should no longer be selected. - COMPARE_URL(dialogHelper.dialog->currentFile(), QUrl::fromLocalFile(tempFile2->fileName())); - COMPARE_URLS(dialogHelper.dialog->currentFiles(), { QUrl::fromLocalFile(tempFile2->fileName()) }); + COMPARE_URL(dialogHelper.dialog->currentFile(), QUrl::fromLocalFile(tempFile2CanonicalPath)); + COMPARE_URLS(dialogHelper.dialog->currentFiles(), { QUrl::fromLocalFile(tempFile2CanonicalPath) }); } // Get the text edit visible with Ctrl+L. @@ -1275,18 +1304,18 @@ void tst_QQuickFileDialogImpl::fileMode() // For OpenFile(s), we do what Qt Quick Dialogs 1.x did, and restore the previous (valid) dir path. // The currentFile(s) should remain unchanged too. QVERIFY(dialogHelper.dialog->isVisible()); - COMPARE_URL(dialogHelper.dialog->currentFolder(), QUrl::fromLocalFile(tempDir.path())); - QCOMPARE(breadcrumbBar->textField()->text(), tempDir.path()); + COMPARE_URL(dialogHelper.dialog->currentFolder(), QUrl::fromLocalFile(tempDirCanonicalPath)); + QCOMPARE(breadcrumbBar->textField()->text(), tempDirCanonicalPath); // Should be unchanged from the last time. if (fileMode == QQuickFileDialog::OpenFiles) { - COMPARE_URL(dialogHelper.dialog->currentFile(), QUrl::fromLocalFile(tempFile1->fileName())); + COMPARE_URL(dialogHelper.dialog->currentFile(), QUrl::fromLocalFile(tempFile1CanonicalPath)); const QList<QUrl> expectedSelectedFiles = { - QUrl::fromLocalFile(tempFile1->fileName()), QUrl::fromLocalFile(tempFile2->fileName()) }; + QUrl::fromLocalFile(tempFile1CanonicalPath), QUrl::fromLocalFile(tempFile2CanonicalPath) }; COMPARE_URLS(dialogHelper.dialog->currentFiles(), expectedSelectedFiles); } else { // OpenFile - COMPARE_URL(dialogHelper.dialog->currentFile(), QUrl::fromLocalFile(tempFile2->fileName())); - COMPARE_URLS(dialogHelper.dialog->currentFiles(), { QUrl::fromLocalFile(tempFile2->fileName()) }); + COMPARE_URL(dialogHelper.dialog->currentFile(), QUrl::fromLocalFile(tempFile2CanonicalPath)); + COMPARE_URLS(dialogHelper.dialog->currentFiles(), { QUrl::fromLocalFile(tempFile2CanonicalPath) }); } } } @@ -1371,7 +1400,7 @@ void tst_QQuickFileDialogImpl::setSelectedFile() QFETCH(QQuickFileDialog::FileMode, fileMode); // Open the dialog. - const auto tempFile1Url = QUrl::fromLocalFile(tempFile1->fileName()); + const auto tempFile1Url = QUrl::fromLocalFile(tempFile1CanonicalPath); const QVariantMap initialProperties = { { "tempFile1Url", QVariant::fromValue(tempFile1Url) }, { "fileMode", QVariant::fromValue(fileMode) } @@ -1384,12 +1413,12 @@ void tst_QQuickFileDialogImpl::setSelectedFile() OPEN_QUICK_DIALOG(); // The selected file should be what we set. - VERIFY_FILE_SELECTED_AND_FOCUSED(QUrl::fromLocalFile(tempDir.path()), tempFile1Url, 1); + VERIFY_FILE_SELECTED_AND_FOCUSED(QUrl::fromLocalFile(tempDirCanonicalPath), tempFile1Url, 1); // Select the next file in the view by navigating with the down key. // We know it already has focus, as VERIFY_FILE_SELECTED_AND_FOCUSED checks that. QTest::keyClick(dialogHelper.window(), Qt::Key_Down); - const auto tempFile2Url = QUrl::fromLocalFile(tempFile2->fileName()); + const auto tempFile2Url = QUrl::fromLocalFile(tempFile2CanonicalPath); COMPARE_URL(dialogHelper.quickDialog->selectedFile(), tempFile2Url); COMPARE_URL(dialogHelper.dialog->selectedFile(), tempFile2Url); @@ -1402,10 +1431,10 @@ void tst_QQuickFileDialogImpl::setSelectedFile() QCOMPARE(dialogHelper.dialog->result(), QQuickFileDialog::Accepted); // Set a different initial selectedFile and re-open. - dialogHelper.dialog->setSelectedFile(QUrl::fromLocalFile(tempFile1->fileName())); + dialogHelper.dialog->setSelectedFile(QUrl::fromLocalFile(tempFile1CanonicalPath)); QVERIFY(dialogHelper.openDialog()); QTRY_VERIFY(dialogHelper.isQuickDialogOpen()); - VERIFY_FILE_SELECTED_AND_FOCUSED(QUrl::fromLocalFile(tempDir.path()), tempFile1Url, 1); + VERIFY_FILE_SELECTED_AND_FOCUSED(QUrl::fromLocalFile(tempDirCanonicalPath), tempFile1Url, 1); // Close it. dialogHelper.dialog->close(); @@ -1414,7 +1443,7 @@ void tst_QQuickFileDialogImpl::setSelectedFile() // Try to set an invalid selectedFile; it should be a no-op for modes other than SaveFile, // and the previous selectedFile should still be selected. - const QString invalidPath = tempDir.path() + "/does-not-exist.txt"; + const QString invalidPath = tempDirCanonicalPath + "/does-not-exist.txt"; if (fileMode != QQuickFileDialog::SaveFile) { QTest::ignoreMessage(QtWarningMsg, QRegularExpression(QLatin1String(".*QML FileDialog: Cannot set ") + invalidPath + QLatin1String(" as a selected file because it doesn't exist"))); @@ -1422,7 +1451,7 @@ void tst_QQuickFileDialogImpl::setSelectedFile() dialogHelper.dialog->setSelectedFile(QUrl::fromLocalFile(invalidPath)); QVERIFY(dialogHelper.openDialog()); if (fileMode != QQuickFileDialog::SaveFile) { - VERIFY_FILE_SELECTED_AND_FOCUSED(QUrl::fromLocalFile(tempDir.path()), tempFile1Url, 1); + VERIFY_FILE_SELECTED_AND_FOCUSED(QUrl::fromLocalFile(tempDirCanonicalPath), tempFile1Url, 1); } else { QTRY_COMPARE(dialogHelper.fileDialogListView->currentIndex(), -1); } @@ -1474,7 +1503,7 @@ void tst_QQuickFileDialogImpl::selectExistingFileShouldWarnUserWhenFileModeEqual { FileDialogTestHelper dialogHelper(this, "fileDialog.qml"); dialogHelper.dialog->setFileMode(QQuickFileDialog::SaveFile); - dialogHelper.dialog->setSelectedFile(QUrl::fromLocalFile(tempFile1->fileName())); + dialogHelper.dialog->setSelectedFile(QUrl::fromLocalFile(tempFile1CanonicalPath)); OPEN_QUICK_DIALOG(); QQuickTest::qWaitForPolish(dialogHelper.window()); @@ -1554,8 +1583,8 @@ void tst_QQuickFileDialogImpl::selectExistingFileShouldWarnUserWhenFileModeEqual void tst_QQuickFileDialogImpl::fileNameTextFieldOnlyChangesWhenSelectingFiles() { const auto tempSubFile1Url = QUrl::fromLocalFile(tempSubFile1->fileName()); - const auto tempSubDirUrl = QUrl::fromLocalFile(tempSubDir.path()); - const auto tempFile11Url = QUrl::fromLocalFile(tempFile1->fileName()); + const auto tempSubDirUrl = QUrl::fromLocalFile(tempSubDirCanonicalPath); + const auto tempFile11Url = QUrl::fromLocalFile(tempFile1CanonicalPath); const QVariantMap initialProperties = { { "tempFile1Url", QVariant::fromValue(tempSubFile1Url) }, |
