Merge remote-tracking branch 'origin/7.0'

Conflicts:
	cmake/QtCreatorIDEBranding.cmake
	qbs/modules/qtc/qtc.qbs
	qtcreator_ide_branding.pri
	src/plugins/studiowelcome/recentpresets.h
	src/plugins/studiowelcome/userpresets.h

Change-Id: Ie573b945eb28347a36ee1b3582fbd6ab0c0f866c
This commit is contained in:
Eike Ziller
2022-03-28 15:10:11 +02:00
62 changed files with 974 additions and 880 deletions
@@ -17,14 +17,12 @@ add_qtc_test(tst_qml_wizard
SOURCES
wizardfactories-test.cpp
stylemodel-test.cpp
recentpresets-test.cpp
userpresets-test.cpp
presetmodel-test.cpp
test-utilities.h
test-main.cpp
"${StudioWelcomeDir}/wizardfactories.cpp"
"${StudioWelcomeDir}/stylemodel.cpp"
"${StudioWelcomeDir}/recentpresets.cpp"
"${StudioWelcomeDir}/userpresets.cpp"
"${StudioWelcomeDir}/presetmodel.cpp"
)
@@ -100,6 +100,14 @@ UserPresetData aUserPreset(const QString &categId, const QString &wizardName, co
return preset;
}
UserPresetData aRecentPreset(const QString &categId, const QString &wizardName, const QString &screenSizeName)
{
UserPresetData preset = aUserPreset(categId, wizardName, wizardName);
preset.screenSize = screenSizeName;
return preset;
}
MATCHER_P2(PresetIs, category, name, PrintToString(PresetItem{name, category}))
{
return arg->categoryId == category && arg->wizardName == name;
@@ -139,6 +147,7 @@ TEST(QdsPresetModel, haveSameArraySizeForPresetsAndCategories)
PresetData data;
data.setData(
/*wizard presets*/
{
aCategory("A.categ", "A", {"item a", "item b"}),
aCategory("B.categ", "B", {"item c", "item d"}),
@@ -157,6 +166,7 @@ TEST(QdsPresetModel, haveWizardPresetsNoRecents)
// When
data.setData(
/*wizard presets*/
{
aCategory("A.categ", "A", {"item a", "item b"}),
aCategory("B.categ", "B", {"item c", "item d"}),
@@ -179,6 +189,7 @@ TEST(QdsPresetModel, whenHaveUserPresetsButNoWizardPresetsReturnEmpty)
// When
data.setData({/*builtin presets*/},
/*user presets*/
{
aUserPreset("A.Mobile", "Scroll", "iPhone5"),
aUserPreset("B.Desktop", "Launcher", "MacBook"),
@@ -196,9 +207,10 @@ TEST(QdsPresetModel, haveRecentsNoWizardPresets)
data.setData({/*wizardPresets*/},
{/*user presets*/},
/*recent presets*/
{
{"A.categ", "Desktop", "640 x 480"},
{"B.categ", "Mobile", "800 x 600"},
aRecentPreset("A.categ", "Desktop", "640 x 480"),
aRecentPreset("B.categ", "Mobile", "800 x 600"),
});
ASSERT_THAT(data.categories(), IsEmpty());
@@ -220,8 +232,8 @@ TEST(QdsPresetModel, recentsAddedWithWizardPresets)
{/*user presets*/},
/*recents*/
{
{"A.categ", "Desktop", "800 x 600"},
{"B.categ", "Mobile", "640 x 480"},
aRecentPreset("A.categ", "Desktop", "800 x 600"),
aRecentPreset("B.categ", "Mobile", "640 x 480"),
});
// Then
@@ -247,6 +259,7 @@ TEST(QdsPresetModel, userPresetsAddedWithWizardPresets)
aCategory("A.categ", "A", {"Desktop", "item b"}),
aCategory("B.categ", "B", {"Mobile"}),
},
/*user presets*/
{
aUserPreset("A.categ", "Desktop", "Windows10"),
},
@@ -272,6 +285,7 @@ TEST(QdsPresetModel, doesNotAddUserPresetsOfNonExistingCategory)
{
aCategory("A.categ", "A", {"Desktop"}), // Only category "A.categ" exists
},
/*user presets*/
{
aUserPreset("Bad.Categ", "Desktop", "Windows8"), // Bad.Categ does not exist
},
@@ -293,6 +307,7 @@ TEST(QdsPresetModel, doesNotAddUserPresetIfWizardPresetItRefersToDoesNotExist)
{
aCategory("A.categ", "A", {"Desktop"}),
},
/*user presets*/
{
aUserPreset("B.categ", "BadWizard", "Tablet"), // BadWizard referenced does not exist
},
@@ -314,6 +329,7 @@ TEST(QdsPresetModel, userPresetWithSameNameAsWizardPreset)
{
aCategory("A.categ", "A", {"Desktop"}),
},
/*user presets*/
{
aUserPreset("A.categ", "Desktop", "Desktop"),
},
@@ -326,58 +342,7 @@ TEST(QdsPresetModel, userPresetWithSameNameAsWizardPreset)
ElementsAre(UserPresetIs("A.categ", "Desktop", "Desktop"))));
}
TEST(QdsPresetModel, recentOfUserPresetReferringToExistingWizardPreset)
{
// Given
PresetData data;
// When
data.setData(
/*wizard presets*/
{
aCategory("A.categ", "A", {"Desktop"}),
},
{
aUserPreset("A.categ", "Desktop", "Windows 7"),
},
/*recents*/
{
{"A.categ", "Windows 7", "200 x 300", /*is user*/true}
});
// Then
ASSERT_THAT(data.categories(), ElementsAre("Recents", "A", "Custom"));
ASSERT_THAT(data.presets(),
ElementsAre(ElementsAre(UserPresetIs("A.categ", "Desktop", "Windows 7")),
ElementsAre(PresetIs("A.categ", "Desktop")),
ElementsAre(UserPresetIs("A.categ", "Desktop", "Windows 7"))));
}
TEST(QdsPresetModel, recentOfUserPresetReferringToNonexistingWizardPreset)
{
// Given
PresetData data;
// When
data.setData(
/*wizard presets*/
{
aCategory("A.categ", "A", {"Desktop"}),
},
{
aUserPreset("A.categ", "Not-Desktop", "Windows 7"), // Non-existing Wizard Preset
},
/*recents*/
{
{"A.categ", "Windows 7", "200 x 300", /*is user*/true}
});
// Then
ASSERT_THAT(data.categories(), ElementsAre("A"));
ASSERT_THAT(data.presets(), ElementsAre(ElementsAre(PresetIs("A.categ", "Desktop"))));
}
TEST(QdsPresetModel, recentOfNonExistentUserPreset)
TEST(QdsPresetModel, recentOfNonExistentWizardPreset)
{
// Given
PresetData data;
@@ -391,7 +356,7 @@ TEST(QdsPresetModel, recentOfNonExistentUserPreset)
{/*user presets*/},
/*recents*/
{
{"A.categ", "Windows 7", "200 x 300", /*is user*/true}
aRecentPreset("A.categ", "Windows 7", "200 x 300")
});
// Then
@@ -415,9 +380,9 @@ TEST(QdsPresetModel, recentsShouldNotBeSorted)
{/*user presets*/},
/*recents*/
{
{"Z.categ", "Z.desktop", "200 x 300"},
{"B.categ", "Mobile", "200 x 300"},
{"A.categ", "Desktop", "200 x 300"},
aRecentPreset("Z.categ", "Z.desktop", "200 x 300"),
aRecentPreset("B.categ", "Mobile", "200 x 300"),
aRecentPreset("A.categ", "Desktop", "200 x 300"),
});
// Then
@@ -442,9 +407,9 @@ TEST(QdsPresetModel, recentsOfSameWizardProjectButDifferentSizesAreRecognizedAsD
{/*user presets*/},
/*recents*/
{
{"B.categ", "Mobile", "400 x 400"},
{"B.categ", "Mobile", "200 x 300"},
{"A.categ", "Desktop", "640 x 480"},
aRecentPreset("B.categ", "Mobile", "400 x 400"),
aRecentPreset("B.categ", "Mobile", "200 x 300"),
aRecentPreset("A.categ", "Desktop", "640 x 480"),
});
// Then
@@ -454,6 +419,35 @@ TEST(QdsPresetModel, recentsOfSameWizardProjectButDifferentSizesAreRecognizedAsD
PresetIs("A.categ", "Desktop", "640 x 480")));
}
TEST(QdsPresetModel, allowRecentsWithTheSameName)
{
// Given
PresetData data;
// When
data.setData(
/*wizard presets*/
{
aCategory("A.categ", "A", {"Desktop"}),
},
{/*user presets*/},
/*recents*/
{
/* NOTE: it is assumed recents with the same name and size have other fields that
* distinguishes them from one another. It is the responsibility of the caller, who
* calls data.setData() to make sure that the recents do not contain duplicates. */
aRecentPreset("A.categ", "Desktop", "200 x 300"),
aRecentPreset("A.categ", "Desktop", "200 x 300"),
aRecentPreset("A.categ", "Desktop", "200 x 300"),
});
// Then
ASSERT_THAT(data.presets()[0],
ElementsAre(PresetIs("A.categ", "Desktop"),
PresetIs("A.categ", "Desktop"),
PresetIs("A.categ", "Desktop")));
}
TEST(QdsPresetModel, outdatedRecentsAreNotShown)
{
// Given
@@ -469,8 +463,8 @@ TEST(QdsPresetModel, outdatedRecentsAreNotShown)
{/*user presets*/},
/*recents*/
{
{"B.categ", "NoLongerExists", "400 x 400"},
{"A.categ", "Desktop", "640 x 480"},
aRecentPreset("B.categ", "NoLongerExists", "400 x 400"),
aRecentPreset("A.categ", "Desktop", "640 x 480"),
});
// Then
@@ -1,303 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2022 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#include "test-utilities.h"
#include <QDir>
#include <QRandomGenerator>
#include <QTime>
#include "recentpresets.h"
#include "utils/filepath.h"
#include "utils/temporarydirectory.h"
using namespace StudioWelcome;
constexpr char GROUP_NAME[] = "RecentPresets";
constexpr char ITEMS[] = "Wizards";
namespace StudioWelcome {
void PrintTo(const RecentPresetData &recent, std::ostream *os)
{
*os << "{categId: " << recent.category << ", name: " << recent.presetName
<< ", size: " << recent.sizeName << ", isUser: " << recent.isUserPreset;
*os << "}";
}
} // namespace StudioWelcome
class QdsRecentPresets : public ::testing::Test
{
protected:
RecentPresetsStore aStoreWithRecents(const QStringList &items)
{
settings.beginGroup(GROUP_NAME);
settings.setValue(ITEMS, items);
settings.endGroup();
return RecentPresetsStore{&settings};
}
RecentPresetsStore aStoreWithOne(const QVariant &item)
{
settings.beginGroup(GROUP_NAME);
settings.setValue(ITEMS, item);
settings.endGroup();
return RecentPresetsStore{&settings};
}
protected:
Utils::TemporaryDirectory tempDir{"recentpresets-XXXXXX"};
QSettings settings{tempDir.filePath("test").toString(), QSettings::IniFormat};
private:
QString settingsPath;
};
/******************* TESTS *******************/
TEST_F(QdsRecentPresets, readFromEmptyStore)
{
RecentPresetsStore store{&settings};
std::vector<RecentPresetData> recents = store.fetchAll();
ASSERT_THAT(recents, IsEmpty());
}
TEST_F(QdsRecentPresets, readEmptyRecentPresets)
{
RecentPresetsStore store = aStoreWithOne("");
std::vector<RecentPresetData> recents = store.fetchAll();
ASSERT_THAT(recents, IsEmpty());
}
TEST_F(QdsRecentPresets, readOneRecentPresetAsList)
{
RecentPresetsStore store = aStoreWithRecents({"category/preset:640 x 480"});
std::vector<RecentPresetData> recents = store.fetchAll();
ASSERT_THAT(recents, ElementsAre(RecentPresetData("category", "preset", "640 x 480")));
}
TEST_F(QdsRecentPresets, readOneRecentPresetAsString)
{
RecentPresetsStore store = aStoreWithOne("category/preset:200 x 300");
std::vector<RecentPresetData> recents = store.fetchAll();
ASSERT_THAT(recents, ElementsAre(RecentPresetData("category", "preset", "200 x 300")));
}
TEST_F(QdsRecentPresets, readOneRecentUserPresetAsString)
{
RecentPresetsStore store = aStoreWithOne("category/[U]preset:200 x 300");
std::vector<RecentPresetData> recents = store.fetchAll();
ASSERT_THAT(recents, ElementsAre(RecentPresetData("category", "preset", "200 x 300", true)));
}
TEST_F(QdsRecentPresets, readBadRecentPresetAsString)
{
RecentPresetsStore store = aStoreWithOne("no_category_only_preset");
std::vector<RecentPresetData> recents = store.fetchAll();
ASSERT_THAT(recents, IsEmpty());
}
TEST_F(QdsRecentPresets, readBadRecentPresetAsInt)
{
RecentPresetsStore store = aStoreWithOne(32);
std::vector<RecentPresetData> recents = store.fetchAll();
ASSERT_THAT(recents, IsEmpty());
}
TEST_F(QdsRecentPresets, readBadRecentPresetsInList)
{
RecentPresetsStore store = aStoreWithRecents({
"bad1", // no category, no size
"categ/name:800 x 600", // good
"categ/bad2", //no size
"categ/bad3:", //no size
"categ 1/bad4:200 x 300", // category has space
"categ/bad5: 400 x 300", // size starts with space
"categ/bad6:400", // bad size
"categ/[U]user:300 x 200", // good
"categ/[u]user2:300 x 200", // small cap "U"
"categ/[x]user3:300 x 200", // must be letter "U"
"categ/[U] user4:300 x 200", // space
});
std::vector<RecentPresetData> recents = store.fetchAll();
ASSERT_THAT(recents,
ElementsAre(RecentPresetData("categ", "name", "800 x 600", false),
RecentPresetData("categ", "user", "300 x 200", true)));
}
TEST_F(QdsRecentPresets, readTwoRecentPresets)
{
RecentPresetsStore store = aStoreWithRecents(
{"category_1/preset 1:640 x 480", "category_2/preset 2:320 x 200"});
std::vector<RecentPresetData> recents = store.fetchAll();
ASSERT_THAT(recents,
ElementsAre(RecentPresetData("category_1", "preset 1", "640 x 480"),
RecentPresetData("category_2", "preset 2", "320 x 200")));
}
TEST_F(QdsRecentPresets, readRecentsToDifferentKindsOfPresets)
{
RecentPresetsStore store = aStoreWithRecents(
{"category_1/preset 1:640 x 480", "category_2/[U]preset 2:320 x 200"});
std::vector<RecentPresetData> recents = store.fetchAll();
ASSERT_THAT(recents,
ElementsAre(RecentPresetData("category_1", "preset 1", "640 x 480", false),
RecentPresetData("category_2", "preset 2", "320 x 200", true)));
}
TEST_F(QdsRecentPresets, addFirstRecentPreset)
{
RecentPresetsStore store{&settings};
store.add("A.Category", "Normal Application", "400 x 600");
std::vector<RecentPresetData> recents = store.fetchAll();
ASSERT_THAT(recents, ElementsAre(RecentPresetData("A.Category", "Normal Application", "400 x 600")));
}
TEST_F(QdsRecentPresets, addFirstRecentUserPreset)
{
RecentPresetsStore store{&settings};
store.add("A.Category", "Normal Application", "400 x 600", /*user preset*/ true);
std::vector<RecentPresetData> recents = store.fetchAll();
ASSERT_THAT(recents,
ElementsAre(RecentPresetData("A.Category", "Normal Application", "400 x 600", true)));
}
TEST_F(QdsRecentPresets, addExistingFirstRecentPreset)
{
RecentPresetsStore store = aStoreWithRecents({"category/preset:200 x 300"});
ASSERT_THAT(store.fetchAll(), ElementsAre(RecentPresetData("category", "preset", "200 x 300")));
store.add("category", "preset", "200 x 300");
std::vector<RecentPresetData> recents = store.fetchAll();
ASSERT_THAT(recents, ElementsAre(RecentPresetData("category", "preset", "200 x 300")));
}
TEST_F(QdsRecentPresets, addRecentUserPresetWithSameNameAsExistingRecentNormalPreset)
{
RecentPresetsStore store = aStoreWithRecents({"category/preset:200 x 300"});
ASSERT_THAT(store.fetchAll(), ElementsAre(RecentPresetData("category", "preset", "200 x 300")));
store.add("category", "preset", "200 x 300", /*user preset*/ true);
std::vector<RecentPresetData> recents = store.fetchAll();
ASSERT_THAT(recents,
ElementsAre(RecentPresetData("category", "preset", "200 x 300", true),
RecentPresetData("category", "preset", "200 x 300", false)));
}
TEST_F(QdsRecentPresets, addSecondRecentPreset)
{
RecentPresetsStore store = aStoreWithRecents({"A.Category/Preset 1:800 x 600"});
store.add("A.Category", "Preset 2", "640 x 480");
std::vector<RecentPresetData> recents = store.fetchAll();
ASSERT_THAT(recents,
ElementsAre(RecentPresetData("A.Category", "Preset 2", "640 x 480"),
RecentPresetData("A.Category", "Preset 1", "800 x 600")));
}
TEST_F(QdsRecentPresets, addSecondRecentPresetSameKindButDifferentSize)
{
RecentPresetsStore store = aStoreWithRecents({"A.Category/Preset:800 x 600"});
store.add("A.Category", "Preset", "640 x 480");
std::vector<RecentPresetData> recents = store.fetchAll();
ASSERT_THAT(recents,
ElementsAre(RecentPresetData("A.Category", "Preset", "640 x 480"),
RecentPresetData("A.Category", "Preset", "800 x 600")));
}
TEST_F(QdsRecentPresets, fetchesRecentPresetsInTheReverseOrderTheyWereAdded)
{
RecentPresetsStore store{&settings};
store.add("A.Category", "Preset 1", "640 x 480");
store.add("A.Category", "Preset 2", "640 x 480");
store.add("A.Category", "Preset 3", "800 x 600");
std::vector<RecentPresetData> recents = store.fetchAll();
ASSERT_THAT(recents,
ElementsAre(RecentPresetData("A.Category", "Preset 3", "800 x 600"),
RecentPresetData("A.Category", "Preset 2", "640 x 480"),
RecentPresetData("A.Category", "Preset 1", "640 x 480")));
}
TEST_F(QdsRecentPresets, addingAnExistingRecentPresetMakesItTheFirst)
{
RecentPresetsStore store = aStoreWithRecents({"A.Category/Preset 1:200 x 300",
"A.Category/Preset 2:200 x 300",
"A.Category/Preset 3:640 x 480"});
store.add("A.Category", "Preset 3", "640 x 480");
std::vector<RecentPresetData> recents = store.fetchAll();
ASSERT_THAT(recents,
ElementsAre(RecentPresetData("A.Category", "Preset 3", "640 x 480"),
RecentPresetData("A.Category", "Preset 1", "200 x 300"),
RecentPresetData("A.Category", "Preset 2", "200 x 300")));
}
TEST_F(QdsRecentPresets, addingTooManyRecentPresetsRemovesTheOldestOne)
{
RecentPresetsStore store = aStoreWithRecents(
{"A.Category/Preset 2:200 x 300", "A.Category/Preset 1:200 x 300"});
store.setMaximum(2);
store.add("A.Category", "Preset 3", "200 x 300");
std::vector<RecentPresetData> recents = store.fetchAll();
ASSERT_THAT(recents,
ElementsAre(RecentPresetData("A.Category", "Preset 3", "200 x 300"),
RecentPresetData("A.Category", "Preset 2", "200 x 300")));
}
@@ -29,6 +29,10 @@
#include <utils/filepath.h>
#include <utils/temporarydirectory.h>
#include <QJsonArray>
#include <QJsonObject>
#include <QJsonDocument>
namespace StudioWelcome {
void PrintTo(const UserPresetData &preset, std::ostream *os)
@@ -64,69 +68,85 @@ using namespace StudioWelcome;
constexpr char ARRAY_NAME[] = "UserPresets";
class FakeStoreIo : public StoreIo
{
public:
QByteArray read() const override
{
return data.toUtf8();
}
void write(const QByteArray &bytes) override
{
data = bytes;
}
QString data;
};
class QdsUserPresets : public ::testing::Test
{
protected:
void SetUp()
{
settings = std::make_unique<QSettings>(tempDir.filePath("test").toString(),
QSettings::IniFormat);
storeIo = std::make_unique<FakeStoreIo>();
}
UserPresetsStore anEmptyStore() { return UserPresetsStore{std::move(settings)}; }
UserPresetsStore anEmptyStore()
{
return UserPresetsStore{std::move(storeIo), StorePolicy::UniqueNames};
}
UserPresetsStore aStoreWithZeroItems()
{
settings->beginWriteArray(ARRAY_NAME, 0);
settings->endArray();
storeIo->data = "[]";
return UserPresetsStore{std::move(settings)};
return UserPresetsStore{std::move(storeIo), StorePolicy::UniqueNames};
}
UserPresetsStore aStoreWithOne(const UserPresetData &preset)
UserPresetsStore aStoreWithOne(const UserPresetData &preset,
StorePolicy policy = StorePolicy::UniqueNames)
{
settings->beginWriteArray(ARRAY_NAME, 1);
settings->setArrayIndex(0);
QJsonArray array({QJsonObject{{"categoryId", preset.categoryId},
{"wizardName", preset.wizardName},
{"name", preset.name},
{"screenSize", preset.screenSize},
{"useQtVirtualKeyboard", preset.useQtVirtualKeyboard},
{"qtVersion", preset.qtVersion},
{"styleName", preset.styleName}}});
QJsonDocument doc{array};
storeIo->data = doc.toJson();
settings->setValue("categoryId", preset.categoryId);
settings->setValue("wizardName", preset.wizardName);
settings->setValue("name", preset.name);
settings->setValue("screenSize", preset.screenSize);
settings->setValue("useQtVirtualKeyboard", preset.useQtVirtualKeyboard);
settings->setValue("qtVersion", preset.qtVersion);
settings->setValue("styleName", preset.styleName);
settings->endArray();
return UserPresetsStore{std::move(settings)};
return UserPresetsStore{std::move(storeIo), policy};
}
UserPresetsStore aStoreWithPresets(const std::vector<UserPresetData> &presets)
UserPresetsStore aStoreWithPresets(const std::vector<UserPresetData> &presetItems)
{
settings->beginWriteArray(ARRAY_NAME, presets.size());
QJsonArray array;
for (size_t i = 0; i < presets.size(); ++i) {
settings->setArrayIndex(i);
const auto &preset = presets[i];
for (const auto &preset : presetItems) {
QJsonObject obj({{"categoryId", preset.categoryId},
{"wizardName", preset.wizardName},
{"name", preset.name},
{"screenSize", preset.screenSize},
{"useQtVirtualKeyboard", preset.useQtVirtualKeyboard},
{"qtVersion", preset.qtVersion},
{"styleName", preset.styleName}});
settings->setValue("categoryId", preset.categoryId);
settings->setValue("wizardName", preset.wizardName);
settings->setValue("name", preset.name);
settings->setValue("screenSize", preset.screenSize);
settings->setValue("useQtVirtualKeyboard", preset.useQtVirtualKeyboard);
settings->setValue("qtVersion", preset.qtVersion);
settings->setValue("styleName", preset.styleName);
array.append(QJsonValue{obj});
}
settings->endArray();
return UserPresetsStore{std::move(settings)};
QJsonDocument doc{array};
storeIo->data = doc.toJson();
return UserPresetsStore{std::move(storeIo), StorePolicy::UniqueNames};
}
Utils::TemporaryDirectory tempDir{"userpresets-XXXXXX"};
std::unique_ptr<QSettings> settings;
std::unique_ptr<FakeStoreIo> storeIo;
private:
QString settingsPath;
QString storeIoPath;
};
/******************* TESTS *******************/
@@ -234,10 +254,10 @@ TEST_F(QdsUserPresets, saveIncompletePreset)
ASSERT_THAT(presets, ElementsAre(preset));
}
TEST_F(QdsUserPresets, cannotSavePresetWithSameName)
TEST_F(QdsUserPresets, cannotSavePresetWithSameNameForUniqueNamesPolicy)
{
UserPresetData existing{"B.categ", "3D App", "Same Name", "400 x 20", true, "Qt 5", "Material Dark"};
auto store = aStoreWithOne(existing);
auto store = aStoreWithOne(existing, StorePolicy::UniqueNames);
UserPresetData newPreset{"C.categ", "Empty", "Same Name", "100 x 30", false, "Qt 6", "Fusion"};
bool saved = store.save(newPreset);
@@ -246,6 +266,30 @@ TEST_F(QdsUserPresets, cannotSavePresetWithSameName)
ASSERT_THAT(store.fetchAll(), ElementsAreArray({existing}));
}
TEST_F(QdsUserPresets, canSavePresetWithSameNameForUniqueValuesPolicy)
{
UserPresetData existing{"B.categ", "3D App", "Same Name", "400 x 20", true, "Qt 5", "Material Dark"};
auto store = aStoreWithOne(existing, StorePolicy::UniqueValues);
// NOTE: only Style is different
UserPresetData newPreset{"B.categ", "3D App", "Same Name", "400 x 20", true, "Qt 5", "Fusion"};
bool saved = store.save(newPreset);
ASSERT_TRUE(saved);
ASSERT_THAT(store.fetchAll(), ElementsAreArray({existing, newPreset}));
}
TEST_F(QdsUserPresets, cannotSaveExactCopyForUniqueValuesPolicy)
{
UserPresetData existing{"B.categ", "3D App", "Same Name", "400 x 20", true, "Qt 5", "Material Dark"};
auto store = aStoreWithOne(existing, StorePolicy::UniqueNames);
bool saved = store.save(existing);
ASSERT_FALSE(saved);
ASSERT_THAT(store.fetchAll(), ElementsAreArray({existing}));
}
TEST_F(QdsUserPresets, saveNewPreset)
{
UserPresetData existing{"A.categ", "3D App", "iPhone7", "400 x 20", true, "Qt 5", "Material Dark"};
@@ -258,6 +302,54 @@ TEST_F(QdsUserPresets, saveNewPreset)
ASSERT_THAT(presets, ElementsAre(existing, newPreset));
}
TEST_F(QdsUserPresets, canLimitPresetsToAMaximum)
{
std::vector<UserPresetData> existing{
{"A.categ", "AppA", "iPhone7", "400 x 20", true, "Qt 5", "Material Dark"},
{"B.categ", "AppB", "iPhone7", "400 x 20", true, "Qt 5", "Material Dark"},
{"C.categ", "AppC", "iPhone7", "400 x 20", true, "Qt 5", "Material Dark"},
};
auto store = aStoreWithPresets(existing);
store.setMaximum(3);
UserPresetData newPreset{"D.categ", "AppD", "Huawei", "100 x 30", true, "Qt 6", "Fusion"};
store.save(newPreset);
auto presets = store.fetchAll();
ASSERT_THAT(presets, ElementsAre(existing[1], existing[2], newPreset));
}
TEST_F(QdsUserPresets, canLimitPresetsToAMaximumForReverseOrder)
{
std::vector<UserPresetData> existing{
{"A.categ", "AppA", "iPhone7", "400 x 20", true, "Qt 5", "Material Dark"},
{"B.categ", "AppB", "iPhone7", "400 x 20", true, "Qt 5", "Material Dark"},
{"C.categ", "AppC", "iPhone7", "400 x 20", true, "Qt 5", "Material Dark"},
};
auto store = aStoreWithPresets(existing);
store.setMaximum(3);
store.setReverseOrder();
UserPresetData newPreset{"D.categ", "AppD", "Huawei", "100 x 30", true, "Qt 6", "Fusion"};
store.save(newPreset);
auto presets = store.fetchAll();
ASSERT_THAT(presets, ElementsAre(newPreset, existing[0], existing[1]));
}
TEST_F(QdsUserPresets, canSavePresetsInReverseOrder)
{
UserPresetData existing{"A.categ", "3D App", "iPhone7", "400 x 20", true, "Qt 5", "Material Dark"};
auto store = aStoreWithOne(existing, StorePolicy::UniqueNames);
store.setReverseOrder();
UserPresetData newPreset{"A.categ", "Empty", "Huawei", "100 x 30", true, "Qt 6", "Fusion"};
store.save(newPreset);
auto presets = store.fetchAll();
ASSERT_THAT(presets, ElementsAre(newPreset, existing));
}
TEST_F(QdsUserPresets, removeUserPresetFromEmptyStore)
{
UserPresetData preset{"C.categ", "2D App", "Android", "", false, "", ""};
+3 -3
View File
@@ -46,11 +46,11 @@ class Targets:
"Desktop 5.14.1 default"]))
@staticmethod
def availableTargetClasses():
def availableTargetClasses(ignoreValidity=False):
availableTargets = set(Targets.ALL_TARGETS)
if not qt4Available:
if not qt4Available and not ignoreValidity:
availableTargets.remove(Targets.DESKTOP_4_8_7_DEFAULT)
if not qt4Available or platform.system() in ('Windows', 'Microsoft'):
if not (qt4Available or ignoreValidity) or platform.system() in ('Windows', 'Microsoft'):
availableTargets.remove(Targets.EMBEDDED_LINUX)
elif platform.system() == 'Darwin':
availableTargets.remove(Targets.DESKTOP_5_4_1_GCC)
+11 -6
View File
@@ -207,7 +207,7 @@ def __verifyFileCreation__(path, expectedFiles):
def __modifyAvailableTargets__(available, requiredQt, asStrings=False):
versionFinder = re.compile("^Desktop (\\d{1}\.\\d{1,2}\.\\d{1,2}).*$")
tmp = list(available) # we need a deep copy
if Qt5Path.toVersionTuple(requiredQt) > (4,8,7):
if Qt5Path.toVersionTuple(requiredQt) > (4,8,7) and qt4Available:
toBeRemoved = Targets.EMBEDDED_LINUX
if asStrings:
toBeRemoved = Targets.getStringForTarget(toBeRemoved)
@@ -221,6 +221,8 @@ def __modifyAvailableTargets__(available, requiredQt, asStrings=False):
if found:
if Qt5Path.toVersionTuple(found.group(1)) < Qt5Path.toVersionTuple(requiredQt):
available.discard(currentItem)
elif currentItem.endswith(" (invalid)"):
available.discard(currentItem)
def __getProjectFileName__(projectName, buildSystem):
if buildSystem is None or buildSystem == "CMake":
@@ -523,7 +525,9 @@ def __closeSubprocessByPushingStop__(isQtQuickUI):
# configured Qt versions and Toolchains and cannot be looked up the same way
# if you set getAsStrings to True this function returns a list of strings instead
# of the constants defined in Targets
def __getSupportedPlatforms__(text, templateName, getAsStrings=False):
# ignoreValidity if true kits will be considered available even if they are configured
# to use an invalid Qt
def __getSupportedPlatforms__(text, templateName, getAsStrings=False, ignoreValidity=False):
reqPattern = re.compile("requires qt (?P<version>\d+\.\d+(\.\d+)?)", re.IGNORECASE)
res = reqPattern.search(text)
if res:
@@ -536,11 +540,12 @@ def __getSupportedPlatforms__(text, templateName, getAsStrings=False):
supports = text[text.find('Supported Platforms'):].split(":")[1].strip().split("\n")
result = set()
if 'Desktop' in supports:
if (version == None or version < "5.0") and not templateName.startswith("Qt Quick 2"):
if qt4Available:
if (version == None or version < "5.0") and not templateName.startswith("Qt Quick"):
neverIgnoreValidity = templateName in ("Qt Custom Designer Widget", "Code Snippet", "Subdirs Project")
if qt4Available or ignoreValidity and not neverIgnoreValidity:
result.add(Targets.DESKTOP_4_8_7_DEFAULT)
if platform.system() in ("Linux", "Darwin"):
result.add(Targets.EMBEDDED_LINUX)
if platform.system() in ("Linux", "Darwin"):
result.add(Targets.EMBEDDED_LINUX)
result = result.union(set([Targets.DESKTOP_5_10_1_DEFAULT, Targets.DESKTOP_5_14_1_DEFAULT]))
if platform.system() != 'Darwin':
result.add(Targets.DESKTOP_5_4_1_GCC)
+3
View File
@@ -366,6 +366,9 @@ def getConfiguredKits():
def __setQtVersionForKit__(kit, kitName, kitsQtVersionName):
mouseClick(waitForObjectItem(":BuildAndRun_QTreeView", kit))
qtVersionStr = str(waitForObjectExists(":Kits_QtVersion_QComboBox").currentText)
invalid = qtVersionStr.endswith(" (invalid)")
if invalid:
qtVersionStr = qtVersionStr[:-10]
kitsQtVersionName[kitName] = qtVersionStr
# end of internal function for iterate kits
+5 -5
View File
@@ -1,6 +1,6 @@
############################################################################
#
# Copyright (C) 2016 The Qt Company Ltd.
# Copyright (C) 2022 The Qt Company Ltd.
# Contact: https://www.qt.io/licensing/
#
# This file is part of Qt Creator.
@@ -93,8 +93,8 @@ def main():
example = findExampleOrTutorial(listView, ".*", True)
test.verify(example is None, "Verifying: No example is shown.")
proFiles = map(lambda p: os.path.join(p, "opengl", "2dpainting", "2dpainting.pro"),
Qt5Path.getPaths(Qt5Path.EXAMPLES))
proFiles = [os.path.join(p, "opengl", "2dpainting", "2dpainting.pro")
for p in Qt5Path.getPaths(Qt5Path.EXAMPLES)]
cleanUpUserFiles(proFiles)
for p in proFiles:
removePackagingDirectory(os.path.dirname(p))
@@ -115,8 +115,8 @@ def main():
# go to "Welcome" page and choose another example
switchViewTo(ViewConstants.WELCOME)
proFiles = map(lambda p: os.path.join(p, "widgets", "itemviews", "addressbook", "addressbook.pro"),
Qt5Path.getPaths(Qt5Path.EXAMPLES))
proFiles = [os.path.join(p, "widgets", "itemviews", "addressbook", "addressbook.pro")
for p in Qt5Path.getPaths(Qt5Path.EXAMPLES)]
cleanUpUserFiles(proFiles)
for p in proFiles:
removePackagingDirectory(os.path.dirname(p))
@@ -156,7 +156,7 @@ def __createProject__(category, template):
origTxt = safeGetTextBrowserText()
mouseClick(waitForObjectItem(templatesView, template))
waitFor("origTxt != safeGetTextBrowserText() != ''", 2000)
displayedPlatforms = __getSupportedPlatforms__(safeGetTextBrowserText(), template, True)[0]
displayedPlatforms = __getSupportedPlatforms__(safeGetTextBrowserText(), template, True, True)[0]
safeClickButton("Choose...")
# don't check because project could exist
__createProjectSetNameAndPath__(os.path.expanduser("~"), 'untitled', False)
@@ -54,9 +54,9 @@ def main():
startQC()
if not startedWithoutPluginError():
return
createProject_Qt_Console(tempDir(), "SquishProject")
createProject_Qt_Console(tempDir(), "SquishProject", buildSystem = "qmake")
switchViewTo(ViewConstants.PROJECTS)
verifyProjectsMode(Targets.getTargetsAsStrings(Targets.availableTargetClasses()))
verifyProjectsMode(Targets.getTargetsAsStrings(Targets.availableTargetClasses(True)))
iterateKits(True, False, __removeKit__)
clickButton(waitForObject(":Options.OK_QPushButton"))
verifyProjectsMode([])
@@ -165,7 +165,7 @@ def main():
startQC()
if not startedWithoutPluginError():
return
createProject_Qt_GUI(srcPath, projectName, addToVersionControl = "Git")
createProject_Qt_GUI(srcPath, projectName, addToVersionControl = "Git", buildSystem = "qmake")
openVcsLog()
vcsLog = waitForObject("{type='Core::OutputWindow' unnamed='1' visible='1' "
"window=':Qt Creator_Core::Internal::MainWindow'}").plainText