2022-06-22 12:33:48 +00:00
|
|
|
// Copyright (C) 2022 The Qt Company Ltd.
|
|
|
|
// Copyright (C) 2016 Intel Corporation.
|
|
|
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
|
|
|
|
|
|
|
#include <QtGui/private/qlocalfileapi_p.h>
|
|
|
|
#include <QTest>
|
|
|
|
#include <emscripten/val.h>
|
|
|
|
|
|
|
|
class tst_LocalFileApi : public QObject
|
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
|
|
|
|
private:
|
2022-09-23 13:27:50 +00:00
|
|
|
emscripten::val makeAccept(std::vector<emscripten::val> types)
|
|
|
|
{
|
2022-06-22 12:33:48 +00:00
|
|
|
auto accept = emscripten::val::object();
|
|
|
|
accept.set("application/octet-stream",
|
|
|
|
emscripten::val::array(std::move(types)));
|
|
|
|
return accept;
|
|
|
|
}
|
|
|
|
|
2022-09-23 13:27:50 +00:00
|
|
|
emscripten::val makeType(QString description, std::vector<emscripten::val> acceptExtensions)
|
|
|
|
{
|
2022-06-22 12:33:48 +00:00
|
|
|
using namespace emscripten;
|
|
|
|
|
|
|
|
auto type = val::object();
|
|
|
|
type.set("description", description.toStdString());
|
|
|
|
|
|
|
|
auto accept = val::object();
|
|
|
|
accept.set("application/octet-stream",
|
|
|
|
val::array(std::move(acceptExtensions)));
|
|
|
|
type.set("accept", makeAccept(std::move(acceptExtensions)));
|
|
|
|
|
|
|
|
return type;
|
|
|
|
}
|
|
|
|
|
|
|
|
emscripten::val makeOpenFileOptions(bool acceptMultiple, std::vector<emscripten::val> types) {
|
|
|
|
using namespace emscripten;
|
|
|
|
|
|
|
|
auto webFilter = val::object();
|
|
|
|
webFilter.set("types", val::array(std::move(types)));
|
|
|
|
if (!types.empty())
|
|
|
|
webFilter.set("excludeAcceptAllOption", val(true));
|
|
|
|
webFilter.set("multiple", val(acceptMultiple));
|
|
|
|
|
|
|
|
return webFilter;
|
|
|
|
}
|
|
|
|
|
|
|
|
emscripten::val makeSaveFileOptions(QString suggestedName, std::vector<emscripten::val> types) {
|
|
|
|
using namespace emscripten;
|
|
|
|
|
|
|
|
auto webFilter = val::object();
|
|
|
|
webFilter.set("suggestedName", val(suggestedName.toStdString()));
|
|
|
|
webFilter.set("types", val::array(std::move(types)));
|
|
|
|
|
|
|
|
return webFilter;
|
|
|
|
}
|
|
|
|
|
|
|
|
private Q_SLOTS:
|
|
|
|
void fileExtensionFilterTransformation_data();
|
|
|
|
void fileExtensionFilterTransformation();
|
|
|
|
void acceptTransformation_data();
|
|
|
|
void acceptTransformation();
|
|
|
|
void typeTransformation_data();
|
|
|
|
void typeTransformation();
|
|
|
|
void openFileOptions_data();
|
|
|
|
void openFileOptions();
|
|
|
|
void saveFileOptions_data();
|
|
|
|
void saveFileOptions();
|
2022-09-23 13:27:50 +00:00
|
|
|
void fileInputAccept_data();
|
|
|
|
void fileInputAccept();
|
2022-06-22 12:33:48 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
bool valDeepEquals(emscripten::val lhs, emscripten::val rhs)
|
|
|
|
{
|
|
|
|
auto json = emscripten::val::global("JSON");
|
|
|
|
auto lhsAsJsonString = json.call<emscripten::val>("stringify", lhs);
|
|
|
|
auto rhsAsJsonString = json.call<emscripten::val>("stringify", rhs);
|
|
|
|
|
|
|
|
return lhsAsJsonString.equals(rhsAsJsonString);
|
|
|
|
}
|
|
|
|
|
|
|
|
void tst_LocalFileApi::fileExtensionFilterTransformation_data()
|
|
|
|
{
|
|
|
|
QTest::addColumn<QString>("qtFileFilter");
|
2022-09-23 13:27:50 +00:00
|
|
|
QTest::addColumn<std::optional<QString>>("expectedWebExtensionFilter");
|
|
|
|
|
|
|
|
QTest::newRow("PNG extension with an asterisk")
|
|
|
|
<< QString("*.png") << std::make_optional<QString>(".png");
|
|
|
|
QTest::newRow("Long extension with an asterisk")
|
|
|
|
<< QString("*.someotherfile") << std::make_optional<QString>(".someotherfile");
|
|
|
|
QTest::newRow(".dat with no asterisk")
|
|
|
|
<< QString(".dat") << std::make_optional<QString>(".dat");
|
|
|
|
QTest::newRow("Multiple asterisks") << QString("*ot*.abc") << std::optional<QString>();
|
|
|
|
QTest::newRow("Filename") << QString("abcd.abc") << std::optional<QString>();
|
|
|
|
QTest::newRow("match all") << QString("*.*") << std::optional<QString>();
|
2022-06-22 12:33:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void tst_LocalFileApi::fileExtensionFilterTransformation()
|
|
|
|
{
|
|
|
|
QFETCH(QString, qtFileFilter);
|
2022-09-23 13:27:50 +00:00
|
|
|
QFETCH(std::optional<QString>, expectedWebExtensionFilter);
|
2022-06-22 12:33:48 +00:00
|
|
|
|
|
|
|
auto result = LocalFileApi::Type::Accept::MimeType::Extension::fromQt(qtFileFilter);
|
|
|
|
if (expectedWebExtensionFilter) {
|
2022-09-23 13:27:50 +00:00
|
|
|
QCOMPARE_EQ(expectedWebExtensionFilter, result->value());
|
2022-06-22 12:33:48 +00:00
|
|
|
} else {
|
|
|
|
QVERIFY(!result.has_value());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void tst_LocalFileApi::acceptTransformation_data()
|
|
|
|
{
|
|
|
|
using namespace emscripten;
|
|
|
|
|
|
|
|
QTest::addColumn<QString>("qtFilterList");
|
2022-09-23 13:27:50 +00:00
|
|
|
QTest::addColumn<QStringList>("expectedExtensionList");
|
2022-06-22 12:33:48 +00:00
|
|
|
|
2022-09-23 13:27:50 +00:00
|
|
|
QTest::newRow("Multiple types")
|
|
|
|
<< QString("*.png *.other *.txt") << QStringList{ ".png", ".other", ".txt" };
|
2022-06-22 12:33:48 +00:00
|
|
|
|
2022-09-23 13:27:50 +00:00
|
|
|
QTest::newRow("Single type") << QString("*.png") << QStringList{ ".png" };
|
2022-06-22 12:33:48 +00:00
|
|
|
|
2022-09-23 13:27:50 +00:00
|
|
|
QTest::newRow("No filter when accepts all") << QString("*.*") << QStringList();
|
2022-06-22 12:33:48 +00:00
|
|
|
|
2022-09-23 13:27:50 +00:00
|
|
|
QTest::newRow("No filter when one filter accepts all") << QString("*.* *.jpg") << QStringList();
|
2022-06-22 12:33:48 +00:00
|
|
|
|
|
|
|
QTest::newRow("Weird spaces") << QString(" *.jpg *.png *.icon ")
|
2022-09-23 13:27:50 +00:00
|
|
|
<< QStringList{ ".jpg", ".png", ".icon" };
|
2022-06-22 12:33:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void tst_LocalFileApi::acceptTransformation()
|
|
|
|
{
|
|
|
|
QFETCH(QString, qtFilterList);
|
2022-09-23 13:27:50 +00:00
|
|
|
QFETCH(QStringList, expectedExtensionList);
|
2022-06-22 12:33:48 +00:00
|
|
|
|
|
|
|
auto result = LocalFileApi::Type::Accept::fromQt(qtFilterList);
|
2022-09-23 13:27:50 +00:00
|
|
|
if (expectedExtensionList.isEmpty()) {
|
2022-06-22 12:33:48 +00:00
|
|
|
QVERIFY(!result.has_value());
|
2022-09-23 13:27:50 +00:00
|
|
|
} else {
|
|
|
|
QStringList transformed;
|
|
|
|
std::transform(result->mimeType().extensions().begin(),
|
|
|
|
result->mimeType().extensions().end(), std::back_inserter(transformed),
|
|
|
|
[](const LocalFileApi::Type::Accept::MimeType::Extension &extension) {
|
|
|
|
return extension.value().toString();
|
|
|
|
});
|
|
|
|
QCOMPARE_EQ(expectedExtensionList, transformed);
|
2022-06-22 12:33:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void tst_LocalFileApi::typeTransformation_data()
|
|
|
|
{
|
|
|
|
using namespace emscripten;
|
|
|
|
|
|
|
|
QTest::addColumn<QString>("qtFilterList");
|
2022-09-23 13:27:50 +00:00
|
|
|
QTest::addColumn<QString>("expectedDescription");
|
|
|
|
QTest::addColumn<QStringList>("expectedExtensions");
|
2022-06-22 12:33:48 +00:00
|
|
|
|
2022-09-23 13:27:50 +00:00
|
|
|
QTest::newRow("With description")
|
|
|
|
<< QString("Text files (*.txt)") << QString("Text files") << QStringList{ ".txt" };
|
2022-06-22 12:33:48 +00:00
|
|
|
|
2022-09-23 13:27:50 +00:00
|
|
|
QTest::newRow("No description") << QString("*.jpg") << QString("") << QStringList{ ".jpg" };
|
2022-06-22 12:33:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void tst_LocalFileApi::typeTransformation()
|
|
|
|
{
|
|
|
|
QFETCH(QString, qtFilterList);
|
2022-09-23 13:27:50 +00:00
|
|
|
QFETCH(QString, expectedDescription);
|
|
|
|
QFETCH(QStringList, expectedExtensions);
|
2022-06-22 12:33:48 +00:00
|
|
|
|
|
|
|
auto result = LocalFileApi::Type::fromQt(qtFilterList);
|
2022-09-23 13:27:50 +00:00
|
|
|
QCOMPARE_EQ(result->description(), expectedDescription);
|
|
|
|
|
|
|
|
QStringList transformed;
|
|
|
|
std::transform(result->accept()->mimeType().extensions().begin(),
|
|
|
|
result->accept()->mimeType().extensions().end(), std::back_inserter(transformed),
|
|
|
|
[](const LocalFileApi::Type::Accept::MimeType::Extension &extension) {
|
|
|
|
return extension.value().toString();
|
|
|
|
});
|
|
|
|
QCOMPARE_EQ(expectedExtensions, transformed);
|
2022-06-22 12:33:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void tst_LocalFileApi::openFileOptions_data()
|
|
|
|
{
|
|
|
|
using namespace emscripten;
|
|
|
|
|
|
|
|
QTest::addColumn<QStringList>("qtFilterList");
|
|
|
|
QTest::addColumn<bool>("multiple");
|
|
|
|
QTest::addColumn<emscripten::val>("expectedWebType");
|
|
|
|
|
|
|
|
QTest::newRow("Multiple files") << QStringList({"Text files (*.txt)", "Images (*.jpg *.png)", "*.bat"})
|
|
|
|
<< true
|
|
|
|
<< makeOpenFileOptions(true, { makeType("Text files", { val(".txt")}), makeType("Images", { val(".jpg"), val(".png")}), makeType("", { val(".bat")})});
|
|
|
|
QTest::newRow("Single file") << QStringList({"Text files (*.txt)", "Images (*.jpg *.png)", "*.bat"})
|
|
|
|
<< false
|
|
|
|
<< makeOpenFileOptions(false, { makeType("Text files", { val(".txt")}), makeType("Images", { val(".jpg"), val(".png")}), makeType("", { val(".bat")})});
|
|
|
|
}
|
|
|
|
|
|
|
|
void tst_LocalFileApi::openFileOptions()
|
|
|
|
{
|
|
|
|
QFETCH(QStringList, qtFilterList);
|
|
|
|
QFETCH(bool, multiple);
|
|
|
|
QFETCH(emscripten::val, expectedWebType);
|
|
|
|
|
|
|
|
auto result = LocalFileApi::makeOpenFileOptions(qtFilterList, multiple);
|
|
|
|
QVERIFY(valDeepEquals(result, expectedWebType));
|
|
|
|
}
|
|
|
|
|
|
|
|
void tst_LocalFileApi::saveFileOptions_data()
|
|
|
|
{
|
|
|
|
using namespace emscripten;
|
|
|
|
|
|
|
|
QTest::addColumn<QStringList>("qtFilterList");
|
|
|
|
QTest::addColumn<QString>("suggestedName");
|
|
|
|
QTest::addColumn<emscripten::val>("expectedWebType");
|
|
|
|
|
|
|
|
QTest::newRow("Multiple files") << QStringList({"Text files (*.txt)", "Images (*.jpg *.png)", "*.bat"})
|
|
|
|
<< "someName1"
|
|
|
|
<< makeSaveFileOptions("someName1", { makeType("Text files", { val(".txt")}), makeType("Images", { val(".jpg"), val(".png")}), makeType("", { val(".bat")})});
|
|
|
|
QTest::newRow("Single file") << QStringList({"Text files (*.txt)", "Images (*.jpg *.png)", "*.bat"})
|
|
|
|
<< "some name 2"
|
|
|
|
<< makeSaveFileOptions("some name 2", { makeType("Text files", { val(".txt")}), makeType("Images", { val(".jpg"), val(".png")}), makeType("", { val(".bat")})});
|
|
|
|
}
|
|
|
|
|
|
|
|
void tst_LocalFileApi::saveFileOptions()
|
|
|
|
{
|
|
|
|
QFETCH(QStringList, qtFilterList);
|
|
|
|
QFETCH(QString, suggestedName);
|
|
|
|
QFETCH(emscripten::val, expectedWebType);
|
|
|
|
|
|
|
|
auto result = LocalFileApi::makeSaveFileOptions(qtFilterList, suggestedName.toStdString());
|
|
|
|
QVERIFY(valDeepEquals(result, expectedWebType));
|
|
|
|
}
|
|
|
|
|
2022-09-23 13:27:50 +00:00
|
|
|
void tst_LocalFileApi::fileInputAccept_data()
|
|
|
|
{
|
|
|
|
using namespace emscripten;
|
|
|
|
|
|
|
|
QTest::addColumn<QStringList>("qtFilterList");
|
|
|
|
QTest::addColumn<QString>("expectedAccept");
|
|
|
|
|
|
|
|
QTest::newRow("Multiple files")
|
|
|
|
<< QStringList{ "Text files (*.txt)", "Images (*.jpg *.png)", "*.bat" }
|
|
|
|
<< ".txt,.jpg,.png,.bat";
|
|
|
|
QTest::newRow("Spaces") << QStringList{ " Documents (*.doc)", "Everything (*.*)",
|
|
|
|
" Stuff ( *.stf *.tng)", " *.exe" }
|
|
|
|
<< ".doc,.stf,.tng,.exe";
|
|
|
|
}
|
|
|
|
|
|
|
|
void tst_LocalFileApi::fileInputAccept()
|
|
|
|
{
|
|
|
|
QFETCH(QStringList, qtFilterList);
|
|
|
|
QFETCH(QString, expectedAccept);
|
|
|
|
|
|
|
|
auto result = LocalFileApi::makeFileInputAccept(qtFilterList);
|
|
|
|
QCOMPARE_EQ(expectedAccept, QString::fromStdString(result));
|
|
|
|
}
|
|
|
|
|
2022-06-22 12:33:48 +00:00
|
|
|
QTEST_APPLESS_MAIN(tst_LocalFileApi)
|
|
|
|
#include "tst_localfileapi.moc"
|